ip.h - vx32 - Local 9vx git repository for patches.
(HTM) git clone git://r-36.net/vx32
(DIR) Log
(DIR) Files
(DIR) 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*);