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