add the 'i' and 'V' formats back
[akaros.git] / kern / src / net / eipconv.c
1 // INFERNO
2 #include <vfs.h>
3 #include <kfs.h>
4 #include <slab.h>
5 #include <kmalloc.h>
6 #include <kref.h>
7 #include <string.h>
8 #include <stdio.h>
9 #include <assert.h>
10 #include <error.h>
11 #include <cpio.h>
12 #include <pmap.h>
13 #include <smp.h>
14 #include <ip.h>
15
16 enum {
17         Isprefix = 16,
18 };
19
20 uint8_t prefixvals[256] = {
21         [0x00] 0 | Isprefix,
22         [0x80] 1 | Isprefix,
23         [0xC0] 2 | Isprefix,
24         [0xE0] 3 | Isprefix,
25         [0xF0] 4 | Isprefix,
26         [0xF8] 5 | Isprefix,
27         [0xFC] 6 | Isprefix,
28         [0xFE] 7 | Isprefix,
29         [0xFF] 8 | Isprefix,
30 };
31
32 static char *efmt = "0x%.2lx0x%.2lx0x%.2lx0x%.2lx0x%.2lx0x%.2lx";
33 static char *ifmt = "%d.%d.%d.%d";
34
35 void printemac(void (*putch)(int, void**), void **putdat, uint8_t *mac)
36 {
37         printfmt(putch, putdat, efmt, mac[0], mac[1], mac[2], mac[3], mac[4],
38                                          mac[5]);
39 }
40
41 void printip(void (*putch)(int, void**), void **putdat, uint8_t *ip)
42 {
43         int i, j, eln, eli;
44         uint16_t s;
45         if (memcmp(ip, v4prefix, 12) == 0)
46                 printfmt(putch, putdat, ifmt, ip[12], ip[13], ip[14], ip[15]);
47         else {
48                 /* find longest elision */
49                 eln = eli = -1;
50                 for (i = 0; i < 16; i += 2) {
51                         for (j = i; j < 16; j += 2)
52                                 if (ip[j] != 0 || ip[j + 1] != 0)
53                                         break;
54                         if (j > i && j - i > eln) {
55                                 eli = i;
56                                 eln = j - i;
57                         }
58                 }
59
60                 /* print with possible elision */
61                 for (i = 0; i < 16; i += 2) {
62                         if (i == eli) {
63                                 /* not sure what to do ... we don't get
64                                  * the number of bytes back from printing.
65                                  */
66                                 printfmt(putch, putdat, "::");
67                                 i += eln;
68                                 if (i >= 16)
69                                         break;
70                         } else if (i != 0)
71                                 printfmt(putch, putdat, ":");
72
73                         s = (ip[i] << 8) + ip[i + 1];
74                         printfmt(putch, putdat, "0x%x", s);
75                 }
76         }
77 }
78
79 void printipv4(void (*putch)(int, void**), void **putdat, uint8_t *p)
80 {
81         printfmt(putch, putdat, ifmt, p[0], p[1], p[2], p[3]);
82 }
83
84 void printipmask(void (*putch)(int, void**), void **putdat, uint8_t *ip)
85 {
86         int i, j, n;
87         /* look for a prefix mask */
88         for (i = 0; i < 16; i++)
89                 if (ip[i] != 0xff)
90                         break;
91         if (i < 16) {
92                 if ((prefixvals[ip[i]] & Isprefix) == 0){
93                         printip(putch, putdat, ip);
94                         return;
95                 }
96                 for (j = i + 1; j < 16; j++)
97                         if (ip[j] != 0){
98                                 printip(putch, putdat, ip);
99                                 return;
100                         }
101                 n = 8 * i + (prefixvals[ip[i]] & ~Isprefix);
102         } else
103                 n = 8 * 16;
104
105         /* got one, use /xx format */
106         printfmt(putch, putdat, "/%d", n);
107 }
108
109 static uint8_t testvec[11][16] = {
110         {0,0,0,0,0,0,0,0,0,0,0xff,0xff,1,3,4,5,} ,
111         {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,} ,
112         {0xff,0xff,0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,} ,
113         {0xff,0xff,0xff,0xc0,0,0,0,0,0,0,0,0,0,0,0,0,} ,
114         {0xff,0xff,0xff,0xff,0xe0,0,0,0,0,0,0,0,0,0,0,0,} ,
115         {0xff,0xff,0xff,0xff,0xff,0xf0,0,0,0,0,0,0,0,0,0,0,} ,
116         {0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0,0,0,0,0,0,0,0,0,} ,
117         {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,} ,
118         {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,} ,
119         {0,0,0,0,0,0x11,0,0,0,0,0,0,0,0,0,0,} ,
120         {0,0,0,0x11,0,0,0,0,0,0,0,0,0,0,0,0x12,} ,
121 };
122
123 /* handy dandy test function. When in doubt, you can call this from the monitor.
124  * I doubt we want this long term.
125  * Google 'remove before flight'.
126  */
127 void testeip(void)
128 {
129         int i;
130         for (i = 0; i < 11; i++)
131                 printk("%I\n", &testvec[i]);
132
133 }