Add support for coreboot tables
[akaros.git] / kern / include / ip.h
1 // INFERNO
2
3 #ifndef ROS_KERN_IP_H
4 #define ROS_KERN_IP_H
5
6 enum {
7         Addrlen = 64,
8         Maxproto = 20,
9         Nhash = 64,
10         Maxincall = 5,
11         Nchans = 256,
12         MAClen = 16,    /* longest mac address */
13
14         MAXTTL = 255,
15         DFLTTOS = 0,
16
17         IPaddrlen = 16,
18         IPv4addrlen = 4,
19         IPv4off = 12,
20         IPllen = 4,
21
22         /* ip versions */
23         V4 = 4,
24         V6 = 6,
25         IP_VER4 = 0x40,
26         IP_VER6 = 0x60,
27
28         /* 2^Lroot trees in the root table */
29         Lroot = 10,
30
31         Maxpath = 64,
32 };
33
34 enum {
35         Idle = 0,
36         Announcing = 1,
37         Announced = 2,
38         Connecting = 3,
39         Connected = 4,
40 };
41
42 /*
43  *  one per conversation directory
44  */
45 struct Proto;
46 struct conv {
47         qlock_t qlock;
48
49         int x;                                          /* conversation index */
50         struct Proto *p;
51
52         int restricted;                         /* remote port is restricted */
53         uint32_t ttl;                           /* max time to live */
54         uint32_t tos;                           /* type of service */
55         int ignoreadvice;                       /* don't terminate connection on icmp errors */
56
57         uint8_t ipversion;
58         uint8_t laddr[IPaddrlen];       /* local IP address */
59         uint8_t raddr[IPaddrlen];       /* remote IP address */
60         uint16_t lport;                         /* local port number */
61         uint16_t rport;                         /* remote port number */
62
63         char *owner;                            /* protections */
64         int perm;
65         int inuse;                                      /* opens of listen/data/ctl */
66         int length;
67         int state;
68
69         /* udp specific */
70         int headers;                            /* data src/dst headers in udp */
71         int reliable;                           /* true if reliable udp */
72
73         struct conv *incall;            /* calls waiting to be listened for */
74         struct conv *next;
75
76         struct queue *rq;                       /* queued data waiting to be read */
77         struct queue *wq;                       /* queued data waiting to be written */
78         struct queue *eq;                       /* returned error packets */
79         struct queue *sq;                       /* snooping queue */
80         atomic_t snoopers;                      /* number of processes with snoop open */
81
82         struct rendez cr;
83         char cerr[ERRMAX];
84
85         qlock_t listenq;
86         struct rendez listenr;
87
88         struct Ipmulti *multi;          /* multicast bindings for this interface */
89
90         void *ptcl;                                     /* Protocol specific stuff */
91
92         struct route *r;                        /* last route used */
93         uint32_t rgen;                          /* routetable generation for *r */
94 };
95
96 struct Ipifc;
97 struct Fs;
98
99 struct medium {
100         char *name;
101         int hsize;                                      /* medium header size */
102         int mintu;                                      /* default min mtu */
103         int maxtu;                                      /* default max mtu */
104         int maclen;                                     /* mac address length  */
105         void (*bind) (struct Ipifc * unused_Ipifc, int unused_int,
106                                   char **unused_char_pp_t);
107         void (*unbind) (struct Ipifc * unused_Ipifc);
108         void (*bwrite) (struct Ipifc * ifc,
109                                         struct block * b, int version, uint8_t * ip);
110
111         /* for arming interfaces to receive multicast */
112         void (*addmulti) (struct Ipifc * ifc, uint8_t * a, uint8_t * ia);
113         void (*remmulti) (struct Ipifc * ifc, uint8_t * a, uint8_t * ia);
114
115         /* process packets written to 'data' */
116         void (*pktin) (struct Fs * f, struct Ipifc * ifc, struct block * bp);
117
118         /* routes for router boards */
119         void (*addroute) (struct Ipifc * ifc, int unused_int, uint8_t * u8p,
120                                           uint8_t *, uint8_t * u8p2, int);
121         void (*remroute) (struct Ipifc * ifc, int i, uint8_t * u8p,
122                                           uint8_t * uu8p2);
123         void (*flushroutes) (struct Ipifc * ifc);
124
125         /* for routing multicast groups */
126         void (*joinmulti) (struct Ipifc * ifc, uint8_t * a, uint8_t * ia);
127         void (*leavemulti) (struct Ipifc * ifc, uint8_t * a, uint8_t * ia);
128
129         /* address resolution */
130         void (*ares) (struct Fs *, int unused_int, uint8_t * unused_uint8_p_t, uint8_t *, int, int);    /* resolve */
131         void (*areg) (struct Ipifc * unused_Ipifc, uint8_t * unused_uint8_p_t); /* register */
132
133         /* v6 address generation */
134         void (*pref2addr) (uint8_t * pref, uint8_t * ea);
135
136         int unbindonclose;                      /* if non-zero, unbind on last close */
137 };
138
139 /* logical interface associated with a physical one */
140 struct Iplifc {
141         uint8_t local[IPaddrlen];
142         uint8_t mask[IPaddrlen];
143         uint8_t remote[IPaddrlen];
144         uint8_t net[IPaddrlen];
145         uint8_t tentative;                      /* =1 => v6 dup disc on, =0 => confirmed unique */
146         uint8_t onlink;                         /* =1 => onlink, =0 offlink. */
147         uint8_t autoflag;                       /* v6 autonomous flag */
148         long validlt;                           /* v6 valid lifetime */
149         long preflt;                            /* v6 preferred lifetime */
150         long origint;                           /* time when addr was added */
151         struct Iplink *link;            /* addresses linked to this lifc */
152         struct Iplifc *next;
153 };
154
155 /* binding twixt Ipself and Iplifc */
156 struct Iplink {
157         struct Ipself *self;
158         struct Iplifc *lifc;
159         struct Iplink *selflink;        /* next link for this local address */
160         struct Iplink *lifclink;        /* next link for this ifc */
161         uint32_t expire;
162         struct Iplink *next;            /* free list */
163         struct kref ref;
164 };
165
166 /* rfc 2461, pp.40--43. */
167
168 /* default values, one per stack */
169 struct routerparams {
170         int mflag;
171         int oflag;
172         int maxraint;
173         int minraint;
174         int linkmtu;
175         int reachtime;
176         int rxmitra;
177         int ttl;
178         int routerlt;
179 };
180
181 struct Ipifc {
182         rwlock_t rwlock;
183
184         struct conv *conv;                      /* link to its conversation structure */
185         char dev[64];                           /* device we're attached to */
186         struct medium *m;                       /* Media pointer */
187         int maxtu;                                      /* Maximum transfer unit */
188         int mintu;                                      /* Minumum tranfer unit */
189         int mbps;                                       /* megabits per second */
190         void *arg;                                      /* medium specific */
191         int reassemble;                         /* reassemble IP packets before forwarding */
192
193         /* these are used so that we can unbind on the fly */
194         spinlock_t idlock;
195         uint8_t ifcid;                          /* incremented each 'bind/unbind/add/remove' */
196         int ref;                                        /* number of proc's using this Ipifc */
197         struct rendez wait;                     /* where unbinder waits for ref == 0 */
198         int unbinding;
199
200         uint8_t mac[MAClen];            /* MAC address */
201
202         struct Iplifc *lifc;            /* logical interfaces on this physical one */
203
204         uint32_t in, out;                       /* message statistics */
205         uint32_t inerr, outerr;         /* ... */
206
207         uint8_t sendra6;                        /* == 1 => send router advs on this ifc */
208         uint8_t recvra6;                        /* == 1 => recv router advs on this ifc */
209         struct routerparams rp;         /* router parameters as in RFC 2461, pp.40--43. 
210                                                                    used only if node is router */
211 };
212
213 /*
214  *  one per multicast-lifc pair used by a struct conv
215  */
216 struct Ipmulti {
217         uint8_t ma[IPaddrlen];
218         uint8_t ia[IPaddrlen];
219         struct Ipmulti *next;
220 };
221
222 /*
223  *  hash table for 2 ip addresses + 2 ports
224  */
225 enum {
226         Nipht = 521,                            /* convenient prime */
227
228         IPmatchexact = 0,       /* match on 4 tuple */
229         IPmatchany,     /* *!* */
230         IPmatchport,    /* *!port */
231         IPmatchaddr,    /* addr!* */
232         IPmatchpa,      /* addr!port */
233 };
234 struct Iphash {
235         struct Iphash *next;
236         struct conv *c;
237         int match;
238 };
239
240 struct Iphash;
241 struct Ipht {
242         spinlock_t lock;
243         struct Iphash *tab[Nipht];
244 };
245 void iphtadd(struct Ipht *, struct conv *);
246 void iphtrem(struct Ipht *, struct conv *);
247 struct conv *iphtlook(struct Ipht *ht, uint8_t * sa, uint16_t sp, uint8_t * da,
248                                           uint16_t dp);
249
250 /*
251  *  one per multiplexed Protocol
252  */
253 struct Proto {
254         qlock_t qlock;
255         char *name;                                     /* protocol name */
256         int x;                                          /* protocol index */
257         int ipproto;                            /* ip protocol type */
258
259         char *(*connect) (struct conv *, char **unused_char_pp_t, int);
260         char *(*announce) (struct conv *, char **unused_char_pp_t, int);
261         char *(*bind) (struct conv *, char **unused_char_pp_t, int);
262         int (*state) (struct conv *, char *unused_char_p_t, int);
263         void (*create) (struct conv *);
264         void (*close) (struct conv *);
265         void (*rcv) (struct Proto *, struct Ipifc *, struct block *);
266         char *(*ctl) (struct conv *, char **unused_char_pp_t, int);
267         void (*advise) (struct Proto *, struct block *, char *unused_char_p_t);
268         int (*stats) (struct Proto *, char *unused_char_p_t, int);
269         int (*local) (struct conv *, char *unused_char_p_t, int);
270         int (*remote) (struct conv *, char *unused_char_p_t, int);
271         int (*inuse) (struct conv *);
272         int (*gc) (struct Proto *);     /* returns true if any conversations are freed */
273         void (*newconv) (struct Proto * udp, struct conv * conv);
274
275         struct Fs *f;                           /* file system this proto is part of */
276         struct conv **conv;                     /* array of conversations */
277         int ptclsize;                           /* size of per protocol ctl block */
278         int nc;                                         /* number of conversations */
279         int ac;
280         struct qid qid;                         /* qid for protocol directory */
281         uint16_t nextport;
282         uint16_t nextrport;
283
284         void *priv;
285 };
286
287 /*
288  *  Stream for sending packets to user level
289  */
290 struct IProuter {
291         qlock_t qlock;
292         int opens;
293         struct queue *q;
294 };
295
296 /*
297  *  one per IP protocol stack
298  */
299 struct Fs {
300         rwlock_t rwlock;
301         int dev;
302
303         int np;
304         struct Proto *p[Maxproto + 1];  /* list of supported protocols */
305         struct Proto *t2p[256];         /* vector of all protocols */
306         struct Proto *ipifc;            /* kludge for ipifcremroute & ipifcaddroute */
307         struct Proto *ipmux;            /* kludge for finding an ip multiplexor */
308
309         struct IP *ip;
310         struct Ipselftab *self;
311         struct arp *arp;
312         struct V6params *v6p;
313         struct IProuter iprouter;
314
315         struct route *v4root[1 << Lroot];       /* v4 routing forest */
316         struct route *v6root[1 << Lroot];       /* v6 routing forest */
317         struct route *queue;            /* used as temp when reinjecting routes */
318
319         struct Netlog *alog;
320         struct Ifclog *ilog;
321
322         char ndb[1024];                         /* an ndb entry for this interface */
323         int ndbvers;
324         long ndbmtime;
325 };
326
327 /* one per default router known to host */
328 struct V6router {
329         uint8_t inuse;
330         struct Ipifc *ifc;
331         int ifcid;
332         uint8_t routeraddr[IPaddrlen];
333         long ltorigin;
334         struct routerparams rp;
335 };
336
337 struct hostparams {
338         int rxmithost;
339 };
340
341 struct V6params {
342         struct routerparams rp;         /* v6 params, one copy per node now */
343         struct hostparams hp;
344         struct V6router v6rlist[3];     /* max 3 default routers, currently */
345         int cdrouter;                           /* uses only v6rlist[cdrouter] if   */
346         /* cdrouter >= 0. */
347 };
348
349 int Fsconnected(struct conv *, char *unused_char_p_t);
350 struct conv *Fsnewcall(struct conv *, uint8_t * unused_uint8_p_t, uint16_t,
351                                            uint8_t *, uint16_t, uint8_t unused_uint8_t);
352 int Fspcolstats(char *unused_char_p_t, int);
353 int Fsproto(struct Fs *, struct Proto *);
354 int Fsbuiltinproto(struct Fs *, uint8_t unused_uint8_t);
355 struct conv *Fsprotoclone(struct Proto *, char *unused_char_p_t);
356 struct Proto *Fsrcvpcol(struct Fs *, uint8_t unused_uint8_t);
357 struct Proto *Fsrcvpcolx(struct Fs *, uint8_t unused_uint8_t);
358 char *Fsstdconnect(struct conv *, char **unused_char_pp_t, int);
359 char *Fsstdannounce(struct conv *, char **unused_char_pp_t, int);
360 char *Fsstdbind(struct conv *, char **unused_char_pp_t, int);
361 uint32_t scalednconv(void);
362
363 /* 
364  *  logging
365  */
366 enum {
367         Logip = 1 << 1,
368         Logtcp = 1 << 2,
369         Logfs = 1 << 3,
370         Logil = 1 << 4,
371         Logicmp = 1 << 5,
372         Logudp = 1 << 6,
373         Logcompress = 1 << 7,
374         Logilmsg = 1 << 8,
375         Loggre = 1 << 9,
376         Logppp = 1 << 10,
377         Logtcprxmt = 1 << 11,
378         Logigmp = 1 << 12,
379         Logudpmsg = 1 << 13,
380         Logipmsg = 1 << 14,
381         Logrudp = 1 << 15,
382         Logrudpmsg = 1 << 16,
383         Logesp = 1 << 17,
384         Logtcpwin = 1 << 18,
385 };
386
387 void netloginit(struct Fs *);
388 void netlogopen(struct Fs *);
389 void netlogclose(struct Fs *);
390 void netlogctl(struct Fs *, char *unused_char_p_t, int);
391 long netlogread(struct Fs *, void *, uint32_t, long);
392 void netlog(struct Fs *, int unused_int, char *unused_char_p_t, ...);
393 void ifcloginit(struct Fs *);
394 long ifclogread(struct Fs *, struct chan *, void *, uint32_t, long);
395 void ifclog(struct Fs *, uint8_t *, int);
396 void ifclogopen(struct Fs *, struct chan *);
397 void ifclogclose(struct Fs *, struct chan *);
398
399 /*
400  *  iproute.c
401  */
402
403 enum {
404
405         /* type bits */
406         Rv4 = (1 << 0),                         /* this is a version 4 route */
407         Rifc = (1 << 1),        /* this route is a directly connected interface */
408         Rptpt = (1 << 2),       /* this route is a pt to pt interface */
409         Runi = (1 << 3),        /* a unicast self address */
410         Rbcast = (1 << 4),      /* a broadcast self address */
411         Rmulti = (1 << 5),      /* a multicast self address */
412         Rproxy = (1 << 6),      /* this route should be proxied */
413 };
414
415 struct routewalk {
416         int o;
417         int h;
418         char *p;
419         char *e;
420         void *state;
421         void (*walk) (struct route *, struct routewalk *);
422 };
423
424 struct RouteTree {
425         struct route *right;
426         struct route *left;
427         struct route *mid;
428         uint8_t depth;
429         uint8_t type;
430         uint8_t ifcid;                          /* must match ifc->id */
431         struct Ipifc *ifc;
432         char tag[4];
433         struct kref kref;
434 };
435
436 struct V4route {
437         uint32_t address;
438         uint32_t endaddress;
439         uint8_t gate[IPv4addrlen];
440 };
441
442 struct V6route {
443         uint32_t address[IPllen];
444         uint32_t endaddress[IPllen];
445         uint8_t gate[IPaddrlen];
446 };
447
448 struct route {
449         struct RouteTree rt;
450
451         union {
452                 struct V6route v6;
453                 struct V4route v4;
454         };
455 };
456 extern void v4addroute(struct Fs *f, char *tag, uint8_t * a, uint8_t * mask,
457                                            uint8_t * gate, int type);
458 extern void v6addroute(struct Fs *f, char *tag, uint8_t * a, uint8_t * mask,
459                                            uint8_t * gate, int type);
460 extern void v4delroute(struct Fs *f, uint8_t * a, uint8_t * mask, int dolock);
461 extern void v6delroute(struct Fs *f, uint8_t * a, uint8_t * mask, int dolock);
462 extern struct route *v4lookup(struct Fs *f, uint8_t * a, struct conv *c);
463 extern struct route *v6lookup(struct Fs *f, uint8_t * a, struct conv *c);
464 extern long routeread(struct Fs *f, char *unused_char_p_t, uint32_t, int);
465 extern long routewrite(struct Fs *f, struct chan *, char *unused_char_p_t, int);
466 extern void routetype(int unused_int, char *unused_char_p_t);
467 extern void ipwalkroutes(struct Fs *, struct routewalk *);
468 extern void convroute(struct route *r, uint8_t * u8pt, uint8_t * u8pt1,
469                                           uint8_t * u8pt2, char *unused_char_p_t, int *intp);
470
471 /*
472  *  devip.c
473  */
474
475 /*
476  *  Hanging off every ip channel's ->aux is the following structure.
477  *  It maintains the state used by devip and iproute.
478  */
479 struct IPaux {
480         char *owner;                            /* the user that did the attach */
481         char tag[4];
482 };
483
484 extern struct IPaux *newipaux(char *unused_char_p_t, char *);
485
486 /*
487  *  arp.c
488  */
489 struct arpent {
490         uint8_t ip[IPaddrlen];
491         uint8_t mac[MAClen];
492         struct medium *type;            /* media type */
493         struct arpent *hash;
494         struct block *hold;
495         struct block *last;
496         unsigned int ctime;                     /* time entry was created or refreshed */
497         unsigned int utime;                     /* time entry was last used */
498         uint8_t state;
499         struct arpent *nextrxt;         /* re-transmit chain */
500         unsigned int rtime;                     /* time for next retransmission */
501         uint8_t rxtsrem;
502         struct Ipifc *ifc;
503         uint8_t ifcid;                          /* must match ifc->id */
504 };
505
506 extern void arpinit(struct Fs *);
507 extern int arpread(struct arp *, char *unused_char_p_t, uint32_t, int);
508 extern int arpwrite(struct Fs *, char *unused_char_p_t, int);
509 extern struct arpent *arpget(struct arp *, struct block *bp, int version,
510                                                          struct Ipifc *ifc, uint8_t * ip, uint8_t * h);
511 extern void arprelease(struct arp *, struct arpent *a);
512 extern struct block *arpresolve(struct arp *, struct arpent *a,
513                                                                 struct medium *type, uint8_t * mac);
514 extern void arpenter(struct Fs *, int version, uint8_t * ip,
515                                          uint8_t * mac, int len, int norefresh);
516
517 /*
518  * ipaux.c
519  */
520
521 extern int myetheraddr(uint8_t * unused_uint8_p_t, char *unused_char_p_t);
522 extern uint32_t parseip(uint8_t * unused_uint8_p_t, char *unused_char_p_t);
523 extern uint32_t parseipmask(uint8_t * unused_uint8_p_t, char *unused_char_p_t);
524 extern char *v4parseip(uint8_t * unused_uint8_p_t, char *unused_char_p_t);
525 extern void maskip(uint8_t * from, uint8_t * mask, uint8_t * to);
526 extern int parsemac(uint8_t * to, char *from, int len);
527 extern uint8_t *defmask(uint8_t * unused_uint8_p_t);
528 extern int isv4(uint8_t * unused_uint8_p_t);
529 extern void v4tov6(uint8_t * v6, uint8_t * v4);
530 extern int v6tov4(uint8_t * v4, uint8_t * v6);
531 //extern int    eipfmt(Fmt*);
532
533 #define ipmove(x, y) memmove(x, y, IPaddrlen)
534 #define ipcmp(x, y) ( (x)[IPaddrlen-1] != (y)[IPaddrlen-1] || memcmp(x, y, IPaddrlen) )
535
536 extern uint8_t IPv4bcast[IPaddrlen];
537 extern uint8_t IPv4bcastobs[IPaddrlen];
538 extern uint8_t IPv4allsys[IPaddrlen];
539 extern uint8_t IPv4allrouter[IPaddrlen];
540 extern uint8_t IPnoaddr[IPaddrlen];
541 extern uint8_t v4prefix[IPaddrlen];
542 extern uint8_t IPallbits[IPaddrlen];
543
544 /*
545  *  media
546  */
547 extern struct medium ethermedium;
548 extern struct medium nullmedium;
549 extern struct medium pktmedium;
550 extern struct medium tripmedium;
551
552 /*
553  *  ipifc.c
554  */
555 extern struct medium *ipfindmedium(char *name);
556 extern void addipmedium(struct medium *med);
557 extern int ipforme(struct Fs *, uint8_t * addr);
558 extern int iptentative(struct Fs *, uint8_t * addr);
559 extern int ipisbm(uint8_t *);
560 extern int ipismulticast(uint8_t *);
561 extern struct Ipifc *findipifc(struct Fs *, uint8_t * remote, int type);
562 extern void findprimaryip(struct Fs *, uint8_t * unused_uint8_p_t);
563 extern void findlocalip(struct Fs *, uint8_t * local, uint8_t * remote);
564 extern int ipv4local(struct Ipifc *ifc, uint8_t * addr);
565 extern int ipv6local(struct Ipifc *ifc, uint8_t * addr);
566 extern int ipv6anylocal(struct Ipifc *ifc, uint8_t * addr);
567 extern struct Iplifc *iplocalonifc(struct Ipifc *ifc, uint8_t * ip);
568 extern int ipproxyifc(struct Fs *f, struct Ipifc *ifc, uint8_t * ip);
569 extern int ipismulticast(uint8_t * ip);
570 extern int ipisbooting(void);
571 extern int ipifccheckin(struct Ipifc *ifc, struct medium *med);
572 extern void ipifccheckout(struct Ipifc *ifc);
573 extern int ipifcgrab(struct Ipifc *ifc);
574 extern void ipifcaddroute(struct Fs *, int unused_int,
575                                                   uint8_t * unused_uint8_p_t, uint8_t *, uint8_t *,
576                                                   int);
577 extern void ipifcremroute(struct Fs *, int unused_int, uint8_t * u8pt,
578                                                   uint8_t * u8pt2);
579 extern void ipifcremmulti(struct conv *c, uint8_t * ma, uint8_t * ia);
580 extern void ipifcaddmulti(struct conv *c, uint8_t * ma, uint8_t * ia);
581 extern char *ipifcrem(struct Ipifc *ifc, char **argv, int argc);
582 extern char *ipifcadd(struct Ipifc *ifc, char **argv, int argc, int tentative,
583                                           struct Iplifc *lifcp);
584 extern long ipselftabread(struct Fs *, char *a, uint32_t offset, int n);
585 extern char *ipifcaddpref6(struct Ipifc *ifc, char **argv, int argc);
586 extern void ipsendra6(struct Fs *f, int on);
587
588 /*
589  *  ip.c
590  */
591 extern void iprouting(struct Fs *, int);
592 extern void icmpnoconv(struct Fs *, struct block *);
593 extern void icmpcantfrag(struct Fs *, struct block *, int);
594 extern void icmpttlexceeded(struct Fs *, uint8_t * unused_uint8_p_t,
595                                         struct block *);
596
597 uint16_t ipchecksum(uint8_t *addr, int len);
598 extern uint16_t ipcsum(uint8_t * unused_uint8_p_t);
599 extern void ipiput4(struct Fs *, struct Ipifc *unused_ipifc, struct block *);
600 extern void ipiput6(struct Fs *, struct Ipifc *unused_ipifc, struct block *);
601 extern int ipoput4(struct Fs *,
602                                    struct block *, int unused_int, int, int, struct conv *);
603 extern int ipoput6(struct Fs *,
604                                    struct block *, int unused_int, int, int, struct conv *);
605 extern int ipstats(struct Fs *, char *unused_char_p_t, int);
606 extern uint16_t ptclbsum(uint8_t * unused_uint8_p_t, int);
607 extern uint16_t ptclcsum(struct block *, int unused_int, int);
608 extern void ip_init(struct Fs *);
609 extern void update_mtucache(uint8_t * unused_uint8_p_t, uint32_t);
610 extern uint32_t restrict_mtu(uint8_t * unused_uint8_p_t, uint32_t);
611
612 /*
613  * bootp.c
614  */
615 char *(*bootp) (struct Ipifc * unused_ipifc);
616 int (*bootpread) (char *unused_char_p_t, uint32_t, int);
617
618 /*
619  *  iprouter.c
620  */
621 void useriprouter(struct Fs *, struct Ipifc *unused_ipifc, struct block *);
622 void iprouteropen(struct Fs *);
623 void iprouterclose(struct Fs *);
624 long iprouterread(struct Fs *, void *, int);
625
626 /*
627  *  resolving inferno/plan9 differences
628  */
629 struct chan *commonfdtochan(int unused_int, int, int, int);
630 char *commonuser(void);
631 char *commonerror(void);
632
633 /*
634  * chandial.c
635  */
636 extern struct chan *chandial(char *u1, char *u2, char *u3, struct chan **c);
637
638 /*
639  *  global to all of the stack
640  */
641 extern void (*igmpreportfn) (struct Ipifc * unused_ipifc,
642                                                          uint8_t * unused_uint8_p_t);
643
644 /* IPV6 */
645 /* rfc 3513 defines the address prefices */
646 #define isv6mcast(addr)   ((addr)[0] == 0xff)
647 #define islinklocal(addr) ((addr)[0] == 0xfe && ((addr)[1] & 0xc0) == 0x80)
648 #define issitelocal(addr) ((addr)[0] == 0xfe && ((addr)[1] & 0xc0) == 0xc0)
649 #define isv6global(addr) (((addr)[0] & 0xe0) == 0x20)
650
651 #define optexsts(np) (nhgets((np)->ploadlen) > 24)
652 #define issmcast(addr) (memcmp((addr), v6solicitednode, 13) == 0)
653
654 /* from RFC 2460 */
655
656 typedef struct Ip6hdr Ip6hdr;
657 typedef struct Opthdr Opthdr;
658 typedef struct Routinghdr Routinghdr;
659 typedef struct Fraghdr6 Fraghdr6;
660
661 struct ip6hdr {
662         uint8_t vcf[4];                         // version:4, traffic class:8, flow label:20
663         uint8_t ploadlen[2];            // payload length: packet length - 40
664         uint8_t proto;                          // next header type
665         uint8_t ttl;                            // hop limit
666         uint8_t src[IPaddrlen];
667         uint8_t dst[IPaddrlen];
668 };
669
670 struct Opthdr {
671         uint8_t nexthdr;
672         uint8_t len;
673 };
674
675 struct Routinghdr {
676         uint8_t nexthdr;
677         uint8_t len;
678         uint8_t rtetype;
679         uint8_t segrem;
680 };
681
682 struct fraghdr6 {
683         uint8_t nexthdr;
684         uint8_t res;
685         uint8_t offsetRM[2];            // Offset, Res, M flag
686         uint8_t id[4];
687 };
688
689 enum {                                                  /* Header Types */
690         HBH = 0,                                        //?
691         ICMP = 1,
692         IGMP = 2,
693         GGP = 3,
694         IPINIP = 4,
695         ST = 5,
696         TCP = 6,
697         UDP = 17,
698         ISO_TP4 = 29,
699         RH = 43,
700         FH = 44,
701         IDRP = 45,
702         RSVP = 46,
703         AH = 51,
704         ESP = 52,
705         ICMPv6 = 58,
706         NNH = 59,
707         DOH = 60,
708         ISO_IP = 80,
709         IGRP = 88,
710         OSPF = 89,
711
712         Maxhdrtype = 256,
713 };
714
715 enum {
716         //  multicast flgs and scop
717
718         well_known_flg = 0,
719         transient_flg = 1,
720
721         node_local_scop = 1,
722         link_local_scop = 2,
723         site_local_scop = 5,
724         org_local_scop = 8,
725         global_scop = 14,
726
727         //  various prefix lengths
728
729         SOLN_PREF_LEN = 13,
730
731         //  icmpv6 unreach codes
732         icmp6_no_route = 0,
733         icmp6_ad_prohib = 1,
734         icmp6_unassigned = 2,
735         icmp6_adr_unreach = 3,
736         icmp6_port_unreach = 4,
737         icmp6_unkn_code = 5,
738
739         //  various flags & constants
740
741         v6MINTU = 1280,
742         HOP_LIMIT = 255,
743         ETHERHDR_LEN = 14,
744         IPV6HDR_LEN = 40,
745         IPV4HDR_LEN = 20,
746
747         //  option types
748
749         SRC_LLADDRESS = 1,
750         TARGET_LLADDRESS = 2,
751         PREFIX_INFO = 3,
752         REDIR_HEADER = 4,
753         MTU_OPTION = 5,
754
755         SRC_UNSPEC = 0,
756         SRC_UNI = 1,
757         TARG_UNI = 2,
758         TARG_MULTI = 3,
759
760         t_unitent = 1,
761         t_uniproxy = 2,
762         t_unirany = 3,
763
764         //  Router constants (all times in milliseconds)
765
766         MAX_INITIAL_RTR_ADVERT_INTERVAL = 16000,
767         MAX_INITIAL_RTR_ADVERTISEMENTS = 3,
768         MAX_FINAL_RTR_ADVERTISEMENTS = 3,
769         MIN_DELAY_BETWEEN_RAS = 3000,
770         MAX_RA_DELAY_TIME = 500,
771
772         //  Host constants
773
774         MAX_RTR_SOLICITATION_DELAY = 1000,
775         RTR_SOLICITATION_INTERVAL = 4000,
776         MAX_RTR_SOLICITATIONS = 3,
777
778         //  Node constants
779
780         MAX_MULTICAST_SOLICIT = 3,
781         MAX_UNICAST_SOLICIT = 3,
782         MAX_ANYCAST_DELAY_TIME = 1000,
783         MAX_NEIGHBOR_ADVERTISEMENT = 3,
784         REACHABLE_TIME = 30000,
785         RETRANS_TIMER = 1000,
786         DELAY_FIRST_PROBE_TIME = 5000,
787
788 };
789
790 extern void ipv62smcast(uint8_t *, uint8_t *);
791 extern void icmpns(struct Fs *f, uint8_t * src, int suni, uint8_t * targ,
792                                    int tuni, uint8_t * mac);
793 extern void icmpna(struct Fs *f, uint8_t * src, uint8_t * dst, uint8_t * targ,
794                                    uint8_t * mac, uint8_t flags);
795 extern void icmpttlexceeded6(struct Fs *f, struct Ipifc *ifc, struct block *bp);
796 extern void icmppkttoobig6(struct Fs *f, struct Ipifc *ifc, struct block *bp);
797 extern void icmphostunr(struct Fs *f,
798                                                 struct Ipifc *ifc,
799                                                 struct block *bp, int code, int free);
800
801 extern uint8_t v6allnodesN[IPaddrlen];
802 extern uint8_t v6allnodesL[IPaddrlen];
803 extern uint8_t v6allroutersN[IPaddrlen];
804 extern uint8_t v6allroutersL[IPaddrlen];
805 extern uint8_t v6allnodesNmask[IPaddrlen];
806 extern uint8_t v6allnodesLmask[IPaddrlen];
807 extern uint8_t v6allroutersS[IPaddrlen];
808 extern uint8_t v6solicitednode[IPaddrlen];
809 extern uint8_t v6solicitednodemask[IPaddrlen];
810 extern uint8_t v6Unspecified[IPaddrlen];
811 extern uint8_t v6loopback[IPaddrlen];
812 extern uint8_t v6loopbackmask[IPaddrlen];
813 extern uint8_t v6linklocal[IPaddrlen];
814 extern uint8_t v6linklocalmask[IPaddrlen];
815 extern uint8_t v6sitelocal[IPaddrlen];
816 extern uint8_t v6sitelocalmask[IPaddrlen];
817 extern uint8_t v6glunicast[IPaddrlen];
818 extern uint8_t v6multicast[IPaddrlen];
819 extern uint8_t v6multicastmask[IPaddrlen];
820
821 extern int v6llpreflen;
822 extern int v6slpreflen;
823 extern int v6lbpreflen;
824 extern int v6mcpreflen;
825 extern int v6snpreflen;
826 extern int v6aNpreflen;
827 extern int v6aLpreflen;
828
829 extern int ReTransTimer;
830
831 int kdial(char *dest, char *local, char *dir, int *cfdp);
832
833 /* network interfaces and ethernet */
834 // INFERNO
835
836 enum {
837         Nmaxaddr = 64,
838         Nmhash = 31,
839
840         Ncloneqid = 1,
841         Naddrqid,
842         N2ndqid,
843         N3rdqid,
844         Ndataqid,
845         Nctlqid,
846         Nstatqid,
847         Ntypeqid,
848         Nifstatqid,
849 };
850
851 /*
852  *  Macros to manage Qid's used for multiplexed devices
853  */
854 #define NETTYPE(x)      (((uint32_t)x)&0x1f)
855 /* The net's ID + 1 is stored starting at 1 << 5.  So ID 0 = 32, ID 1 = 64, and
856  * NETID == -1 means no netid */
857 #define NETID(x)        (((uint32_t)(x) >> 5) - 1)
858 #define NETQID(i,t)     ((((uint32_t)(i) + 1) << 5) | (t))
859
860 /*
861  *  one per multiplexed connection
862  */
863 struct netfile {
864         qlock_t qlock;
865
866         int inuse;
867         uint32_t mode;
868         char owner[KNAMELEN];
869
870         int type;                                       /* multiplexor type */
871         int prom;                                       /* promiscuous mode */
872         int scan;                                       /* base station scanning interval */
873         int bridge;                                     /* bridge mode */
874         int headersonly;                        /* headers only - no data */
875         uint8_t maddr[8];                       /* bitmask of multicast addresses requested */
876         int nmaddr;                                     /* number of multicast addresses */
877
878         struct queue *in;                       /* input buffer */
879 };
880
881 /*
882  *  a network address
883  */
884 struct netaddr {
885         struct netaddr *next;           /* allocation chain */
886         struct netaddr *hnext;
887         uint8_t addr[Nmaxaddr];
888         int ref;                                        /* leaving this as an int, not a kref.  no reaping, yet. */
889 };
890
891 /*
892  *  a network interface
893  */
894 struct netif {
895         qlock_t qlock;
896
897         /* multiplexing */
898         char name[KNAMELEN];            /* for top level directory */
899         int nfile;                                      /* max number of Netfiles */
900         struct netfile **f;
901
902         /* about net */
903         int limit;                                      /* flow control */
904         int alen;                                       /* address length */
905         int mbps;                                       /* megabits per sec */
906         int link;                                       /* link status */
907         uint8_t addr[Nmaxaddr];
908         uint8_t bcast[Nmaxaddr];
909         struct netaddr *maddr;          /* known multicast addresses */
910         int nmaddr;                                     /* number of known multicast addresses */
911         struct netaddr *mhash[Nmhash];  /* hash table of multicast addresses */
912         int prom;                                       /* number of promiscuous opens */
913         int scan;                                       /* number of base station scanners */
914         int all;                                        /* number of -1 multiplexors */
915
916         /* statistics */
917         int misses;
918         int inpackets;
919         int outpackets;
920         int crcs;                                       /* input crc errors */
921         int oerrs;                                      /* output errors */
922         int frames;                                     /* framing errors */
923         int overflows;                          /* packet overflows */
924         int buffs;                                      /* buffering errors */
925         int soverflows;                         /* software overflow */
926
927         /* routines for touching the hardware */
928         void *arg;
929         void (*promiscuous) (void *, int);
930         void (*multicast) (void *, uint8_t * unused_uint8_p_t, int);
931         void (*scanbs) (void *, unsigned nt);   /* scan for base stations */
932 };
933
934 void netifinit(struct netif *, char *, int, uint32_t);
935 struct walkqid *netifwalk(struct netif *, struct chan *, struct chan *, char **,
936                                                   int);
937 struct chan *netifopen(struct netif *, struct chan *, int);
938 void netifclose(struct netif *, struct chan *);
939 long netifread(struct netif *, struct chan *, void *, long, uint32_t);
940 struct block *netifbread(struct netif *, struct chan *, long, uint32_t);
941 long netifwrite(struct netif *, struct chan *, void *, long);
942 int netifwstat(struct netif *, struct chan *, uint8_t *, int);
943 int netifstat(struct netif *, struct chan *, uint8_t *, int);
944 int activemulti(struct netif *, uint8_t *, int);
945
946 /*
947  *  Ethernet specific
948  */
949 enum {
950         Eaddrlen = 6,
951         ETHERMINTU = 60,        /* minimum transmit size */
952         ETHERMAXTU = 1514,      /* maximum transmit size */
953         ETHERHDRSIZE = 14,      /* size of an ethernet header */
954 };
955
956 struct etherpkt {
957         uint8_t d[Eaddrlen];
958         uint8_t s[Eaddrlen];
959         uint8_t type[2];
960         uint8_t data[1500];
961 };
962 // INFERNO
963 enum {
964         MaxEther = 4,
965         MaxFID = 16,
966         Ntypes = 8,
967 };
968
969 struct ether {
970         rwlock_t rwlock;
971         int ctlrno;
972         char *type;
973         int irq;
974         int port;
975         int minmtu;
976         int maxmtu;
977         uint8_t ea[Eaddrlen];
978         int encry;
979
980         void (*attach) (struct ether *);        /* filled in by reset routine */
981         void (*closed) (struct ether *);
982         void (*detach) (struct ether *);
983         void (*transmit) (struct ether *);
984         void (*interrupt) (struct hw_trapframe *, void *);
985         long (*ifstat) (struct ether *, void *, long, uint32_t);
986         long (*ctl) (struct ether *, void *, long);     /* custom ctl messages */
987         void (*power) (struct ether *, int);    /* power on/off */
988         void (*shutdown) (struct ether *);      /* shutdown hardware before reboot */
989         void *ctlr;
990         int pcmslot;                            /* PCMCIA */
991         int fullduplex;                         /* non-zero if full duplex */
992         int vlanid;                                     /* non-zero if vlan */
993
994         struct queue *oq;
995
996         qlock_t vlq;                            /* array change */
997         int nvlan;
998         struct ether *vlans[MaxFID];
999
1000         /* another case where we wish we had anon struct members. */
1001         struct netif netif;
1002 };
1003
1004 extern struct block *etheriq(struct ether *, struct block *, int);
1005 extern void addethercard(char *unused_char_p_t, int (*)(struct ether *));
1006 extern int archether(int unused_int, struct ether *);
1007
1008 #define NEXT_RING(x, len) (((x) + 1) % (len))
1009 #define PREV_RING(x, len) (((x) == 0) ? (len) - 1: (x) - 1)
1010
1011 #endif /* ROS_KERN_IP_H */