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