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