]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/ip/ip.h
kernel: dont use atomic increment for Proc.nlocks, maintain Lock.m for lock(), use...
[plan9front.git] / sys / src / 9 / ip / ip.h
1 typedef struct  Conv    Conv;
2 typedef struct  Fragment4 Fragment4;
3 typedef struct  Fragment6 Fragment6;
4 typedef struct  Fs      Fs;
5 typedef union   Hwaddr  Hwaddr;
6 typedef struct  IP      IP;
7 typedef struct  IPaux   IPaux;
8 typedef struct  Ip4hdr  Ip4hdr;
9 typedef struct  Ipfrag  Ipfrag;
10 typedef struct  Ipself  Ipself;
11 typedef struct  Ipselftab       Ipselftab;
12 typedef struct  Iplink  Iplink;
13 typedef struct  Iplifc  Iplifc;
14 typedef struct  Ipmulti Ipmulti;
15 typedef struct  Ipifc   Ipifc;
16 typedef struct  Iphash  Iphash;
17 typedef struct  Ipht    Ipht;
18 typedef struct  Netlog  Netlog;
19 typedef struct  Medium  Medium;
20 typedef struct  Proto   Proto;
21 typedef struct  Arpent  Arpent;
22 typedef struct  Arp Arp;
23 typedef struct  Route   Route;
24
25 typedef struct  Routerparams    Routerparams;
26 typedef struct  Hostparams      Hostparams;
27 typedef struct  v6router        v6router;
28 typedef struct  v6params        v6params;
29
30 #pragma incomplete Arp
31 #pragma incomplete Ipself
32 #pragma incomplete Ipselftab
33 #pragma incomplete IP
34 #pragma incomplete Netlog
35
36 enum
37 {
38         Addrlen=        64,
39         Maxproto=       20,
40         Nhash=          64,
41         Maxincall=      10,
42         Nchans=         1024,
43         MAClen=         16,             /* longest mac address */
44
45         MAXTTL=         255,
46         DFLTTOS=        0,
47
48         IPaddrlen=      16,
49         IPv4addrlen=    4,
50         IPv4off=        12,
51         IPllen=         4,
52
53         /* ip versions */
54         V4=             4,
55         V6=             6,
56         IP_VER4=        0x40,
57         IP_VER6=        0x60,
58         IP_HLEN4=       5,              /* v4: Header length in words */
59         IP_DF=          0x4000,         /* v4: Don't fragment */
60         IP_MF=          0x2000,         /* v4: More fragments */
61         IP4HDR=         20,             /* sizeof(Ip4hdr) */
62         IP_MAX=         64*1024,        /* Max. Internet packet size, v4 & v6 */
63
64         /* 2^Lroot trees in the root table */
65         Lroot=          10,
66
67         Maxpath =       64,
68 };
69
70 enum
71 {
72         Idle=           0,
73         Announcing=     1,
74         Announced=      2,
75         Connecting=     3,
76         Connected=      4,
77 };
78
79 /* MIB II counters */
80 enum
81 {
82         Forwarding,
83         DefaultTTL,
84         InReceives,
85         InHdrErrors,
86         InAddrErrors,
87         ForwDatagrams,
88         InUnknownProtos,
89         InDiscards,
90         InDelivers,
91         OutRequests,
92         OutDiscards,
93         OutNoRoutes,
94         ReasmTimeout,
95         ReasmReqds,
96         ReasmOKs,
97         ReasmFails,
98         FragOKs,
99         FragFails,
100         FragCreates,
101
102         Nipstats,
103 };
104
105 struct Fragment4
106 {
107         Block*  blist;
108         Fragment4*      next;
109         ulong   src;
110         ulong   dst;
111         ushort  id;
112         ulong   age;
113 };
114
115 struct Fragment6
116 {
117         Block*  blist;
118         Fragment6*      next;
119         uchar   src[IPaddrlen];
120         uchar   dst[IPaddrlen];
121         uint    id;
122         ulong   age;
123 };
124
125 struct Ipfrag
126 {
127         ushort  foff;
128         ushort  flen;
129
130         uchar   payload[];
131 };
132
133 #define IPFRAGSZ offsetof(Ipfrag, payload[0])
134
135 /* an instance of IP */
136 struct IP
137 {
138         uvlong          stats[Nipstats];
139
140         QLock           fraglock4;
141         Fragment4*      flisthead4;
142         Fragment4*      fragfree4;
143         Ref             id4;
144
145         QLock           fraglock6;
146         Fragment6*      flisthead6;
147         Fragment6*      fragfree6;
148         Ref             id6;
149
150         int             iprouting;      /* true if we route like a gateway */
151 };
152
153 /* on the wire packet header */
154 struct Ip4hdr
155 {
156         uchar   vihl;           /* Version and header length */
157         uchar   tos;            /* Type of service */
158         uchar   length[2];      /* packet length */
159         uchar   id[2];          /* ip->identification */
160         uchar   frag[2];        /* Fragment information */
161         uchar   ttl;            /* Time to live */
162         uchar   proto;          /* Protocol */
163         uchar   cksum[2];       /* Header checksum */
164         uchar   src[4];         /* IP source */
165         uchar   dst[4];         /* IP destination */
166 };
167
168 /*
169  *  one per conversation directory
170  */
171 struct Conv
172 {
173         QLock;
174
175         int     x;                      /* conversation index */
176         Proto*  p;
177
178         int     restricted;             /* remote port is restricted */
179         uint    ttl;                    /* max time to live */
180         uint    tos;                    /* type of service */
181         int     ignoreadvice;           /* don't terminate connection on icmp errors */
182
183         uchar   ipversion;
184         uchar   laddr[IPaddrlen];       /* local IP address */
185         uchar   raddr[IPaddrlen];       /* remote IP address */
186         ushort  lport;                  /* local port number */
187         ushort  rport;                  /* remote port number */
188
189         char    *owner;                 /* protections */
190         int     perm;
191         int     inuse;                  /* opens of listen/data/ctl */
192         int     length;
193         int     state;
194
195         int     maxfragsize;            /* If set, used for fragmentation */
196
197         /* udp specific */
198         int     headers;                /* data src/dst headers in udp */
199         int     reliable;               /* true if reliable udp */
200
201         Conv*   incall;                 /* calls waiting to be listened for */
202         Conv*   next;
203
204         Queue*  rq;                     /* queued data waiting to be read */
205         Queue*  wq;                     /* queued data waiting to be written */
206         Queue*  eq;                     /* returned error packets */
207         Queue*  sq;                     /* snooping queue */
208         Ref     snoopers;               /* number of processes with snoop open */
209
210         QLock   car;
211         Rendez  cr;
212         char    cerr[ERRMAX];
213
214         QLock   listenq;
215         Rendez  listenr;
216
217         Ipmulti *multi;                 /* multicast bindings for this interface */
218
219         void*   ptcl;                   /* protocol specific stuff */
220
221         Route   *r;                     /* last route used */
222         ulong   rgen;                   /* routetable generation for *r */
223 };
224
225 struct Medium
226 {
227         char    *name;
228         int     hsize;          /* medium header size */
229         int     mintu;          /* default min mtu */
230         int     maxtu;          /* default max mtu */
231         int     maclen;         /* mac address length  */
232         void    (*bind)(Ipifc*, int, char**);
233         void    (*unbind)(Ipifc*);
234         void    (*bwrite)(Ipifc *ifc, Block *b, int version, uchar *ip);
235
236         /* for arming interfaces to receive multicast */
237         void    (*addmulti)(Ipifc *ifc, uchar *a, uchar *ia);
238         void    (*remmulti)(Ipifc *ifc, uchar *a, uchar *ia);
239
240         /* process packets written to 'data' */
241         void    (*pktin)(Fs *f, Ipifc *ifc, Block *bp);
242
243         /* routes for router boards */
244         void    (*addroute)(Ipifc *ifc, int, uchar*, uchar*, uchar*, int);
245         void    (*remroute)(Ipifc *ifc, int, uchar*, uchar*);
246         void    (*flushroutes)(Ipifc *ifc);
247
248         /* for routing multicast groups */
249         void    (*joinmulti)(Ipifc *ifc, uchar *a, uchar *ia);
250         void    (*leavemulti)(Ipifc *ifc, uchar *a, uchar *ia);
251
252         /* address resolution */
253         void    (*ares)(Fs*, int, uchar*, uchar*, int, int);    /* resolve */
254         void    (*areg)(Ipifc*, uchar*);                        /* register */
255
256         /* v6 address generation */
257         void    (*pref2addr)(uchar *pref, uchar *ea);
258
259         int     unbindonclose;  /* if non-zero, unbind on last close */
260 };
261
262 /* logical interface associated with a physical one */
263 struct Iplifc
264 {
265         uchar   local[IPaddrlen];
266         uchar   mask[IPaddrlen];
267         uchar   remote[IPaddrlen];
268         uchar   net[IPaddrlen];
269         uchar   tentative;      /* =1 => v6 dup disc on, =0 => confirmed unique */
270         uchar   onlink;         /* =1 => onlink, =0 offlink. */
271         uchar   autoflag;       /* v6 autonomous flag */
272         long    validlt;        /* v6 valid lifetime */
273         long    preflt;         /* v6 preferred lifetime */
274         long    origint;        /* time when addr was added */
275         Iplink  *link;          /* addresses linked to this lifc */
276         Iplifc  *next;
277 };
278
279 /* binding twixt Ipself and Iplifc */
280 struct Iplink
281 {
282         Ipself  *self;
283         Iplifc  *lifc;
284         Iplink  *selflink;      /* next link for this local address */
285         Iplink  *lifclink;      /* next link for this ifc */
286         ulong   expire;
287         Iplink  *next;          /* free list */
288         int     ref;
289 };
290
291 /* rfc 2461, pp.40—43. */
292
293 /* default values, one per stack */
294 struct Routerparams {
295         int     mflag;          /* flag: managed address configuration */
296         int     oflag;          /* flag: other stateful configuration */
297         int     maxraint;       /* max. router adv interval (ms) */
298         int     minraint;       /* min. router adv interval (ms) */
299         int     linkmtu;        /* mtu options */
300         int     reachtime;      /* reachable time */
301         int     rxmitra;        /* retransmit interval */
302         int     ttl;            /* cur hop count limit */
303         int     routerlt;       /* router lifetime */
304 };
305
306 struct Hostparams {
307         int     rxmithost;
308 };
309
310 struct Ipifc
311 {
312         RWlock;
313
314         Conv    *conv;          /* link to its conversation structure */
315         char    dev[64];        /* device we're attached to */
316         Medium  *m;             /* Media pointer */
317         int     maxtu;          /* Maximum transfer unit */
318         int     mintu;          /* Minumum tranfer unit */
319         int     mbps;           /* megabits per second */
320         void    *arg;           /* medium specific */
321         int     reassemble;     /* reassemble IP packets before forwarding */
322
323         /* these are used so that we can unbind on the fly */
324         Lock    idlock;
325         uchar   ifcid;          /* incremented each 'bind/unbind/add/remove' */
326         int     ref;            /* number of proc's using this ipifc */
327         Rendez  wait;           /* where unbinder waits for ref == 0 */
328         int     unbinding;
329
330         uchar   mac[MAClen];    /* MAC address */
331
332         Iplifc  *lifc;          /* logical interfaces on this physical one */
333
334         ulong   in, out;        /* message statistics */
335         ulong   inerr, outerr;  /* ... */
336
337         uchar   sendra6;        /* flag: send router advs on this ifc */
338         uchar   recvra6;        /* flag: recv router advs on this ifc */
339         Routerparams rp;        /* router parameters as in RFC 2461, pp.40—43.
340                                         used only if node is router */
341 };
342
343 /*
344  *  one per multicast-lifc pair used by a Conv
345  */
346 struct Ipmulti
347 {
348         uchar   ma[IPaddrlen];
349         uchar   ia[IPaddrlen];
350         Ipmulti *next;
351 };
352
353 /*
354  *  hash table for 2 ip addresses + 2 ports
355  */
356 enum
357 {
358         Nipht=          521,    /* convenient prime */
359
360         IPmatchexact=   0,      /* match on 4 tuple */
361         IPmatchany,             /* *!* */
362         IPmatchport,            /* *!port */
363         IPmatchaddr,            /* addr!* */
364         IPmatchpa,              /* addr!port */
365 };
366 struct Iphash
367 {
368         Iphash  *next;
369         Conv    *c;
370         int     match;
371 };
372 struct Ipht
373 {
374         Lock;
375         Iphash  *tab[Nipht];
376 };
377 void iphtadd(Ipht*, Conv*);
378 void iphtrem(Ipht*, Conv*);
379 Conv* iphtlook(Ipht *ht, uchar *sa, ushort sp, uchar *da, ushort dp);
380
381 /*
382  *  one per multiplexed protocol
383  */
384 struct Proto
385 {
386         QLock;
387         char*           name;           /* protocol name */
388         int             x;              /* protocol index */
389         int             ipproto;        /* ip protocol type */
390
391         char*           (*connect)(Conv*, char**, int);
392         char*           (*announce)(Conv*, char**, int);
393         char*           (*bind)(Conv*, char**, int);
394         int             (*state)(Conv*, char*, int);
395         void            (*create)(Conv*);
396         void            (*close)(Conv*);
397         void            (*rcv)(Proto*, Ipifc*, Block*);
398         char*           (*ctl)(Conv*, char**, int);
399         void            (*advise)(Proto*, Block*, char*);
400         int             (*stats)(Proto*, char*, int);
401         int             (*local)(Conv*, char*, int);
402         int             (*remote)(Conv*, char*, int);
403         int             (*inuse)(Conv*);
404         int             (*gc)(Proto*);  /* returns true if any conversations are freed */
405
406         Fs              *f;             /* file system this proto is part of */
407         Conv            **conv;         /* array of conversations */
408         int             ptclsize;       /* size of per protocol ctl block */
409         int             nc;             /* number of conversations */
410         int             ac;
411         Qid             qid;            /* qid for protocol directory */
412         ushort          nextrport;
413
414         void            *priv;
415 };
416
417
418 /*
419  *  one per IP protocol stack
420  */
421 struct Fs
422 {
423         RWlock;
424         int     dev;
425
426         int     np;
427         Proto*  p[Maxproto+1];          /* list of supported protocols */
428         Proto*  t2p[256];               /* vector of all protocols */
429         Proto*  ipifc;                  /* kludge for ipifcremroute & ipifcaddroute */
430         Proto*  ipmux;                  /* kludge for finding an ip multiplexor */
431
432         IP      *ip;
433         Ipselftab       *self;
434         Arp     *arp;
435         v6params        *v6p;
436
437         Route   *v4root[1<<Lroot];      /* v4 routing forest */
438         Route   *v6root[1<<Lroot];      /* v6 routing forest */
439         Route   *queue;                 /* used as temp when reinjecting routes */
440
441         Netlog  *alog;
442
443         char    ndb[1024];              /* an ndb entry for this interface */
444         int     ndbvers;
445         long    ndbmtime;
446 };
447
448 /* one per default router known to host */
449 struct v6router {
450         uchar   inuse;
451         Ipifc   *ifc;
452         int     ifcid;
453         uchar   routeraddr[IPaddrlen];
454         long    ltorigin;
455         Routerparams    rp;
456 };
457
458 struct v6params
459 {
460         Routerparams    rp;             /* v6 params, one copy per node now */
461         Hostparams      hp;
462         v6router        v6rlist[3];     /* max 3 default routers, currently */
463         int             cdrouter;       /* uses only v6rlist[cdrouter] if   */
464                                         /* cdrouter >= 0. */
465 };
466
467
468 int     Fsconnected(Conv*, char*);
469 Conv*   Fsnewcall(Conv*, uchar*, ushort, uchar*, ushort, uchar);
470 int     Fspcolstats(char*, int);
471 int     Fsproto(Fs*, Proto*);
472 int     Fsbuiltinproto(Fs*, uchar);
473 Conv*   Fsprotoclone(Proto*, char*);
474 Proto*  Fsrcvpcol(Fs*, uchar);
475 Proto*  Fsrcvpcolx(Fs*, uchar);
476 char*   Fsstdconnect(Conv*, char**, int);
477 char*   Fsstdannounce(Conv*, char**, int);
478 char*   Fsstdbind(Conv*, char**, int);
479 ulong   scalednconv(void);
480 void    closeconv(Conv*);
481 /*
482  *  logging
483  */
484 enum
485 {
486         Logip=          1<<1,
487         Logtcp=         1<<2,
488         Logfs=          1<<3,
489         Logil=          1<<4,
490         Logicmp=        1<<5,
491         Logudp=         1<<6,
492         Logcompress=    1<<7,
493         Logilmsg=       1<<8,
494         Loggre=         1<<9,
495         Logppp=         1<<10,
496         Logtcprxmt=     1<<11,
497         Logigmp=        1<<12,
498         Logudpmsg=      1<<13,
499         Logipmsg=       1<<14,
500         Logrudp=        1<<15,
501         Logrudpmsg=     1<<16,
502         Logesp=         1<<17,
503         Logtcpwin=      1<<18,
504 };
505
506 void    netloginit(Fs*);
507 void    netlogopen(Fs*);
508 void    netlogclose(Fs*);
509 void    netlogctl(Fs*, char*, int);
510 long    netlogread(Fs*, void*, ulong, long);
511 void    netlog(Fs*, int, char*, ...);
512 void    ifcloginit(Fs*);
513 long    ifclogread(Fs*, Chan *,void*, ulong, long);
514 void    ifclog(Fs*, uchar *, int);
515 void    ifclogopen(Fs*, Chan*);
516 void    ifclogclose(Fs*, Chan*);
517
518 #pragma varargck argpos netlog  3
519
520 /*
521  *  iproute.c
522  */
523 typedef struct RouteTree RouteTree;
524 typedef struct Routewalk Routewalk;
525 typedef struct V4route V4route;
526 typedef struct V6route V6route;
527
528 enum
529 {
530
531         /* type bits */
532         Rv4=            (1<<0),         /* this is a version 4 route */
533         Rifc=           (1<<1),         /* this route is a directly connected interface */
534         Rptpt=          (1<<2),         /* this route is a pt to pt interface */
535         Runi=           (1<<3),         /* a unicast self address */
536         Rbcast=         (1<<4),         /* a broadcast self address */
537         Rmulti=         (1<<5),         /* a multicast self address */
538         Rproxy=         (1<<6),         /* this route should be proxied */
539 };
540
541 struct Routewalk
542 {
543         int     o;
544         int     h;
545         char*   p;
546         char*   e;
547         void*   state;
548         void    (*walk)(Route*, Routewalk*);
549 };
550
551 struct  RouteTree
552 {
553         Route*  right;
554         Route*  left;
555         Route*  mid;
556         uchar   depth;
557         uchar   type;
558         uchar   ifcid;          /* must match ifc->id */
559         Ipifc   *ifc;
560         char    tag[4];
561         int     ref;
562 };
563
564 struct V4route
565 {
566         ulong   address;
567         ulong   endaddress;
568         uchar   gate[IPv4addrlen];
569 };
570
571 struct V6route
572 {
573         ulong   address[IPllen];
574         ulong   endaddress[IPllen];
575         uchar   gate[IPaddrlen];
576 };
577
578 struct Route
579 {
580         RouteTree;
581
582         union {
583                 V6route v6;
584                 V4route v4;
585         };
586 };
587 extern void     v4addroute(Fs *f, char *tag, uchar *a, uchar *mask, uchar *gate, int type);
588 extern void     v6addroute(Fs *f, char *tag, uchar *a, uchar *mask, uchar *gate, int type);
589 extern void     v4delroute(Fs *f, uchar *a, uchar *mask, int dolock);
590 extern void     v6delroute(Fs *f, uchar *a, uchar *mask, int dolock);
591 extern Route*   v4lookup(Fs *f, uchar *a, Conv *c);
592 extern Route*   v6lookup(Fs *f, uchar *a, Conv *c);
593 extern long     routeread(Fs *f, char*, ulong, int);
594 extern long     routewrite(Fs *f, Chan*, char*, int);
595 extern void     routetype(int, char*);
596 extern void     ipwalkroutes(Fs*, Routewalk*);
597 extern void     convroute(Route*, uchar*, uchar*, uchar*, char*, int*);
598
599 /*
600  *  devip.c
601  */
602
603 /*
604  *  Hanging off every ip channel's ->aux is the following structure.
605  *  It maintains the state used by devip and iproute.
606  */
607 struct IPaux
608 {
609         char    *owner;         /* the user that did the attach */
610         char    tag[4];
611 };
612
613 extern IPaux*   newipaux(char*, char*);
614
615 /*
616  *  arp.c
617  */
618 struct Arpent
619 {
620         uchar   ip[IPaddrlen];
621         uchar   mac[MAClen];
622         Medium  *type;                  /* media type */
623         Arpent* hash;
624         Block*  hold;
625         Block*  last;
626         uint    ctime;                  /* time entry was created or refreshed */
627         uint    utime;                  /* time entry was last used */
628         uchar   state;
629         Arpent  *nextrxt;               /* re-transmit chain */
630         uint    rtime;                  /* time for next retransmission */
631         uchar   rxtsrem;
632         Ipifc   *ifc;
633         uchar   ifcid;                  /* must match ifc->id */
634 };
635
636 extern void     arpinit(Fs*);
637 extern int      arpread(Arp*, char*, ulong, int);
638 extern int      arpwrite(Fs*, char*, int);
639 extern Arpent*  arpget(Arp*, Block *bp, int version, Ipifc *ifc, uchar *ip, uchar *h);
640 extern void     arprelease(Arp*, Arpent *a);
641 extern Block*   arpresolve(Arp*, Arpent *a, Medium *type, uchar *mac);
642 extern void     arpenter(Fs*, int version, uchar *ip, uchar *mac, int len, int norefresh);
643
644 /*
645  * ipaux.c
646  */
647
648 extern int      myetheraddr(uchar*, char*);
649 extern vlong    parseip(uchar*, char*);
650 extern vlong    parseipmask(uchar*, char*);
651 extern char*    v4parseip(uchar*, char*);
652 extern void     maskip(uchar *from, uchar *mask, uchar *to);
653 extern int      parsemac(uchar *to, char *from, int len);
654 extern uchar*   defmask(uchar*);
655 extern int      isv4(uchar*);
656 extern void     v4tov6(uchar *v6, uchar *v4);
657 extern int      v6tov4(uchar *v4, uchar *v6);
658 extern int      eipfmt(Fmt*);
659
660 #define ipmove(x, y) memmove(x, y, IPaddrlen)
661 #define ipcmp(x, y) ( (x)[IPaddrlen-1] != (y)[IPaddrlen-1] || memcmp(x, y, IPaddrlen) )
662
663 extern uchar IPv4bcast[IPaddrlen];
664 extern uchar IPv4bcastobs[IPaddrlen];
665 extern uchar IPv4allsys[IPaddrlen];
666 extern uchar IPv4allrouter[IPaddrlen];
667 extern uchar IPnoaddr[IPaddrlen];
668 extern uchar v4prefix[IPaddrlen];
669 extern uchar IPallbits[IPaddrlen];
670
671 #define NOW     TK2MS(MACHP(0)->ticks)
672
673 /*
674  *  media
675  */
676 extern Medium   ethermedium;
677 extern Medium   nullmedium;
678 extern Medium   pktmedium;
679
680 /*
681  *  ipifc.c
682  */
683 extern Medium*  ipfindmedium(char *name);
684 extern void     addipmedium(Medium *med);
685 extern int      ipforme(Fs*, uchar *addr);
686 extern int      iptentative(Fs*, uchar *addr);
687 extern int      ipisbm(uchar *);
688 extern int      ipismulticast(uchar *);
689 extern Ipifc*   findipifc(Fs*, uchar *remote, int type);
690 extern void     findlocalip(Fs*, uchar *local, uchar *remote);
691 extern int      ipv4local(Ipifc *ifc, uchar *addr);
692 extern int      ipv6local(Ipifc *ifc, uchar *addr);
693 extern int      ipv6anylocal(Ipifc *ifc, uchar *addr);
694 extern Iplifc*  iplocalonifc(Ipifc *ifc, uchar *ip);
695 extern int      ipproxyifc(Fs *f, Ipifc *ifc, uchar *ip);
696 extern int      ipismulticast(uchar *ip);
697 extern int      ipisbooting(void);
698 extern int      ipifccheckin(Ipifc *ifc, Medium *med);
699 extern void     ipifccheckout(Ipifc *ifc);
700 extern int      ipifcgrab(Ipifc *ifc);
701 extern void     ipifcaddroute(Fs*, int, uchar*, uchar*, uchar*, int);
702 extern void     ipifcremroute(Fs*, int, uchar*, uchar*);
703 extern void     ipifcremmulti(Conv *c, uchar *ma, uchar *ia);
704 extern void     ipifcaddmulti(Conv *c, uchar *ma, uchar *ia);
705 extern char*    ipifcrem(Ipifc *ifc, char **argv, int argc);
706 extern char*    ipifcadd(Ipifc *ifc, char **argv, int argc, int tentative, Iplifc *lifcp);
707 extern long     ipselftabread(Fs*, char *a, ulong offset, int n);
708 extern char*    ipifcadd6(Ipifc *ifc, char**argv, int argc);
709 /*
710  *  ip.c
711  */
712 extern void     iprouting(Fs*, int);
713 extern void     icmpnoconv(Fs*, Block*);
714 extern void     icmpcantfrag(Fs*, Block*, int);
715 extern void     icmpttlexceeded(Fs*, uchar*, Block*);
716 extern ushort   ipcsum(uchar*);
717 extern void     ipiput4(Fs*, Ipifc*, Block*);
718 extern void     ipiput6(Fs*, Ipifc*, Block*);
719 extern int      ipoput4(Fs*, Block*, int, int, int, Conv*);
720 extern int      ipoput6(Fs*, Block*, int, int, int, Conv*);
721 extern int      ipstats(Fs*, char*, int);
722 extern ushort   ptclbsum(uchar*, int);
723 extern ushort   ptclcsum(Block*, int, int);
724 extern void     ip_init(Fs*);
725 extern void     update_mtucache(uchar*, ulong);
726 extern ulong    restrict_mtu(uchar*, ulong);
727 /*
728  * bootp.c
729  */
730 extern int      bootpread(char*, ulong, int);
731
732 /*
733  *  resolving inferno/plan9 differences
734  */
735 char*           commonuser(void);
736 char*           commonerror(void);
737
738 /*
739  * chandial.c
740  */
741 extern Chan*    chandial(char*, char*, char*, Chan**);
742
743 /*
744  *  global to all of the stack
745  */
746 extern void     (*igmpreportfn)(Ipifc*, uchar*);