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