Add %E, %I, and %M formats.
authorRonald G. Minnich <rminnich@google.com>
Wed, 22 Jan 2014 17:24:48 +0000 (09:24 -0800)
committerRonald G. Minnich <rminnich@google.com>
Wed, 22 Jan 2014 17:24:48 +0000 (09:24 -0800)
%E will print an enet mac.

%I will take a uint8_t * and figure out what kind of address
it is and print it. %M does that for masks.

Signed-off-by: Ronald G. Minnich <rminnich@google.com>
kern/include/stdio.h
kern/src/net/Kbuild
kern/src/net/eipconv.c [new file with mode: 0644]
kern/src/net/eipconvtest.c [deleted file]
kern/src/net/ipaux.c
kern/src/printfmt.c

index 67b6e93..4f61246 100644 (file)
@@ -52,4 +52,10 @@ int  vfprintf(int fd, const char *NTS fmt, va_list);
 int readline(char *buf, size_t buf_l, const char *prompt, ...);
 
 char *seprintf(char *buf, char *end, const char *fmt, ...);
+
+// kern/src/net/eipconv.c
+void printemac(void (*putch)(int, void**), void **putdat, uint8_t *mac);
+void printip(void (*putch)(int, void**), void **putdat, uint8_t *ip);
+void printipmask(void (*putch)(int, void**), void **putdat, uint8_t *ip);
+
 #endif /* !ROS_INC_STDIO_H */
index aaa1d38..a87bfdc 100644 (file)
@@ -2,6 +2,7 @@ obj-y                                           += arp.o
 #obj-y                                         += compress.o
 obj-y                                          += devip.o
 obj-y                                          += dial.o
+obj-y                                          += eipconv.o
 obj-y                                          += ethermedium.o
 obj-y                                          += icmp.o
 obj-y                                          += icmp6.o
diff --git a/kern/src/net/eipconv.c b/kern/src/net/eipconv.c
new file mode 100644 (file)
index 0000000..b69ead6
--- /dev/null
@@ -0,0 +1,143 @@
+// INFERNO
+#include <vfs.h>
+#include <kfs.h>
+#include <slab.h>
+#include <kmalloc.h>
+#include <kref.h>
+#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+#include <error.h>
+#include <cpio.h>
+#include <pmap.h>
+#include <smp.h>
+#include <ip.h>
+
+enum {
+       Isprefix = 16,
+};
+
+uint8_t prefixvals[256] = {
+       [0x00] 0 | Isprefix,
+       [0x80] 1 | Isprefix,
+       [0xC0] 2 | Isprefix,
+       [0xE0] 3 | Isprefix,
+       [0xF0] 4 | Isprefix,
+       [0xF8] 5 | Isprefix,
+       [0xFC] 6 | Isprefix,
+       [0xFE] 7 | Isprefix,
+       [0xFF] 8 | Isprefix,
+};
+
+static char *efmt = "0x%.2lx0x%.2lx0x%.2lx0x%.2lx0x%.2lx0x%.2lx";
+static char *ifmt = "%d.%d.%d.%d";
+
+void printemac(void (*putch)(int, void**), void **putdat, uint8_t *mac)
+{
+       printfmt(putch, putdat, efmt, mac[0], mac[1], mac[2], mac[3], mac[4],
+                                        mac[5]);
+}
+
+void printip(void (*putch)(int, void**), void **putdat, uint8_t *ip)
+{
+       int i, j, eln, eli;
+       uint16_t s;
+       if (memcmp(ip, v4prefix, 12) == 0)
+               printfmt(putch, putdat, ifmt, ip[12], ip[13], ip[14], ip[15]);
+       else {
+               /* find longest elision */
+               eln = eli = -1;
+               for (i = 0; i < 16; i += 2) {
+                       for (j = i; j < 16; j += 2)
+                               if (ip[j] != 0 || ip[j + 1] != 0)
+                                       break;
+                       if (j > i && j - i > eln) {
+                               eli = i;
+                               eln = j - i;
+                       }
+               }
+
+               /* print with possible elision */
+               for (i = 0; i < 16; i += 2) {
+                       if (i == eli) {
+                               /* not sure what to do ... we don't get
+                                * the number of bytes back from printing.
+                                */
+                               printfmt(putch, putdat, "::");
+                               i += eln;
+                               if (i >= 16)
+                                       break;
+                       } else if (i != 0)
+                               printfmt(putch, putdat, ":");
+
+                       s = (ip[i] << 8) + ip[i + 1];
+                       printfmt(putch, putdat, "0x%x", s);
+               }
+       }
+}
+
+/* what format to use? */
+#if 0
+case 'i':      /* v6 address as 4 longs */
+                       lp = va_arg(ap, uint32_t *);
+                       for (i = 0; i < 4; i++)
+                               hnputl(ip + 4 * i, *lp++);
+                       p = ip;
+                       goto common;
+
+               case 'V':       /* v4 ip address */
+                       p = va_arg(ap, uint8_t *);
+                       printfmt(putch, putdat, ifmt, p[0], p[1], p[2], p[3]);
+                       break;
+#endif
+
+void printipmask(void (*putch)(int, void**), void **putdat, uint8_t *ip)
+{
+       int i, j, n;
+       /* look for a prefix mask */
+       for (i = 0; i < 16; i++)
+               if (ip[i] != 0xff)
+                       break;
+       if (i < 16) {
+               if ((prefixvals[ip[i]] & Isprefix) == 0){
+                       printip(putch, putdat, ip);
+                       return;
+               }
+               for (j = i + 1; j < 16; j++)
+                       if (ip[j] != 0){
+                               printip(putch, putdat, ip);
+                               return;
+                       }
+               n = 8 * i + (prefixvals[ip[i]] & ~Isprefix);
+       } else
+               n = 8 * 16;
+
+       /* got one, use /xx format */
+       printfmt(putch, putdat, "/%d", n);
+}
+
+static uint8_t testvec[11][16] = {
+       {0,0,0,0,0,0,0,0,0,0,0xff,0xff,1,3,4,5,} ,
+       {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,} ,
+       {0xff,0xff,0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,} ,
+       {0xff,0xff,0xff,0xc0,0,0,0,0,0,0,0,0,0,0,0,0,} ,
+       {0xff,0xff,0xff,0xff,0xe0,0,0,0,0,0,0,0,0,0,0,0,} ,
+       {0xff,0xff,0xff,0xff,0xff,0xf0,0,0,0,0,0,0,0,0,0,0,} ,
+       {0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0,0,0,0,0,0,0,0,0,} ,
+       {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,} ,
+       {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,} ,
+       {0,0,0,0,0,0x11,0,0,0,0,0,0,0,0,0,0,} ,
+       {0,0,0,0x11,0,0,0,0,0,0,0,0,0,0,0,0x12,} ,
+};
+
+/* handy dandy test function. When in doubt, you can call this from the monitor.
+ * I doubt we want this long term.
+ * Google 'remove before flight'.
+ */
+void testeip(void)
+{
+       int i;
+       for (i = 0; i < 11; i++)
+               printk("%I\n", &testvec[i]);
+
+}
diff --git a/kern/src/net/eipconvtest.c b/kern/src/net/eipconvtest.c
deleted file mode 100644 (file)
index 03a5e5c..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-// INFERNO
-#if 0
-#include <vfs.h>
-#include <kfs.h>
-#include <slab.h>
-#include <kmalloc.h>
-#include <kref.h>
-#include <string.h>
-#include <stdio.h>
-#include <assert.h>
-#include <error.h>
-#include <cpio.h>
-#include <pmap.h>
-#include <smp.h>
-#include <ip.h>
-#endif
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <stdarg.h>
-#include <string.h>
-
-typedef unsigned char uint8_t;
-typedef unsigned short uint16_t;
-typedef unsigned long uint32_t;
-
-enum {
-       Isprefix = 16,
-};
-
-uint8_t prefixvals[256] = {
-       [0x00] 0 | Isprefix,
-       [0x80] 1 | Isprefix,
-       [0xC0] 2 | Isprefix,
-       [0xE0] 3 | Isprefix,
-       [0xF0] 4 | Isprefix,
-       [0xF8] 5 | Isprefix,
-       [0xFC] 6 | Isprefix,
-       [0xFE] 7 | Isprefix,
-       [0xFF] 8 | Isprefix,
-};
-
-uint8_t v4prefix[16] = {
-       0, 0, 0, 0,
-       0, 0, 0, 0,
-       0, 0, 0xff, 0xff,
-       0, 0, 0, 0
-};
-
-void hnputl(void *p, uint32_t v)
-{
-       uint8_t *a;
-
-       a = p;
-       a[0] = v >> 24;
-       a[1] = v >> 16;
-       a[2] = v >> 8;
-       a[3] = v;
-}
-
-char *eipconv(int fmt, ...)
-{
-       va_list ap;
-       static char buf[8 * 5];
-       static char *efmt = "0x%.2lx0x%.2lx0x%.2lx0x%.2lx0x%.2lx0x%.2lx";
-       static char *ifmt = "%d.%d.%d.%d";
-       uint8_t *p, ip[16];
-       uint32_t *lp;
-       uint16_t s;
-       int i, j, n, eln, eli;
-       va_start(ap, fmt);
-       switch (fmt) {
-               case 'E':       /* Ethernet address */
-                       p = va_arg(ap, uint8_t *);
-                       snprintf(buf, sizeof(buf), efmt, p[0], p[1], p[2], p[3], p[4],
-                                        p[5]);
-                       break;
-               case 'I':       /* Ip address */
-                       p = va_arg(ap, uint8_t *);
-common:
-                       if (memcmp(p, v4prefix, 12) == 0)
-                               snprintf(buf, sizeof(buf), ifmt, p[12], p[13], p[14], p[15]);
-                       else {
-                               /* find longest elision */
-                               eln = eli = -1;
-                               for (i = 0; i < 16; i += 2) {
-                                       for (j = i; j < 16; j += 2)
-                                               if (p[j] != 0 || p[j + 1] != 0)
-                                                       break;
-                                       if (j > i && j - i > eln) {
-                                               eli = i;
-                                               eln = j - i;
-                                       }
-                               }
-
-                               /* print with possible elision */
-                               n = 0;
-                               for (i = 0; i < 16; i += 2) {
-                                       if (i == eli) {
-                                               n += snprintf(buf, sizeof(buf) + n, "::");
-                                               i += eln;
-                                               if (i >= 16)
-                                                       break;
-                                       } else if (i != 0)
-                                               n += snprintf(buf, sizeof(buf) + n, ":");
-                                       s = (p[i] << 8) + p[i + 1];
-                                       n += snprintf(buf, sizeof(buf) + n, "0x%x", s);
-                               }
-                       }
-                       break;
-               case 'i':       /* v6 address as 4 longs */
-                       lp = va_arg(ap, uint32_t *);
-                       for (i = 0; i < 4; i++)
-                               hnputl(ip + 4 * i, *lp++);
-                       p = ip;
-                       goto common;
-               case 'V':       /* v4 ip address */
-                       p = va_arg(ap, uint8_t *);
-                       snprintf(buf, sizeof(buf), ifmt, p[0], p[1], p[2], p[3]);
-                       break;
-               case 'M':       /* ip mask */
-                       p = va_arg(ap, uint8_t *);
-
-                       /* look for a prefix mask */
-                       for (i = 0; i < 16; i++)
-                               if (p[i] != 0xff)
-                                       break;
-                       if (i < 16) {
-                               if ((prefixvals[p[i]] & Isprefix) == 0)
-                                       goto common;
-                               for (j = i + 1; j < 16; j++)
-                                       if (p[j] != 0)
-                                               goto common;
-                               n = 8 * i + (prefixvals[p[i]] & ~Isprefix);
-                       } else
-                               n = 8 * 16;
-
-                       /* got one, use /xx format */
-                       snprintf(buf, sizeof(buf), "/%d", n);
-                       break;
-               default:
-                       strncpy(buf, "(eipconv)", sizeof(buf));
-       }
-
-       return buf;
-}
-
-uint8_t testvec[11][16] = {
-       {0,0,0,0,0,0,0,0,0,0,0xff,0xff,1,3,4,5,} ,
-       {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,} ,
-       {0xff,0xff,0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,} ,
-       {0xff,0xff,0xff,0xc0,0,0,0,0,0,0,0,0,0,0,0,0,} ,
-       {0xff,0xff,0xff,0xff,0xe0,0,0,0,0,0,0,0,0,0,0,0,} ,
-       {0xff,0xff,0xff,0xff,0xff,0xf0,0,0,0,0,0,0,0,0,0,0,} ,
-       {0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0,0,0,0,0,0,0,0,0,} ,
-       {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,} ,
-       {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,} ,
-       {0,0,0,0,0,0x11,0,0,0,0,0,0,0,0,0,0,} ,
-       {0,0,0,0x11,0,0,0,0,0,0,0,0,0,0,0,0x12,} ,
-};
-
-void main(void)
-{
-       int i;
-       for (i = 0; i < 11; i++)
-               printf("%s\n", eipconv('I', &testvec[i]));
-
-}
index dcba7ef..1b6ecb7 100644 (file)
@@ -53,7 +53,6 @@ uint8_t v4prefix[IPaddrlen] = {
        0, 0, 0, 0
 };
 
-
 char *v6hdrtypes[Maxhdrtype] =
 {
        [HBH]           "HopbyHop",
@@ -274,95 +273,6 @@ static uint8_t prefixvals[256] =
 [0xFF] 8 | Isprefix,
 };
 
-#warning "what did we do about eipfmt?"
-
-int
-eipfmt(void)
-{
-       return 0;
-#if 0
-       char buf[5*8];
-       static char *efmt = "0x%.2lx0x%.2lx0x%.2lx0x%.2lx0x%.2lx0x%.2lx";
-       static char *ifmt = "%d.%d.%d.%d";
-       uint8_t *p, ip[16];
-       uint32_t *lp;
-       uint16_t s;
-       int i, j, n, eln, eli;
-
-       switch(f->r) {
-       case 'E':               /* Ethernet address */
-               p = va_arg(f->args, uint8_t *unused_uint8_p_t);
-               return fmtprint(f, efmt, p[0], p[1], p[2], p[3], p[4], p[5]);
-               return fmtstrncpy(f,  buf, sizeof(f));
-
-       case 'I':               /* Ip address */
-               p = va_arg(f->args, uint8_t *unused_uint8_p_t);
-common:
-               if(memcmp(p, v4prefix, 12) == 0)
-                       return fmtprint(f, ifmt, p[12], p[13], p[14], p[15]);
-
-               /* find longest elision */
-               eln = eli = -1;
-               for(i = 0; i < 16; i += 2){
-                       for(j = i; j < 16; j += 2)
-                               if(p[j] != 0 || p[j+1] != 0)
-                                       break;
-                       if(j > i && j - i > eln){
-                               eli = i;
-                               eln = j - i;
-                       }
-               }
-
-               /* print with possible elision */
-               n = 0;
-               for(i = 0; i < 16; i += 2){
-                       if(i == eli){
-                               n += sprint(buf+n, "::");
-                               i += eln;
-                               if(i >= 16)
-                                       break;
-                       } else if(i != 0)
-                               n += sprint(buf+n, ":");
-                       s = (p[i]<<8) + p[i+1];
-                       n += sprint(buf+n, "0x%x", s);
-               }
-               return fmtstrncpy(f,  buf, sizeof(f));
-
-       case 'i':               /* v6 address as 4 longs */
-               lp = va_arg(f->args, uint32_t*);
-               for(i = 0; i < 4; i++)
-                       hnputl(ip+4*i, *lp++);
-               p = ip;
-               goto common;
-
-       case 'V':               /* v4 ip address */
-               p = va_arg(f->args, uint8_t *unused_uint8_p_t);
-               return fmtprint(f, ifmt, p[0], p[1], p[2], p[3]);
-
-       case 'M':               /* ip mask */
-               p = va_arg(f->args, uint8_t *unused_uint8_p_t);
-
-               /* look for a prefix mask */
-               for(i = 0; i < 16; i++)
-                       if(p[i] != 0xff)
-                               break;
-               if(i < 16){
-                       if((prefixvals[p[i]] & Isprefix) == 0)
-                               goto common;
-                       for(j = i+1; j < 16; j++)
-                               if(p[j] != 0)
-                                       goto common;
-                       n = 8*i + (prefixvals[p[i]] & ~Isprefix);
-               } else
-                       n = 8*16;
-
-               /* got one, use /xx format */
-               return fmtprint(f, "/%d", n);
-       }
-       return fmtstrncpy(f,  "(eipfmt)", sizeof(f));
-#endif
-}
-
 #define CLASS(p) ((*( uint8_t *)(p))>>6)
 
 extern char*
index 2050782..e30b928 100644 (file)
@@ -58,6 +58,8 @@ void vprintfmt(void (*putch)(int, void**), void **putdat, const char *fmt, va_li
        unsigned long long num;
        int base, lflag, width, precision, altflag;
        char padc;
+       uint8_t *mac, *ip, *mask;
+       int i;
 
        while (1) {
                while ((ch = *(unsigned char *) fmt) != '%') {
@@ -82,7 +84,7 @@ void vprintfmt(void (*putch)(int, void**), void **putdat, const char *fmt, va_li
                case '-':
                        padc = '-';
                        goto reswitch;
-                       
+
                // flag to pad with 0's instead of spaces
                case '0':
                        padc = '0';
@@ -145,6 +147,24 @@ void vprintfmt(void (*putch)(int, void**), void **putdat, const char *fmt, va_li
                                printfmt(putch, putdat, "%s", error_string[err]);
                        break;
 
+               case 'E': // ENET MAC
+                       if ((mac = va_arg(ap, uint8_t *)) == NULL){
+                               char *s = "00:00:00:00:00:00";
+                               while(*s)
+                                       putch(*s++, putdat);
+                       }
+                       printemac(putch, putdat, mac);
+                       break;
+               case 'I':
+                       /* what to do if they screw up? */
+                       if ((ip = va_arg(ap, uint8_t *)) != NULL)
+                               printip(putch, putdat, ip);
+                       break;
+               case 'M':
+                       /* what to do if they screw up? */
+                       if ((mask = va_arg(ap, uint8_t *)) != NULL)
+                               printipmask(putch, putdat, mask);
+                       break;
                // string
                case 's':
                        if ((p = va_arg(ap, char *)) == NULL)
@@ -215,7 +235,7 @@ void vprintfmt(void (*putch)(int, void**), void **putdat, const char *fmt, va_li
                case '%':
                        putch(ch, putdat);
                        break;
-                       
+
                // unrecognized escape sequence - just print it literally
                default:
                        putch('%', putdat);