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*);