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