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