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