From 5d15e975c22dcd37ab5594708533a2219db2d513 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 13 Feb 1992 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1992-02-13 --- gnot/lib.h | 1 + port/arp.h | 3 +++ port/chan.c | 27 ++++++++++------------ port/devarp.c | 52 +++++++++++++++++++++++++++++++++++------- port/devcons.c | 2 ++ port/devip.c | 4 ++-- port/deviproute.c | 2 +- port/devroot.c | 2 ++ port/ipdat.h | 10 +++++++- port/lib.h | 1 + port/stil.c | 4 ++-- port/stip.c | 58 +++++++++++++++++++++++++++-------------------- port/tcpoutput.c | 2 +- 13 files changed, 113 insertions(+), 55 deletions(-) diff --git a/gnot/lib.h b/gnot/lib.h index 84db7ca9550a177c9a01cc88818fa2da909b9d4e..4280cc0f1afc20bd234daa35c4b00234789906ad 100644 --- a/gnot/lib.h +++ b/gnot/lib.h @@ -30,6 +30,7 @@ extern int atoi(char*); extern int runetochar(char*, Rune*); extern int chartorune(Rune*, char*); extern int countrune(char*); +extern char* utfrune(char*, long); /* * print routines diff --git a/port/arp.h b/port/arp.h index 80570b311bba2744e9a2d45bf8c692ad0209ebff..17a71fb142b10ada312c720636e87cfa2314b7e7 100644 --- a/port/arp.h +++ b/port/arp.h @@ -1,3 +1,6 @@ +/* + * this file used by (at least) the kernel, arpd, snoopy, tboot + */ typedef struct Arppkt Arppkt; typedef struct Arpentry Arpentry; typedef struct Arpstats Arpstats; diff --git a/port/chan.c b/port/chan.c index 5afe383d816f2a551966795bcaeb8a23b2a8a9cf..3f787ccc9bec58e7865ef20fa98718ba16df6f00 100644 --- a/port/chan.c +++ b/port/chan.c @@ -669,28 +669,25 @@ nameok(char *elem) char* nextelem(char *name, char *elem) { - int i, user, c; + int i, user, w; char *end, *e; + Rune r; if(*name == '/') error(Efilename); - end = memchr(name, 0, NAMELEN); - if(end == 0){ - end = memchr(name, '/', NAMELEN); - if(end == 0) - error(Efilename); - }else{ - e = memchr(name, '/', end-name); - if(e) - end = e; - } + end = utfrune(name, '/'); + if(end == 0) + end = strchr(name, 0); + w = end-name; + if(w >= NAMELEN) + error(Efilename); + memmove(elem, name, w); + elem[w] = 0; while(name < end){ - c = *(uchar*)name++; - if(isfrog[c]) + name += chartorune(&r, name); + if(rqid.path == CHDIR){ + if(i) + return -1; + q.path = CHDIR | arpdir2qid; + devdir(c, q, "arp", 0, eve, 0555, dp); + return 1; + } + + /* next level uses table */ + return devgen(c, arptab, Narptab, i, dp); +} + void arpreset(void) { @@ -109,13 +133,13 @@ arpclone(Chan *c, Chan *nc) int arpwalk(Chan *c, char *name) { - return devwalk(c, name, arptab, (long)Narptab, devgen); + return devwalk(c, name, 0, 0, arpgen); } void arpstat(Chan *c, char *db) { - devstat(c, db, arptab, (long)Narptab, devgen); + devstat(c, db, 0, 0, arpgen); } Chan * @@ -182,7 +206,7 @@ arpread(Chan *c, void *a, long n, ulong offset) switch((int)(c->qid.path&~CHDIR)){ case arpdirqid: - return devdirread(c, a, n, arptab, Narptab, devgen); + return devdirread(c, a, n, 0, 0, arpgen); case arpdataqid: bytes = c->offset; while(bytes < conf.arp*ARP_ENTRYLEN && n) { @@ -283,6 +307,8 @@ arpoput(Queue *q, Block *bp) { uchar ip[4]; Etherhdr *eh; + Ipaddr addr; + static int dropped; if(bp->type != M_DATA) { if(Servq == 0 && streamparse("arpd", bp)) { @@ -295,7 +321,8 @@ arpoput(Queue *q, Block *bp) } if(!Servq) { - print("arp: No server, packet dropped\n"); + if((dropped++ % 1000) == 0) + print("arp: No server, packet dropped\n"); freeb(bp); return; } @@ -308,12 +335,20 @@ arpoput(Queue *q, Block *bp) iproute(eh->dst, ip); - /* Send downstream to the ethernet */ + /* if a known ip addr, send downstream to the ethernet */ if(arplookup(ip, eh->d)) { PUTNEXT(q, bp); return; } + /* if ip broadcast, use ether bcast address */ + addr = nhgetl(eh->dst); + if(addr == Myip[Mybcast] || addr == Myip[Mynet] || addr == Myip[Mysubnet]){ + memset(eh->d, 0xff, sizeof(eh->d)); + PUTNEXT(q, bp); + return; + } + /* Push the packet up to the arp server for address resolution */ memmove(eh->d, ip, sizeof(ip)); PUTNEXT(Servq, bp); @@ -443,6 +478,7 @@ arplinkhead(Arpcache *ap) ap->frwd = arplruhead; ap->prev = 0; + arplruhead = ap; } } diff --git a/port/devcons.c b/port/devcons.c index a6a04fe29781810781f25888e67f5bd7df5c63b7..840254e0cf6b4dc8d27cc180a35d35d6e4e559c2 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -850,6 +850,8 @@ conswrite(Chan *c, void *va, long n, ulong offset) break; case Qswap: + if(conf.cntrlp && strcmp(u->p->user, eve) != 0) + error(Eperm); if(n >= sizeof buf) error(Egreg); memmove(buf, va, n); /* so we can NUL-terminate */ diff --git a/port/devip.c b/port/devip.c index b20872dbdb1d1007b5bef6110dd23d29645b1b2c..ceaab492b8a31985486dc8436375d4b596f4bf45 100644 --- a/port/devip.c +++ b/port/devip.c @@ -433,7 +433,7 @@ udpstoput(Queue *q, Block *bp) uh->frag[1] = 0; hnputs(uh->udpplen, ptcllen); hnputl(uh->udpdst, ipc->dst); - hnputl(uh->udpsrc, Myip); + hnputl(uh->udpsrc, Myip[Myself]); hnputs(uh->udpsport, ipc->psrc); hnputs(uh->udpdport, ipc->pdst); hnputs(uh->udplen, ptcllen); @@ -583,7 +583,7 @@ iplocalfill(Chan *c, char *buf, int len) connection = STREAMID(c->qid.path); cp = &ipconv[c->dev][connection]; - sprint(buf, "%d.%d.%d.%d %d\n", fmtaddr(Myip), cp->psrc); + sprint(buf, "%d.%d.%d.%d %d\n", fmtaddr(Myip[Myself]), cp->psrc); } void diff --git a/port/deviproute.c b/port/deviproute.c index 509c8a9e9825a21754a225e44e010777c6fef234..9dd089e66cbb08df682fc04bf46bba85c2c6111c 100644 --- a/port/deviproute.c +++ b/port/deviproute.c @@ -58,7 +58,7 @@ iproute(uchar *dst, uchar *gate) ulong udst; udst = nhgetl(dst); - if((udst&Mymask) == (Myip&Mymask)){ + if((udst&Mymask) == (Myip[Myself]&Mymask)){ memmove(gate, dst, 4); return; } diff --git a/port/devroot.c b/port/devroot.c index 0cbe173a2b6b061afcf3c37f323fc1085af679f9..78e339f5d590fd582fd2b0d4e776095effde4ac9 100644 --- a/port/devroot.c +++ b/port/devroot.c @@ -12,6 +12,7 @@ enum{ Qdev, Qenv, Qproc, + Qnet, Qboot, Qcfs, @@ -31,6 +32,7 @@ Dirtab rootdir[]={ "dev", {Qdev|CHDIR}, 0, 0777, "env", {Qenv|CHDIR}, 0, 0777, "proc", {Qproc|CHDIR}, 0, 0777, + "net", {Qnet|CHDIR}, 0, 0777, }; #define NROOT (sizeof rootdir/sizeof(Dirtab)) Dirtab rootpdir[]={ diff --git a/port/ipdat.h b/port/ipdat.h index 904aede2e78aff485c4b770b04cb63475ef2feee..4a65644425f64167ddedbd70d4f7cd214d144d5b 100644 --- a/port/ipdat.h +++ b/port/ipdat.h @@ -503,7 +503,7 @@ int ipforme(uchar*); #define WORKBUF 64 -extern Ipaddr Myip; +extern Ipaddr Myip[4]; extern Ipaddr Mymask; extern Ipaddr classmask[4]; extern Ipconv *ipconv[]; @@ -516,3 +516,11 @@ extern Qinfo udpinfo; extern Qinfo ilinfo; extern Qinfo arpinfo; extern Queue *Ipoutput; + +/* offsets into Myip */ +enum { + Myself= 0, + Mybcast= 1, + Mynet= 3, + Mysubnet= 5, +}; diff --git a/port/lib.h b/port/lib.h index 84db7ca9550a177c9a01cc88818fa2da909b9d4e..4280cc0f1afc20bd234daa35c4b00234789906ad 100644 --- a/port/lib.h +++ b/port/lib.h @@ -30,6 +30,7 @@ extern int atoi(char*); extern int runetochar(char*, Rune*); extern int chartorune(Rune*, char*); extern int countrune(char*); +extern char* utfrune(char*, long); /* * print routines diff --git a/port/stil.c b/port/stil.c index a3af582ceb5268a111e2d2804b1df72cc11c1c92..c2ee5414c62a8b74dfe794137b42361d83083155 100644 --- a/port/stil.c +++ b/port/stil.c @@ -154,7 +154,7 @@ iloput(Queue *q, Block *bp) /* Ip fields */ ih->frag[0] = 0; ih->frag[1] = 0; - hnputl(ih->src, Myip); + hnputl(ih->src, Myip[Myself]); hnputl(ih->dst, ipc->dst); ih->proto = IP_ILPROTO; /* Il fields */ @@ -633,7 +633,7 @@ ilsendctl(Ipconv *ipc, Ilhdr *inih, int type, ulong id, ulong ack) /* Ip fields */ ih->proto = IP_ILPROTO; - hnputl(ih->src, Myip); + hnputl(ih->src, Myip[Myself]); hnputs(ih->illen, IL_HDRSIZE); ih->frag[0] = 0; ih->frag[1] = 0; diff --git a/port/stip.c b/port/stip.c index 6829af1eee6b3cf0c71dcbebec90a042044fe492..5b2d3d8ba4a354dc469fd11a324cb70aa63aa12b 100644 --- a/port/stip.c +++ b/port/stip.c @@ -26,17 +26,19 @@ QLock fraglock; Queue *Etherq; -Ipaddr Myip; +Ipaddr Myip[4]; Ipaddr Mymask; Ipaddr Mynetmask; uchar Netmyip[4]; /* In Network byte order */ uchar bcast[4] = { 0xff, 0xff, 0xff, 0xff }; +Ipaddr Me[7]; /* possible addresses for me */ /* Predeclaration */ static void ipetherclose(Queue*); static void ipetheriput(Queue*, Block*); static void ipetheropen(Queue*, Stream*); static void ipetheroput(Queue*, Block*); +static void ipsetaddrs(void); /* * the ethernet multiplexor stream module definition @@ -79,6 +81,7 @@ ipetheropen(Queue *q, Stream *s) Etherq = WR(q); s->opens++; /* Hold this queue in place */ s->inuse++; + ipsetaddrs(); } else { ipc = &ipconv[s->dev][s->id]; RD(q)->ptr = (void *)ipc; @@ -179,18 +182,20 @@ ipetheroput(Queue *q, Block *bp) if(strncmp(eve, u->p->user, sizeof(eve)) != 0) error(Eperm); ptr = bp->rptr; - Myip = ipparse((char *)ptr); - Netmyip[0] = (Myip>>24)&0xff; - Netmyip[1] = (Myip>>16)&0xff; - Netmyip[2] = (Myip>>8)&0xff; - Netmyip[3] = Myip&0xff; - Mymask = classmask[Myip>>30]; + Myip[Myself] = ipparse((char *)ptr); + Netmyip[0] = (Myip[Myself]>>24)&0xff; + Netmyip[1] = (Myip[Myself]>>16)&0xff; + Netmyip[2] = (Myip[Myself]>>8)&0xff; + Netmyip[3] = Myip[Myself]&0xff; + Mymask = classmask[Myip[Myself]>>30]; while(*ptr != ' ' && *ptr) ptr++; if(*ptr) - Mymask = ipparse((char *)ptr); - Mynetmask = Mymask; + Mynetmask = ipparse((char *)ptr); + else + Mynetmask = Mymask; freeb(bp); + ipsetaddrs(); } else PUTNEXT(Etherq, bp); @@ -353,34 +358,37 @@ drop: freeb(bp); } +void +ipsetaddrs(void) +{ + Myip[1] = ~0; /* local broadcast */ + Myip[2] = 0; /* local broadcast - old */ + Myip[Mysubnet] = Myip[Myself] | ~Mynetmask; /* subnet broadcast */ + Myip[Mysubnet+1] = Myip[Myself] & Mynetmask; /* subnet broadcast - old */ + Myip[Mynet] = Myip[Myself] | ~Mymask; /* net broadcast */ + Myip[Mynet+1] = Myip[Myself] & Mymask; /* net broadcast - old */ +} + int ipforme(uchar *addr) { Ipaddr haddr; - - if(memcmp(addr, Netmyip, sizeof(Netmyip)) == 0) - return 1; + Ipaddr *p; haddr = nhgetl(addr); - /* My subnet broadcast */ - if((haddr&Mymask) == (Myip&Mymask)) - return 1; - - /* My network broadcast */ - if((haddr&Mynetmask) == (Myip&Mynetmask)) - return 1; + /* try my address plus all the forms of ip broadcast */ + for(p = Myip; p < &Myip[7]; p++) + if(haddr == *p); + return 1; - /* Real ip broadcast */ - if(haddr == 0) - return 1; - - /* Old style 255.255.255.255 address */ - if(haddr == ~0) + /* if we haven't set an address yet, accept anything we get */ + if(Myip[Myself] == 0) return 1; return 0; } + Block * ip_reassemble(int offset, Block *bp, Etherhdr *ip) { diff --git a/port/tcpoutput.c b/port/tcpoutput.c index 8b89e4ceef13e572cf0cf2583a4af37d03f3b3d5..b3369e834e11bd23f472a1677795cd09c4858c83 100644 --- a/port/tcpoutput.c +++ b/port/tcpoutput.c @@ -129,7 +129,7 @@ tcp_output(Ipconv *s) /* Fill in fields of pseudo IP header */ hnputl(ph.tcpdst, s->dst); - hnputl(ph.tcpsrc, Myip); + hnputl(ph.tcpsrc, Myip[Myself]); hnputs(ph.tcpsport, s->psrc); hnputs(ph.tcpdport, s->pdst);