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