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