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