From a18dd0f8d3e945c2f7764d6420039e0b9a44c0ff Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 26 Nov 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-11-26 --- port/chan.c | 1 + port/devip.c | 66 +++++++++++++++++++++++++----------------------- port/devlance.c | 17 +++++++++---- port/ipdat.h | 12 ++------- port/stil.c | 1 - port/stip.c | 41 +++++++++++++++++++++++++++--- port/stream.c | 2 +- port/tcpif.c | 1 + port/tcpinput.c | 18 +------------ port/tcpoutput.c | 3 +-- 10 files changed, 92 insertions(+), 70 deletions(-) diff --git a/port/chan.c b/port/chan.c index c180fea6043bfd5f8d941da081a6c68be25a7415..158b15b4367aad591f74069d3b105815fae2a76b 100644 --- a/port/chan.c +++ b/port/chan.c @@ -410,6 +410,7 @@ createdir(Chan *c) nc = clone(f->to, 0); nc->mnt = f; runlock(&pg->ns); + poperror(); close(c); return nc; } diff --git a/port/devip.c b/port/devip.c index e065e93c95dd8423a1a274916677c0fb019983b7..99102a8450314b9bb4586f0eb2e496ead3a616d3 100644 --- a/port/devip.c +++ b/port/devip.c @@ -19,6 +19,7 @@ int udpsum = 1; Queue *Ipoutput; /* Control message stream for tcp/il */ Ipifc *ipifc; /* IP protocol interfaces for stip */ Ipconv *ipconv[Nrprotocol]; /* Connections for each protocol */ +Network *ipnet[Nrprotocol]; /* User level interface for protocol */ QLock ipalloc; /* Protocol port allocation lock */ /* ARPA User Datagram Protocol */ @@ -44,30 +45,30 @@ Qinfo ilinfo = { iliput, iloput, ilopen, ilclose, "il" }; Qinfo *protocols[] = { &tcpinfo, &udpinfo, &ilinfo, 0 }; void -ipinitifc(Ipifc *ifc, Qinfo *stproto, Ipconv *cp) +ipinitnet(Network *np, Qinfo *stproto, Ipconv *cp) { int j; for(j = 0; j < conf.ip; j++, cp++){ cp->index = j; cp->stproto = stproto; - cp->ipinterface = ifc; + cp->net = np; } - ifc->net.name = stproto->name; - ifc->net.nconv = conf.ip; - ifc->net.devp = &ipinfo; - ifc->net.protop = stproto; + np->name = stproto->name; + np->nconv = conf.ip; + np->devp = &ipinfo; + np->protop = stproto; if(stproto != &udpinfo) - ifc->net.listen = iplisten; - ifc->net.clone = ipclonecon; - ifc->net.prot = (Netprot *)ialloc(sizeof(Netprot) * conf.ip, 0); - ifc->net.ninfo = 3; - ifc->net.info[0].name = "remote"; - ifc->net.info[0].fill = ipremotefill; - ifc->net.info[1].name = "local"; - ifc->net.info[1].fill = iplocalfill; - ifc->net.info[2].name = "status"; - ifc->net.info[2].fill = ipstatusfill; + np->listen = iplisten; + np->clone = ipclonecon; + np->prot = (Netprot *)ialloc(sizeof(Netprot) * conf.ip, 0); + np->ninfo = 3; + np->info[0].name = "remote"; + np->info[0].fill = ipremotefill; + np->info[1].name = "local"; + np->info[1].fill = iplocalfill; + np->info[2].name = "status"; + np->info[2].fill = ipstatusfill; } void @@ -79,7 +80,8 @@ ipreset(void) for(i = 0; protocols[i]; i++) { ipconv[i] = (Ipconv *)ialloc(sizeof(Ipconv) * conf.ip, 0); - ipinitifc(&ipifc[i], protocols[i], ipconv[i]); + ipnet[i] = (Network *)ialloc(sizeof(Network), 0); + ipinitnet(ipnet[i], protocols[i], ipconv[i]); newqinfo(protocols[i]); } @@ -119,19 +121,19 @@ ipclone(Chan *c, Chan *nc) int ipwalk(Chan *c, char *name) { - return netwalk(c, name, &ipifc[c->dev].net); + return netwalk(c, name, ipnet[c->dev]); } void ipstat(Chan *c, char *db) { - netstat(c, db, &ipifc[c->dev].net); + netstat(c, db, ipnet[c->dev]); } Chan * ipopen(Chan *c, int omode) { - return netopen(c, omode, &ipifc[c->dev].net); + return netopen(c, omode, ipnet[c->dev]); } int @@ -150,7 +152,6 @@ Ipconv * ipincoming(Ipconv *base, Ipconv *from) { Ipconv *new, *etab; - Ipifc *ifc; etab = &base[conf.ip]; for(new = base; new < etab; new++) { @@ -161,13 +162,12 @@ ipincoming(Ipconv *base, Ipconv *from) qunlock(new); continue; } - ifc = base->ipinterface; if(from) /* copy ownership from listening channel */ - netown(&ifc->net, new->index, ifc->net.prot[from->index].owner, 0); + netown(new->net, new->index, new->net->prot[from->index].owner, 0); else /* current user becomes owner */ - netown(&ifc->net, new->index, u->p->user, 0); + netown(new->net, new->index, u->p->user, 0); new->ref = 1; qunlock(new); return new; @@ -193,7 +193,7 @@ ipremove(Chan *c) void ipwstat(Chan *c, char *dp) { - netwstat(c, dp, &ipifc[c->dev].net); + netwstat(c, dp, ipnet[c->dev]); } void @@ -206,7 +206,7 @@ ipclose(Chan *c) long ipread(Chan *c, void *a, long n, ulong offset) { - return netread(c, a, n, offset, &ipifc[c->dev].net); + return netread(c, a, n, offset, ipnet[c->dev]); } long @@ -454,7 +454,6 @@ udpstclose(Queue *q) ipc->dst = 0; closeipifc(ipc->ipinterface); - netdisown(&ipc->ipinterface->net, ipc->index); } void @@ -484,9 +483,9 @@ tcpstoput(Queue *q, Block *bp) Ipconv *s; Tcpctl *tcb; int len, errnum; + Block *f; s = (Ipconv *)(q->ptr); - len = blen(bp); tcb = &s->tcpctl; if(bp->type == M_CTL) { @@ -512,8 +511,14 @@ tcpstoput(Queue *q, Block *bp) case ESTABLISHED: case CLOSE_WAIT: qlock(tcb); - appendb(&tcb->sndq, bp); - tcb->sndcnt += len; + tcb->sndcnt += blen(bp); + if(tcb->sndq == 0) + tcb->sndq = bp; + else { + for(f = tcb->sndq; f->next; f = f->next) + ; + f->next = bp; + } tcprcvwin(s); tcp_output(s); qunlock(tcb); @@ -675,7 +680,6 @@ tcpstclose(Queue *q) qunlock(tcb); break; } - netdisown(&s->ipinterface->net, s->index); } diff --git a/port/devlance.c b/port/devlance.c index 63af56b5bca04025e27fb10abf78a5fcf9d6e413..53215afcbb88ae0f83a0beebbc876bc69b3204e6 100644 --- a/port/devlance.c +++ b/port/devlance.c @@ -118,6 +118,7 @@ typedef struct { /* sadistics */ + int misses; int inpackets; int outpackets; int crcs; /* input crc errors */ @@ -318,10 +319,18 @@ lanceoput(Queue *q, Block *bp ) } } + /* restart the lance if'n it needs it */ + if(l.misses > 4){ + l.misses = 0; + print("restarting lance\n"); + lancestart(0, 1); + } + /* * only one transmitter at a time */ qlock(&l.tlock); + if(waserror()){ freeb(bp); qunlock(&l.tlock); @@ -659,7 +668,6 @@ lanceintr(void) int i; ushort csr; Lancemem *lm = LANCEMEM; - static int misses; csr = *l.rdp; @@ -672,7 +680,7 @@ lanceintr(void) * see if an error occurred */ if(csr & (BABL|MISS|MERR)){ - if(misses++ < 4) + if(l.misses++ < 4) print("lance err %ux\n", csr); } @@ -685,10 +693,8 @@ lanceintr(void) /* * look for rcv'd packets, just wakeup the input process */ - if(l.rl!=l.rc && (MPus(lm->rmr[l.rl].flags) & OWN)==0){ - misses = 0; + if(l.rl!=l.rc && (MPus(lm->rmr[l.rl].flags) & OWN)==0) wakeup(&l.rr); - } /* * look for xmitt'd packets, wake any process waiting for a @@ -780,6 +786,7 @@ lancekproc(void *arg) } for(; l.rl!=l.rc && (MPus(lm->rmr[l.rl].flags) & OWN)==0 ; l.rl=RSUCC(l.rl)){ l.inpackets++; + l.misses = 0; m = &(lm->rmr[l.rl]); t = MPus(m->flags); if(t & ERR){ diff --git a/port/ipdat.h b/port/ipdat.h index 0198806d26d13accef208528e0fb27dbe3ff652c..82445d815211835c4be1d2c71b2852e2228c7fa1 100644 --- a/port/ipdat.h +++ b/port/ipdat.h @@ -231,17 +231,9 @@ struct Tcpctl Block *rcvq; ushort rcvcnt; - Block *rcvoobq; - ushort rcvoobcnt; - Block *sndq; /* List of data going out */ ushort sndcnt; /* Amount of data in send queue */ - Block *sndoobq; /* List of blocks going oob */ - ushort sndoobcnt; /* Size of out of band queue */ - ushort oobmark; /* Out of band sequence mark */ - char oobflags; /* Out of band data flags */ - Reseq *reseq; /* Resequencing queue */ Timer timer; Timer acktimer; /* Acknoledge timer */ @@ -279,6 +271,7 @@ struct Ipconv int ref; int index; Qinfo *stproto; /* Stream protocol for this device */ + Network *net; /* user level network interface */ Ipaddr dst; /* Destination from connect */ Port psrc; /* Source port */ Port pdst; /* Destination port */ @@ -375,7 +368,6 @@ struct Ipifc int maxmtu; /* Maximum transfer unit */ int minmtu; /* Minumum tranfer unit */ int hsize; /* Media header size */ - Network net; Lock; }; @@ -460,7 +452,6 @@ int trim(Tcpctl *, Tcp *, Block **, ushort *); void add_reseq(Tcpctl *, char, Tcp *, Block *, ushort); void close_self(Ipconv *, int); int seq_gt(int, int); -void appendb(Block **, Block *); Ipconv *ip_conn(Ipconv *, Port, Port, Ipaddr dest, char proto); void ipmkdir(Qinfo *, Dirtab *, Ipconv *); Ipconv *ipincoming(Ipconv*, Ipconv*); @@ -499,6 +490,7 @@ void iloutoforder(Ipconv*, Ilhdr*, Block*); void iplocalfill(Chan*, char*, int); void ipremotefill(Chan*, char*, int); void ipstatusfill(Chan*, char*, int); +int ipforme(uchar*); #define fmtaddr(xx) (xx>>24)&0xff,(xx>>16)&0xff,(xx>>8)&0xff,xx&0xff #define MIN(a, b) ((a) < (b) ? (a) : (b)) diff --git a/port/stil.c b/port/stil.c index ad46eacd19de4659053b1788d4bac84fa504a4b0..ee3ec074cbc9a6d3494ef052aed6fab2ec6079bd 100644 --- a/port/stil.c +++ b/port/stil.c @@ -104,7 +104,6 @@ ilclose(Queue *q) s->dst = 0; break; } - netdisown(&s->ipinterface->net, s->index); } void diff --git a/port/stip.c b/port/stip.c index 63da113f98ff1f781a068d9020ac050836d08bc8..adec41d52b4936c4877a9c5bd0d71a60f640aa00 100644 --- a/port/stip.c +++ b/port/stip.c @@ -28,6 +28,7 @@ Queue *Etherq; Ipaddr Myip; Ipaddr Mymask; +Ipaddr Mynetmask; uchar Netmyip[4]; /* In Network byte order */ uchar bcast[4] = { 0xff, 0xff, 0xff, 0xff }; @@ -142,8 +143,10 @@ ipetherclose(Queue *q) Ipconv *ipc; ipc = (Ipconv *)(q->ptr); - if(ipc) + if(ipc){ + netdisown(ipc->net, ipc->index); ipc->ref = 0; + } } void @@ -184,6 +187,10 @@ ipetheroput(Queue *q, Block *bp) ptr++; if(*ptr) Mymask = ipparse((char *)ptr); + /* + * Temporary Until we understand real subnets + */ + Mynetmask = Mymask; freeb(bp); } else @@ -310,10 +317,10 @@ ipetheriput(Queue *q, Block *bp) } /* Look to see if its for me before we waste time checksuming it */ - if(memcmp(h->dst, Netmyip, sizeof(Netmyip)) != 0 && - memcmp(h->dst, bcast, sizeof(bcast)) != 0) + if(ipforme(h->dst) == 0) goto drop; + if(ipcksum && ip_csum(&h->vihl)) { print("ip: checksum error (from %d.%d.%d.%d ?)\n", h->src[0], h->src[1], h->src[2], h->src[3]); @@ -346,6 +353,34 @@ drop: freeb(bp); } +int +ipforme(uchar *addr) +{ + Ipaddr haddr; + + if(memcmp(addr, Netmyip, sizeof(Netmyip)) == 0) + return 1; + + haddr = nhgetl(addr); + + /* My subnet broadcast */ + if((haddr&Mymask) == (Myip&Mymask)) + return 1; + + /* My network broadcast */ + if((haddr&Mynetmask) == (Myip&Mynetmask)) + return 1; + + /* Real ip broadcast */ + if(haddr == 0) + return 1; + + /* Old style 255.255.255.255 address */ + if(haddr == ~0) + return 1; + + return 0; +} Block * ip_reassemble(int offset, Block *bp, Etherhdr *ip) { diff --git a/port/stream.c b/port/stream.c index db42bb3caf782fdbde1518c890efc0f8f7be0095..cd203a0a32f9dc4991ea9d738116d2bcc4e7bfa0 100644 --- a/port/stream.c +++ b/port/stream.c @@ -540,7 +540,7 @@ getq(Queue *q) q->last = 0; q->len -= BLEN(bp); q->nb--; - if((q->flag&QHIWAT) && q->lennbflag&QHIWAT) && q->lennbother){ wakeup(q->other->next->other->rp); q->flag &= ~QHIWAT; } diff --git a/port/tcpif.c b/port/tcpif.c index 8dac80674eeff0663b4241bb94d7ceab4471f708..65ef38144fad0fd1342476c5c158324bff6f80f0 100644 --- a/port/tcpif.c +++ b/port/tcpif.c @@ -27,6 +27,7 @@ state_upcall(Ipconv *s, char oldstate, char newstate) s->psrc = 0; s->pdst = 0; s->dst = 0; + /* NO break */ case CLOSE_WAIT: /* Remote closes */ if(s->readq == 0) break; diff --git a/port/tcpinput.c b/port/tcpinput.c index 109f7d0167500464bc629686f580d06b0a8e0e0e..d4880fa6aaf723559f68c1e778a074b95165fdac 100644 --- a/port/tcpinput.c +++ b/port/tcpinput.c @@ -744,22 +744,6 @@ copyupb(Block **bph, uchar *data, int count) return bytes; } -void -appendb(Block **list, Block *bp) -{ - Block *f; - - if(f = *list) { - while(f->next) - f = f->next; - f->next = bp; - } - else - *list = bp; - - bp->next = 0; -} - int dupb(Block **hp, Block *bp, int offset, int count) { @@ -803,7 +787,7 @@ copyb(Block *bp, int count) Block *nbp, *head, *tail; int i; - head = 0; + head = tail = 0; while(bp && count) { i = BLEN(bp); nbp = allocb(i); diff --git a/port/tcpoutput.c b/port/tcpoutput.c index 9439d1af8fb30c7a6fb238de251b76cd7ab604f3..0a98fe2abf4dcb4ee77632f95614801c10e8c915 100644 --- a/port/tcpoutput.c +++ b/port/tcpoutput.c @@ -108,8 +108,7 @@ tcp_output(Ipconv *s) /* If the entire send queue will now be in the pipe, set the * push flag */ - if((dsize != 0) && - ((sent + ssize) == (tcb->rcvcnt + tcb->rcvoobcnt))) + if(sent+dsize == qlen) seg.flags |= PSH; /* If this transmission includes previously transmitted data,