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