| plan 9 kernel history: overview | file list | diff list |
1991/0401/port/deviproute.c (diff list | history)
| 1991/0331/sys/src/9/port/deviproute.c:4,12 – 1991/0401/sys/src/9/port/deviproute.c:4,20 (short | long | prev | next) | ||
| 1991/0331 | #include "dat.h" #include "fns.h" #include "errno.h" | |
| 1991/0401 | #include "arp.h" #include "ipdat.h" | |
| 1991/0330 | ||
| 1991/0331 | #include "devtab.h" | |
| 1991/0401 | /* * All ip numbers and masks are stored as ulongs. * All interfaces to this code uses the standard byte * string representation. */ | |
| 1991/0330 | typedef struct Iproute Iproute; typedef struct Iprtab Iprtab; | |
| 1991/0331/sys/src/9/port/deviproute.c:16,41 – 1991/0401/sys/src/9/port/deviproute.c:24,35 | ||
| 1991/0330 | }; /* | |
| 1991/0331 |
| |
| 1991/0330 |
| |
| 1991/0401 | ulong dst; ulong gate; ulong mask; | |
| 1991/0330 | Iproute *next; int inuse; }; | |
| 1991/0331/sys/src/9/port/deviproute.c:48,130 – 1991/0401/sys/src/9/port/deviproute.c:42,85 | ||
| 1991/0330 | Iprtab iprtab; | |
| 1991/0331 | /* | |
| 1991/0330 |
| |
| 1991/0331 |
| |
| 1991/0330 |
| |
| 1991/0331 |
| |
| 1991/0330 | ||
| 1991/0331 |
| |
| 1991/0330 |
| |
| 1991/0401 | * r->mask & dst == r->dst | |
| 1991/0330 | * * If there are several matches, the one whose mask has the most | |
| 1991/0401 | * leading ones (and hence is the most specific) wins. This is * forced by storing the routes in decreasing number of ones order * and returning the first match. The default gateway has no ones * in the mask and is thus the last matched. | |
| 1991/0330 | */ void iproute(uchar *dst, uchar *gate) { Iproute *r; | |
| 1991/0401 | ulong udst; | |
| 1991/0330 | ||
| 1991/0401 | udst = nhgetl(dst); if((udst&Mymask) == (Myip&Mymask)){ memmove(gate, dst, 4); return; } | |
| 1991/0330 | /* * first check routes */ | |
| 1991/0401 | if((r->mask&udst) == r->dst){ hnputl(gate, r->gate); | |
| 1991/0330 | return; } } | |
| 1991/0401 | * else just return the same address | |
| 1991/0330 | */ memmove(gate, dst, 4); } /* | |
| 1991/0331/sys/src/9/port/deviproute.c:133,152 – 1991/0401/sys/src/9/port/deviproute.c:88,103 | ||
| 1991/0330 | * NOTE: A default route has an all zeroes mask and dst. */ void | |
| 1991/0401 | ipaddroute(ulong dst, ulong mask, ulong gate) | |
| 1991/0330 | { Iproute *r, *e, *free; int i; | |
| 1991/0331 |
| |
| 1991/0401 | if((dst&mask) != dst) errors("bad ip route"); | |
| 1991/0330 | /* * see if we already have a route for | |
| 1991/0331/sys/src/9/port/deviproute.c:159,182 – 1991/0401/sys/src/9/port/deviproute.c:110,135 | ||
| 1991/0330 | free = r; continue; } | |
| 1991/0401 | if(dst==r->dst && mask==r->mask){ r->gate = gate; | |
| 1991/0330 | unlock(&iprtab); return; } } | |
| 1991/0331 |
| |
| 1991/0401 | if(free == 0){ unlock(&iprtab); | |
| 1991/0331 | errors("no free ip routes"); | |
| 1991/0401 | } | |
| 1991/0330 | /* * add the new route in sorted order */ | |
| 1991/0401 | free->dst = dst; free->mask = mask; free->gate = gate; | |
| 1991/0330 | free->inuse = 1; | |
| 1991/0401 | for(r = e = iprtab.first; r; r = r->next){ if(mask > r->mask) | |
| 1991/0330 | break; e = r; } | |
| 1991/0331/sys/src/9/port/deviproute.c:193,205 – 1991/0401/sys/src/9/port/deviproute.c:146,158 | ||
| 1991/0330 | * remove a route */ void | |
| 1991/0401 | ipremroute(ulong dst, ulong mask) | |
| 1991/0330 | { Iproute *r, *e; lock(&iprtab); | |
| 1991/0401 | for(r = e = iprtab.first; r; r = r->next){ if(dst==r->dst && mask==r->mask){ | |
| 1991/0330 | if(r == iprtab.first) iprtab.first = r->next; else | |
| 1991/0331/sys/src/9/port/deviproute.c:317,325 – 1991/0401/sys/src/9/port/deviproute.c:270,279 | ||
| 1991/0331 | long iprouteread(Chan *c, void *a, long n) { | |
| 1991/0401 | char buf[IPR_ENTRYLEN*3]; | |
| 1991/0331 | Iproute *r; int part, bytes, size; | |
| 1991/0401 | uchar dst[4], mask[4], gate[4]; | |
| 1991/0331 | switch((int)(c->qid.path&~CHDIR)){ case Qdir: | |
| 1991/0331/sys/src/9/port/deviproute.c:328,353 – 1991/0401/sys/src/9/port/deviproute.c:282,312 | ||
| 1991/0331 | lock(&iprtab); part = c->offset/IPR_ENTRYLEN; for(r = iprtab.first; part && r; r = r->next) | |
| 1991/0401 | part--; | |
| 1991/0331 | bytes = c->offset; | |
| 1991/0401 | while(r && bytes < iprtab.n*IPR_ENTRYLEN && n){ | |
| 1991/0331 | part = bytes%IPR_ENTRYLEN; | |
| 1991/0401 | hnputl(dst, r->dst); hnputl(mask, r->mask); hnputl(gate, r->gate); | |
| 1991/0331 | sprint(buf,"%d.%d.%d.%d & %d.%d.%d.%d -> %d.%d.%d.%d%s", | |
| 1991/0401 | dst[0], dst[1], dst[2], dst[3], mask[0], mask[1], mask[2], mask[3], gate[0], gate[1], gate[2], gate[3], | |
| 1991/0331 | PAD); buf[IPR_ENTRYLEN-1] = '\n'; size = IPR_ENTRYLEN - part; | |
| 1991/0401 | if(size > n) size = n; | |
| 1991/0331 | memmove(a, buf+part, size); a = (void *)((int)a + size); n -= size; bytes += size; | |
| 1991/0401 | r = r->next; | |
| 1991/0331 | } unlock(&iprtab); return bytes - c->offset; | |
| 1991/0331/sys/src/9/port/deviproute.c:364,370 – 1991/0401/sys/src/9/port/deviproute.c:323,329 | ||
| 1991/0331 | { char buf[IPR_ENTRYLEN]; char *field[4]; | |
| 1991/0401 | Ipaddr mask, dst, gate; | |
| 1991/0331 | int m; switch((int)(c->qid.path&~CHDIR)){ | |
| 1991/0331/sys/src/9/port/deviproute.c:377,391 – 1991/0401/sys/src/9/port/deviproute.c:336,350 | ||
| 1991/0331 | else if(strcmp(field[0], "add") == 0){ switch(m){ case 4: | |
| 1991/0401 | dst = ipparse(field[1]); mask = ipparse(field[2]); gate = ipparse(field[3]); | |
| 1991/0331 | ipaddroute(dst, mask, gate); break; case 3: | |
| 1991/0401 | dst = ipparse(field[1]); gate = ipparse(field[2]); ipaddroute(dst, classmask[dst>>30], gate); | |
| 1991/0331 | break; default: error(Ebadarg); | |
| 1991/0331/sys/src/9/port/deviproute.c:393,405 – 1991/0401/sys/src/9/port/deviproute.c:352,364 | ||
| 1991/0331 | } else if(strcmp(field[0], "delete") == 0){ switch(m){ case 3: | |
| 1991/0401 | dst = ipparse(field[1]); mask = ipparse(field[2]); | |
| 1991/0331 | ipremroute(dst, mask); break; case 2: | |
| 1991/0401 | dst = ipparse(field[1]); ipremroute(dst, classmask[dst>>30]); | |
| 1991/0331 | break; default: error(Ebadarg); | |