ip.c is in
[akaros.git] / kern / src / net / ip.h
1
2 enum
3 {
4         Addrlen=        64,
5         Maxproto=       20,
6         Nhash=          64,
7         Maxincall=      5,
8         Nchans=         256,
9         MAClen=         16,             /* longest mac address */
10
11         MAXTTL=         255,
12         DFLTTOS=        0,
13
14         IPaddrlen=      16,
15         IPv4addrlen=    4,
16         IPv4off=        12,
17         IPllen=         4,
18
19         /* ip versions */
20         V4=             4,
21         V6=             6,
22         IP_VER4=        0x40,
23         IP_VER6=        0x60,
24
25         /* 2^Lroot trees in the root table */
26         Lroot=          10,
27
28         Maxpath =       64,
29 };
30
31 enum
32 {
33         Idle=           0,
34         Announcing=     1,
35         Announced=      2,
36         Connecting=     3,
37         Connected=      4,
38 };
39
40 /*
41  *  one per conversation directory
42  */
43 struct Conv
44 {
45         QLock;
46
47         int     x;                      /* conversation index */
48         Proto*  p;
49
50         int     restricted;             /* remote port is restricted */
51         uint    ttl;                    /* max time to live */
52         uint    tos;                    /* type of service */
53         int     ignoreadvice;           /* don't terminate connection on icmp errors */
54
55         uchar   ipversion;
56         uchar   laddr[IPaddrlen];       /* local IP address */
57         uchar   raddr[IPaddrlen];       /* remote IP address */
58         ushort  lport;                  /* local port number */
59         ushort  rport;                  /* remote port number */
60
61         char    *owner;                 /* protections */
62         int     perm;
63         int     inuse;                  /* opens of listen/data/ctl */
64         int     length;
65         int     state;
66
67         /* udp specific */
68         int     headers;                /* data src/dst headers in udp */
69         int     reliable;               /* true if reliable udp */
70
71         Conv*   incall;                 /* calls waiting to be listened for */
72         Conv*   next;
73
74         Queue*  rq;                     /* queued data waiting to be read */
75         Queue*  wq;                     /* queued data waiting to be written */
76         Queue*  eq;                     /* returned error packets */
77         Queue*  sq;                     /* snooping queue */
78         Ref     snoopers;               /* number of processes with snoop open */
79
80         Rendez  cr;
81         char    cerr[ERRMAX];
82
83         QLock   listenq;
84         Rendez  listenr;
85
86         Ipmulti *multi;                 /* multicast bindings for this interface */
87
88         void*   ptcl;                   /* protocol specific stuff */
89
90         Route   *r;                     /* last route used */
91         ulong   rgen;                   /* routetable generation for *r */
92 };
93
94 struct Medium
95 {
96         char    *name;
97         int     hsize;          /* medium header size */
98         int     mintu;          /* default min mtu */
99         int     maxtu;          /* default max mtu */
100         int     maclen;         /* mac address length  */
101         void    (*bind)(struct Ipifc*, int, char**);
102         void    (*unbind)(struct Ipifc*);
103         void    (*bwrite)(struct Ipifc *ifc, Block *b, int version, uchar *ip);
104
105         /* for arming interfaces to receive multicast */
106         void    (*addmulti)(struct Ipifc *ifc, uchar *a, uchar *ia);
107         void    (*remmulti)(struct Ipifc *ifc, uchar *a, uchar *ia);
108
109         /* process packets written to 'data' */
110         void    (*pktin)(struct Fs *f, struct Ipifc *ifc, Block *bp);
111
112         /* routes for router boards */
113         void    (*addroute)(struct Ipifc *ifc, int, uchar*, uchar*, uchar*, int);
114         void    (*remroute)(struct Ipifc *ifc, int, uchar*, uchar*);
115         void    (*flushroutes)(struct Ipifc *ifc);
116
117         /* for routing multicast groups */
118         void    (*joinmulti)(struct Ipifc *ifc, uchar *a, uchar *ia);
119         void    (*leavemulti)(struct Ipifc *ifc, uchar *a, uchar *ia);
120
121         /* address resolution */
122         void    (*ares)(struct Fs*, int, uchar*, uchar*, int, int);     /* resolve */
123         void    (*areg)(struct Ipifc*, uchar*);                 /* register */
124
125         /* v6 address generation */
126         void    (*pref2addr)(uchar *pref, uchar *ea);
127
128         int     unbindonclose;  /* if non-zero, unbind on last close */
129 };
130
131 /* logical interface associated with a physical one */
132 struct Iplifc
133 {
134         uchar   local[IPaddrlen];
135         uchar   mask[IPaddrlen];
136         uchar   remote[IPaddrlen];
137         uchar   net[IPaddrlen];
138         uchar   tentative;      /* =1 => v6 dup disc on, =0 => confirmed unique */
139         uchar   onlink;         /* =1 => onlink, =0 offlink. */
140         uchar   autoflag;       /* v6 autonomous flag */
141         long    validlt;        /* v6 valid lifetime */
142         long    preflt;         /* v6 preferred lifetime */
143         long    origint;        /* time when addr was added */
144         Iplink  *link;          /* addresses linked to this lifc */
145         Iplifc  *next;
146 };
147
148 /* binding twixt Ipself and Iplifc */
149 struct Iplink
150 {
151         Ipself  *self;
152         Iplifc  *lifc;
153         Iplink  *selflink;      /* next link for this local address */
154         Iplink  *lifclink;      /* next link for this ifc */
155         ulong   expire;
156         Iplink  *next;          /* free list */
157         int     ref;
158 };
159
160 /* rfc 2461, pp.40--43. */
161
162 /* default values, one per stack */
163 struct Routerparams {
164         int     mflag;
165         int     oflag;
166         int     maxraint;
167         int     minraint;
168         int     linkmtu;
169         int     reachtime;
170         int     rxmitra;
171         int     ttl;
172         int     routerlt;       
173 };
174
175 struct Hostparams {
176         int     rxmithost;
177 };
178
179 struct Ipifc
180 {
181         RWlock;
182         
183         Conv    *conv;          /* link to its conversation structure */
184         char    dev[64];        /* device we're attached to */
185         Medium  *m;             /* Media pointer */
186         int     maxtu;          /* Maximum transfer unit */
187         int     mintu;          /* Minumum tranfer unit */
188         int     mbps;           /* megabits per second */
189         void    *arg;           /* medium specific */
190         int     reassemble;     /* reassemble IP packets before forwarding */
191
192         /* these are used so that we can unbind on the fly */
193         Lock    idlock;
194         uchar   ifcid;          /* incremented each 'bind/unbind/add/remove' */
195         int     ref;            /* number of proc's using this ipifc */
196         Rendez  wait;           /* where unbinder waits for ref == 0 */
197         int     unbinding;
198
199         uchar   mac[MAClen];    /* MAC address */
200
201         Iplifc  *lifc;          /* logical interfaces on this physical one */
202
203         ulong   in, out;        /* message statistics */
204         ulong   inerr, outerr;  /* ... */
205
206         uchar   sendra6;        /* == 1 => send router advs on this ifc */
207         uchar   recvra6;        /* == 1 => recv router advs on this ifc */
208         Routerparams rp;        /* router parameters as in RFC 2461, pp.40--43. 
209                                         used only if node is router */
210 };
211
212 /*
213  *  one per multicast-lifc pair used by a Conv
214  */
215 struct Ipmulti
216 {
217         uchar   ma[IPaddrlen];
218         uchar   ia[IPaddrlen];
219         Ipmulti *next;
220 };
221
222 /*
223  *  hash table for 2 ip addresses + 2 ports
224  */
225 enum
226 {
227         Nipht=          521,    /* convenient prime */
228
229         IPmatchexact=   0,      /* match on 4 tuple */
230         IPmatchany,             /* *!* */
231         IPmatchport,            /* *!port */
232         IPmatchaddr,            /* addr!* */
233         IPmatchpa,              /* addr!port */
234 };
235 struct Iphash
236 {
237         Iphash  *next;
238         Conv    *c;
239         int     match;
240 };
241 struct Ipht
242 {
243         Lock;
244         Iphash  *tab[Nipht];
245 };
246 void iphtadd(Ipht*, Conv*);
247 void iphtrem(Ipht*, Conv*);
248 Conv* iphtlook(Ipht *ht, uchar *sa, ushort sp, uchar *da, ushort dp);
249
250 /*
251  *  one per multiplexed protocol
252  */
253 struct Proto
254 {
255         QLock;
256         char*           name;           /* protocol name */
257         int             x;              /* protocol index */
258         int             ipproto;        /* ip protocol type */
259
260         char*           (*connect)(Conv*, char**, int);
261         char*           (*announce)(Conv*, char**, int);
262         char*           (*bind)(Conv*, char**, int);
263         int             (*state)(Conv*, char*, int);
264         void            (*create)(Conv*);
265         void            (*close)(Conv*);
266         void            (*rcv)(Proto*, struct Ipifc*, Block*);
267         char*           (*ctl)(Conv*, char**, int);
268         void            (*advise)(Proto*, Block*, char*);
269         int             (*stats)(Proto*, char*, int);
270         int             (*local)(Conv*, char*, int);
271         int             (*remote)(Conv*, char*, int);
272         int             (*inuse)(Conv*);
273         int             (*gc)(Proto*);  /* returns true if any conversations are freed */
274
275         Fs              *f;             /* file system this proto is part of */
276         Conv            **conv;         /* array of conversations */
277         int             ptclsize;       /* size of per protocol ctl block */
278         int             nc;             /* number of conversations */
279         int             ac;
280         Qid             qid;            /* qid for protocol directory */
281         ushort          nextport;
282         ushort          nextrport;
283
284         void            *priv;
285 };
286
287 /*
288  *  Stream for sending packets to user level
289  */
290 struct IProuter {
291         QLock;
292         int     opens;
293         Queue   *q;
294 };
295
296 /*
297  *  one per IP protocol stack
298  */
299 struct Fs
300 {
301         RWlock;
302         int     dev;
303
304         int     np;
305         Proto*  p[Maxproto+1];          /* list of supported protocols */
306         Proto*  t2p[256];               /* vector of all protocols */
307         Proto*  ipifc;                  /* kludge for ipifcremroute & ipifcaddroute */
308         Proto*  ipmux;                  /* kludge for finding an ip multiplexor */
309
310         IP      *ip;
311         Ipselftab       *self;
312         Arp     *arp;
313         V6params        *v6p;
314         IProuter iprouter;
315
316         Route   *v4root[1<<Lroot];      /* v4 routing forest */
317         Route   *v6root[1<<Lroot];      /* v6 routing forest */
318         Route   *queue;                 /* used as temp when reinjecting routes */
319
320         Netlog  *alog;
321         Ifclog  *ilog;
322
323         char    ndb[1024];              /* an ndb entry for this interface */
324         int     ndbvers;
325         long    ndbmtime;
326 };
327
328 /* one per default router known to host */
329 struct V6router {
330         uchar   inuse;
331         Ipifc   *ifc;
332         int     ifcid;
333         uchar   routeraddr[IPaddrlen];
334         long    ltorigin;
335         Routerparams    rp;
336 };
337
338 struct V6params
339 {
340         Routerparams    rp;             /* v6 params, one copy per node now */
341         Hostparams      hp;
342         V6router        v6rlist[3];     /* max 3 default routers, currently */
343         int             cdrouter;       /* uses only v6rlist[cdrouter] if   */ 
344                                         /* cdrouter >= 0. */
345 };
346
347
348 int     Fsconnected(Conv*, char*);
349 Conv*   Fsnewcall(Conv*, uchar*, ushort, uchar*, ushort, uchar);
350 int     Fspcolstats(char*, int);
351 int     Fsproto(struct Fs*, Proto*);
352 int     Fsbuiltinproto(struct Fs*, uchar);
353 Conv*   Fsprotoclone(Proto*, char*);
354 Proto*  Fsrcvpcol(struct Fs*, uchar);
355 Proto*  Fsrcvpcolx(struct Fs*, uchar);
356 char*   Fsstdconnect(Conv*, char**, int);
357 char*   Fsstdannounce(Conv*, char**, int);
358 char*   Fsstdbind(Conv*, char**, int);
359 ulong   scalednconv(void);
360
361 /* 
362  *  logging
363  */
364 enum
365 {
366         Logip=          1<<1,
367         Logtcp=         1<<2,
368         Logfs=          1<<3,
369         Logil=          1<<4,
370         Logicmp=        1<<5,
371         Logudp=         1<<6,
372         Logcompress=    1<<7,
373         Logilmsg=       1<<8,
374         Loggre=         1<<9,
375         Logppp=         1<<10,
376         Logtcprxmt=     1<<11,
377         Logigmp=        1<<12,
378         Logudpmsg=      1<<13,
379         Logipmsg=       1<<14,
380         Logrudp=        1<<15,
381         Logrudpmsg=     1<<16,
382         Logesp=         1<<17,
383         Logtcpwin=      1<<18,
384 };
385
386 void    netloginit(struct Fs*);
387 void    netlogopen(struct Fs*);
388 void    netlogclose(struct Fs*);
389 void    netlogctl(struct Fs*, char*, int);
390 long    netlogread(struct Fs*, void*, ulong, long);
391 void    netlog(struct Fs*, int, char*, ...);
392 void    ifcloginit(struct Fs*);
393 long    ifclogread(struct Fs*, Chan *,void*, ulong, long);
394 void    ifclog(struct Fs*, uchar *, int);
395 void    ifclogopen(struct Fs*, Chan*);
396 void    ifclogclose(struct Fs*, Chan*);
397
398 /*
399  *  iproute.c
400  */
401 typedef struct RouteTree RouteTree;
402 typedef struct Routewalk Routewalk;
403 typedef struct V4route V4route;
404 typedef struct V6route V6route;
405
406 enum
407 {
408
409         /* type bits */
410         Rv4=            (1<<0),         /* this is a version 4 route */
411         Rifc=           (1<<1),         /* this route is a directly connected interface */
412         Rptpt=          (1<<2),         /* this route is a pt to pt interface */
413         Runi=           (1<<3),         /* a unicast self address */
414         Rbcast=         (1<<4),         /* a broadcast self address */
415         Rmulti=         (1<<5),         /* a multicast self address */
416         Rproxy=         (1<<6),         /* this route should be proxied */
417 };
418
419 struct Routewalk
420 {
421         int     o;
422         int     h;
423         char*   p;
424         char*   e;
425         void*   state;
426         void    (*walk)(Route*, Routewalk*);
427 };
428
429 struct  RouteTree
430 {
431         Route*  right;
432         Route*  left;
433         Route*  mid;
434         uchar   depth;
435         uchar   type;
436         uchar   ifcid;          /* must match ifc->id */
437         Ipifc   *ifc;
438         char    tag[4];
439         int     ref;
440 };
441
442 struct V4route
443 {
444         ulong   address;
445         ulong   endaddress;
446         uchar   gate[IPv4addrlen];
447 };
448
449 struct V6route
450 {
451         ulong   address[IPllen];
452         ulong   endaddress[IPllen];
453         uchar   gate[IPaddrlen];
454 };
455
456 struct Route
457 {
458         RouteTree;
459
460         union {
461                 V6route v6;
462                 V4route v4;
463         };
464 };
465 extern void     v4addroute(struct Fs *f, char *tag, uchar *a, uchar *mask, uchar *gate, int type);
466 extern void     v6addroute(struct Fs *f, char *tag, uchar *a, uchar *mask, uchar *gate, int type);
467 extern void     v4delroute(struct Fs *f, uchar *a, uchar *mask, int dolock);
468 extern void     v6delroute(struct Fs *f, uchar *a, uchar *mask, int dolock);
469 extern Route*   v4lookup(struct Fs *f, uchar *a, Conv *c);
470 extern Route*   v6lookup(struct Fs *f, uchar *a, Conv *c);
471 extern long     routeread(struct Fs *f, char*, ulong, int);
472 extern long     routewrite(struct Fs *f, Chan*, char*, int);
473 extern void     routetype(int, char*);
474 extern void     ipwalkroutes(struct Fs*, Routewalk*);
475 extern void     convroute(Route*, uchar*, uchar*, uchar*, char*, int*);
476
477 /*
478  *  devip.c
479  */
480
481 /*
482  *  Hanging off every ip channel's ->aux is the following structure.
483  *  It maintains the state used by devip and iproute.
484  */
485 struct IPaux
486 {
487         char    *owner;         /* the user that did the attach */
488         char    tag[4];
489 };
490
491 extern IPaux*   newipaux(char*, char*);
492
493 /*
494  *  arp.c
495  */
496 struct Arpent
497 {
498         uchar   ip[IPaddrlen];
499         uchar   mac[MAClen];
500         Medium  *type;                  /* media type */
501         Arpent* hash;
502         Block*  hold;
503         Block*  last;
504         uint    ctime;                  /* time entry was created or refreshed */
505         uint    utime;                  /* time entry was last used */
506         uchar   state;
507         Arpent  *nextrxt;               /* re-transmit chain */
508         uint    rtime;                  /* time for next retransmission */
509         uchar   rxtsrem;
510         Ipifc   *ifc;
511         uchar   ifcid;                  /* must match ifc->id */
512 };
513
514 extern void     arpinit(struct Fs*);
515 extern int      arpread(Arp*, char*, ulong, int);
516 extern int      arpwrite(struct Fs*, char*, int);
517 extern Arpent*  arpget(Arp*, Block *bp, int version, struct Ipifc *ifc, uchar *ip, uchar *h);
518 extern void     arprelease(Arp*, Arpent *a);
519 extern Block*   arpresolve(Arp*, Arpent *a, Medium *type, uchar *mac);
520 extern void     arpenter(struct Fs*, int version, uchar *ip, uchar *mac, int len, int norefresh);
521
522 /*
523  * ipaux.c
524  */
525
526 extern int      myetheraddr(uchar*, char*);
527 extern ulong    parseip(uchar*, char*);
528 extern ulong    parseipmask(uchar*, char*);
529 extern char*    v4parseip(uchar*, char*);
530 extern void     maskip(uchar *from, uchar *mask, uchar *to);
531 extern int      parsemac(uchar *to, char *from, int len);
532 extern uchar*   defmask(uchar*);
533 extern int      isv4(uchar*);
534 extern void     v4tov6(uchar *v6, uchar *v4);
535 extern int      v6tov4(uchar *v4, uchar *v6);
536 extern int      eipfmt(Fmt*);
537
538 #define ipmove(x, y) memmove(x, y, IPaddrlen)
539 #define ipcmp(x, y) ( (x)[IPaddrlen-1] != (y)[IPaddrlen-1] || memcmp(x, y, IPaddrlen) )
540
541 extern uchar IPv4bcast[IPaddrlen];
542 extern uchar IPv4bcastobs[IPaddrlen];
543 extern uchar IPv4allsys[IPaddrlen];
544 extern uchar IPv4allrouter[IPaddrlen];
545 extern uchar IPnoaddr[IPaddrlen];
546 extern uchar v4prefix[IPaddrlen];
547 extern uchar IPallbits[IPaddrlen];
548
549 #define NOW     TK2MS(MACHP(0)->ticks)
550
551 /*
552  *  media
553  */
554 extern Medium   ethermedium;
555 extern Medium   nullmedium;
556 extern Medium   pktmedium;
557 extern Medium   tripmedium;
558
559 /*
560  *  ipifc.c
561  */
562 extern Medium*  ipfindmedium(char *name);
563 extern void     addipmedium(Medium *med);
564 extern int      ipforme(struct Fs*, uchar *addr);
565 extern int      iptentative(struct Fs*, uchar *addr);
566 extern int      ipisbm(uchar *);
567 extern int      ipismulticast(uchar *);
568 extern struct Ipifc*    findipifc(struct Fs*, uchar *remote, int type);
569 extern void     findprimaryip(struct Fs*, uchar*);
570 extern void     findlocalip(struct Fs*, uchar *local, uchar *remote);
571 extern int      ipv4local(struct Ipifc *ifc, uchar *addr);
572 extern int      ipv6local(struct Ipifc *ifc, uchar *addr);
573 extern int      ipv6anylocal(struct Ipifc *ifc, uchar *addr);
574 extern Iplifc*  iplocalonifc(struct Ipifc *ifc, uchar *ip);
575 extern int      ipproxyifc(struct Fs *f, struct Ipifc *ifc, uchar *ip);
576 extern int      ipismulticast(uchar *ip);
577 extern int      ipisbooting(void);
578 extern int      ipifccheckin(struct Ipifc *ifc, Medium *med);
579 extern void     ipifccheckout(struct Ipifc *ifc);
580 extern int      ipifcgrab(struct Ipifc *ifc);
581 extern void     ipifcaddroute(struct Fs*, int, uchar*, uchar*, uchar*, int);
582 extern void     ipifcremroute(struct Fs*, int, uchar*, uchar*);
583 extern void     ipifcremmulti(Conv *c, uchar *ma, uchar *ia);
584 extern void     ipifcaddmulti(Conv *c, uchar *ma, uchar *ia);
585 extern char*    ipifcrem(struct Ipifc *ifc, char **argv, int argc);
586 extern char*    ipifcadd(struct Ipifc *ifc, char **argv, int argc, int tentative, Iplifc *lifcp);
587 extern long     ipselftabread(struct Fs*, char *a, ulong offset, int n);
588 extern char*    ipifcaddpref6(struct Ipifc *ifc, char**argv, int argc);
589 extern void     ipsendra6(struct Fs *f, int on);
590
591 /*
592  *  ip.c
593  */
594 extern void     iprouting(struct Fs*, int);
595 extern void     icmpnoconv(struct Fs*, Block*);
596 extern void     icmpcantfrag(struct Fs*, Block*, int);
597 extern void     icmpttlexceeded(struct Fs*, uchar*, Block*);
598 extern ushort   ipcsum(uchar*);
599 extern void     ipiput4(struct Fs*, struct Ipifc*, Block*);
600 extern void     ipiput6(struct Fs*, struct Ipifc*, Block*);
601 extern int      ipoput4(struct Fs*, Block*, int, int, int, Conv*);
602 extern int      ipoput6(struct Fs*, Block*, int, int, int, Conv*);
603 extern int      ipstats(struct Fs*, char*, int);
604 extern ushort   ptclbsum(uchar*, int);
605 extern ushort   ptclcsum(Block*, int, int);
606 extern void     ip_init(struct Fs*);
607 extern void     update_mtucache(uchar*, ulong);
608 extern ulong    restrict_mtu(uchar*, ulong);
609
610 /*
611  * bootp.c
612  */
613 char*   (*bootp)(struct Ipifc*);
614 int     (*bootpread)(char*, ulong, int);
615
616 /*
617  *  iprouter.c
618  */
619 void    useriprouter(struct Fs*, struct Ipifc*, Block*);
620 void    iprouteropen(struct Fs*);
621 void    iprouterclose(struct Fs*);
622 long    iprouterread(struct Fs*, void*, int);
623
624 /*
625  *  resolving inferno/plan9 differences
626  */
627 Chan*           commonfdtochan(int, int, int, int);
628 char*           commonuser(void);
629 char*           commonerror(void);
630
631 /*
632  * chandial.c
633  */
634 extern Chan*    chandial(char*, char*, char*, Chan**);
635
636 /*
637  *  global to all of the stack
638  */
639 extern void     (*igmpreportfn)(struct Ipifc*, uchar*);