Use linker functions for NIC and medium pre-init
[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 /* what format to use? */
80 #if 0
81 case 'i':       /* v6 address as 4 longs */
82                         lp = va_arg(ap, uint32_t *);
83                         for (i = 0; i < 4; i++)
84                                 hnputl(ip + 4 * i, *lp++);
85                         p = ip;
86                         goto common;
87
88                 case 'V':       /* v4 ip address */
89                         p = va_arg(ap, uint8_t *);
90                         printfmt(putch, putdat, ifmt, p[0], p[1], p[2], p[3]);
91                         break;
92 #endif
93
94 void printipmask(void (*putch)(int, void**), void **putdat, uint8_t *ip)
95 {
96         int i, j, n;
97         /* look for a prefix mask */
98         for (i = 0; i < 16; i++)
99                 if (ip[i] != 0xff)
100                         break;
101         if (i < 16) {
102                 if ((prefixvals[ip[i]] & Isprefix) == 0){
103                         printip(putch, putdat, ip);
104                         return;
105                 }
106                 for (j = i + 1; j < 16; j++)
107                         if (ip[j] != 0){
108                                 printip(putch, putdat, ip);
109                                 return;
110                         }
111                 n = 8 * i + (prefixvals[ip[i]] & ~Isprefix);
112         } else
113                 n = 8 * 16;
114
115         /* got one, use /xx format */
116         printfmt(putch, putdat, "/%d", n);
117 }
118
119 static uint8_t testvec[11][16] = {
120         {0,0,0,0,0,0,0,0,0,0,0xff,0xff,1,3,4,5,} ,
121         {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,} ,
122         {0xff,0xff,0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,} ,
123         {0xff,0xff,0xff,0xc0,0,0,0,0,0,0,0,0,0,0,0,0,} ,
124         {0xff,0xff,0xff,0xff,0xe0,0,0,0,0,0,0,0,0,0,0,0,} ,
125         {0xff,0xff,0xff,0xff,0xff,0xf0,0,0,0,0,0,0,0,0,0,0,} ,
126         {0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0,0,0,0,0,0,0,0,0,} ,
127         {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,} ,
128         {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,} ,
129         {0,0,0,0,0,0x11,0,0,0,0,0,0,0,0,0,0,} ,
130         {0,0,0,0x11,0,0,0,0,0,0,0,0,0,0,0,0x12,} ,
131 };
132
133 /* handy dandy test function. When in doubt, you can call this from the monitor.
134  * I doubt we want this long term.
135  * Google 'remove before flight'.
136  */
137 void testeip(void)
138 {
139         int i;
140         for (i = 0; i < 11; i++)
141                 printk("%I\n", &testvec[i]);
142
143 }