| typedef struct Conv Conv; |
| typedef struct Fragment4 Fragment4; |
| typedef struct Fragment6 Fragment6; |
| typedef struct Fs Fs; |
| typedef union Hwaddr Hwaddr; |
| typedef struct IP IP; |
| typedef struct IPaux IPaux; |
| typedef struct Ip4hdr Ip4hdr; |
| typedef struct Ipfrag Ipfrag; |
| typedef struct Ipself Ipself; |
| typedef struct Ipselftab Ipselftab; |
| typedef struct Iplink Iplink; |
| typedef struct Iplifc Iplifc; |
| typedef struct Ipmulti Ipmulti; |
| typedef struct Ipifc Ipifc; |
| typedef struct Iphash Iphash; |
| typedef struct Ipht Ipht; |
| typedef struct Netlog Netlog; |
| typedef struct Medium Medium; |
| typedef struct Proto Proto; |
| typedef struct Arpent Arpent; |
| typedef struct Arp Arp; |
| typedef struct Route Route; |
| |
| typedef struct Routerparams Routerparams; |
| typedef struct Hostparams Hostparams; |
| typedef struct v6router v6router; |
| typedef struct v6params v6params; |
| |
| #pragma incomplete Arp |
| #pragma incomplete Ipself |
| #pragma incomplete Ipselftab |
| #pragma incomplete IP |
| #pragma incomplete Netlog |
| |
| enum |
| { |
| Addrlen= 64, |
| Maxproto= 20, |
| Nhash= 64, |
| Maxincall= 128, |
| Nchans= 1024, |
| MAClen= 16, /* longest mac address */ |
| |
| MAXTTL= 255, |
| DFLTTOS= 0, |
| |
| IPaddrlen= 16, |
| IPv4addrlen= 4, |
| IPv4off= 12, |
| IPllen= 4, |
| |
| /* ip versions */ |
| V4= 4, |
| V6= 6, |
| IP_VER4= 0x40, |
| IP_VER6= 0x60, |
| IP_HLEN4= 5, /* v4: Header length in words */ |
| IP_DF= 0x4000, /* v4: Don't fragment */ |
| IP_MF= 0x2000, /* v4: More fragments */ |
| IP4HDR= 20, /* sizeof(Ip4hdr) */ |
| IP_MAX= 64*1024, /* Max. Internet packet size, v4 & v6 */ |
| |
| /* 2^Lroot trees in the root table */ |
| Lroot= 10, |
| |
| Maxpath = 64, |
| }; |
| |
| enum |
| { |
| Idle= 0, |
| Announcing= 1, |
| Announced= 2, |
| Connecting= 3, |
| Connected= 4, |
| }; |
| |
| /* MIB II counters */ |
| enum |
| { |
| Forwarding, |
| DefaultTTL, |
| InReceives, |
| InHdrErrors, |
| InAddrErrors, |
| ForwDatagrams, |
| InUnknownProtos, |
| InDiscards, |
| InDelivers, |
| OutRequests, |
| OutDiscards, |
| OutNoRoutes, |
| ReasmTimeout, |
| ReasmReqds, |
| ReasmOKs, |
| ReasmFails, |
| FragOKs, |
| FragFails, |
| FragCreates, |
| |
| Nipstats, |
| }; |
| |
| struct Fragment4 |
| { |
| Block* blist; |
| Fragment4* next; |
| ulong src; |
| ulong dst; |
| ushort id; |
| ulong age; |
| }; |
| |
| struct Fragment6 |
| { |
| Block* blist; |
| Fragment6* next; |
| uchar src[IPaddrlen]; |
| uchar dst[IPaddrlen]; |
| uint id; |
| ulong age; |
| }; |
| |
| struct Ipfrag |
| { |
| ushort foff; |
| ushort flen; |
| |
| uchar payload[]; |
| }; |
| |
| #define IPFRAGSZ offsetof(Ipfrag, payload[0]) |
| |
| /* an instance of IP */ |
| struct IP |
| { |
| uvlong stats[Nipstats]; |
| |
| QLock fraglock4; |
| Fragment4* flisthead4; |
| Fragment4* fragfree4; |
| Ref id4; |
| |
| QLock fraglock6; |
| Fragment6* flisthead6; |
| Fragment6* fragfree6; |
| Ref id6; |
| |
| int iprouting; /* true if we route like a gateway */ |
| }; |
| |
| /* on the wire packet header */ |
| struct Ip4hdr |
| { |
| uchar vihl; /* Version and header length */ |
| uchar tos; /* Type of service */ |
| uchar length[2]; /* packet length */ |
| uchar id[2]; /* ip->identification */ |
| uchar frag[2]; /* Fragment information */ |
| uchar ttl; /* Time to live */ |
| uchar proto; /* Protocol */ |
| uchar cksum[2]; /* Header checksum */ |
| uchar src[4]; /* IP source */ |
| uchar dst[4]; /* IP destination */ |
| }; |
| |
| /* |
| * one per conversation directory |
| */ |
| struct Conv |
| { |
| QLock; |
| |
| int x; /* conversation index */ |
| Proto* p; |
| |
| int restricted; /* remote port is restricted */ |
| uint ttl; /* max time to live */ |
| uint tos; /* type of service */ |
| int ignoreadvice; /* don't terminate connection on icmp errors */ |
| |
| uchar ipversion; |
| uchar laddr[IPaddrlen]; /* local IP address */ |
| uchar raddr[IPaddrlen]; /* remote IP address */ |
| ushort lport; /* local port number */ |
| ushort rport; /* remote port number */ |
| |
| char *owner; /* protections */ |
| int perm; |
| int inuse; /* opens of listen/data/ctl */ |
| int length; |
| int state; |
| |
| int maxfragsize; /* If set, used for fragmentation */ |
| |
| /* udp specific */ |
| int headers; /* data src/dst headers in udp */ |
| int reliable; /* true if reliable udp */ |
| |
| Conv* incall; /* calls waiting to be listened for */ |
| Conv* next; |
| |
| Queue* rq; /* queued data waiting to be read */ |
| Queue* wq; /* queued data waiting to be written */ |
| Queue* eq; /* returned error packets */ |
| Queue* sq; /* snooping queue */ |
| Ref snoopers; /* number of processes with snoop open */ |
| |
| QLock car; |
| Rendez cr; |
| char cerr[ERRMAX]; |
| |
| QLock listenq; |
| Rendez listenr; |
| |
| Ipmulti *multi; /* multicast bindings for this interface */ |
| |
| void* ptcl; /* protocol specific stuff */ |
| |
| Route *r; /* last route used */ |
| ulong rgen; /* routetable generation for *r */ |
| }; |
| |
| struct Medium |
| { |
| char *name; |
| int hsize; /* medium header size */ |
| int mintu; /* default min mtu */ |
| int maxtu; /* default max mtu */ |
| int maclen; /* mac address length */ |
| void (*bind)(Ipifc*, int, char**); |
| void (*unbind)(Ipifc*); |
| void (*bwrite)(Ipifc *ifc, Block *b, int version, uchar *ip); |
| |
| /* for arming interfaces to receive multicast */ |
| void (*addmulti)(Ipifc *ifc, uchar *a, uchar *ia); |
| void (*remmulti)(Ipifc *ifc, uchar *a, uchar *ia); |
| |
| /* process packets written to 'data' */ |
| void (*pktin)(Fs *f, Ipifc *ifc, Block *bp); |
| |
| /* routes for router boards */ |
| void (*addroute)(Ipifc *ifc, int, uchar*, uchar*, uchar*, int); |
| void (*remroute)(Ipifc *ifc, int, uchar*, uchar*); |
| void (*flushroutes)(Ipifc *ifc); |
| |
| /* for routing multicast groups */ |
| void (*joinmulti)(Ipifc *ifc, uchar *a, uchar *ia); |
| void (*leavemulti)(Ipifc *ifc, uchar *a, uchar *ia); |
| |
| /* address resolution */ |
| void (*ares)(Fs*, int, uchar*, uchar*, int, int); /* resolve */ |
| void (*areg)(Ipifc*, uchar*); /* register */ |
| |
| /* v6 address generation */ |
| void (*pref2addr)(uchar *pref, uchar *ea); |
| |
| int unbindonclose; /* if non-zero, unbind on last close */ |
| }; |
| |
| /* logical interface associated with a physical one */ |
| struct Iplifc |
| { |
| uchar local[IPaddrlen]; |
| uchar mask[IPaddrlen]; |
| uchar remote[IPaddrlen]; |
| uchar net[IPaddrlen]; |
| uchar tentative; /* =1 => v6 dup disc on, =0 => confirmed unique */ |
| uchar onlink; /* =1 => onlink, =0 offlink. */ |
| uchar autoflag; /* v6 autonomous flag */ |
| long validlt; /* v6 valid lifetime */ |
| long preflt; /* v6 preferred lifetime */ |
| long origint; /* time when addr was added */ |
| Iplink *link; /* addresses linked to this lifc */ |
| Iplifc *next; |
| }; |
| |
| /* binding twixt Ipself and Iplifc */ |
| struct Iplink |
| { |
| Ipself *self; |
| Iplifc *lifc; |
| Iplink *selflink; /* next link for this local address */ |
| Iplink *lifclink; /* next link for this ifc */ |
| ulong expire; |
| Iplink *next; /* free list */ |
| int ref; |
| }; |
| |
| /* rfc 2461, pp.40—43. */ |
| |
| /* default values, one per stack */ |
| struct Routerparams { |
| int mflag; /* flag: managed address configuration */ |
| int oflag; /* flag: other stateful configuration */ |
| int maxraint; /* max. router adv interval (ms) */ |
| int minraint; /* min. router adv interval (ms) */ |
| int linkmtu; /* mtu options */ |
| int reachtime; /* reachable time */ |
| int rxmitra; /* retransmit interval */ |
| int ttl; /* cur hop count limit */ |
| int routerlt; /* router lifetime */ |
| }; |
| |
| struct Hostparams { |
| int rxmithost; |
| }; |
| |
| struct Ipifc |
| { |
| RWlock; |
| |
| Conv *conv; /* link to its conversation structure */ |
| char dev[64]; /* device we're attached to */ |
| Medium *medium; /* Media pointer */ |
| int maxtu; /* Maximum transfer unit */ |
| int mintu; /* Minumum tranfer unit */ |
| int mbps; /* megabits per second */ |
| void *arg; /* medium specific */ |
| int reassemble; /* reassemble IP packets before forwarding */ |
| |
| /* these are used so that we can unbind on the fly */ |
| Lock idlock; |
| uchar ifcid; /* incremented each 'bind/unbind/add/remove' */ |
| int ref; /* number of proc's using this ipifc */ |
| Rendez wait; /* where unbinder waits for ref == 0 */ |
| int unbinding; |
| |
| uchar mac[MAClen]; /* MAC address */ |
| |
| Iplifc *lifc; /* logical interfaces on this physical one */ |
| |
| ulong in, out; /* message statistics */ |
| ulong inerr, outerr; /* ... */ |
| |
| uchar sendra6; /* flag: send router advs on this ifc */ |
| uchar recvra6; /* flag: recv router advs on this ifc */ |
| Routerparams rp; /* router parameters as in RFC 2461, pp.40—43. |
| used only if node is router */ |
| }; |
| |
| /* |
| * one per multicast-lifc pair used by a Conv |
| */ |
| struct Ipmulti |
| { |
| uchar ma[IPaddrlen]; |
| uchar ia[IPaddrlen]; |
| Ipmulti *next; |
| }; |
| |
| /* |
| * hash table for 2 ip addresses + 2 ports |
| */ |
| enum |
| { |
| Nipht= 521, /* convenient prime */ |
| |
| IPmatchexact= 0, /* match on 4 tuple */ |
| IPmatchany, /* *!* */ |
| IPmatchport, /* *!port */ |
| IPmatchaddr, /* addr!* */ |
| IPmatchpa, /* addr!port */ |
| }; |
| struct Iphash |
| { |
| Iphash *next; |
| Conv *c; |
| int match; |
| }; |
| struct Ipht |
| { |
| Lock; |
| Iphash *tab[Nipht]; |
| }; |
| void iphtadd(Ipht*, Conv*); |
| void iphtrem(Ipht*, Conv*); |
| Conv* iphtlook(Ipht *ht, uchar *sa, ushort sp, uchar *da, ushort dp); |
| |
| /* |
| * one per multiplexed protocol |
| */ |
| struct Proto |
| { |
| QLock; |
| char* name; /* protocol name */ |
| int x; /* protocol index */ |
| int ipproto; /* ip protocol type */ |
| |
| char* (*connect)(Conv*, char**, int); |
| char* (*announce)(Conv*, char**, int); |
| char* (*bind)(Conv*, char**, int); |
| int (*state)(Conv*, char*, int); |
| void (*create)(Conv*); |
| void (*close)(Conv*); |
| void (*rcv)(Proto*, Ipifc*, Block*); |
| char* (*ctl)(Conv*, char**, int); |
| void (*advise)(Proto*, Block*, char*); |
| int (*stats)(Proto*, char*, int); |
| int (*local)(Conv*, char*, int); |
| int (*remote)(Conv*, char*, int); |
| int (*inuse)(Conv*); |
| int (*gc)(Proto*); /* returns true if any conversations are freed */ |
| |
| Fs *f; /* file system this proto is part of */ |
| Conv **conv; /* array of conversations */ |
| int ptclsize; /* size of per protocol ctl block */ |
| int nc; /* number of conversations */ |
| int ac; |
| Qid qid; /* qid for protocol directory */ |
| ushort nextrport; |
| |
| void *priv; |
| }; |
| |
| |
| /* |
| * one per IP protocol stack |
| */ |
| struct Fs |
| { |
| RWlock; |
| int dev; |
| |
| int np; |
| Proto* p[Maxproto+1]; /* list of supported protocols */ |
| Proto* t2p[256]; /* vector of all protocols */ |
| Proto* ipifc; /* kludge for ipifcremroute & ipifcaddroute */ |
| Proto* ipmux; /* kludge for finding an ip multiplexor */ |
| |
| IP *ip; |
| Ipselftab *self; |
| Arp *arp; |
| v6params *v6p; |
| |
| Route *v4root[1<<Lroot]; /* v4 routing forest */ |
| Route *v6root[1<<Lroot]; /* v6 routing forest */ |
| Route *queue; /* used as temp when reinjecting routes */ |
| |
| Netlog *alog; |
| |
| char ndb[1024]; /* an ndb entry for this interface */ |
| int ndbvers; |
| long ndbmtime; |
| }; |
| |
| /* one per default router known to host */ |
| struct v6router { |
| uchar inuse; |
| Ipifc *ifc; |
| int ifcid; |
| uchar routeraddr[IPaddrlen]; |
| long ltorigin; |
| Routerparams rp; |
| }; |
| |
| struct v6params |
| { |
| Routerparams rp; /* v6 params, one copy per node now */ |
| Hostparams hp; |
| v6router v6rlist[3]; /* max 3 default routers, currently */ |
| int cdrouter; /* uses only v6rlist[cdrouter] if */ |
| /* cdrouter >= 0. */ |
| }; |
| |
| |
| int Fsconnected(Conv*, char*); |
| Conv* Fsnewcall(Conv*, uchar*, ushort, uchar*, ushort, uchar); |
| int Fspcolstats(char*, int); |
| int Fsproto(Fs*, Proto*); |
| int Fsbuiltinproto(Fs*, uchar); |
| Conv* Fsprotoclone(Proto*, char*); |
| Proto* Fsrcvpcol(Fs*, uchar); |
| Proto* Fsrcvpcolx(Fs*, uchar); |
| char* Fsstdconnect(Conv*, char**, int); |
| char* Fsstdannounce(Conv*, char**, int); |
| char* Fsstdbind(Conv*, char**, int); |
| ulong scalednconv(void); |
| void closeconv(Conv*); |
| /* |
| * logging |
| */ |
| enum |
| { |
| Logip= 1<<1, |
| Logtcp= 1<<2, |
| Logfs= 1<<3, |
| Logicmp= 1<<5, |
| Logudp= 1<<6, |
| Logcompress= 1<<7, |
| Loggre= 1<<9, |
| Logppp= 1<<10, |
| Logtcprxmt= 1<<11, |
| Logigmp= 1<<12, |
| Logudpmsg= 1<<13, |
| Logipmsg= 1<<14, |
| Logrudp= 1<<15, |
| Logrudpmsg= 1<<16, |
| Logesp= 1<<17, |
| Logtcpwin= 1<<18, |
| }; |
| |
| void netloginit(Fs*); |
| void netlogopen(Fs*); |
| void netlogclose(Fs*); |
| void netlogctl(Fs*, char*, int); |
| long netlogread(Fs*, void*, ulong, long); |
| void netlog(Fs*, int, char*, ...); |
| void ifcloginit(Fs*); |
| long ifclogread(Fs*, Chan *,void*, ulong, long); |
| void ifclog(Fs*, uchar *, int); |
| void ifclogopen(Fs*, Chan*); |
| void ifclogclose(Fs*, Chan*); |
| |
| #pragma varargck argpos netlog 3 |
| |
| /* |
| * iproute.c |
| */ |
| typedef struct RouteTree RouteTree; |
| typedef struct Routewalk Routewalk; |
| typedef struct V4route V4route; |
| typedef struct V6route V6route; |
| |
| enum |
| { |
| |
| /* type bits */ |
| Rv4= (1<<0), /* this is a version 4 route */ |
| Rifc= (1<<1), /* this route is a directly connected interface */ |
| Rptpt= (1<<2), /* this route is a pt to pt interface */ |
| Runi= (1<<3), /* a unicast self address */ |
| Rbcast= (1<<4), /* a broadcast self address */ |
| Rmulti= (1<<5), /* a multicast self address */ |
| Rproxy= (1<<6), /* this route should be proxied */ |
| }; |
| |
| struct Routewalk |
| { |
| int o; |
| int h; |
| char* p; |
| char* e; |
| void* state; |
| void (*walk)(Route*, Routewalk*); |
| }; |
| |
| struct RouteTree |
| { |
| Route* right; |
| Route* left; |
| Route* mid; |
| uchar depth; |
| uchar type; |
| uchar ifcid; /* must match ifc->id */ |
| Ipifc *ifc; |
| char tag[4]; |
| int ref; |
| }; |
| |
| struct V4route |
| { |
| ulong address; |
| ulong endaddress; |
| uchar gate[IPv4addrlen]; |
| }; |
| |
| struct V6route |
| { |
| ulong address[IPllen]; |
| ulong endaddress[IPllen]; |
| uchar gate[IPaddrlen]; |
| }; |
| |
| struct Route |
| { |
| RouteTree; |
| |
| union { |
| V6route v6; |
| V4route v4; |
| }; |
| }; |
| extern void v4addroute(Fs *f, char *tag, uchar *a, uchar *mask, uchar *gate, int type); |
| extern void v6addroute(Fs *f, char *tag, uchar *a, uchar *mask, uchar *gate, int type); |
| extern void v4delroute(Fs *f, uchar *a, uchar *mask, int dolock); |
| extern void v6delroute(Fs *f, uchar *a, uchar *mask, int dolock); |
| extern Route* v4lookup(Fs *f, uchar *a, Conv *c); |
| extern Route* v6lookup(Fs *f, uchar *a, Conv *c); |
| extern long routeread(Fs *f, char*, ulong, int); |
| extern long routewrite(Fs *f, Chan*, char*, int); |
| extern void routetype(int, char*); |
| extern void ipwalkroutes(Fs*, Routewalk*); |
| extern void convroute(Route*, uchar*, uchar*, uchar*, char*, int*); |
| |
| /* |
| * devip.c |
| */ |
| |
| /* |
| * Hanging off every ip channel's ->aux is the following structure. |
| * It maintains the state used by devip and iproute. |
| */ |
| struct IPaux |
| { |
| char *owner; /* the user that did the attach */ |
| char tag[4]; |
| }; |
| |
| extern IPaux* newipaux(char*, char*); |
| |
| /* |
| * arp.c |
| */ |
| struct Arpent |
| { |
| uchar ip[IPaddrlen]; |
| uchar mac[MAClen]; |
| Medium *type; /* media type */ |
| Arpent* hash; |
| Block* hold; |
| Block* last; |
| uint ctime; /* time entry was created or refreshed */ |
| uint utime; /* time entry was last used */ |
| uchar state; |
| Arpent *nextrxt; /* re-transmit chain */ |
| uint rtime; /* time for next retransmission */ |
| uchar rxtsrem; |
| Ipifc *ifc; |
| uchar ifcid; /* must match ifc->id */ |
| }; |
| |
| extern void arpinit(Fs*); |
| extern int arpread(Arp*, char*, ulong, int); |
| extern int arpwrite(Fs*, char*, int); |
| extern Arpent* arpget(Arp*, Block *bp, int version, Ipifc *ifc, uchar *ip, uchar *h); |
| extern void arprelease(Arp*, Arpent *a); |
| extern Block* arpresolve(Arp*, Arpent *a, Medium *type, uchar *mac); |
| extern void arpenter(Fs*, int version, uchar *ip, uchar *mac, int len, int norefresh); |
| |
| /* |
| * ipaux.c |
| */ |
| |
| extern int myetheraddr(uchar*, char*); |
| extern vlong parseip(uchar*, char*); |
| extern vlong parseipmask(uchar*, char*); |
| extern char* v4parseip(uchar*, char*); |
| extern void maskip(uchar *from, uchar *mask, uchar *to); |
| extern int parsemac(uchar *to, char *from, int len); |
| extern uchar* defmask(uchar*); |
| extern int isv4(uchar*); |
| extern void v4tov6(uchar *v6, uchar *v4); |
| extern int v6tov4(uchar *v4, uchar *v6); |
| extern int eipfmt(Fmt*); |
| |
| #define ipmove(x, y) memmove(x, y, IPaddrlen) |
| #define ipcmp(x, y) ( (x)[IPaddrlen-1] != (y)[IPaddrlen-1] || memcmp(x, y, IPaddrlen) ) |
| |
| extern uchar IPv4bcast[IPaddrlen]; |
| extern uchar IPv4bcastobs[IPaddrlen]; |
| extern uchar IPv4allsys[IPaddrlen]; |
| extern uchar IPv4allrouter[IPaddrlen]; |
| extern uchar IPnoaddr[IPaddrlen]; |
| extern uchar v4prefix[IPaddrlen]; |
| extern uchar IPallbits[IPaddrlen]; |
| |
| #define NOW TK2MS(sys->ticks) |
| |
| /* |
| * media |
| */ |
| extern Medium ethermedium; |
| extern Medium nullmedium; |
| extern Medium pktmedium; |
| |
| /* |
| * ipifc.c |
| */ |
| extern Medium* ipfindmedium(char *name); |
| extern void addipmedium(Medium *med); |
| extern int ipforme(Fs*, uchar *addr); |
| extern int iptentative(Fs*, uchar *addr); |
| extern int ipisbm(uchar *); |
| extern int ipismulticast(uchar *); |
| extern Ipifc* findipifc(Fs*, uchar *remote, int type); |
| extern void findlocalip(Fs*, uchar *local, uchar *remote); |
| extern int ipv4local(Ipifc *ifc, uchar *addr); |
| extern int ipv6local(Ipifc *ifc, uchar *addr); |
| extern int ipv6anylocal(Ipifc *ifc, uchar *addr); |
| extern Iplifc* iplocalonifc(Ipifc *ifc, uchar *ip); |
| extern int ipproxyifc(Fs *f, Ipifc *ifc, uchar *ip); |
| extern int ipismulticast(uchar *ip); |
| extern int ipisbooting(void); |
| extern int ipifccheckin(Ipifc *ifc, Medium *med); |
| extern void ipifccheckout(Ipifc *ifc); |
| extern int ipifcgrab(Ipifc *ifc); |
| extern void ipifcaddroute(Fs*, int, uchar*, uchar*, uchar*, int); |
| extern void ipifcremroute(Fs*, int, uchar*, uchar*); |
| extern void ipifcremmulti(Conv *c, uchar *ma, uchar *ia); |
| extern void ipifcaddmulti(Conv *c, uchar *ma, uchar *ia); |
| extern char* ipifcrem(Ipifc *ifc, char **argv, int argc); |
| extern char* ipifcadd(Ipifc *ifc, char **argv, int argc, int tentative, Iplifc *lifcp); |
| extern long ipselftabread(Fs*, char *a, ulong offset, int n); |
| extern char* ipifcadd6(Ipifc *ifc, char**argv, int argc); |
| /* |
| * ip.c |
| */ |
| extern void iprouting(Fs*, int); |
| extern void icmpnoconv(Fs*, Block*); |
| extern void icmpcantfrag(Fs*, Block*, int); |
| extern void icmpttlexceeded(Fs*, uchar*, Block*); |
| extern ushort ipcsum(uchar*); |
| extern void ipiput4(Fs*, Ipifc*, Block*); |
| extern void ipiput6(Fs*, Ipifc*, Block*); |
| extern int ipoput4(Fs*, Block*, int, int, int, Conv*); |
| extern int ipoput6(Fs*, Block*, int, int, int, Conv*); |
| extern int ipstats(Fs*, char*, int); |
| extern ushort ptclbsum(uchar*, int); |
| extern ushort ptclcsum(Block*, int, int); |
| extern void ip_init(Fs*); |
| extern void update_mtucache(uchar*, ulong); |
| extern ulong restrict_mtu(uchar*, ulong); |
| /* |
| * bootp.c |
| */ |
| extern int bootpread(char*, ulong, int); |
| |
| /* |
| * resolving inferno/plan9 differences |
| */ |
| char* commonuser(void); |
| char* commonerror(void); |
| |
| /* |
| * chandial.c |
| */ |
| extern Chan* chandial(char*, char*, char*, Chan**); |
| |
| /* |
| * global to all of the stack |
| */ |
| extern void (*igmpreportfn)(Ipifc*, uchar*); |