~kris/9p

9hist

207854f2b900ae32db661b28ae302fefd08072d1 — David du Colombier 27 years ago 57627e7
Plan 9 from Bell Labs 1999-07-31
M ip/arp.c => ip/arp.c +8 -6
@@ 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 */
	}


M ip/ethermedium.c => ip/ethermedium.c +55 -20
@@ 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); /**/

M ip/ip.h => ip/ip.h +3 -1
@@ 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 */
};

M ip/ipifc.c => ip/ipifc.c +35 -1
@@ 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;
			}
		}
	}
}

M ip/netlog.c => ip/netlog.c +2 -7
@@ 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

M ip/nullmedium.c => ip/nullmedium.c +4 -17
@@ 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

M ip/pktmedium.c => ip/pktmedium.c +10 -18
@@ 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,
};

/*

M ip/tripmedium.c => ip/tripmedium.c +12 -22
@@ 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;

M port/devbridge.c => port/devbridge.c +6 -7
@@ 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)

M port/devroot.c => port/devroot.c +32 -45
@@ 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 = {

M port/log.c => port/log.c +2 -7
@@ 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

M port/portdat.h => port/portdat.h +1 -1
@@ 735,7 735,7 @@ struct Logflag {

struct Cmdbuf
{
	char	buf[64];
	char	buf[256];
	char	*f[16];
	int	nf;
};