xref: /plan9/sys/src/9/ip/ip.h (revision 588d0145e19f8596f2f4442d05dd8a9eda147983)
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=	64,	/* max. conn.s in listen q not accepted yet */
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 	Logicmp=	1<<5,
490 	Logudp=		1<<6,
491 	Logcompress=	1<<7,
492 	Loggre=		1<<9,
493 	Logppp=		1<<10,
494 	Logtcprxmt=	1<<11,
495 	Logigmp=	1<<12,
496 	Logudpmsg=	1<<13,
497 	Logipmsg=	1<<14,
498 	Logrudp=	1<<15,
499 	Logrudpmsg=	1<<16,
500 	Logesp=		1<<17,
501 	Logtcpwin=	1<<18,
502 };
503 
504 void	netloginit(Fs*);
505 void	netlogopen(Fs*);
506 void	netlogclose(Fs*);
507 void	netlogctl(Fs*, char*, int);
508 long	netlogread(Fs*, void*, ulong, long);
509 void	netlog(Fs*, int, char*, ...);
510 void	ifcloginit(Fs*);
511 long	ifclogread(Fs*, Chan *,void*, ulong, long);
512 void	ifclog(Fs*, uchar *, int);
513 void	ifclogopen(Fs*, Chan*);
514 void	ifclogclose(Fs*, Chan*);
515 
516 #pragma varargck argpos netlog	3
517 
518 /*
519  *  iproute.c
520  */
521 typedef	struct RouteTree RouteTree;
522 typedef struct Routewalk Routewalk;
523 typedef struct V4route V4route;
524 typedef struct V6route V6route;
525 
526 enum
527 {
528 
529 	/* type bits */
530 	Rv4=		(1<<0),		/* this is a version 4 route */
531 	Rifc=		(1<<1),		/* this route is a directly connected interface */
532 	Rptpt=		(1<<2),		/* this route is a pt to pt interface */
533 	Runi=		(1<<3),		/* a unicast self address */
534 	Rbcast=		(1<<4),		/* a broadcast self address */
535 	Rmulti=		(1<<5),		/* a multicast self address */
536 	Rproxy=		(1<<6),		/* this route should be proxied */
537 };
538 
539 struct Routewalk
540 {
541 	int	o;
542 	int	h;
543 	char*	p;
544 	char*	e;
545 	void*	state;
546 	void	(*walk)(Route*, Routewalk*);
547 };
548 
549 struct	RouteTree
550 {
551 	Route*	right;
552 	Route*	left;
553 	Route*	mid;
554 	uchar	depth;
555 	uchar	type;
556 	uchar	ifcid;		/* must match ifc->id */
557 	Ipifc	*ifc;
558 	char	tag[4];
559 	int	ref;
560 };
561 
562 struct V4route
563 {
564 	ulong	address;
565 	ulong	endaddress;
566 	uchar	gate[IPv4addrlen];
567 };
568 
569 struct V6route
570 {
571 	ulong	address[IPllen];
572 	ulong	endaddress[IPllen];
573 	uchar	gate[IPaddrlen];
574 };
575 
576 struct Route
577 {
578 	RouteTree;
579 
580 	union {
581 		V6route	v6;
582 		V4route v4;
583 	};
584 };
585 extern void	v4addroute(Fs *f, char *tag, uchar *a, uchar *mask, uchar *gate, int type);
586 extern void	v6addroute(Fs *f, char *tag, uchar *a, uchar *mask, uchar *gate, int type);
587 extern void	v4delroute(Fs *f, uchar *a, uchar *mask, int dolock);
588 extern void	v6delroute(Fs *f, uchar *a, uchar *mask, int dolock);
589 extern Route*	v4lookup(Fs *f, uchar *a, Conv *c);
590 extern Route*	v6lookup(Fs *f, uchar *a, Conv *c);
591 extern long	routeread(Fs *f, char*, ulong, int);
592 extern long	routewrite(Fs *f, Chan*, char*, int);
593 extern void	routetype(int, char*);
594 extern void	ipwalkroutes(Fs*, Routewalk*);
595 extern void	convroute(Route*, uchar*, uchar*, uchar*, char*, int*);
596 
597 /*
598  *  devip.c
599  */
600 
601 /*
602  *  Hanging off every ip channel's ->aux is the following structure.
603  *  It maintains the state used by devip and iproute.
604  */
605 struct IPaux
606 {
607 	char	*owner;		/* the user that did the attach */
608 	char	tag[4];
609 };
610 
611 extern IPaux*	newipaux(char*, char*);
612 
613 /*
614  *  arp.c
615  */
616 struct Arpent
617 {
618 	uchar	ip[IPaddrlen];
619 	uchar	mac[MAClen];
620 	Medium	*type;			/* media type */
621 	Arpent*	hash;
622 	Block*	hold;
623 	Block*	last;
624 	uint	ctime;			/* time entry was created or refreshed */
625 	uint	utime;			/* time entry was last used */
626 	uchar	state;
627 	Arpent	*nextrxt;		/* re-transmit chain */
628 	uint	rtime;			/* time for next retransmission */
629 	uchar	rxtsrem;
630 	Ipifc	*ifc;
631 	uchar	ifcid;			/* must match ifc->id */
632 };
633 
634 extern void	arpinit(Fs*);
635 extern int	arpread(Arp*, char*, ulong, int);
636 extern int	arpwrite(Fs*, char*, int);
637 extern Arpent*	arpget(Arp*, Block *bp, int version, Ipifc *ifc, uchar *ip, uchar *h);
638 extern void	arprelease(Arp*, Arpent *a);
639 extern Block*	arpresolve(Arp*, Arpent *a, Medium *type, uchar *mac);
640 extern void	arpenter(Fs*, int version, uchar *ip, uchar *mac, int len, int norefresh);
641 
642 /*
643  * ipaux.c
644  */
645 
646 extern int	myetheraddr(uchar*, char*);
647 extern vlong	parseip(uchar*, char*);
648 extern vlong	parseipmask(uchar*, char*);
649 extern char*	v4parseip(uchar*, char*);
650 extern void	maskip(uchar *from, uchar *mask, uchar *to);
651 extern int	parsemac(uchar *to, char *from, int len);
652 extern uchar*	defmask(uchar*);
653 extern int	isv4(uchar*);
654 extern void	v4tov6(uchar *v6, uchar *v4);
655 extern int	v6tov4(uchar *v4, uchar *v6);
656 extern int	eipfmt(Fmt*);
657 
658 #define	ipmove(x, y) memmove(x, y, IPaddrlen)
659 #define	ipcmp(x, y) ( (x)[IPaddrlen-1] != (y)[IPaddrlen-1] || memcmp(x, y, IPaddrlen) )
660 
661 extern uchar IPv4bcast[IPaddrlen];
662 extern uchar IPv4bcastobs[IPaddrlen];
663 extern uchar IPv4allsys[IPaddrlen];
664 extern uchar IPv4allrouter[IPaddrlen];
665 extern uchar IPnoaddr[IPaddrlen];
666 extern uchar v4prefix[IPaddrlen];
667 extern uchar IPallbits[IPaddrlen];
668 
669 #define	NOW	TK2MS(MACHP(0)->ticks)
670 
671 /*
672  *  media
673  */
674 extern Medium	ethermedium;
675 extern Medium	nullmedium;
676 extern Medium	pktmedium;
677 
678 /*
679  *  ipifc.c
680  */
681 extern Medium*	ipfindmedium(char *name);
682 extern void	addipmedium(Medium *med);
683 extern int	ipforme(Fs*, uchar *addr);
684 extern int	iptentative(Fs*, uchar *addr);
685 extern int	ipisbm(uchar *);
686 extern int	ipismulticast(uchar *);
687 extern Ipifc*	findipifc(Fs*, uchar *remote, int type);
688 extern void	findlocalip(Fs*, uchar *local, uchar *remote);
689 extern int	ipv4local(Ipifc *ifc, uchar *addr);
690 extern int	ipv6local(Ipifc *ifc, uchar *addr);
691 extern int	ipv6anylocal(Ipifc *ifc, uchar *addr);
692 extern Iplifc*	iplocalonifc(Ipifc *ifc, uchar *ip);
693 extern int	ipproxyifc(Fs *f, Ipifc *ifc, uchar *ip);
694 extern int	ipismulticast(uchar *ip);
695 extern int	ipisbooting(void);
696 extern int	ipifccheckin(Ipifc *ifc, Medium *med);
697 extern void	ipifccheckout(Ipifc *ifc);
698 extern int	ipifcgrab(Ipifc *ifc);
699 extern void	ipifcaddroute(Fs*, int, uchar*, uchar*, uchar*, int);
700 extern void	ipifcremroute(Fs*, int, uchar*, uchar*);
701 extern void	ipifcremmulti(Conv *c, uchar *ma, uchar *ia);
702 extern void	ipifcaddmulti(Conv *c, uchar *ma, uchar *ia);
703 extern char*	ipifcrem(Ipifc *ifc, char **argv, int argc);
704 extern char*	ipifcadd(Ipifc *ifc, char **argv, int argc, int tentative, Iplifc *lifcp);
705 extern long	ipselftabread(Fs*, char *a, ulong offset, int n);
706 extern char*	ipifcadd6(Ipifc *ifc, char**argv, int argc);
707 /*
708  *  ip.c
709  */
710 extern void	iprouting(Fs*, int);
711 extern void	icmpnoconv(Fs*, Block*);
712 extern void	icmpcantfrag(Fs*, Block*, int);
713 extern void	icmpttlexceeded(Fs*, uchar*, Block*);
714 extern ushort	ipcsum(uchar*);
715 extern void	ipiput4(Fs*, Ipifc*, Block*);
716 extern void	ipiput6(Fs*, Ipifc*, Block*);
717 extern int	ipoput4(Fs*, Block*, int, int, int, Conv*);
718 extern int	ipoput6(Fs*, Block*, int, int, int, Conv*);
719 extern int	ipstats(Fs*, char*, int);
720 extern ushort	ptclbsum(uchar*, int);
721 extern ushort	ptclcsum(Block*, int, int);
722 extern void	ip_init(Fs*);
723 extern void	update_mtucache(uchar*, ulong);
724 extern ulong	restrict_mtu(uchar*, ulong);
725 /*
726  * bootp.c
727  */
728 extern int	bootpread(char*, ulong, int);
729 
730 /*
731  *  resolving inferno/plan9 differences
732  */
733 char*		commonuser(void);
734 char*		commonerror(void);
735 
736 /*
737  * chandial.c
738  */
739 extern Chan*	chandial(char*, char*, char*, Chan**);
740 
741 /*
742  *  global to all of the stack
743  */
744 extern void	(*igmpreportfn)(Ipifc*, uchar*);
745