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