~kris/9p

9hist

c678a0fe17a7dd1c822a7a35bcb77a8d96e4eb50 — David du Colombier 35 years ago 812b029
Plan 9 from Bell Labs 1991-03-31
2 files changed, 225 insertions(+), 20 deletions(-)

M port/deviproute.c
M power/devhotrod.c
M port/deviproute.c => port/deviproute.c +224 -18
@@ 1,5 1,11 @@
#include <u.h>
#include <libc.h>
#include	"u.h"
#include	"lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"errno.h"

#include	"devtab.h"

typedef	struct Iproute	Iproute;
typedef	struct Iprtab	Iprtab;


@@ 20,6 26,9 @@ uchar classmask[4][4] = {
};
#define CLASSMASK(x)	classmask[(*x>>6) & 3]

uchar netbytes[4] = { 1, 1, 2, 3 };
#define NETBYTES(x)	netbytes[(*x>>6) & 3]

/*
 *  routes
 */


@@ 31,27 40,36 @@ struct Iproute {
	int	inuse;
};
struct Iprtab {
/*	Lock; */
	Iproute *first;
	Iproute	r[Nroutes];	/* routings */
	Lock;
	int	n;		/* number of valid routes */
	Iproute *first;		/* list of valid routes */
	Iproute	r[Nroutes];	/* all routes */
};
Iprtab	iprtab;

#define lock(x)
#define unlock(x)

/*
 *  Convert string to ip address.  This is rediculously difficult because
 *  the designers of ip decided to allow any leading zero bytes in the
 *  host part to be left out.
 */
void
printroute(void)
strtoip(char *s, uchar *addr)
{
	Iproute *r;
	int i, off, first;
	char *rptr = s;

	print("\n");
	for(r = iprtab.first; r; r = r->next)
		print("%d.%d.%d.%d  %d.%d.%d.%d  %d.%d.%d.%d\n",
			r->dst[0], r->dst[1], r->dst[2], r->dst[3],
			r->mask[0], r->mask[1], r->mask[2], r->mask[3],
			r->gate[0], r->gate[1], r->gate[2], r->gate[3]);
	print("\n");
	/* convert the bytes */
	for(i = 0; i<4 & *rptr; i++)
		addr[i] = strtoul(rptr, &rptr, 0);

	/* move host bytes to the right place */
	first = NETBYTES(addr);
	off = 4 - i;
	if(off)
		while(i != first){
			--i;
			addr[i+off] = addr[i];
		}
}

/*


@@ 128,7 146,7 @@ ipaddroute(uchar *dst, uchar *mask, uchar *gate)
	 */
	for(i = 0; i < 4; i++)
		if((dst[i]&mask[i]) != dst[i])
			return;
			errors("bad ip route");

	/*
	 *  see if we already have a route for


@@ 147,6 165,8 @@ ipaddroute(uchar *dst, uchar *mask, uchar *gate)
			return;
		}
	}
	if(free == 0)
		errors("no free ip routes");

	/*
	 *  add the new route in sorted order


@@ 165,6 185,7 @@ ipaddroute(uchar *dst, uchar *mask, uchar *gate)
		iprtab.first = free;
	else
		e->next = free;
	iprtab.n++;
	unlock(&iprtab);
}



@@ 184,6 205,7 @@ ipremroute(uchar *dst, uchar *mask)
			else
				e->next = r->next;
			r->inuse = 0;
			iprtab.n--;
			break;
		}
		e = r;


@@ 203,5 225,189 @@ ipflushroute(void)
	for(r = iprtab.first; r; r = r->next)
		r->inuse = 0;
	iprtab.first = 0;
	iprtab.n = 0;
	unlock(&iprtab);
}

/*
 *  device interface
 */
enum{
	Qdir,
	Qdata,
};
Dirtab iproutetab[]={
	"iproute",		Qdata,		0,	0600,
};
#define Niproutetab (sizeof(iproutetab)/sizeof(Dirtab))

void
iproutereset(void)
{
}

void
iprouteinit(void)
{
}

Chan *
iprouteattach(char *spec)
{
	return devattach('R', spec);
}

Chan *
iprouteclone(Chan *c, Chan *nc)
{
	return devclone(c, nc);
}

int
iproutewalk(Chan *c, char *name)
{
	return devwalk(c, name, iproutetab, (long)Niproutetab, devgen);
}

void
iproutestat(Chan *c, char *db)
{
	devstat(c, db, iproutetab, (long)Niproutetab, devgen);
}

Chan *
iprouteopen(Chan *c, int omode)
{
	if(c->qid.path == CHDIR){
		if(omode != OREAD)
			error(Eperm);
	}
	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	return c;
}

void
iproutecreate(Chan *c, char *name, int omode, ulong perm)
{
	error(Eperm);
}

void
iprouteremove(Chan *c)
{
	error(Eperm);
}

void
iproutewstat(Chan *c, char *dp)
{
	error(Eperm);
}

void
iprouteclose(Chan *c)
{
}

#define IPR_ENTRYLEN 54
#define PAD "                                                                  "

long
iprouteread(Chan *c, void *a, long n)
{
	char	buf[IPR_ENTRYLEN*2];
	Iproute	*r;
	int	part, bytes, size;

	switch((int)(c->qid.path&~CHDIR)){
	case Qdir:
		return devdirread(c, a, n, iproutetab, Niproutetab, devgen);
	case Qdata:
		lock(&iprtab);
		part = c->offset/IPR_ENTRYLEN;
		for(r = iprtab.first; part && r; r = r->next)
			;
		bytes = c->offset;
		while(bytes < iprtab.n*IPR_ENTRYLEN && n){
			part = bytes%IPR_ENTRYLEN;

			sprint(buf,"%d.%d.%d.%d & %d.%d.%d.%d -> %d.%d.%d.%d%s",
				r->dst[0], r->dst[1], r->dst[2], r->dst[3],
				r->mask[0], r->mask[1], r->mask[2], r->mask[3],
				r->gate[0], r->gate[1], r->gate[2], r->gate[3],
				PAD); 
			
			buf[IPR_ENTRYLEN-1] = '\n';

			size = IPR_ENTRYLEN - part;
			size = MIN(n, size);
			memmove(a, buf+part, size);

			a = (void *)((int)a + size);
			n -= size;
			bytes += size;
		}
		unlock(&iprtab);
		return bytes - c->offset;
		break;
	default:
		n=0;
		break;
	}
	return n;
}

long
iproutewrite(Chan *c, char *a, long n)
{
	char buf[IPR_ENTRYLEN];
	char *field[4];
	uchar mask[4], dst[4], gate[4];
	int m;

	switch((int)(c->qid.path&~CHDIR)){
	case Qdata:
		strncpy(buf, a, sizeof buf);
		m = getfields(buf, field, 4, ' ');

		if(strncmp(field[0], "flush", 5) == 0)
			ipflushroute();
		else if(strcmp(field[0], "add") == 0){
			switch(m){
			case 4:
				strtoip(field[1], dst);
				strtoip(field[2], mask);
				strtoip(field[3], gate);
				ipaddroute(dst, mask, gate);
				break;
			case 3:
				strtoip(field[1], dst);
				strtoip(field[2], gate);
				ipaddroute(dst, 0, gate);
				break;
			default:
				error(Ebadarg);
			}
		} else if(strcmp(field[0], "delete") == 0){
			switch(m){
			case 3:
				strtoip(field[1], dst);
				strtoip(field[2], mask);
				ipremroute(dst, mask);
				break;
			case 2:
				strtoip(field[1], dst);
				ipremroute(dst, 0);
				break;
			default:
				error(Ebadarg);
			}
		}
		break;
	default:
		error(Ebadusefd);
	}
	return n;
}

M power/devhotrod.c => power/devhotrod.c +1 -2
@@ 13,7 13,6 @@
/*
 * If defined, ENABMEMTEST causes memory test to be run at device open
 */
#define	ENABMEMTEST
#ifdef	ENABMEMTEST
void	mem(Hot*, ulong*, ulong);
#define	NTESTBUF	256


@@ 26,7 25,7 @@ ulong	testbuf[NTESTBUF];
/*
 * If 1, ENABCKSUM causes data transfers to have checksums
 */
#define	ENABCKSUM	1
#define	ENABCKSUM	0

typedef struct Hotrod	Hotrod;