ip.h 15 KB

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