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