From 207854f2b900ae32db661b28ae302fefd08072d1 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 31 Jul 1999 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1999-07-31 --- ip/arp.c | 14 +++++---- ip/ethermedium.c | 75 +++++++++++++++++++++++++++++++++------------- ip/ip.h | 4 ++- ip/ipifc.c | 36 +++++++++++++++++++++- ip/netlog.c | 9 ++---- ip/nullmedium.c | 21 +++---------- ip/pktmedium.c | 28 +++++++----------- ip/tripmedium.c | 34 ++++++++------------- port/devbridge.c | 13 ++++---- port/devroot.c | 77 ++++++++++++++++++++---------------------------- port/log.c | 9 ++---- port/portdat.h | 2 +- 12 files changed, 170 insertions(+), 152 deletions(-) diff --git a/ip/arp.c b/ip/arp.c index 18c451b9b598b7ad51adba7b1165d4d984f564af..55bff89bcc37504e49e3d4155f0417f1a776059f 100644 --- a/ip/arp.c +++ b/ip/arp.c @@ -124,12 +124,14 @@ arpget(Arp *arp, Block *bp, int version, Medium *type, uchar *ip, uchar *mac) } a->used = msec; if(a->state == AWAIT){ - if(a->hold) - a->last->list = bp; - else - a->hold = bp; - a->last = bp; - bp->list = nil; + if(bp != nil){ + if(a->hold) + a->last->list = bp; + else + a->hold = bp; + a->last = bp; + bp->list = nil; + } return a; /* return with arp qlocked */ } diff --git a/ip/ethermedium.c b/ip/ethermedium.c index 0a8bee251152c5e8113886d7f9356837742bd93d..e4eff7580a09cc17e258edc7b59171b0dff1721a 100644 --- a/ip/ethermedium.c +++ b/ip/ethermedium.c @@ -24,29 +24,24 @@ static void etheraddmulti(Ipifc *ifc, uchar *a, uchar *ia); static void etherremmulti(Ipifc *ifc, uchar *a, uchar *ia); static Block* multicastarp(Fs *f, Arpent *a, uchar *mac); static void sendarp(Ipifc *ifc, Arpent *a); +static void sendgarp(Ipifc *ifc, uchar*); static int multicastea(uchar *ea, uchar *ip); static void recvarpproc(void*); Medium ethermedium = { - "ether", - 14, - 60, - 1514, - 6, - etherbind, - etherunbind, - etherbwrite, - etheraddmulti, - etherremmulti, - nil, /* pktin */ - nil, /* addroute */ - nil, /* remroute */ - nil, /* flushroute */ - nil, /* joinmulti */ - nil, /* leavemulti */ - arpenter, /* ares */ - 0, /* don't unbind on last close */ +.name= "ether", +.hsize= 14, +.minmtu= 60, +.maxmtu= 1514, +.maclen= 6, +.bind= etherbind, +.unbind= etherunbind, +.bwrite= etherbwrite, +.addmulti= etheraddmulti, +.remmulti= etherremmulti, +.ares= arpenter, +.areg= sendgarp, }; typedef struct Etherrock Etherrock; @@ -373,6 +368,46 @@ sendarp(Ipifc *ifc, Arpent *a) print("arp: send: %r\n"); } +/* + * send a gratuitous arp to refresh arp caches + */ +static void +sendgarp(Ipifc *ifc, uchar *ip) +{ + int n; + Block *bp; + Etherarp *e; + Etherrock *er = ifc->arg; + + /* don't arp for our initial non address */ + if(ipcmp(ip, IPnoaddr) == 0) + return; + + n = sizeof(Etherarp); + if(n < ethermedium.minmtu) + n = ethermedium.minmtu; + bp = allocb(n); + memset(bp->rp, 0, n); + e = (Etherarp*)bp->rp; + memmove(e->tpa, ip+IPv4off, sizeof(e->tpa)); + memmove(e->spa, ip+IPv4off, sizeof(e->spa)); + memmove(e->sha, ifc->mac, sizeof(e->sha)); + memset(e->d, 0xff, sizeof(e->d)); /* ethernet broadcast */ + memmove(e->s, ifc->mac, sizeof(e->s)); + + hnputs(e->type, ETARP); + hnputs(e->hrd, 1); + hnputs(e->pro, ETIP); + e->hln = sizeof(e->sha); + e->pln = sizeof(e->spa); + hnputs(e->op, ARPREQUEST); + bp->wp += n; + + n = devtab[er->achan->type]->bwrite(er->achan, bp, 0); + if(n < 0) + print("garp: send: %r\n"); +} + static void recvarp(Ipifc *ifc) { @@ -404,7 +439,7 @@ recvarp(Ipifc *ifc) /* check for someone that think's they're me */ v4tov6(ip, e->spa); - if(iplocalonifc(ifc, ip)){ + if(iplocalonifc(ifc, ip) || ipproxyifc(er->f, ifc, ip)){ if(memcmp(e->sha, ifc->mac, sizeof(e->sha)) != 0) print("arp: 0x%E also has ip addr %V\n", e->sha, e->spa); } else { @@ -420,7 +455,7 @@ recvarp(Ipifc *ifc) /* answer only requests for our address or systems we're proxying for */ v4tov6(ip, e->tpa); if(!iplocalonifc(ifc, ip)) - if(ipproxyifc(er->f, ifc, ip) == 0) + if(!ipproxyifc(er->f, ifc, ip)) break; /* print("arp: rem %I %E (for %I)\n", e->spa, e->sha, e->tpa); /**/ diff --git a/ip/ip.h b/ip/ip.h index 2d07ad2a3a956468f8c9e4699295a3767ed6a3e7..8456bd17123cb893622f58cefae4606173dc3015 100644 --- a/ip/ip.h +++ b/ip/ip.h @@ -126,7 +126,9 @@ struct Medium void (*joinmulti)(Ipifc *ifc, uchar *a, uchar *ia); void (*leavemulti)(Ipifc *ifc, uchar *a, uchar *ia); - void (*ares)(Fs*, int, uchar*, uchar*, int, int); + /* address resolution */ + void (*ares)(Fs*, int, uchar*, uchar*, int, int); /* resolve */ + void (*areg)(Ipifc*, uchar*); /* register */ int unbindonclose; /* if non-zero, unbind on last close */ }; diff --git a/ip/ipifc.c b/ip/ipifc.c index 21a9be760904baef7e3dda3c85332f30c3ef849d..a194490e0a94a98f7596d28eb09d58d2bd6d2002 100644 --- a/ip/ipifc.c +++ b/ip/ipifc.c @@ -66,6 +66,7 @@ static void addselfcache(Fs *f, Ipifc *ifc, Iplifc *lifc, uchar *a, int type); static void remselfcache(Fs *f, Ipifc *ifc, Iplifc *lifc, uchar *a); static char* ipifcjoinmulti(Ipifc *ifc, char **argv, int argc); static char* ipifcleavemulti(Ipifc *ifc, char **argv, int argc); +static void ipifcregisterproxy(Fs*, Ipifc*, uchar*); /* * link in a new medium @@ -409,8 +410,10 @@ ipifcadd(Ipifc *ifc, char **argv, int argc) addselfcache(f, ifc, lifc, ip, Runi); - if(type & Rptpt) + if(type & Rptpt){ + ipifcregisterproxy(f, ifc, rem); goto out; + } /* add subnet directed broadcast addresses to the self cache */ for(i = 0; i < IPaddrlen; i++) @@ -436,6 +439,10 @@ ipifcadd(Ipifc *ifc, char **argv, int argc) addselfcache(f, ifc, lifc, IPv4bcast, Rbcast); + /* register the address on this network for address resolution */ + if(ifc->m->areg != nil) + (*ifc->m->areg)(ifc, ip); + out: wunlock(ifc); return nil; @@ -1231,3 +1238,30 @@ ipifcleavemulti(Ipifc *ifc, char **argv, int argc) return nil; } +static void +ipifcregisterproxy(Fs *f, Ipifc *ifc, uchar *ip) +{ + Conv **cp, **e; + Ipifc *nifc; + Iplifc *lifc; + uchar net[IPaddrlen]; + + /* register the address on any network that will proxy for us */ + e = &f->ipifc->conv[f->ipifc->nc]; + for(cp = f->ipifc->conv; cp < e; cp++){ + if(*cp == nil) + continue; + nifc = (Ipifc*)(*cp)->ptcl; + if(nifc->m->areg == nil) + continue; + if(nifc == ifc) + continue; + for(lifc = nifc->lifc; lifc; lifc = lifc->next){ + maskip(ip, lifc->mask, net); + if(ipcmp(net, lifc->remote) == 0){ + (*nifc->m->areg)(nifc, ip); + break; + } + } + } +} diff --git a/ip/netlog.c b/ip/netlog.c index 473a6f82941874c65e2640a710acefcb9eb046be..4e81ee84545107fe1f80576b7a54ec69c81c705f 100644 --- a/ip/netlog.c +++ b/ip/netlog.c @@ -132,15 +132,10 @@ netlogread(Fs *f, void *a, ulong, long n) f->alog->len -= n; unlock(f->alog); - i = n; + i = n-d; p = a; - if(d){ - memmove(p, rptr, d); - i -= d; - p += d; - rptr = f->alog->buf; - } memmove(p, rptr, i); + memmove(p+i, f->alog->buf, d); break; } else diff --git a/ip/nullmedium.c b/ip/nullmedium.c index 7f44c0f764b8fe839c49151397a935a4885a3830..7795a2f1b16bae874ba3f1945fe77dfa1eb74302 100644 --- a/ip/nullmedium.c +++ b/ip/nullmedium.c @@ -27,23 +27,10 @@ nullbwrite(Ipifc*, Block*, int, uchar*) Medium nullmedium = { - "null", - 0, /* medium header size */ - 0, /* default min mtu */ - 0, /* default max mtu */ - 0, /* mac address length */ - nullbind, - nullunbind, - nullbwrite, - nil, /* addmulti */ - nil, /* remmulti */ - nil, /* pktin */ - nil, /* addroute */ - nil, /* remroute */ - nil, /* flushroute */ - nil, /* joinmulti */ - nil, /* leave multi */ - 0, /* don't unbind on last close */ +.name= "null", +.bind= nullbind, +.unbind= nullunbind, +.bwrite= nullbwrite, }; void diff --git a/ip/pktmedium.c b/ip/pktmedium.c index 455083eece1701ee4847821a0436b9bf01e4d866..f044c1c868e31c0320a9b59f1b19949cad62828b 100644 --- a/ip/pktmedium.c +++ b/ip/pktmedium.c @@ -16,24 +16,16 @@ static void pktin(Fs*, Ipifc *ifc, Block *bp); Medium pktmedium = { - "pkt", - 14, - 40, - 4*1024, - 6, - pktbind, - pktunbind, - pktbwrite, - nil, /* addmulti */ - nil, /* remmulti */ - pktin, - nil, /* addroute */ - nil, /* remroute */ - nil, /* flushroute */ - nil, /* joinmulti */ - nil, /* leave multi */ - nil, /* ares */ - 1, /* unbind on last close */ +.name= "pkt", +.hsize= 14, +.minmtu= 40, +.maxmtu= 4*1024, +.maclen= 6, +.bind= pktbind, +.unbind= pktunbind, +.bwrite= pktbwrite, +.pktin= pktin, +.unbindonclose= 1, }; /* diff --git a/ip/tripmedium.c b/ip/tripmedium.c index f644485519fd2e2a1382bded9a13bd808a6f59d1..c96f9bdaef36235886d127d7a4b3f3fd514d0490 100644 --- a/ip/tripmedium.c +++ b/ip/tripmedium.c @@ -21,28 +21,18 @@ static void tripares(Fs*, int, uchar*, uchar*, int, int); Medium tripmedium = { - "trip", - 0, /* Header size */ - - 20, /* Min TU */ - 64*1024, /* Max TU */ - - LCIMACSIZE, /* Maximum MAC address length */ - - tripbind, - tripunbind, - tripbwrite, - tripaddmulti, - tripremmulti, - nil, /* pktin */ - tripaddroute, - tripremroute, - nil, /* flushroutes */ - nil, /* joinmulti */ - nil, /* leavemulti */ - tripares, /* address cache enter */ - - 0 +.name= "trip", +.minmtu= 20, +.maxmtu= 64*1024, +.maclen= LCIMACSIZE, +.bind= tripbind, +.unbind= tripunbind, +.bwrite= tripbwrite, +.addmulti= tripaddmulti, +.remmulti= tripremmulti, +.addroute= tripaddroute, +.remroute= tripremroute, +.ares= tripares, }; typedef struct Tripinfo Tripinfo; diff --git a/port/devbridge.c b/port/devbridge.c index 2946f5ad204bec417324899d621fab7153f4584f..b6f3ec81968310ed08406e18cc751f9f314a229e 100644 --- a/port/devbridge.c +++ b/port/devbridge.c @@ -266,7 +266,7 @@ bridgeread(Chan *c, void *a, long n, vlong off) char buf[256]; Bridge *b = bridgetab + c->dev; Port *port; - int i; + int i, ingood, outgood; USED(off); switch(TYPE(c->qid)) { @@ -294,9 +294,11 @@ bridgeread(Chan *c, void *a, long n, vlong off) i += snprint(buf+i, sizeof(buf)-i, "tunnel %I: ", port->addr); break; } - i += snprint(buf+i, sizeof(buf)-i, "in=%d/%d/%d out=%d/%d/%d\n", - port->in, port->inmulti, port->inunknown, - port->out, port->outmulti, port->outunknown); + ingood = port->in-port->inmulti-port->inunknown; + outgood = port->out-port->outmulti-port->outunknown; + i += snprint(buf+i, sizeof(buf)-i, "in=%d(%d:%d:%d) out=%d(%d:%d:%d)\n", + port->in, ingood, port->inmulti, port->inunknown, + port->out, outgood, port->outmulti, port->outunknown); USED(i); } n = readstr(off, a, n, buf); @@ -317,7 +319,6 @@ bridgewrite(Chan *c, void *a, long n, vlong off) char *p; USED(off); - switch(TYPE(c->qid)) { default: error(Eperm); @@ -482,7 +483,6 @@ portbind(Bridge *b, int argc, char *argv[]) portfree(port); nexterror(); } - port->type = type; memmove(port->addr, addr, Addrlen); switch(port->type) { @@ -822,7 +822,6 @@ etherread(void *a) if(waserror()) { if(bp) freeb(bp); -print("devbridge: etherread: %r\n"); continue; } if(blocklen(bp) < ETHERMINTU) diff --git a/port/devroot.c b/port/devroot.c index a27a17c67f9134ea3895a187b128b4b0b5423320..a2df3d8f377cdda2951ca67dda58d697c22e491f 100644 --- a/port/devroot.c +++ b/port/devroot.c @@ -7,37 +7,21 @@ enum{ Qdir= 0, - Qbin, - Qdev, - Qenv, - Qproc, - Qnet, - Qnetalt, Qrecover, - Qroot, /* boot root */ - // add new entries above this - Qboot, /* readable files */ - - Nfiles=13, /* max root files */ + Nfiles=32, /* max root files */ }; extern ulong bootlen; extern uchar bootcode[]; -Dirtab rootdir[Nfiles]={ - "bin", {Qbin|CHDIR}, 0, 0777, - "dev", {Qdev|CHDIR}, 0, 0777, - "env", {Qenv|CHDIR}, 0, 0777, - "proc", {Qproc|CHDIR}, 0, 0777, - "net", {Qnet|CHDIR}, 0, 0777, - "net.alt", {Qnetalt|CHDIR}, 0, 0777, +Dirtab rootdir[Nfiles]= +{ "recover", {Qrecover}, 0, 0777, - "root", {Qroot|CHDIR}, 0, 0777, }; static uchar *rootdata[Nfiles]; -static int nroot = Qboot - 1; +static int nroot = 1; static int recovbusy; typedef struct Recover Recover; @@ -59,45 +43,55 @@ struct /* * add a root file */ -void -addrootfile(char *name, uchar *contents, ulong len) +static void +addroot(char *name, uchar *contents, ulong len, int perm) { Dirtab *d; - if(nroot >= Nfiles) panic("too many root files"); rootdata[nroot] = contents; d = &rootdir[nroot]; strcpy(d->name, name); d->length = len; - d->perm = 0555; + d->perm = perm; d->qid.path = nroot+1; + if(perm & CHDIR) + d->qid.path |= CHDIR; nroot++; } +/* + * add a root file + */ +void +addrootfile(char *name, uchar *contents, ulong len) +{ + addroot(name, contents, len, 0555); +} + /* * add a root file */ static void addrootdir(char *name) { - Dirtab *d; - - if(nroot >= Nfiles) - panic("too many root files"); - rootdata[nroot] = nil; - d = &rootdir[nroot]; - strcpy(d->name, name); - d->length = 0; - d->perm = 0; - d->qid.path = nroot+1; - nroot++; + addroot(name, nil, 0, CHDIR); } static void rootreset(void) { + addrootdir("bin"); + addrootdir("dev"); + addrootdir("env"); + addrootdir("proc"); + addrootdir("net"); + addrootdir("net.alt"); + addrootdir("root"); + addrootdir("srv"); + addrootdir("xsrv"); + addrootfile("boot", bootcode, bootlen); /* always have a boot file */ } @@ -203,9 +197,6 @@ rootread(Chan *c, void *buf, long n, vlong off) return n; } - if(t < Qboot) - return 0; - d = &rootdir[t-1]; data = rootdata[t-1]; if(offset >= d->length) @@ -239,16 +230,12 @@ rootwrite(Chan *c, void *buf, long n, vlong) static void rootcreate(Chan *c, char *name, int mode, ulong perm) { - if(!iseve()) - error(Eperm); - if(c->qid.path != (CHDIR|Qdir)) - error(Eperm); - perm &= 0777|CHDIR; - if((perm & CHDIR) == 0) + if(!iseve() || c->qid.path != (CHDIR|Qdir) || + (perm & CHDIR) == 0 || mode != OREAD) error(Eperm); addrootdir(name); c->flag |= COPEN; - c->mode = mode & ~OWRITE; + c->mode = OREAD; } Dev rootdevtab = { diff --git a/port/log.c b/port/log.c index ed40c0f6b3ecc1475820e82d4fe30df9cfc89d84..529ac4d7d2eaa105c212b3ee23bea73580e220c9 100644 --- a/port/log.c +++ b/port/log.c @@ -82,15 +82,10 @@ logread(Log *alog, void *a, ulong, long n) alog->len -= n; unlock(alog); - i = n; + i = n-d; p = a; - if(d){ - memmove(p, rptr, d); - i -= d; - p += d; - rptr = alog->buf; - } memmove(p, rptr, i); + memmove(p+i, alog->buf, d); break; } else diff --git a/port/portdat.h b/port/portdat.h index 26872c405e13d100fd36ad415efdbb02007dd0a8..ef3afe6cccafa4eaebe3d4ab3b79112622f28fd4 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -735,7 +735,7 @@ struct Logflag { struct Cmdbuf { - char buf[64]; + char buf[256]; char *f[16]; int nf; };