Add the Inferno license to files we got from Inferno
[akaros.git] / kern / src / net / eipconv.c
1 /* Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
2  * Portions Copyright © 1997-1999 Vita Nuova Limited
3  * Portions Copyright © 2000-2007 Vita Nuova Holdings Limited
4  *                                (www.vitanuova.com)
5  * Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
6  *
7  * Modified for the Akaros operating system:
8  * Copyright (c) 2013-2014 The Regents of the University of California
9  * Copyright (c) 2013-2015 Google Inc.
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a copy
12  * of this software and associated documentation files (the "Software"), to deal
13  * in the Software without restriction, including without limitation the rights
14  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15  * copies of the Software, and to permit persons to whom the Software is
16  * furnished to do so, subject to the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be included in
19  * all copies or substantial portions of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
24  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27  * SOFTWARE. */
28
29 #include <vfs.h>
30 #include <kfs.h>
31 #include <slab.h>
32 #include <kmalloc.h>
33 #include <kref.h>
34 #include <string.h>
35 #include <stdio.h>
36 #include <assert.h>
37 #include <error.h>
38 #include <cpio.h>
39 #include <pmap.h>
40 #include <smp.h>
41 #include <ip.h>
42
43 enum {
44         Isprefix = 16,
45 };
46
47 uint8_t prefixvals[256] = {
48         [0x00] 0 | Isprefix,
49         [0x80] 1 | Isprefix,
50         [0xC0] 2 | Isprefix,
51         [0xE0] 3 | Isprefix,
52         [0xF0] 4 | Isprefix,
53         [0xF8] 5 | Isprefix,
54         [0xFC] 6 | Isprefix,
55         [0xFE] 7 | Isprefix,
56         [0xFF] 8 | Isprefix,
57 };
58
59 static char *efmt = "%02x:%02x:%02x:%02x:%02x:%02x";
60 static char *ifmt = "%d.%d.%d.%d";
61
62 void printemac(void (*putch) (int, void **), void **putdat, uint8_t * mac)
63 {
64         printfmt(putch, putdat, efmt, mac[0], mac[1], mac[2], mac[3], mac[4],
65                          mac[5]);
66 }
67
68 void printip(void (*putch) (int, void **), void **putdat, uint8_t * ip)
69 {
70         int i, j, eln, eli;
71         uint16_t s;
72         if (memcmp(ip, v4prefix, 12) == 0)
73                 printfmt(putch, putdat, ifmt, ip[12], ip[13], ip[14], ip[15]);
74         else {
75                 /* find longest elision */
76                 eln = eli = -1;
77                 for (i = 0; i < 16; i += 2) {
78                         for (j = i; j < 16; j += 2)
79                                 if (ip[j] != 0 || ip[j + 1] != 0)
80                                         break;
81                         if (j > i && j - i > eln) {
82                                 eli = i;
83                                 eln = j - i;
84                         }
85                 }
86
87                 /* print with possible elision */
88                 for (i = 0; i < 16; i += 2) {
89                         if (i == eli) {
90                                 /* not sure what to do ... we don't get
91                                  * the number of bytes back from printing.
92                                  */
93                                 printfmt(putch, putdat, "::");
94                                 i += eln;
95                                 if (i >= 16)
96                                         break;
97                         } else if (i != 0)
98                                 printfmt(putch, putdat, ":");
99
100                         s = (ip[i] << 8) + ip[i + 1];
101                         printfmt(putch, putdat, "0x%x", s);
102                 }
103         }
104 }
105
106 void printipv4(void (*putch) (int, void **), void **putdat, uint8_t * p)
107 {
108         printfmt(putch, putdat, ifmt, p[0], p[1], p[2], p[3]);
109 }
110
111 void printipmask(void (*putch) (int, void **), void **putdat, uint8_t * ip)
112 {
113         int i, j, n;
114         /* look for a prefix mask */
115         for (i = 0; i < 16; i++)
116                 if (ip[i] != 0xff)
117                         break;
118         if (i < 16) {
119                 if ((prefixvals[ip[i]] & Isprefix) == 0) {
120                         printip(putch, putdat, ip);
121                         return;
122                 }
123                 for (j = i + 1; j < 16; j++)
124                         if (ip[j] != 0) {
125                                 printip(putch, putdat, ip);
126                                 return;
127                         }
128                 n = 8 * i + (prefixvals[ip[i]] & ~Isprefix);
129         } else
130                 n = 8 * 16;
131
132         /* got one, use /xx format */
133         printfmt(putch, putdat, "/%d", n);
134 }
135
136 void printqid(void (*putch) (int, void **), void **putdat, struct qid *q)
137 {
138         printfmt(putch, putdat, "{path:%p,type:%02x,vers:%p}",
139                  q->path, q->type, q->vers);
140
141 }
142
143 void printcname(void (*putch) (int, void **), void **putdat, struct cname *c)
144 {
145         if (c)
146                 printfmt(putch, putdat, "{ref %d, alen %d, len %d, s %s}",
147                         kref_refcnt(&c->ref), c->alen, c->len, c->s);
148 }
149
150 void printchan(void (*putch) (int, void **), void **putdat, struct chan *c)
151 {
152         if (! c)
153                 return;
154         printfmt(putch, putdat, "(%p): ", c);
155         printfmt(putch, putdat, "%slocked ", spin_locked(&c->lock) ? "":"un");
156         printfmt(putch, putdat, "refs %p ", kref_refcnt(&c->ref));
157 //      printfmt(putch, putdat, "%p ", struct chan *next,
158 //      printfmt(putch, putdat, "%p ", struct chan *link,
159         printfmt(putch, putdat, "off %p ", c->offset);
160         printfmt(putch, putdat, "type %p ", c->type);
161         if (c->type != -1)
162                 printfmt(putch, putdat, "(#%s) ", devtab[c->type].name);
163         printfmt(putch, putdat, "dev %p ", c->dev);
164         printfmt(putch, putdat, "mode %p ", c->mode);
165         printfmt(putch, putdat, "flag %p ", c->flag);
166         printfmt(putch, putdat, "qid");
167         printqid(putch, putdat, &c->qid);
168         printfmt(putch, putdat, " fid %p ", c->fid);
169         printfmt(putch, putdat, "iounit %p ", c->iounit);
170         printfmt(putch, putdat, "umh %p ", c->umh);
171         printfmt(putch, putdat, "umc %p ", c->umc);
172 //      printfmt(putch, putdat, "%p ", qlock_t umqlock,
173         printfmt(putch, putdat, "uri %p ", c->uri);
174         printfmt(putch, putdat, "dri %p ", c->dri);
175         printfmt(putch, putdat, "mountid %p ", c->mountid);
176         printfmt(putch, putdat, "mntcache %p ", c->mcp);
177         printfmt(putch, putdat, "mux %p ", c->mux);
178         if (c->mux && c->mux->c)        printfmt(putch, putdat, "mux->c %p ", c->mux->c);
179         printfmt(putch, putdat, "aux %p ", c->aux);
180         printfmt(putch, putdat, "mchan %p ", c->mchan);
181         printfmt(putch, putdat, "mqid %p ");
182         printqid(putch, putdat, &c->mqid);
183         printfmt(putch, putdat, " cname ");
184         printcname(putch, putdat, c->name);
185         printfmt(putch, putdat, " ateof %p ", c->ateof);
186         printfmt(putch, putdat, "buf %p ", c->buf);
187         printfmt(putch, putdat, "bufused %p ", c->bufused);
188 }
189
190 static uint8_t testvec[11][16] = {
191         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 1, 3, 4, 5,},
192         {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
193          0xff, 0xff, 0xff, 0xff,},
194         {0xff, 0xff, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
195         {0xff, 0xff, 0xff, 0xc0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
196         {0xff, 0xff, 0xff, 0xff, 0xe0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
197         {0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
198         {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
199         {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
200          0xff, 0xff, 0xff, 0xff,},
201         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
202         {0, 0, 0, 0, 0, 0x11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
203         {0, 0, 0, 0x11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x12,},
204 };
205
206 /* handy dandy test function. When in doubt, you can call this from the monitor.
207  * I doubt we want this long term.
208  * Google 'remove before flight'.
209  */
210 void testeip(void)
211 {
212         int i;
213         for (i = 0; i < 11; i++)
214                 printk("%I\n", &testvec[i]);
215
216 }