From c678a0fe17a7dd1c822a7a35bcb77a8d96e4eb50 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sun, 31 Mar 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-03-31 --- port/deviproute.c | 242 ++++++++++++++++++++++++++++++++++++++++++---- power/devhotrod.c | 3 +- 2 files changed, 225 insertions(+), 20 deletions(-) diff --git a/port/deviproute.c b/port/deviproute.c index 3213bf861dcf016c874b1da7bc1fb100b4da0cee..28d46912e58fd517c561248d91e0d7b13cc333f2 100644 --- a/port/deviproute.c +++ b/port/deviproute.c @@ -1,5 +1,11 @@ -#include -#include +#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; +} diff --git a/power/devhotrod.c b/power/devhotrod.c index 083681de604a039244b4ca907ff65da997b21642..1364e141a3e282b935477bbf36f70c15e9cf1911 100644 --- a/power/devhotrod.c +++ b/power/devhotrod.c @@ -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;