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