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