6d179a0eccd161c09aeed1b7d40df4b510260160
[akaros.git] / kern / include / ip.h
1 // INFERNO
2
3 enum
4 {
5         Addrlen=        64,
6         Maxproto=       20,
7         Nhash=          64,
8         Maxincall=      5,
9         Nchans=         256,
10         MAClen=         16,             /* longest mac address */
11
12         MAXTTL=         255,
13         DFLTTOS=        0,
14
15         IPaddrlen=      16,
16         IPv4addrlen=    4,
17         IPv4off=        12,
18         IPllen=         4,
19
20         /* ip versions */
21         V4=             4,
22         V6=             6,
23         IP_VER4=        0x40,
24         IP_VER6=        0x60,
25
26         /* 2^Lroot trees in the root table */
27         Lroot=          10,
28
29         Maxpath =       64,
30 };
31
32 enum
33 {
34         Idle=           0,
35         Announcing=     1,
36         Announced=      2,
37         Connecting=     3,
38         Connected=      4,
39 };
40
41 /*
42  *  one per conversation directory
43  */
44 struct Proto;
45 struct conv
46 {
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         struct kref     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 {
101         char    *name;
102         int     hsize;          /* medium header size */
103         int     mintu;          /* default min mtu */
104         int     maxtu;          /* default max mtu */
105         int     maclen;         /* mac address length  */
106         void    (*bind)(struct Ipifc *unused_Ipifc, int unused_int, 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,
117                              struct block *bp);
118
119         /* routes for router boards */
120         void    (*addroute)(struct Ipifc *ifc, int unused_int, uint8_t *u8p, uint8_t*,
121                                  uint8_t *u8p2, int);
122         void    (*remroute)(struct Ipifc *ifc, int i, uint8_t *u8p, 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 {
142         uint8_t local[IPaddrlen];
143         uint8_t mask[IPaddrlen];
144         uint8_t remote[IPaddrlen];
145         uint8_t net[IPaddrlen];
146         uint8_t tentative;      /* =1 => v6 dup disc on, =0 => confirmed unique */
147         uint8_t onlink;         /* =1 => onlink, =0 offlink. */
148         uint8_t autoflag;       /* v6 autonomous flag */
149         long    validlt;        /* v6 valid lifetime */
150         long    preflt;         /* v6 preferred lifetime */
151         long    origint;        /* time when addr was added */
152         struct Iplink   *link;          /* addresses linked to this lifc */
153         struct iplifc   *next;
154 };
155
156 /* binding twixt Ipself and Iplifc */
157 struct Iplink
158 {
159         struct Ipself   *self;
160         struct iplifc   *lifc;
161         struct Iplink   *selflink;      /* next link for this local address */
162         struct Iplink   *lifclink;      /* next link for this ifc */
163         uint32_t        expire;
164         struct Iplink   *next;          /* free list */
165         int     ref;
166 };
167
168 /* rfc 2461, pp.40--43. */
169
170 /* default values, one per stack */
171 struct routerparams {
172         int     mflag;
173         int     oflag;
174         int     maxraint;
175         int     minraint;
176         int     linkmtu;
177         int     reachtime;
178         int     rxmitra;
179         int     ttl;
180         int     routerlt;       
181 };
182
183 struct Ipifc
184 {
185         rwlock_t rwlock;
186         
187         struct conv     *conv;          /* link to its conversation structure */
188         char    dev[64];        /* device we're attached to */
189         struct medium   *m;             /* Media pointer */
190         int     maxtu;          /* Maximum transfer unit */
191         int     mintu;          /* Minumum tranfer unit */
192         int     mbps;           /* megabits per second */
193         void    *arg;           /* medium specific */
194         int     reassemble;     /* reassemble IP packets before forwarding */
195
196         /* these are used so that we can unbind on the fly */
197         spinlock_t      idlock;
198         uint8_t ifcid;          /* incremented each 'bind/unbind/add/remove' */
199         int     ref;            /* number of proc's using this Ipifc */
200         struct rendez   wait;           /* where unbinder waits for ref == 0 */
201         int     unbinding;
202
203         uint8_t mac[MAClen];    /* MAC address */
204
205         struct Iplifc   *lifc;          /* logical interfaces on this physical one */
206
207         uint32_t        in, out;        /* message statistics */
208         uint32_t        inerr, outerr;  /* ... */
209
210         uint8_t sendra6;        /* == 1 => send router advs on this ifc */
211         uint8_t recvra6;        /* == 1 => recv router advs on this ifc */
212         struct routerparams rp; /* router parameters as in RFC 2461, pp.40--43. 
213                                         used only if node is router */
214 };
215
216 /*
217  *  one per multicast-lifc pair used by a struct conv
218  */
219 struct Ipmulti
220 {
221         uint8_t ma[IPaddrlen];
222         uint8_t ia[IPaddrlen];
223         struct Ipmulti  *next;
224 };
225
226 /*
227  *  hash table for 2 ip addresses + 2 ports
228  */
229 enum
230 {
231         Nipht=          521,    /* convenient prime */
232
233         IPmatchexact=   0,      /* match on 4 tuple */
234         IPmatchany,             /* *!* */
235         IPmatchport,            /* *!port */
236         IPmatchaddr,            /* addr!* */
237         IPmatchpa,              /* addr!port */
238 };
239 struct Iphash
240 {
241         struct iphash   *next;
242         struct conv     *c;
243         int     match;
244 };
245
246 struct Iphash;
247 struct Ipht
248 {
249         spinlock_t lock;
250         struct Iphash   *tab[Nipht];
251 };
252 void iphtadd(struct Ipht*, struct conv*);
253 void iphtrem(struct Ipht*, struct conv*);
254 struct conv* iphtlook(struct Ipht *ht, uint8_t *sa, uint16_t sp, uint8_t *da, uint16_t dp);
255
256 /*
257  *  one per multiplexed Protocol
258  */
259 struct Proto
260 {
261         qlock_t qlock;
262         char*           name;           /* protocol name */
263         int             x;              /* protocol index */
264         int             ipproto;        /* ip protocol type */
265
266         char*           (*connect)(struct conv*, char **unused_char_pp_t, int);
267         char*           (*announce)(struct conv*, char **unused_char_pp_t, int);
268         char*           (*bind)(struct conv*, char **unused_char_pp_t, int);
269         int             (*state)(struct conv*, char *unused_char_p_t, int);
270         void            (*create)(struct conv*);
271         void            (*close)(struct conv*);
272         void            (*rcv)(struct Proto*, struct Ipifc*, struct block*);
273         char*           (*ctl)(struct conv*, char **unused_char_pp_t, int);
274         void            (*advise)(struct Proto*, struct block*, char *unused_char_p_t);
275         int             (*stats)(struct Proto*, char *unused_char_p_t, int);
276         int             (*local)(struct conv*, char *unused_char_p_t, int);
277         int             (*remote)(struct conv*, char *unused_char_p_t, int);
278         int             (*inuse)(struct conv*);
279         int             (*gc)(struct Proto*);   /* returns true if any conversations are freed */
280
281         struct Fs               *f;             /* file system this proto is part of */
282         struct conv             **conv;         /* array of conversations */
283         int             ptclsize;       /* size of per protocol ctl block */
284         int             nc;             /* number of conversations */
285         int             ac;
286         struct qid              qid;            /* qid for protocol directory */
287         uint16_t                nextport;
288         uint16_t                nextrport;
289
290         void            *priv;
291 };
292
293 /*
294  *  Stream for sending packets to user level
295  */
296 struct IProuter {
297         qlock_t qlock;
298         int     opens;
299         struct queue    *q;
300 };
301
302 /*
303  *  one per IP protocol stack
304  */
305 struct Fs
306 {
307         rwlock_t rwlock;
308         int     dev;
309
310         int     np;
311         struct Proto*   p[Maxproto+1];          /* list of supported protocols */
312         struct Proto*   t2p[256];               /* vector of all protocols */
313         struct Proto*   ipifc;                  /* kludge for ipifcremroute & ipifcaddroute */
314         struct Proto*   ipmux;                  /* kludge for finding an ip multiplexor */
315
316         struct IP       *ip;
317         struct Ipselftab        *self;
318         struct arp      *arp;
319         struct V6params *v6p;
320         struct IProuter iprouter;
321
322         struct route    *v4root[1<<Lroot];      /* v4 routing forest */
323         struct route    *v6root[1<<Lroot];      /* v6 routing forest */
324         struct route    *queue;                 /* used as temp when reinjecting routes */
325
326         //Netlog        *alog;
327         struct Ifclog   *ilog;
328
329         char    ndb[1024];              /* an ndb entry for this interface */
330         int     ndbvers;
331         long    ndbmtime;
332 };
333
334 /* one per default router known to host */
335 struct V6router {
336         uint8_t inuse;
337         struct Ipifc    *ifc;
338         int     ifcid;
339         uint8_t routeraddr[IPaddrlen];
340         long    ltorigin;
341         struct routerparams     rp;
342 };
343
344 struct hostparams {
345         int     rxmithost;
346 };
347
348 struct V6params
349 {
350         struct routerparams     rp;             /* v6 params, one copy per node now */
351         struct hostparams       hp;
352         struct V6router v6rlist[3];     /* max 3 default routers, currently */
353         int             cdrouter;       /* uses only v6rlist[cdrouter] if   */ 
354                                         /* cdrouter >= 0. */
355 };
356
357
358 int     Fsconnected(struct conv*, char *unused_char_p_t);
359 struct conv*    Fsnewcall(struct conv*, uint8_t *unused_uint8_p_t, uint16_t, uint8_t*, uint16_t, uint8_t unused_uint8_t);
360 int     Fspcolstats( char *unused_char_p_t, int);
361 int     Fsproto(struct Fs*, struct Proto*);
362 int     Fsbuiltinproto(struct Fs*, uint8_t unused_uint8_t);
363 struct conv*    Fsprotoclone(struct Proto*, char *unused_char_p_t);
364 struct Proto*   Fsrcvpcol(struct Fs*, uint8_t unused_uint8_t);
365 struct Proto*   Fsrcvpcolx(struct Fs*, uint8_t unused_uint8_t);
366 char*   Fsstdconnect(struct conv*, char **unused_char_pp_t, int);
367 char*   Fsstdannounce(struct conv*, char **unused_char_pp_t, int);
368 char*   Fsstdbind(struct conv*, char **unused_char_pp_t, int);
369 uint32_t        scalednconv(void);
370
371 /* 
372  *  logging
373  */
374 enum
375 {
376         Logip=          1<<1,
377         Logtcp=         1<<2,
378         Logfs=          1<<3,
379         Logil=          1<<4,
380         Logicmp=        1<<5,
381         Logudp=         1<<6,
382         Logcompress=    1<<7,
383         Logilmsg=       1<<8,
384         Loggre=         1<<9,
385         Logppp=         1<<10,
386         Logtcprxmt=     1<<11,
387         Logigmp=        1<<12,
388         Logudpmsg=      1<<13,
389         Logipmsg=       1<<14,
390         Logrudp=        1<<15,
391         Logrudpmsg=     1<<16,
392         Logesp=         1<<17,
393         Logtcpwin=      1<<18,
394 };
395
396 void    netloginit(struct Fs*);
397 void    netlogopen(struct Fs*);
398 void    netlogclose(struct Fs*);
399 void    netlogctl(struct Fs*, char *unused_char_p_t, int);
400 long    netlogread(struct Fs*, void*, uint32_t, long);
401 void    netlog(struct Fs*, int unused_int, char *unused_char_p_t, ...);
402 void    ifcloginit(struct Fs*);
403 long    ifclogread(struct Fs*, struct chan *,void*, uint32_t, long);
404 void    ifclog(struct Fs*, uint8_t *, int);
405 void    ifclogopen(struct Fs*, struct chan*);
406 void    ifclogclose(struct Fs*, struct chan*);
407
408 /*
409  *  iproute.c
410  */
411
412 enum
413 {
414
415         /* type bits */
416         Rv4=            (1<<0),         /* this is a version 4 route */
417         Rifc=           (1<<1),         /* this route is a directly connected interface */
418         Rptpt=          (1<<2),         /* this route is a pt to pt interface */
419         Runi=           (1<<3),         /* a unicast self address */
420         Rbcast=         (1<<4),         /* a broadcast self address */
421         Rmulti=         (1<<5),         /* a multicast self address */
422         Rproxy=         (1<<6),         /* this route should be proxied */
423 };
424
425 struct routewalk
426 {
427         int     o;
428         int     h;
429         char*   p;
430         char*   e;
431         void*   state;
432         void    (*walk)(struct route*, struct routewalk*);
433 };
434
435 struct  RouteTree
436 {
437         struct route*   right;
438         struct route*   left;
439         struct route*   mid;
440         uint8_t depth;
441         uint8_t type;
442         uint8_t ifcid;          /* must match ifc->id */
443         struct Ipifc    *ifc;
444         char    tag[4];
445         int     ref;
446 };
447
448 struct V4route
449 {
450         uint32_t        address;
451         uint32_t        endaddress;
452         uint8_t gate[IPv4addrlen];
453 };
454
455 struct V6route
456 {
457         uint32_t        address[IPllen];
458         uint32_t        endaddress[IPllen];
459         uint8_t gate[IPaddrlen];
460 };
461
462 struct route
463 {
464         struct RouteTree rt;
465
466         union {
467                 struct V6route  v6;
468                 struct V4route v4;
469         };
470 };
471 extern void     v4addroute(struct Fs *f, char *tag, uint8_t *a, uint8_t *mask,
472                               uint8_t *gate, int type);
473 extern void     v6addroute(struct Fs *f, char *tag, uint8_t *a, uint8_t *mask,
474                               uint8_t *gate, int type);
475 extern void     v4delroute(struct Fs *f, uint8_t *a, uint8_t *mask, int dolock);
476 extern void     v6delroute(struct Fs *f, uint8_t *a, uint8_t *mask, int dolock);
477 extern struct route*    v4lookup(struct Fs *f, uint8_t *a, struct conv *c);
478 extern struct route*    v6lookup(struct Fs *f, uint8_t *a, struct conv *c);
479 extern long     routeread(struct Fs *f, char *unused_char_p_t, uint32_t, int);
480 extern long     routewrite(struct Fs *f, struct chan*, char *unused_char_p_t, int);
481 extern void     routetype( int unused_int, char *unused_char_p_t);
482 extern void     ipwalkroutes(struct Fs*, struct routewalk*);
483 extern void     convroute(struct route*r, uint8_t *u8pt, uint8_t*u8pt1,
484                          uint8_t *u8pt2, char *unused_char_p_t, int*intp);
485
486 /*
487  *  devip.c
488  */
489
490 /*
491  *  Hanging off every ip channel's ->aux is the following structure.
492  *  It maintains the state used by devip and iproute.
493  */
494 struct IPaux
495 {
496         char    *owner;         /* the user that did the attach */
497         char    tag[4];
498 };
499
500 extern struct IPaux*    newipaux( char *unused_char_p_t, char*);
501
502 /*
503  *  arp.c
504  */
505 struct arpent
506 {
507         uint8_t ip[IPaddrlen];
508         uint8_t mac[MAClen];
509         struct medium   *type;                  /* media type */
510         struct arpent*  hash;
511         struct block*   hold;
512         struct block*   last;
513         unsigned int    ctime;                  /* time entry was created or refreshed */
514         unsigned int    utime;                  /* time entry was last used */
515         uint8_t state;
516         struct arpent   *nextrxt;               /* re-transmit chain */
517         unsigned int    rtime;                  /* time for next retransmission */
518         uint8_t rxtsrem;
519         struct Ipifc    *ifc;
520         uint8_t ifcid;                  /* must match ifc->id */
521 };
522
523 extern void     arpinit(struct Fs*);
524 extern int      arpread(struct arp*, char *unused_char_p_t, uint32_t, int);
525 extern int      arpwrite(struct Fs*, char *unused_char_p_t, int);
526 extern struct arpent*   arpget(struct arp*, struct block *bp, int version, struct Ipifc *ifc, uint8_t *ip,
527                              uint8_t *h);
528 extern void     arprelease(struct arp*, struct arpent *a);
529 extern struct block*    arpresolve(struct arp*, struct arpent *a,
530                                 struct medium *type, uint8_t *mac);
531 extern void     arpenter(struct Fs*, int version, uint8_t *ip,
532                             uint8_t *mac, int len, int norefresh);
533
534 /*
535  * ipaux.c
536  */
537
538 extern int      myetheraddr( uint8_t *unused_uint8_p_t, char *unused_char_p_t);
539 extern uint32_t parseip( uint8_t *unused_uint8_p_t, char *unused_char_p_t);
540 extern uint32_t parseipmask( uint8_t *unused_uint8_p_t, char *unused_char_p_t);
541 extern char*    v4parseip( uint8_t *unused_uint8_p_t, char *unused_char_p_t);
542 extern void     maskip(uint8_t *from, uint8_t *mask, uint8_t *to);
543 extern int      parsemac(uint8_t *to, char *from, int len);
544 extern uint8_t* defmask( uint8_t *unused_uint8_p_t);
545 extern int      isv4( uint8_t *unused_uint8_p_t);
546 extern void     v4tov6(uint8_t *v6, uint8_t *v4);
547 extern int      v6tov4(uint8_t *v4, uint8_t *v6);
548 //extern int    eipfmt(Fmt*);
549
550 #define ipmove(x, y) memmove(x, y, IPaddrlen)
551 #define ipcmp(x, y) ( (x)[IPaddrlen-1] != (y)[IPaddrlen-1] || memcmp(x, y, IPaddrlen) )
552
553 extern uint8_t IPv4bcast[IPaddrlen];
554 extern uint8_t IPv4bcastobs[IPaddrlen];
555 extern uint8_t IPv4allsys[IPaddrlen];
556 extern uint8_t IPv4allrouter[IPaddrlen];
557 extern uint8_t IPnoaddr[IPaddrlen];
558 extern uint8_t v4prefix[IPaddrlen];
559 extern uint8_t IPallbits[IPaddrlen];
560
561 #define NOW     TK2MS(MACHP(0)->ticks)
562
563 /*
564  *  media
565  */
566 extern struct medium    ethermedium;
567 extern struct medium    nullmedium;
568 extern struct medium    pktmedium;
569 extern struct medium    tripmedium;
570
571 /*
572  *  ipifc.c
573  */
574 extern struct medium*   ipfindmedium(char *name);
575 extern void     addipmedium(struct medium *med);
576 extern int      ipforme(struct Fs*, uint8_t *addr);
577 extern int      iptentative(struct Fs*, uint8_t *addr);
578 extern int      ipisbm(uint8_t *);
579 extern int      ipismulticast(uint8_t *);
580 extern struct Ipifc*    findipifc(struct Fs*, uint8_t *remote, int type);
581 extern void     findprimaryip(struct Fs*, uint8_t *unused_uint8_p_t);
582 extern void     findlocalip(struct Fs*, uint8_t *local, uint8_t *remote);
583 extern int      ipv4local(struct Ipifc *ifc, uint8_t *addr);
584 extern int      ipv6local(struct Ipifc *ifc, uint8_t *addr);
585 extern int      ipv6anylocal(struct Ipifc *ifc, uint8_t *addr);
586 extern struct iplifc*   iplocalonifc(struct Ipifc *ifc, uint8_t *ip);
587 extern int      ipproxyifc(struct Fs *f, struct Ipifc *ifc, uint8_t *ip);
588 extern int      ipismulticast(uint8_t *ip);
589 extern int      ipisbooting(void);
590 extern int      ipifccheckin(struct Ipifc *ifc, struct medium *med);
591 extern void     ipifccheckout(struct Ipifc *ifc);
592 extern int      ipifcgrab(struct Ipifc *ifc);
593 extern void     ipifcaddroute(struct Fs*, int unused_int, uint8_t *unused_uint8_p_t, uint8_t*, uint8_t*, int);
594 extern void     ipifcremroute(struct Fs*, int unused_int, uint8_t *u8pt, uint8_t *u8pt2);
595 extern void     ipifcremmulti(struct conv *c, uint8_t *ma, uint8_t *ia);
596 extern void     ipifcaddmulti(struct conv *c, uint8_t *ma, uint8_t *ia);
597 extern char*    ipifcrem(struct Ipifc *ifc, char **argv, int argc);
598 extern char*    ipifcadd(struct Ipifc *ifc, char **argv, int argc, int tentative,
599                              struct iplifc *lifcp);
600 extern long     ipselftabread(struct Fs*, char *a, uint32_t offset, int n);
601 extern char*    ipifcaddpref6(struct Ipifc *ifc, char**argv, int argc);
602 extern void     ipsendra6(struct Fs *f, int on);
603
604 /*
605  *  ip.c
606  */
607 extern void     iprouting(struct Fs*, int);
608 extern void     icmpnoconv(struct Fs*, struct block*);
609 extern void     icmpcantfrag(struct Fs*, struct block*, int);
610 extern void     icmpttlexceeded(struct Fs*, uint8_t *unused_uint8_p_t, struct block*);
611 extern uint16_t ipcsum( uint8_t *unused_uint8_p_t);
612 extern void     ipiput4(struct Fs*, struct Ipifc *unused_ipifc, struct block*);
613 extern void     ipiput6(struct Fs*, struct Ipifc *unused_ipifc, struct block*);
614 extern int      ipoput4(struct Fs*,
615                           struct block*, int unused_int, int, int, struct conv*);
616 extern int      ipoput6(struct Fs*,
617                           struct block*, int unused_int, int, int, struct conv*);
618 extern int      ipstats(struct Fs*, char *unused_char_p_t, int);
619 extern uint16_t ptclbsum( uint8_t *unused_uint8_p_t, int);
620 extern uint16_t ptclcsum(struct block*, int unused_int, int);
621 extern void     ip_init(struct Fs*);
622 extern void     update_mtucache( uint8_t *unused_uint8_p_t, uint32_t);
623 extern uint32_t restrict_mtu( uint8_t *unused_uint8_p_t, uint32_t);
624
625 /*
626  * bootp.c
627  */
628 char*   (*bootp)(struct Ipifc *unused_ipifc);
629 int     (*bootpread)( char *unused_char_p_t, uint32_t, int);
630
631 /*
632  *  iprouter.c
633  */
634 void    useriprouter(struct Fs*, struct Ipifc *unused_ipifc, struct block*);
635 void    iprouteropen(struct Fs*);
636 void    iprouterclose(struct Fs*);
637 long    iprouterread(struct Fs*, void*, int);
638
639 /*
640  *  resolving inferno/plan9 differences
641  */
642 struct chan*            commonfdtochan( int unused_int, int, int, int);
643 char*           commonuser(void);
644 char*           commonerror(void);
645
646 /*
647  * chandial.c
648  */
649 extern struct chan*     chandial( char *u1, char*u2, char*u3, struct chan**c);
650
651 /*
652  *  global to all of the stack
653  */
654 extern void     (*igmpreportfn)(struct Ipifc *unused_ipifc, uint8_t *unused_uint8_p_t);
655
656 /* IPV6 */
657 /* rfc 3513 defines the address prefices */
658 #define isv6mcast(addr)   ((addr)[0] == 0xff)
659 #define islinklocal(addr) ((addr)[0] == 0xfe && ((addr)[1] & 0xc0) == 0x80)
660 #define issitelocal(addr) ((addr)[0] == 0xfe && ((addr)[1] & 0xc0) == 0xc0)
661 #define isv6global(addr) (((addr)[0] & 0xe0) == 0x20)
662
663 #define optexsts(np) (nhgets((np)->ploadlen) > 24)
664 #define issmcast(addr) (memcmp((addr), v6solicitednode, 13) == 0)
665
666 /* from RFC 2460 */
667
668 typedef struct Ip6hdr     Ip6hdr;
669 typedef struct Opthdr     Opthdr;
670 typedef struct Routinghdr Routinghdr;
671 typedef struct Fraghdr6    Fraghdr6;
672
673 struct Ip6hdr {
674         uint8_t vcf[4];         // version:4, traffic class:8, flow label:20
675         uint8_t ploadlen[2];    // payload length: packet length - 40
676         uint8_t proto;          // next header type
677         uint8_t ttl;            // hop limit
678         uint8_t src[IPaddrlen];
679         uint8_t dst[IPaddrlen];
680 };
681
682 struct Opthdr {
683         uint8_t nexthdr;
684         uint8_t len;
685 };
686
687 struct Routinghdr {
688         uint8_t nexthdr;
689         uint8_t len;
690         uint8_t rtetype;
691         uint8_t segrem;
692 };
693
694 struct Fraghdr6 {
695         uint8_t nexthdr;
696         uint8_t res;
697         uint8_t offsetRM[2];    // Offset, Res, M flag
698         uint8_t id[4];
699 };
700
701
702 enum {                  /* Header Types */
703         HBH             = 0,    //?
704         ICMP            = 1,
705         IGMP            = 2,
706         GGP             = 3,
707         IPINIP          = 4,
708         ST              = 5,
709         TCP             = 6,
710         UDP             = 17,
711         ISO_TP4         = 29,
712         RH              = 43,
713         FH              = 44,
714         IDRP            = 45,
715         RSVP            = 46,
716         AH              = 51,
717         ESP             = 52,
718         ICMPv6          = 58,
719         NNH             = 59,
720         DOH             = 60,
721         ISO_IP          = 80,
722         IGRP            = 88,
723         OSPF            = 89,
724
725         Maxhdrtype      = 256,
726 };
727
728
729 enum {
730         //      multicast flgs and scop
731
732         well_known_flg                          = 0,
733         transient_flg                           = 1,
734
735         node_local_scop                         = 1,
736         link_local_scop                         = 2,
737         site_local_scop                         = 5,
738         org_local_scop                          = 8,
739         global_scop                             = 14,
740
741         //      various prefix lengths
742
743         SOLN_PREF_LEN                           = 13,
744
745         //      icmpv6 unreach codes
746         icmp6_no_route                          = 0,
747         icmp6_ad_prohib                         = 1,
748         icmp6_unassigned                        = 2,
749         icmp6_adr_unreach                       = 3,
750         icmp6_port_unreach                      = 4,
751         icmp6_unkn_code                         = 5,
752
753         //      various flags & constants
754
755         v6MINTU                                 = 1280,
756         HOP_LIMIT                               = 255,
757         ETHERHDR_LEN                            = 14,
758         IPV6HDR_LEN                             = 40,
759         IPV4HDR_LEN                             = 20,
760
761         //      option types
762
763         SRC_LLADDRESS                           = 1,
764         TARGET_LLADDRESS                        = 2,
765         PREFIX_INFO                             = 3,
766         REDIR_HEADER                            = 4,
767         MTU_OPTION                              = 5,
768
769         SRC_UNSPEC                              = 0,
770         SRC_UNI                                 = 1,
771         TARG_UNI                                = 2,
772         TARG_MULTI                              = 3,
773
774         t_unitent                               = 1,
775         t_uniproxy                              = 2,
776         t_unirany                               = 3,
777
778         //      Router constants (all times in milliseconds)
779
780         MAX_INITIAL_RTR_ADVERT_INTERVAL         = 16000,
781         MAX_INITIAL_RTR_ADVERTISEMENTS          = 3,
782         MAX_FINAL_RTR_ADVERTISEMENTS            = 3,
783         MIN_DELAY_BETWEEN_RAS                   = 3000,
784         MAX_RA_DELAY_TIME                       = 500,
785
786         //      Host constants
787
788         MAX_RTR_SOLICITATION_DELAY              = 1000,
789         RTR_SOLICITATION_INTERVAL               = 4000,
790         MAX_RTR_SOLICITATIONS                   = 3,
791
792         //      Node constants
793
794         MAX_MULTICAST_SOLICIT                   = 3,
795         MAX_UNICAST_SOLICIT                     = 3,
796         MAX_ANYCAST_DELAY_TIME                  = 1000,
797         MAX_NEIGHBOR_ADVERTISEMENT              = 3,
798         REACHABLE_TIME                          = 30000,
799         RETRANS_TIMER                           = 1000,
800         DELAY_FIRST_PROBE_TIME                  = 5000,
801
802 };
803
804 extern void ipv62smcast(uint8_t *, uint8_t *);
805 extern void icmpns(struct Fs *f, uint8_t* src, int suni, uint8_t* targ, int tuni,
806                    uint8_t* mac);
807 extern void icmpna(struct Fs *f, uint8_t* src, uint8_t* dst, uint8_t* targ, uint8_t* mac,
808                    uint8_t flags);
809 extern void icmpttlexceeded6(struct Fs *f, struct Ipifc *ifc,
810                              struct block *bp);
811 extern void icmppkttoobig6(struct Fs *f, struct Ipifc *ifc, struct block *bp);
812 extern void icmphostunr(struct Fs *f,
813                         struct Ipifc *ifc,
814                         struct block *bp, int code, int free);
815
816 extern uint8_t v6allnodesN[IPaddrlen];
817 extern uint8_t v6allnodesL[IPaddrlen];
818 extern uint8_t v6allroutersN[IPaddrlen];
819 extern uint8_t v6allroutersL[IPaddrlen];
820 extern uint8_t v6allnodesNmask[IPaddrlen];
821 extern uint8_t v6allnodesLmask[IPaddrlen];
822 extern uint8_t v6allroutersS[IPaddrlen];
823 extern uint8_t v6solicitednode[IPaddrlen];
824 extern uint8_t v6solicitednodemask[IPaddrlen];
825 extern uint8_t v6Unspecified[IPaddrlen];
826 extern uint8_t v6loopback[IPaddrlen];
827 extern uint8_t v6loopbackmask[IPaddrlen];
828 extern uint8_t v6linklocal[IPaddrlen];
829 extern uint8_t v6linklocalmask[IPaddrlen];
830 extern uint8_t v6sitelocal[IPaddrlen];
831 extern uint8_t v6sitelocalmask[IPaddrlen];
832 extern uint8_t v6glunicast[IPaddrlen];
833 extern uint8_t v6multicast[IPaddrlen];
834 extern uint8_t v6multicastmask[IPaddrlen];
835
836 extern int v6llpreflen;
837 extern int v6slpreflen;
838 extern int v6lbpreflen;
839 extern int v6mcpreflen;
840 extern int v6snpreflen;
841 extern int v6aNpreflen;
842 extern int v6aLpreflen;
843
844 extern int ReTransTimer;