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