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