vx32

Local 9vx git repository for patches.
git clone git://r-36.net/vx32
Log | Files | Refs

ip.h (16805B)


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