| plan 9 kernel history: overview | file list | diff list |
1991/0331/port/deviproute.c (diff list | history)
| 1991/0330/sys/src/9/port/deviproute.c:1,6 – 1991/0331/sys/src/9/port/deviproute.c:1,12 (short | long | prev | next) | ||
| 1991/0330 |
| |
| 1991/0331 | #include "u.h" #include "lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "errno.h" | |
| 1991/0330 | ||
| 1991/0331 | #include "devtab.h" | |
| 1991/0330 | typedef struct Iproute Iproute; typedef struct Iprtab Iprtab; | |
| 1991/0330/sys/src/9/port/deviproute.c:20,25 – 1991/0331/sys/src/9/port/deviproute.c:26,34 | ||
| 1991/0330 | }; #define CLASSMASK(x) classmask[(*x>>6) & 3] | |
| 1991/0331 | uchar netbytes[4] = { 1, 1, 2, 3 }; #define NETBYTES(x) netbytes[(*x>>6) & 3] | |
| 1991/0330 | /* * routes */ | |
| 1991/0330/sys/src/9/port/deviproute.c:31,57 – 1991/0331/sys/src/9/port/deviproute.c:40,75 | ||
| 1991/0330 | int inuse; }; struct Iprtab { | |
| 1991/0331 | Lock; int n; /* number of valid routes */ Iproute *first; /* list of valid routes */ Iproute r[Nroutes]; /* all routes */ | |
| 1991/0330 | }; Iprtab iprtab; | |
| 1991/0331 | /* * 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. */ | |
| 1991/0330 | void | |
| 1991/0331 | strtoip(char *s, uchar *addr) | |
| 1991/0330 | { | |
| 1991/0331 | int i, off, first; char *rptr = s; | |
| 1991/0330 |
| |
| 1991/0331 | /* 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]; } | |
| 1991/0330 | } /* | |
| 1991/0330/sys/src/9/port/deviproute.c:128,134 – 1991/0331/sys/src/9/port/deviproute.c:146,152 | ||
| 1991/0330 | */ for(i = 0; i < 4; i++) if((dst[i]&mask[i]) != dst[i]) | |
| 1991/0331 | errors("bad ip route"); | |
| 1991/0330 | /* * see if we already have a route for | |
| 1991/0330/sys/src/9/port/deviproute.c:147,152 – 1991/0331/sys/src/9/port/deviproute.c:165,172 | ||
| 1991/0330 | return; } } | |
| 1991/0331 | if(free == 0) errors("no free ip routes"); | |
| 1991/0330 | /* * add the new route in sorted order | |
| 1991/0330/sys/src/9/port/deviproute.c:165,170 – 1991/0331/sys/src/9/port/deviproute.c:185,191 | ||
| 1991/0330 | iprtab.first = free; else e->next = free; | |
| 1991/0331 | iprtab.n++; | |
| 1991/0330 | unlock(&iprtab); } | |
| 1991/0330/sys/src/9/port/deviproute.c:184,189 – 1991/0331/sys/src/9/port/deviproute.c:205,211 | ||
| 1991/0330 | else e->next = r->next; r->inuse = 0; | |
| 1991/0331 | iprtab.n--; | |
| 1991/0330 | break; } e = r; | |
| 1991/0330/sys/src/9/port/deviproute.c:203,207 – 1991/0331/sys/src/9/port/deviproute.c:225,413 | ||
| 1991/0330 | for(r = iprtab.first; r; r = r->next) r->inuse = 0; iprtab.first = 0; | |
| 1991/0331 | iprtab.n = 0; | |
| 1991/0330 | unlock(&iprtab); | |
| 1991/0331 | } /* * 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; | |
| 1991/0330 | } | |