M port/chan.c => port/chan.c +1 -0
@@ 410,6 410,7 @@ createdir(Chan *c)
nc = clone(f->to, 0);
nc->mnt = f;
runlock(&pg->ns);
+ poperror();
close(c);
return nc;
}
M port/devip.c => port/devip.c +35 -31
@@ 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);
}
M port/devlance.c => port/devlance.c +12 -5
@@ 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){
M port/ipdat.h => port/ipdat.h +2 -10
@@ 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))
M port/stil.c => port/stil.c +0 -1
@@ 104,7 104,6 @@ ilclose(Queue *q)
s->dst = 0;
break;
}
- netdisown(&s->ipinterface->net, s->index);
}
void
M port/stip.c => port/stip.c +38 -3
@@ 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)
{
M port/stream.c => port/stream.c +1 -1
@@ 540,7 540,7 @@ getq(Queue *q)
q->last = 0;
q->len -= BLEN(bp);
q->nb--;
- if((q->flag&QHIWAT) && q->len<Streamhi/2 && q->nb<Streambhi/2){
+ if((q->flag&QHIWAT) && q->len<Streamhi/2 && q->nb<Streambhi/2 &&q->other){
wakeup(q->other->next->other->rp);
q->flag &= ~QHIWAT;
}
M port/tcpif.c => port/tcpif.c +1 -0
@@ 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;
M port/tcpinput.c => port/tcpinput.c +1 -17
@@ 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);
M port/tcpoutput.c => port/tcpoutput.c +1 -2
@@ 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,