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