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
5 * Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
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.
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:
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
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
39 MAClen = 16, /* longest mac address */
55 /* 2^Lroot trees in the root table */
77 * one per conversation directory
83 int x; /* conversation index */
86 int restricted; /* remote port is restricted */
87 uint32_t ttl; /* max time to live */
88 uint32_t tos; /* type of service */
89 int ignoreadvice; /* don't terminate connection on icmp errors */
92 uint8_t laddr[IPaddrlen]; /* local IP address */
93 uint8_t raddr[IPaddrlen]; /* remote IP address */
94 uint16_t lport; /* local port number */
95 uint16_t rport; /* remote port number */
97 char *owner; /* protections */
99 int inuse; /* opens of listen/data/ctl */
102 struct queue *rq_save; /* rq created by proto, saved during bypass */
103 struct queue *wq_save; /* wq created by proto, saved during bypass */
106 int headers; /* data src/dst headers in udp */
107 int reliable; /* true if reliable udp */
109 struct conv *incall; /* calls waiting to be listened for */
112 struct queue *rq; /* queued data waiting to be read */
113 struct queue *wq; /* queued data waiting to be written */
114 struct queue *eq; /* returned error packets */
115 struct queue *sq; /* snooping queue */
116 atomic_t snoopers; /* number of processes with snoop open */
118 struct fdtap_slist data_taps;
119 struct fdtap_slist listen_taps;
126 struct rendez listenr;
128 struct Ipmulti *multi; /* multicast bindings for this interface */
130 void *ptcl; /* Protocol specific stuff */
132 struct route *r; /* last route used */
133 uint32_t rgen; /* routetable generation for *r */
141 int hsize; /* medium header size */
142 int mintu; /* default min mtu */
143 int maxtu; /* default max mtu */
144 int maclen; /* mac address length */
145 void (*bind) (struct Ipifc * unused_Ipifc, int unused_int,
146 char **unused_char_pp_t);
147 void (*unbind) (struct Ipifc * unused_Ipifc);
148 void (*bwrite) (struct Ipifc * ifc,
149 struct block * b, int version, uint8_t * ip);
151 /* for arming interfaces to receive multicast */
152 void (*addmulti) (struct Ipifc * ifc, uint8_t * a, uint8_t * ia);
153 void (*remmulti) (struct Ipifc * ifc, uint8_t * a, uint8_t * ia);
155 /* process packets written to 'data' */
156 void (*pktin) (struct Fs * f, struct Ipifc * ifc, struct block * bp);
158 /* routes for router boards */
159 void (*addroute) (struct Ipifc * ifc, int unused_int, uint8_t * u8p,
160 uint8_t *, uint8_t * u8p2, int);
161 void (*remroute) (struct Ipifc * ifc, int i, uint8_t * u8p,
163 void (*flushroutes) (struct Ipifc * ifc);
165 /* for routing multicast groups */
166 void (*joinmulti) (struct Ipifc * ifc, uint8_t * a, uint8_t * ia);
167 void (*leavemulti) (struct Ipifc * ifc, uint8_t * a, uint8_t * ia);
169 /* address resolution */
170 void (*ares) (struct Fs *, int unused_int, uint8_t * unused_uint8_p_t, uint8_t *, int, int); /* resolve */
171 void (*areg) (struct Ipifc * unused_Ipifc, uint8_t * unused_uint8_p_t); /* register */
173 /* v6 address generation */
174 void (*pref2addr) (uint8_t * pref, uint8_t * ea);
176 int unbindonclose; /* if non-zero, unbind on last close */
179 /* logical interface associated with a physical one */
181 uint8_t local[IPaddrlen];
182 uint8_t mask[IPaddrlen];
183 uint8_t remote[IPaddrlen];
184 uint8_t net[IPaddrlen];
185 uint8_t tentative; /* =1 => v6 dup disc on, =0 => confirmed unique */
186 uint8_t onlink; /* =1 => onlink, =0 offlink. */
187 uint8_t autoflag; /* v6 autonomous flag */
188 uint64_t validlt; /* v6 valid lifetime */
189 uint64_t preflt; /* v6 preferred lifetime */
190 uint64_t origint; /* time when addr was added */
191 struct Iplink *link; /* addresses linked to this lifc */
195 /* binding twixt Ipself and Iplifc */
199 struct Iplink *selflink; /* next link for this local address */
200 struct Iplink *lifclink; /* next link for this ifc */
202 struct Iplink *next; /* free list */
206 /* rfc 2461, pp.40--43. */
208 /* default values, one per stack */
209 struct routerparams {
224 struct conv *conv; /* link to its conversation structure */
225 char dev[64]; /* device we're attached to */
226 struct medium *m; /* Media pointer */
227 int maxtu; /* Maximum transfer unit */
228 int mintu; /* Minumum tranfer unit */
229 unsigned int feat; /* Offload features */
230 int mbps; /* megabits per second */
231 void *arg; /* medium specific */
232 int reassemble; /* reassemble IP packets before forwarding */
234 /* these are used so that we can unbind on the fly */
236 uint8_t ifcid; /* incremented each 'bind/unbind/add/remove' */
237 int ref; /* number of proc's using this Ipifc */
238 struct rendez wait; /* where unbinder waits for ref == 0 */
241 uint8_t mac[MAClen]; /* MAC address */
243 struct Iplifc *lifc; /* logical interfaces on this physical one */
245 uint32_t in, out; /* message statistics */
246 uint32_t inerr, outerr; /* ... */
249 uint8_t sendra6; /* == 1 => send router advs on this ifc */
250 uint8_t recvra6; /* == 1 => recv router advs on this ifc */
251 struct routerparams rp; /* router parameters as in RFC 2461, pp.40--43.
252 used only if node is router */
256 * one per multicast-lifc pair used by a struct conv
259 uint8_t ma[IPaddrlen];
260 uint8_t ia[IPaddrlen];
261 struct Ipmulti *next;
265 * hash table for 2 ip addresses + 2 ports
268 Nipht = 521, /* convenient prime */
270 IPmatchexact = 0, /* match on 4 tuple */
271 IPmatchany, /* *!* */
272 IPmatchport, /* *!port */
273 IPmatchaddr, /* addr!* */
274 IPmatchpa, /* addr!port */
285 struct Iphash *tab[Nipht];
287 void iphtadd(struct Ipht *, struct conv *);
288 void iphtrem(struct Ipht *, struct conv *);
289 struct conv *iphtlook(struct Ipht *ht, uint8_t * sa, uint16_t sp, uint8_t * da,
291 void dump_ipht(struct Ipht *ht);
294 * one per multiplexed Protocol
298 char *name; /* protocol name */
299 int x; /* protocol index */
300 int ipproto; /* ip protocol type */
302 void (*connect)(struct conv *, char **, int);
303 void (*announce)(struct conv *, char **, int);
304 void (*bind)(struct conv *, char **, int);
305 void (*bypass)(struct conv *, char **, int);
306 int (*state) (struct conv *, char *unused_char_p_t, int);
307 void (*create) (struct conv *);
308 void (*close) (struct conv *);
309 void (*shutdown)(struct conv *, int);
310 void (*rcv) (struct Proto *, struct Ipifc *, struct block *);
311 void (*ctl)(struct conv *, char **, int);
312 void (*advise) (struct Proto *, struct block *, char *unused_char_p_t);
313 int (*stats) (struct Proto *, char *unused_char_p_t, int);
314 int (*local) (struct conv *, char *unused_char_p_t, int);
315 int (*remote) (struct conv *, char *unused_char_p_t, int);
316 int (*inuse) (struct conv *);
317 int (*gc) (struct Proto *); /* returns true if any conversations are freed */
319 struct Fs *f; /* file system this proto is part of */
320 struct conv **conv; /* array of conversations */
321 int ptclsize; /* size of per protocol ctl block */
322 int nc; /* number of conversations */
324 struct qid qid; /* qid for protocol directory */
332 * Stream for sending packets to user level
341 * one per IP protocol stack
348 struct Proto *p[Maxproto + 1]; /* list of supported protocols */
349 struct Proto *t2p[256]; /* vector of all protocols */
350 struct Proto *ipifc; /* kludge for ipifcremroute & ipifcaddroute */
351 struct Proto *ipmux; /* kludge for finding an ip multiplexor */
354 struct Ipselftab *self;
356 struct V6params *v6p;
357 struct IProuter iprouter;
359 struct route *v4root[1 << Lroot]; /* v4 routing forest */
360 struct route *v6root[1 << Lroot]; /* v6 routing forest */
361 struct route *queue; /* used as temp when reinjecting routes */
366 char ndb[1024]; /* an ndb entry for this interface */
371 /* one per default router known to host */
376 uint8_t routeraddr[IPaddrlen];
378 struct routerparams rp;
386 struct routerparams rp; /* v6 params, one copy per node now */
387 struct hostparams hp;
388 struct V6router v6rlist[3]; /* max 3 default routers, currently */
389 int cdrouter; /* uses only v6rlist[cdrouter] if */
393 int Fsconnected(struct conv *, char *unused_char_p_t);
394 struct conv *Fsnewcall(struct conv *, uint8_t * unused_uint8_p_t, uint16_t,
395 uint8_t *, uint16_t, uint8_t unused_uint8_t);
396 int Fspcolstats(char *unused_char_p_t, int);
397 int Fsproto(struct Fs *, struct Proto *);
398 int Fsbuiltinproto(struct Fs *, uint8_t unused_uint8_t);
399 struct conv *Fsprotoclone(struct Proto *, char *unused_char_p_t);
400 struct Proto *Fsrcvpcol(struct Fs *, uint8_t unused_uint8_t);
401 struct Proto *Fsrcvpcolx(struct Fs *, uint8_t unused_uint8_t);
402 void Fsstdconnect(struct conv *, char **, int);
403 void Fsstdannounce(struct conv *, char **, int);
404 void Fsstdbypass(struct conv *, char **, int);
405 void Fsstdbind(struct conv *, char **, int);
406 uint32_t scalednconv(void);
407 void bypass_or_drop(struct conv *cv, struct block *bp);
419 Logcompress = 1 << 7,
423 Logtcprxmt = 1 << 11,
428 Logrudpmsg = 1 << 16,
430 Logtcpreset = 1 << 18,
431 Logtcpverbose = 1 << 19,
434 void netloginit(struct Fs *);
435 void netlogopen(struct Fs *);
436 void netlogclose(struct Fs *);
437 void netlogctl(struct Fs *, char *unused_char_p_t, int);
438 long netlogread(struct Fs *, void *, uint32_t, long);
439 void netlog(struct Fs *, int unused_int, char *unused_char_p_t, ...);
440 void ifcloginit(struct Fs *);
441 long ifclogread(struct Fs *, struct chan *, void *, uint32_t, long);
442 void ifclog(struct Fs *, uint8_t *, int);
443 void ifclogopen(struct Fs *, struct chan *);
444 void ifclogclose(struct Fs *, struct chan *);
453 Rv4 = (1 << 0), /* this is a version 4 route */
454 Rifc = (1 << 1), /* this route is a directly connected interface */
455 Rptpt = (1 << 2), /* this route is a pt to pt interface */
456 Runi = (1 << 3), /* a unicast self address */
457 Rbcast = (1 << 4), /* a broadcast self address */
458 Rmulti = (1 << 5), /* a multicast self address */
459 Rproxy = (1 << 6), /* this route should be proxied */
468 void (*walk) (struct route *, struct routewalk *);
477 uint8_t ifcid; /* must match ifc->id */
486 uint8_t gate[IPv4addrlen];
490 uint32_t address[IPllen];
491 uint32_t endaddress[IPllen];
492 uint8_t gate[IPaddrlen];
503 extern void v4addroute(struct Fs *f, char *tag, uint8_t * a, uint8_t * mask,
504 uint8_t * gate, int type);
505 extern void v6addroute(struct Fs *f, char *tag, uint8_t * a, uint8_t * mask,
506 uint8_t * gate, int type);
507 extern void v4delroute(struct Fs *f, uint8_t * a, uint8_t * mask, int dolock);
508 extern void v6delroute(struct Fs *f, uint8_t * a, uint8_t * mask, int dolock);
509 extern struct route *v4lookup(struct Fs *f, uint8_t * a, struct conv *c);
510 extern struct route *v6lookup(struct Fs *f, uint8_t * a, struct conv *c);
511 extern long routeread(struct Fs *f, char *unused_char_p_t, uint32_t, int);
512 extern long routewrite(struct Fs *f, struct chan *, char *unused_char_p_t, int);
513 extern void routetype(int unused_int, char *unused_char_p_t);
514 extern void ipwalkroutes(struct Fs *, struct routewalk *);
515 extern void convroute(struct route *r, uint8_t * u8pt, uint8_t * u8pt1,
516 uint8_t * u8pt2, char *unused_char_p_t, int *intp);
523 * Hanging off every ip channel's ->aux is the following structure.
524 * It maintains the state used by devip and iproute.
527 char *owner; /* the user that did the attach */
531 extern struct IPaux *newipaux(char *unused_char_p_t, char *);
537 uint8_t ip[IPaddrlen];
539 struct medium *type; /* media type */
543 uint64_t ctime; /* time entry was created or refreshed */
544 uint64_t utime; /* time entry was last used */
546 struct arpent *nextrxt; /* re-transmit chain */
547 uint64_t rtime; /* time for next retransmission */
550 uint8_t ifcid; /* must match ifc->id */
553 extern void arpinit(struct Fs *);
554 extern int arpread(struct arp *, char *unused_char_p_t, uint32_t, int);
555 extern int arpwrite(struct Fs *, char *unused_char_p_t, long);
556 extern struct arpent *arpget(struct arp *, struct block *bp, int version,
557 struct Ipifc *ifc, uint8_t * ip, uint8_t * h);
558 extern void arprelease(struct arp *, struct arpent *a);
559 extern struct block *arpresolve(struct arp *, struct arpent *a,
560 struct medium *type, uint8_t * mac);
561 extern void arpenter(struct Fs *, int version, uint8_t * ip,
562 uint8_t * mac, int len, int norefresh);
568 extern int myetheraddr(uint8_t * unused_uint8_p_t, char *unused_char_p_t);
569 extern uint32_t parseip(uint8_t * unused_uint8_p_t, char *unused_char_p_t);
570 extern uint32_t parseipmask(uint8_t * unused_uint8_p_t, char *unused_char_p_t);
571 extern char *v4parseip(uint8_t * unused_uint8_p_t, char *unused_char_p_t);
572 extern void maskip(uint8_t * from, uint8_t * mask, uint8_t * to);
573 extern int parsemac(uint8_t * to, char *from, int len);
574 extern uint8_t *defmask(uint8_t * unused_uint8_p_t);
575 extern int isv4(uint8_t * unused_uint8_p_t);
576 extern void v4tov6(uint8_t * v6, uint8_t * v4);
577 extern int v6tov4(uint8_t * v4, uint8_t * v6);
578 //extern int eipfmt(Fmt*);
582 #warning "Potentially unaligned IP addrs!"
584 static inline void ipmove(unsigned char *x, unsigned char *y)
586 uint32_t *a = (uint32_t *)x;
587 uint32_t *b = (uint32_t *)y;
595 static inline long ipcmp(unsigned char *x, unsigned char *y)
597 uint32_t *a = (uint32_t *)x;
598 uint32_t *b = (uint32_t *)y;
599 return (a[0] ^ b[0]) | (a[1] ^ b[1]) |
600 (a[2] ^ b[2]) | (a[3] ^ b[3]);
604 extern uint8_t IPv4_loopback[IPaddrlen];
605 extern uint8_t IPv4_zeroes[IPaddrlen];
606 extern uint8_t IPv4bcast[IPaddrlen];
607 extern uint8_t IPv4bcastobs[IPaddrlen];
608 extern uint8_t IPv4allsys[IPaddrlen];
609 extern uint8_t IPv4allrouter[IPaddrlen];
610 extern uint8_t IPnoaddr[IPaddrlen];
611 extern uint8_t v4prefix[IPaddrlen];
612 extern uint8_t IPallbits[IPaddrlen];
617 extern struct medium ethermedium;
618 extern struct medium nullmedium;
619 extern struct medium pktmedium;
620 extern struct medium tripmedium;
625 extern struct medium *ipfindmedium(char *name);
626 extern void addipmedium(struct medium *med);
627 extern int ipforme(struct Fs *, uint8_t * addr);
628 extern int iptentative(struct Fs *, uint8_t * addr);
629 extern int ipisbm(uint8_t *);
630 extern int ipismulticast(uint8_t *);
631 extern struct Ipifc *findipifc(struct Fs *, uint8_t * remote, int type);
632 extern void findprimaryip(struct Fs *, uint8_t * unused_uint8_p_t);
633 extern void findlocalip(struct Fs *, uint8_t * local, uint8_t * remote);
634 extern int ipv4local(struct Ipifc *ifc, uint8_t * addr);
635 extern int ipv6local(struct Ipifc *ifc, uint8_t * addr);
636 extern int ipv6anylocal(struct Ipifc *ifc, uint8_t * addr);
637 extern struct Iplifc *iplocalonifc(struct Ipifc *ifc, uint8_t * ip);
638 extern int ipproxyifc(struct Fs *f, struct Ipifc *ifc, uint8_t * ip);
639 extern int ipismulticast(uint8_t * ip);
640 extern int ipisbooting(void);
641 extern int ipifccheckin(struct Ipifc *ifc, struct medium *med);
642 extern void ipifccheckout(struct Ipifc *ifc);
643 extern int ipifcgrab(struct Ipifc *ifc);
644 extern void ipifcaddroute(struct Fs *, int unused_int,
645 uint8_t * unused_uint8_p_t, uint8_t *, uint8_t *,
647 extern void ipifcremroute(struct Fs *, int unused_int, uint8_t * u8pt,
649 extern void ipifcremmulti(struct conv *c, uint8_t * ma, uint8_t * ia);
650 extern void ipifcaddmulti(struct conv *c, uint8_t * ma, uint8_t * ia);
651 extern void ipifc_trace_block(struct Ipifc *ifc, struct block *bp);
652 extern long ipselftabread(struct Fs *, char *a, uint32_t offset, int n);
653 extern void ipsendra6(struct Fs *f, int on);
658 extern void iprouting(struct Fs *, int);
659 extern void icmpnoconv(struct Fs *, struct block *);
660 extern void icmpcantfrag(struct Fs *, struct block *, int);
661 extern void icmpttlexceeded(struct Fs *, uint8_t * unused_uint8_p_t,
664 uint16_t ipchecksum(uint8_t *addr, int len);
665 extern uint16_t ipcsum(uint8_t * unused_uint8_p_t);
666 extern void ipiput4(struct Fs *, struct Ipifc *unused_ipifc, struct block *);
667 extern void ipiput6(struct Fs *, struct Ipifc *unused_ipifc, struct block *);
668 extern int ipoput4(struct Fs *,
669 struct block *, int unused_int, int, int, struct conv *);
670 extern int ipoput6(struct Fs *,
671 struct block *, int unused_int, int, int, struct conv *);
672 extern int ipstats(struct Fs *, char *unused_char_p_t, int);
673 extern uint16_t ptclbsum(uint8_t * unused_uint8_p_t, int);
674 extern uint16_t ptclcsum(struct block *, int unused_int, int);
675 extern void ip_init(struct Fs *);
676 extern void update_mtucache(uint8_t * unused_uint8_p_t, uint32_t);
677 extern uint32_t restrict_mtu(uint8_t * unused_uint8_p_t, uint32_t);
679 static inline void ptclcsum_finalize(struct block *bp, unsigned int feat)
681 unsigned int flag = bp->flag & BCKSUM_FLAGS;
684 if (flag && (flag & feat) != flag) {
685 csum_store = bp->rp + bp->checksum_start + bp->checksum_offset;
686 /* NOTE pseudo-header partial checksum (if any) is already placed at
687 * csum_store (e.g. tcpcksum), and the ptclcsum() below will include
688 * that partial checksum as part of the calculation.
690 hnputs((uint16_t *)csum_store,
691 ptclcsum(bp, bp->checksum_start,
692 BLEN(bp) - bp->checksum_start));
693 bp->flag &= ~BCKSUM_FLAGS;
700 void useriprouter(struct Fs *, struct Ipifc *unused_ipifc, struct block *);
701 void iprouteropen(struct Fs *);
702 void iprouterclose(struct Fs *);
703 long iprouterread(struct Fs *, void *, int);
706 * resolving inferno/plan9 differences
708 struct chan *commonfdtochan(int unused_int, int, int, int);
709 char *commonuser(void);
710 char *commonerror(void);
715 extern struct chan *chandial(char *u1, char *u2, char *u3, struct chan **c);
718 * global to all of the stack
720 extern void (*igmpreportfn) (struct Ipifc * unused_ipifc,
721 uint8_t * unused_uint8_p_t);
724 /* rfc 3513 defines the address prefices */
725 #define isv6mcast(addr) ((addr)[0] == 0xff)
726 #define islinklocal(addr) ((addr)[0] == 0xfe && ((addr)[1] & 0xc0) == 0x80)
727 #define issitelocal(addr) ((addr)[0] == 0xfe && ((addr)[1] & 0xc0) == 0xc0)
728 #define isv6global(addr) (((addr)[0] & 0xe0) == 0x20)
730 #define optexsts(np) (nhgets((np)->ploadlen) > 24)
731 #define issmcast(addr) (memcmp((addr), v6solicitednode, 13) == 0)
735 typedef struct Ip6hdr Ip6hdr;
736 typedef struct Opthdr Opthdr;
737 typedef struct Routinghdr Routinghdr;
738 typedef struct Fraghdr6 Fraghdr6;
741 uint8_t vcf[4]; // version:4, traffic class:8, flow label:20
742 uint8_t ploadlen[2]; // payload length: packet length - 40
743 uint8_t proto; // next header type
744 uint8_t ttl; // hop limit
745 uint8_t src[IPaddrlen];
746 uint8_t dst[IPaddrlen];
764 uint8_t offsetRM[2]; // Offset, Res, M flag
768 enum { /* Header Types */
795 // multicast flgs and scop
806 // various prefix lengths
810 // icmpv6 unreach codes
813 icmp6_unassigned = 2,
814 icmp6_adr_unreach = 3,
815 icmp6_port_unreach = 4,
818 // various flags & constants
829 TARGET_LLADDRESS = 2,
843 // Router constants (all times in milliseconds)
845 MAX_INITIAL_RTR_ADVERT_INTERVAL = 16000,
846 MAX_INITIAL_RTR_ADVERTISEMENTS = 3,
847 MAX_FINAL_RTR_ADVERTISEMENTS = 3,
848 MIN_DELAY_BETWEEN_RAS = 3000,
849 MAX_RA_DELAY_TIME = 500,
853 MAX_RTR_SOLICITATION_DELAY = 1000,
854 RTR_SOLICITATION_INTERVAL = 4000,
855 MAX_RTR_SOLICITATIONS = 3,
859 MAX_MULTICAST_SOLICIT = 3,
860 MAX_UNICAST_SOLICIT = 3,
861 MAX_ANYCAST_DELAY_TIME = 1000,
862 MAX_NEIGHBOR_ADVERTISEMENT = 3,
863 REACHABLE_TIME = 30000,
864 RETRANS_TIMER = 1000,
865 DELAY_FIRST_PROBE_TIME = 5000,
869 extern void ipv62smcast(uint8_t *, uint8_t *);
870 extern void icmpns(struct Fs *f, uint8_t * src, int suni, uint8_t * targ,
871 int tuni, uint8_t * mac);
872 extern void icmpna(struct Fs *f, uint8_t * src, uint8_t * dst, uint8_t * targ,
873 uint8_t * mac, uint8_t flags);
874 extern void icmpttlexceeded6(struct Fs *f, struct Ipifc *ifc, struct block *bp);
875 extern void icmppkttoobig6(struct Fs *f, struct Ipifc *ifc, struct block *bp);
876 extern void icmphostunr(struct Fs *f,
878 struct block *bp, int code, int free);
880 extern uint8_t v6allnodesN[IPaddrlen];
881 extern uint8_t v6allnodesL[IPaddrlen];
882 extern uint8_t v6allroutersN[IPaddrlen];
883 extern uint8_t v6allroutersL[IPaddrlen];
884 extern uint8_t v6allnodesNmask[IPaddrlen];
885 extern uint8_t v6allnodesLmask[IPaddrlen];
886 extern uint8_t v6allroutersS[IPaddrlen];
887 extern uint8_t v6solicitednode[IPaddrlen];
888 extern uint8_t v6solicitednodemask[IPaddrlen];
889 extern uint8_t v6Unspecified[IPaddrlen];
890 extern uint8_t v6loopback[IPaddrlen];
891 extern uint8_t v6loopbackmask[IPaddrlen];
892 extern uint8_t v6linklocal[IPaddrlen];
893 extern uint8_t v6linklocalmask[IPaddrlen];
894 extern uint8_t v6sitelocal[IPaddrlen];
895 extern uint8_t v6sitelocalmask[IPaddrlen];
896 extern uint8_t v6glunicast[IPaddrlen];
897 extern uint8_t v6multicast[IPaddrlen];
898 extern uint8_t v6multicastmask[IPaddrlen];
900 extern int v6llpreflen;
901 extern int v6slpreflen;
902 extern int v6lbpreflen;
903 extern int v6mcpreflen;
904 extern int v6snpreflen;
905 extern int v6aNpreflen;
906 extern int v6aLpreflen;
908 extern int ReTransTimer;
910 int kdial(char *dest, char *local, char *dir, int *cfdp);
912 /* network interfaces and ethernet */
930 * Macros to manage Qid's used for multiplexed devices
932 #define NETTYPE(x) (((uint32_t)x)&0x1f)
933 /* The net's ID + 1 is stored starting at 1 << 5. So ID 0 = 32, ID 1 = 64, and
934 * NETID == -1 means no netid */
935 #define NETID(x) (((uint32_t)(x) >> 5) - 1)
936 #define NETQID(i,t) ((((uint32_t)(i) + 1) << 5) | (t))
939 * one per multiplexed connection
946 char owner[KNAMELEN];
948 int type; /* multiplexor type */
949 int prom; /* promiscuous mode */
950 int scan; /* base station scanning interval */
951 int bridge; /* bridge mode */
952 int headersonly; /* headers only - no data */
953 uint8_t maddr[8]; /* bitmask of multicast addresses requested */
954 int nmaddr; /* number of multicast addresses */
956 struct queue *in; /* input buffer */
963 struct netaddr *next; /* allocation chain */
964 struct netaddr *hnext;
965 uint8_t addr[Nmaxaddr];
966 int ref; /* leaving this as an int, not a kref. no reaping, yet. */
970 * These flags overlap with block flags, to make detecting unsupported
971 * offloads efficient.
973 #define NETF_BASE_SHIFT (NS_SHIFT_MAX + 1)
974 #define NETF_PADMIN_SHIFT (NETF_BASE_SHIFT + 0)
975 #define NETF_SG_SHIFT (NETF_BASE_SHIFT + 1)
976 #define NETF_LRO_SHIFT (NETF_BASE_SHIFT + 2)
978 NETF_IPCK = (1 << NS_IPCK_SHIFT), /* xmit ip checksum */
979 NETF_UDPCK = (1 << NS_UDPCK_SHIFT), /* xmit udp checksum */
980 NETF_TCPCK = (1 << NS_TCPCK_SHIFT), /* xmit tcp checksum */
981 NETF_PADMIN = (1 << NETF_PADMIN_SHIFT), /* device pads to mintu */
982 NETF_SG = (1 << NETF_SG_SHIFT), /* device can do scatter/gather */
983 NETF_TSO = (1 << NS_TSO_SHIFT), /* device can do TSO */
984 NETF_LRO = (1 << NETF_LRO_SHIFT), /* device can do LRO */
987 * a network interface
994 char name[KNAMELEN]; /* for top level directory */
995 int nfile; /* max number of Netfiles */
999 int limit; /* flow control */
1000 int alen; /* address length */
1001 int mbps; /* megabits per sec */
1002 int link; /* link status */
1003 unsigned int feat; /* dev features */
1004 uint8_t addr[Nmaxaddr];
1005 uint8_t bcast[Nmaxaddr];
1006 struct netaddr *maddr; /* known multicast addresses */
1007 int nmaddr; /* number of known multicast addresses */
1008 struct netaddr *mhash[Nmhash]; /* hash table of multicast addresses */
1009 int prom; /* number of promiscuous opens */
1010 int scan; /* number of base station scanners */
1011 int all; /* number of -1 multiplexors */
1017 int crcs; /* input crc errors */
1018 int oerrs; /* output errors */
1019 int frames; /* framing errors */
1020 int overflows; /* packet overflows */
1021 int buffs; /* buffering errors */
1022 int soverflows; /* software overflow */
1024 /* routines for touching the hardware */
1026 void (*promiscuous) (void *, int);
1027 void (*multicast) (void *, uint8_t * unused_uint8_p_t, int);
1028 void (*scanbs) (void *, unsigned nt); /* scan for base stations */
1031 void netifinit(struct ether *, char *, int, uint32_t);
1032 struct walkqid *netifwalk(struct ether *, struct chan *, struct chan *,
1035 struct chan *netifopen(struct ether *, struct chan *, int);
1036 void netifclose(struct ether *, struct chan *);
1037 long netifread(struct ether *, struct chan *, void *, long, uint32_t);
1038 struct block *netifbread(struct ether *, struct chan *, long, uint32_t);
1039 long netifwrite(struct ether *, struct chan *, void *, long);
1040 int netifwstat(struct ether *, struct chan *, uint8_t *, int);
1041 int netifstat(struct ether *, struct chan *, uint8_t *, int);
1042 int activemulti(struct ether *, uint8_t *, int);
1049 ETHERMINTU = 60, /* minimum transmit size */
1050 ETHERMAXTU = 1500, /* maximum transmit size */
1051 ETHERHDRSIZE = 14, /* size of an ethernet header */
1055 uint8_t d[Eaddrlen];
1056 uint8_t s[Eaddrlen];
1075 uint8_t ea[Eaddrlen];
1078 void (*attach) (struct ether *); /* filled in by reset routine */
1079 void (*closed) (struct ether *);
1080 void (*detach) (struct ether *);
1081 void (*transmit) (struct ether *);
1082 long (*ifstat) (struct ether *, void *, long, uint32_t);
1083 long (*ctl) (struct ether *, void *, long); /* custom ctl messages */
1084 void (*power) (struct ether *, int); /* power on/off */
1085 void (*shutdown) (struct ether *); /* shutdown hardware before reboot */
1087 int pcmslot; /* PCMCIA */
1088 int fullduplex; /* non-zero if full duplex */
1089 int vlanid; /* non-zero if vlan */
1093 qlock_t vlq; /* array change */
1095 struct ether *vlans[MaxFID];
1100 extern struct block *etheriq(struct ether *, struct block *, int);
1101 extern void addethercard(char *unused_char_p_t, int (*)(struct ether *));
1102 extern int archether(int unused_int, struct ether *);
1104 #define NEXT_RING(x, len) (((x) + 1) % (len))
1105 #define PREV_RING(x, len) (((x) == 0) ? (len) - 1: (x) - 1)