## diffname port/devip.c 1991/0424 ## diff -e /dev/null /n/bootesdump/1991/0424/sys/src/9/port/devip.c 0a #include "u.h" #include "lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "errno.h" #include "arp.h" #include "ipdat.h" #include "devtab.h" enum{ Nrprotocol = 2, /* Number of protocols supported by this driver */ Nipsubdir = 4, /* Number of subdirectory entries per connection */ }; int udpsum = 1; Queue *Tcpoutput; /* Tcp to lance output channel */ Ipifc *ipifc; /* IP protocol interfaces for stip */ Ipconv *ipconv[Nrprotocol]; /* Connections for each protocol */ Dirtab *ipdir[Nrprotocol]; /* Connection directory structures */ QLock ipalloc; /* Protocol port allocation lock */ /* ARPA User Datagram Protocol */ void udpstiput(Queue *, Block *); void udpstoput(Queue *, Block *); void udpstopen(Queue *, Stream *); void udpstclose(Queue *); /* ARPA Transmission Control Protocol */ void tcpstiput(Queue *, Block *); void tcpstoput(Queue *, Block *); void tcpstopen(Queue *, Stream *); void tcpstclose(Queue *); Qinfo tcpinfo = { tcpstiput, tcpstoput, tcpstopen, tcpstclose, "tcp" }; Qinfo udpinfo = { udpstiput, udpstoput, udpstopen, udpstclose, "udp" }; Qinfo *protocols[] = { &tcpinfo, &udpinfo, 0 }; enum{ ipdirqid, iplistenqid, iplportqid, iprportqid, ipstatusqid, ipchanqid, ipcloneqid }; Dirtab ipsubdir[]={ "listen", {iplistenqid}, 0, 0600, "local", {iplportqid}, 0, 0600, "remote", {iprportqid}, 0, 0600, "status", {ipstatusqid}, 0, 0600, }; void ipreset(void) { int i; ipifc = (Ipifc *)ialloc(sizeof(Ipifc) * conf.ip, 0); for(i = 0; i < Nrprotocol; i++) { ipconv[i] = (Ipconv *)ialloc(sizeof(Ipconv) * conf.ip, 0); ipdir[i] = (Dirtab *)ialloc(sizeof(Dirtab) * (conf.ip+1), 0); ipmkdir(protocols[i], ipdir[i], ipconv[i]); newqinfo(protocols[i]); } initfrag(conf.frag); } void ipmkdir(Qinfo *stproto, Dirtab *dir, Ipconv *cp) { Dirtab *etab; int i; etab = &dir[conf.ip]; for(i = 0; dir < etab; i++, cp++, dir++) { cp->stproto = stproto; sprint(dir->name, "%d", i); dir->qid.path = CHDIR|STREAMQID(i, ipchanqid); dir->qid.vers = 0; dir->length = 0; dir->perm = 0600; } /* Make the clone */ strcpy(dir->name, "clone"); dir->qid.path = ipcloneqid; dir->qid.vers = 0; dir->length = 0; dir->perm = 0600; } void ipinit(void) { } Chan * ipattach(char *spec) { Chan *c; int i; for(i = 0; protocols[i]; i++) { if(strcmp(spec, protocols[i]->name) == 0) { c = devattach('I', spec); c->dev = i; return (c); } } error(Enoproto); } Chan * ipclone(Chan *c, Chan *nc) { return devclone(c, nc); } int ipwalk(Chan *c, char *name) { if(c->qid.path == CHDIR) return devwalk(c, name, ipdir[c->dev], conf.ip+1, devgen); else return devwalk(c, name, ipsubdir, Nipsubdir, streamgen); } Chan* ipclwalk(Chan *c, char *name) { return devclwalk(c, name); } void ipstat(Chan *c, char *db) { if(c->qid.path == CHDIR) devstat(c, db, ipdir[c->dev], conf.ip+1, devgen); else if(c->qid.path == ipcloneqid) devstat(c, db, &ipdir[c->dev][conf.ip], 1, devgen); else devstat(c, db, ipsubdir, Nipsubdir, streamgen); } Chan * ipopen(Chan *c, int omode) { Ipconv *cp; cp = &ipconv[c->dev][STREAMID(c->qid.path)]; if(c->qid.path & CHDIR) { if(omode != OREAD) error(Eperm); } else switch(STREAMTYPE(c->qid.path)) { case ipcloneqid: ipclonecon(c); break; case iplportqid: case iprportqid: case ipstatusqid: if(omode != OREAD) error(Ebadarg); break; case iplistenqid: if(cp->stproto != &tcpinfo) error(Eprotonosup); if(cp->backlog == 0) cp->backlog = 1; streamopen(c, &ipinfo); if(c->stream->devq->next->info != cp->stproto) pushq(c->stream, cp->stproto); if(cp->stproto == &tcpinfo) open_tcp(cp, TCP_PASSIVE, Streamhi, 0); iplisten(c, cp, ipconv[c->dev]); break; case Sdataqid: streamopen(c, &ipinfo); if(c->stream->devq->next->info != cp->stproto) pushq(c->stream, cp->stproto); if(cp->stproto == &tcpinfo) open_tcp(cp, TCP_ACTIVE, Streamhi, 0); break; case Sctlqid: streamopen(c, &ipinfo); if(c->stream->devq->next->info != cp->stproto) pushq(c->stream, cp->stproto); break; } c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; return c; } Ipconv * ipclonecon(Chan *c) { Ipconv *base, *new, *etab; base = ipconv[c->dev]; etab = &base[conf.ip]; for(new = base; new < etab; new++) { if(new->ref == 0 && canqlock(new)) { if(new->ref || (new->stproto == &tcpinfo && new->tcpctl.state != CLOSED)) { qunlock(new); continue; } new->ref++; c->qid.path = CHDIR|STREAMQID(new-base, ipchanqid); devwalk(c, "ctl", 0, 0, streamgen); qunlock(new); streamopen(c, &ipinfo); pushq(c->stream, new->stproto); new->ref--; return new; } } error(Enodev); } void ipcreate(Chan *c, char *name, int omode, ulong perm) { error(Eperm); } void ipremove(Chan *c) { error(Eperm); } void ipwstat(Chan *c, char *dp) { error(Eperm); } void ipclose(Chan *c) { if(c->qid.path != CHDIR) streamclose(c); } long ipread(Chan *c, void *a, long n, ulong offset) { int t, connection; Ipconv *cp; char buf[WORKBUF]; t = STREAMTYPE(c->qid.path); if(t >= Slowqid) return streamread(c, a, n); if(c->qid.path == CHDIR) return devdirread(c, a, n, ipdir[c->dev], conf.ip+1, devgen); if(c->qid.path & CHDIR) return devdirread(c, a, n, ipsubdir, Nipsubdir, streamgen); connection = STREAMID(c->qid.path); cp = &ipconv[c->dev][connection]; switch(t) { case iprportqid: sprint(buf, "%d.%d.%d.%d %d\n", fmtaddr(cp->dst), cp->pdst); return stringread(c, a, n, buf, offset); case iplportqid: sprint(buf, "%d.%d.%d.%d %d\n", fmtaddr(Myip), cp->psrc); return stringread(c, a, n, buf, offset); case ipstatusqid: if(cp->stproto == &tcpinfo) { sprint(buf, "tcp/%d %d %s %s\n", connection, cp->ref, tcpstate[cp->tcpctl.state], cp->tcpctl.flags & CLONE ? "listen" : "connect"); } else sprint(buf, "%s/%d %d\n", cp->stproto->name, connection, cp->ref); return stringread(c, a, n, buf, offset); } return Eperm; } long ipwrite(Chan *c, char *a, long n, ulong offset) { int m, backlog, type; char *field[5], buf[256]; Ipconv *cp; Port port, base; type = STREAMTYPE(c->qid.path); if (type == Sdataqid) return streamwrite(c, a, n, 0); if (type == Sctlqid) { cp = &ipconv[c->dev][STREAMID(c->qid.path)]; if(cp->stproto == &tcpinfo && cp->tcpctl.state != CLOSED) return Edevbusy; strncpy(buf, a, sizeof buf); m = getfields(buf, field, 5, ' '); if(strcmp(field[0], "connect") == 0) { if(m != 2) return Ebadarg; switch(getfields(field[1], field, 5, '!')) { default: return Ebadarg; case 2: base = PORTALLOC; break; case 3: if(strcmp(field[2], "r") != 0) return Eperm; base = PRIVPORTALLOC; break; } cp->dst = ipparse(field[0]); cp->pdst = atoi(field[1]); /* If we have no local port assign one */ qlock(&ipalloc); if(cp->psrc == 0) cp->psrc = nextport(ipconv[c->dev], base); qunlock(&ipalloc); } else if(strcmp(field[0], "announce") == 0 || strcmp(field[0], "reserve") == 0) { if(m != 2) return Ebadarg; port = atoi(field[1]); qlock(&ipalloc); if(portused(ipconv[c->dev], port)) { qunlock(&ipalloc); return Einuse; } cp->psrc = port; cp->ptype = *field[0]; qunlock(&ipalloc); } else if(strcmp(field[0], "backlog") == 0) { if(m != 2) return Ebadarg; backlog = atoi(field[1]); if(backlog == 0) return Ebadarg; if(backlog > 5) backlog = 5; cp->backlog = backlog; } else return streamwrite(c, a, n, 0); return n; } return Eperm; } void udpstiput(Queue *q, Block *bp) { if(bp->type == M_CTL) PUTNEXT(q, bp); else panic("udpstiput: Why am I here"); } /* * udprcvmsg - called by stip to multiplex udp ports onto conversations */ void udprcvmsg(Ipconv *muxed, Block *bp) { Ipconv *ifc, *etab; Udphdr *uh; Port dport; ushort sum, len; Ipaddr addr; uh = (Udphdr *)(bp->rptr); /* Put back pseudo header for checksum */ uh->Unused = 0; len = nhgets(uh->udplen); hnputs(uh->udpplen, len); addr = nhgetl(uh->udpsrc); if(udpsum && nhgets(uh->udpcksum)) { if(sum = ptcl_csum(bp, UDP_EHSIZE, len+UDP_PHDRSIZE)) { print("udp: checksum error %x (%d.%d.%d.%d)\n", sum, fmtaddr(addr)); freeb(bp); return; } } dport = nhgets(uh->udpdport); /* Look for a conversation structure for this port */ etab = &muxed[conf.ip]; for(ifc = muxed; ifc < etab; ifc++) { if(ifc->psrc == dport && ifc->ref) { /* Trim the packet down to data size */ len = len - (UDP_HDRSIZE-UDP_PHDRSIZE); bp = btrim(bp, UDP_EHSIZE+UDP_HDRSIZE, len); if(bp == 0) return; /* Stuff the src address into the remote file */ ifc->dst = addr; ifc->pdst = nhgets(uh->udpsport); PUTNEXT(ifc->readq, bp); return; } } freeb(bp); } void udpstoput(Queue *q, Block *bp) { Ipconv *ipc; Udphdr *uh; int dlen, ptcllen, newlen; /* Prepend udp header to packet and pass on to ip layer */ ipc = (Ipconv *)(q->ptr); if(ipc->psrc == 0) error(Enoport); if(bp->type != M_DATA) { freeb(bp); error(Ebadctl); } /* Only allow atomic udp writes to form datagrams */ if(!(bp->flags & S_DELIM)) { freeb(bp); error(Emsgsize); } /* Round packet up to even number of bytes and check we can * send it */ dlen = blen(bp); if(dlen > UDP_DATMAX) { freeb(bp); error(Emsgsize); } newlen = bround(bp, 1); /* Make space to fit udp & ip & ethernet header */ bp = padb(bp, UDP_EHSIZE + UDP_HDRSIZE); uh = (Udphdr *)(bp->rptr); ptcllen = dlen + (UDP_HDRSIZE-UDP_PHDRSIZE); uh->Unused = 0; uh->udpproto = IP_UDPPROTO; hnputs(uh->udpplen, ptcllen); hnputl(uh->udpdst, ipc->dst); hnputl(uh->udpsrc, Myip); hnputs(uh->udpsport, ipc->psrc); hnputs(uh->udpdport, ipc->pdst); hnputs(uh->udplen, ptcllen); uh->udpcksum[0] = 0; uh->udpcksum[1] = 0; hnputs(uh->udpcksum, ptcl_csum(bp, UDP_EHSIZE, newlen+UDP_HDRSIZE)); PUTNEXT(q, bp); } void udpstclose(Queue *q) { Ipconv *ipc; ipc = (Ipconv *)(q->ptr); /* If the port was bound rather than reserved, clear the allocation */ qlock(ipc); if(--ipc->ref == 0 && ipc->ptype == 'b') ipc->psrc = 0; qunlock(ipc); closeipifc(ipc->ipinterface); } void udpstopen(Queue *q, Stream *s) { Ipconv *ipc; ipc = &ipconv[s->dev][s->id]; ipc->ipinterface = newipifc(IP_UDPPROTO, udprcvmsg, ipconv[s->dev], 1500, 512, ETHER_HDR, "UDP"); qlock(ipc); ipc->ref++; qunlock(ipc); ipc->readq = RD(q); RD(q)->ptr = (void *)ipc; WR(q)->next->ptr = (void *)ipc->ipinterface; WR(q)->ptr = (void *)ipc; } void tcpstiput(Queue *q, Block *bp) { if(bp->type == M_CTL) PUTNEXT(q, bp); else panic("tcpstiput: Why am I here"); } void tcpstoput(Queue *q, Block *bp) { Ipconv *s; Tcpctl *tcb; int len, errnum, oob = 0; s = (Ipconv *)(q->ptr); len = blen(bp); tcb = &s->tcpctl; if(s->psrc == 0) error(Enoport); /* Report asynchronous errors */ if(s->err) error(s->err); switch(tcb->state) { case LISTEN: tcb->flags |= ACTIVE; send_syn(tcb); setstate(s, SYN_SENT); /* No break */ case SYN_SENT: case SYN_RECEIVED: case ESTABLISHED: case CLOSE_WAIT: qlock(tcb); if(oob == 0) { appendb(&tcb->sndq, bp); tcb->sndcnt += len; } else { if(tcb->snd.up == tcb->snd.una) tcb->snd.up = tcb->snd.ptr; appendb(&tcb->sndoobq, bp); tcb->sndoobcnt += len; } tcprcvwin(s); tcp_output(s); qunlock(tcb); break; default: freeb(bp); error(Ehungup); } } void tcpstopen(Queue *q, Stream *s) { Ipconv *ipc; /* Start tcp service processes */ if(!Tcpoutput) { Tcpoutput = WR(q); kproc("tcpack", tcpackproc, 0); kproc("tcpflow", tcpflow, &ipconv[s->dev]); } ipc = &ipconv[s->dev][s->id]; ipc->ipinterface = newipifc(IP_TCPPROTO, tcp_input, ipconv[s->dev], 1500, 512, ETHER_HDR, "TCP"); qlock(ipc); ipc->ref++; qunlock(ipc); ipc->readq = RD(q); ipc->readq->rp = &tcpflowr; RD(q)->ptr = (void *)ipc; WR(q)->next->ptr = (void *)ipc->ipinterface; WR(q)->ptr = (void *)ipc; } int tcp_havecon(Ipconv *s) { return s->curlog; } void iplisten(Chan *c, Ipconv *s, Ipconv *base) { Ipconv *etab, *new; qlock(&s->listenq); for(;;) { sleep(&s->listenr, tcp_havecon, s); /* Search for the new connection, clone the control channel and * return an open channel to the listener */ for(new = base, etab = &base[conf.ip]; new < etab; new++) { if(new->psrc == s->psrc && new->pdst != 0 && new->dst && (new->tcpctl.flags & CLONE) == 0) { new->ref++; /* Remove the listen channel reference */ streamclose(c); s->curlog--; /* Attach the control channel to the new connection */ c->qid.path = CHDIR|STREAMQID(new-base, ipchanqid); devwalk(c, "ctl", 0, 0, streamgen); streamopen(c, &ipinfo); pushq(c->stream, new->stproto); new->ref--; qunlock(&s->listenq); return; } } } } void tcpstclose(Queue *q) { Ipconv *s; Tcpctl *tcb; s = (Ipconv *)(q->ptr); tcb = &s->tcpctl; qlock(s); s->ref--; qunlock(s); /* Not interested in data anymore */ s->readq = 0; switch(tcb->state){ case CLOSED: case LISTEN: case SYN_SENT: close_self(s, 0); break; case SYN_RECEIVED: case ESTABLISHED: tcb->sndcnt++; tcb->snd.nxt++; setstate(s, FINWAIT1); goto output; case CLOSE_WAIT: tcb->sndcnt++; tcb->snd.nxt++; setstate(s, LAST_ACK); output: qlock(tcb); tcp_output(s); qunlock(tcb); break; } } /* * Network byte order functions */ void hnputs(uchar *ptr, ushort val) { ptr[0] = val>>8; ptr[1] = val; } void hnputl(uchar *ptr, ulong val) { ptr[0] = val>>24; ptr[1] = val>>16; ptr[2] = val>>8; ptr[3] = val; } ulong nhgetl(uchar *ptr) { return ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]); } ushort nhgets(uchar *ptr) { return ((ptr[0]<<8) | ptr[1]); } /* * ptcl_csum - protcol cecksum routine */ ushort ptcl_csum(Block *bp, int offset, int len) { uchar *addr; ulong losum = 0, hisum = 0; ushort csum; int odd, blen, x; /* Correct to front of data area */ while(bp && offset && offset >= BLEN(bp)) { offset -= BLEN(bp); bp = bp->next; } if(bp == 0) return 0; addr = bp->rptr + offset; blen = BLEN(bp) - offset; odd = 0; while(len) { if(odd) { losum += *addr++; blen--; len--; odd = 0; } for(x = MIN(len, blen); x > 1; x -= 2) { hisum += addr[0]; losum += addr[1]; len -= 2; blen -= 2; addr += 2; } if(blen && x) { odd = 1; hisum += addr[0]; len--; } bp = bp->next; if(bp == 0) break; blen = BLEN(bp); addr = bp->rptr; } losum += hisum>>8; losum += (hisum&0xff)<<8; while((csum = losum>>16) != 0) losum = csum + (losum & 0xffff); losum &= 0xffff; return ~losum & 0xffff; } Block * btrim(Block *bp, int offset, int len) { Block *nb, *startb; ulong l; if(blen(bp) < offset+len) { freeb(bp); return 0; } while((l = BLEN(bp)) < offset) { offset -= l; nb = bp->next; bp->next = 0; freeb(bp); bp = nb; } startb = bp; bp->rptr += offset; while((l = BLEN(bp)) < len) { len -= l; bp = bp->next; } bp->wptr -= (BLEN(bp) - len); bp->flags |= S_DELIM; if(bp->next) { freeb(bp->next); bp->next = 0; } return(startb); } Ipconv * portused(Ipconv *ic, Port port) { Ipconv *ifc, *etab; etab = &ic[conf.ip]; for(ifc = ic; ifc < etab; ifc++) { if(ifc->psrc == port) return ifc; } return 0; } Port nextport(Ipconv *ic, Port base) { Port i; for(i = base; i < PORTMAX; i++) { if(!portused(ic, i)) return(i); } return(0); } /* NEEDS HASHING ! */ Ipconv * ip_conn(Ipconv *ic, Port dst, Port src, Ipaddr dest, char proto) { Ipconv *s, *etab; /* Look for a conversation structure for this port */ etab = &ic[conf.ip]; for(s = ic; s < etab; s++) { if(s->psrc == dst && s->pdst == src && (s->dst == dest || dest == 0)) return s; } return 0; } . ## diffname port/devip.c 1991/0427 ## diff -e /n/bootesdump/1991/0424/sys/src/9/port/devip.c /n/bootesdump/1991/0427/sys/src/9/port/devip.c 138,143d ## diffname port/devip.c 1991/0430 ## diff -e /n/bootesdump/1991/0427/sys/src/9/port/devip.c /n/bootesdump/1991/0430/sys/src/9/port/devip.c 603a . 601a /* This never goes away - we use this queue to send acks/rejects */ s->opens++; /* Flow control and tcp timer processes */ . 597a static int donekproc; . ## diffname port/devip.c 1991/0504 ## diff -e /n/bootesdump/1991/0430/sys/src/9/port/devip.c /n/bootesdump/1991/0504/sys/src/9/port/devip.c 605c s->inuse++; . ## diffname port/devip.c 1991/0516 ## diff -e /n/bootesdump/1991/0504/sys/src/9/port/devip.c /n/bootesdump/1991/0516/sys/src/9/port/devip.c 538,541c PUTNEXT(q, bp); . 387,390c PUTNEXT(q, bp); . 380c error(Eperm); . 369c error(Ebadarg); . 366c error(Ebadarg); . 358c error(Einuse); . 352c error(Ebadarg); . 350a if(cp->stproto == &tcpinfo && cp->tcpctl.state != CLOSED) error(Edevbusy); . 335c error(Eperm); . 329c error(Ebadarg); . 325c error(Ebadarg); . 323a if(cp->stproto == &tcpinfo && cp->tcpctl.state != CLOSED) error(Edevbusy); . 317,318d 300c error(Eperm); . ## diffname port/devip.c 1991/0705 ## diff -e /n/bootesdump/1991/0516/sys/src/9/port/devip.c /n/bootesdump/1991/0705/sys/src/9/port/devip.c 73a tcpinit(); . ## diffname port/devip.c 1991/0723 ## diff -e /n/bootesdump/1991/0705/sys/src/9/port/devip.c /n/bootesdump/1991/0723/sys/src/9/port/devip.c 711,741d ## diffname port/devip.c 1991/1012 ## diff -e /n/bootesdump/1991/0723/sys/src/9/port/devip.c /n/bootesdump/1991/1012/sys/src/9/port/devip.c 66c for(i = 0; protocols[i]; i++) { . 41c enum { . 39c Qinfo *protocols[] = { &tcpinfo, &udpinfo, &ilinfo, 0 }; . 37a Qinfo ilinfo = { iliput, iloput, ilopen, ilclose, "il" }; . 34a /* Plan9 Reliable Datagram Protocol */ void iliput(Queue *, Block *); void iloput(Queue *, Block *); void ilopen(Queue *, Stream *); void ilclose(Queue *); . 12,14c enum { Nrprotocol = 3, /* Number of protocols supported by this driver */ Nipsubdir = 4, /* Number of subdirectory entries per connection */ . ## diffname port/devip.c 1991/1013 ## diff -e /n/bootesdump/1991/1012/sys/src/9/port/devip.c /n/bootesdump/1991/1013/sys/src/9/port/devip.c 861d 722c * ptcl_csum - protcol checksum routine . 608d 12d ## diffname port/devip.c 1991/1014 ## diff -e /n/bootesdump/1991/1013/sys/src/9/port/devip.c /n/bootesdump/1991/1014/sys/src/9/port/devip.c 200c tcpstart(cp, TCP_ACTIVE, Streamhi, 0); else if(cp->stproto == &ilinfo) ilstart(cp, IL_ACTIVE, 10); . 190,191c tcpstart(cp, TCP_PASSIVE, Streamhi, 0); else if(cp->stproto == &ilinfo) ilstart(cp, IL_PASSIVE, 10); . ## diffname port/devip.c 1991/1015 ## diff -e /n/bootesdump/1991/1014/sys/src/9/port/devip.c /n/bootesdump/1991/1015/sys/src/9/port/devip.c 367,368c if((cp->stproto == &tcpinfo && cp->tcpctl.state != CLOSED) || (cp->stproto == &ilinfo && cp->ilctl.state != Ilclosed)) . 336,338c if((cp->stproto == &tcpinfo && cp->tcpctl.state != CLOSED) || (cp->stproto == &ilinfo && cp->ilctl.state != Ilclosed)) error(Edevbusy); . 308,309c sprint(buf, "%s/%d %d\n", cp->stproto->name, connection, cp->ref); . 306c else if(cp->stproto == &ilinfo) sprint(buf, "il/%d %d %s\n", connection, cp->ref, ilstate[cp->ilctl.state]); . 302,304c if(cp->stproto == &tcpinfo) sprint(buf, "tcp/%d %d %s %s\n", connection, cp->ref, tcpstate[cp->tcpctl.state], . 230,231c (new->stproto == &tcpinfo && new->tcpctl.state != CLOSED) || (new->stproto == &ilinfo && new->ilctl.state != Ilclosed)) { . 179c if(cp->stproto != &tcpinfo && cp->stproto != &ilinfo) . ## diffname port/devip.c 1991/1019 ## diff -e /n/bootesdump/1991/1015/sys/src/9/port/devip.c /n/bootesdump/1991/1019/sys/src/9/port/devip.c 619c } /* Flow control and tcp timer processes */ if(tcpkprocs == 0) { tcpkprocs = 1; . 613,616c if(!Ipoutput) { Ipoutput = WR(q); . 611a static int tcpkprocs; . 20c Queue *Ipoutput; /* Control message stream for tcp/il */ . ## diffname port/devip.c 1991/1023 ## diff -e /n/bootesdump/1991/1019/sys/src/9/port/devip.c /n/bootesdump/1991/1023/sys/src/9/port/devip.c 679a . 678d 672a new->newcon = 0; . 671a . 660,667c new = base; for(etab = &base[conf.ip]; new < etab; new++) { if(new->newcon) { . 658c sleep(&s->listenr, iphavecon, s); . 645c iphavecon(Ipconv *s) . 247,248c return 0; . 240,243d 237,238d 228a new = ipincoming(c->dev); if(new == 0) error(Enodev); c->qid.path = CHDIR|STREAMQID(new-base, ipchanqid); devwalk(c, "ctl", 0, 0, streamgen); streamopen(c, &ipinfo); pushq(c->stream, new->stproto); new->ref--; return new; } error(Enodev); } Ipconv * ipincoming(int dev) { Ipconv *base, *new, *etab; base = ipconv[dev]; etab = &base[conf.ip]; for(new = base; new < etab; new++) { . ## diffname port/devip.c 1991/1024 ## diff -e /n/bootesdump/1991/1023/sys/src/9/port/devip.c /n/bootesdump/1991/1024/sys/src/9/port/devip.c 693c print("ip listener!\n"); . 417c return n; . 415a else if(strcmp(field[0], "backlog") == 0) { if(m != 2) error(Ebadarg); backlog = atoi(field[1]); if(backlog == 0) error(Ebadarg); if(backlog > 5) backlog = 5; cp->backlog = backlog; } else return streamwrite(c, a, n, 0); . 414c if(m != 2) error(Ebadarg); port = atoi(field[1]); qlock(&ipalloc); if(portused(ipconv[c->dev], port)) { qunlock(&ipalloc); error(Einuse); } cp->psrc = port; cp->ptype = *field[0]; qunlock(&ipalloc); . 392,412c } else if(strcmp(field[0], "announce") == 0 || strcmp(field[0], "reserve") == 0) { if((cp->stproto == &tcpinfo && cp->tcpctl.state != CLOSED) || (cp->stproto == &ilinfo && cp->ilctl.state != Ilclosed)) error(Edevbusy); . 388,390c /* If we have no local port assign one */ qlock(&ipalloc); if(cp->psrc == 0) cp->psrc = nextport(ipconv[c->dev], base); qunlock(&ipalloc); . 382,386c cp->dst = ipparse(ctlarg[0]); cp->pdst = atoi(ctlarg[1]); . 380a switch(m = getfields(field[1], ctlarg, 5, '!')) { default: error(Ebadarg); case 2: base = PORTALLOC; break; case 3: if(strcmp(ctlarg[2], "r") != 0) error(Eperm); base = PRIVPORTALLOC; break; . 375,379c if(m != 2) error(Ebadarg); . 360,373c if(strcmp(field[0], "connect") == 0) { if((cp->stproto == &tcpinfo && cp->tcpctl.state != CLOSED) || (cp->stproto == &ilinfo && cp->ilctl.state != Ilclosed)) error(Edevbusy); . 357,358c m = getfields(buf, field, 5, ' '); if(m < 1) errors("bad ip control"); . 352,355c m = n; if(m > sizeof(buf)-1) m = sizeof(buf)-1; strncpy(buf, a, m); buf[m] = '\0'; . 349,350c cp = &ipconv[c->dev][STREAMID(c->qid.path)]; . 346,347c if (type != Sctlqid) error(Eperm); . 340a Ipconv *cp; . 338,339c char *field[5], *ctlarg[5], buf[256]; . 250d 248c Ipconv *new, *etab; . 246c ipincoming(Ipconv *base) . 229c new = ipincoming(base); . 184c cp->backlog = 3; . ## diffname port/devip.c 1991/1025 ## diff -e /n/bootesdump/1991/1024/sys/src/9/port/devip.c /n/bootesdump/1991/1025/sys/src/9/port/devip.c 682c poperror(); print("listen awoke\n"); . 679c if(waserror()) { qunlock(&s->listenq); nexterror(); } print("listener on %lux R 0x%lux\n", s, &s->listenr); . 368c switch(getfields(field[1], ctlarg, 5, '!')) { . ## diffname port/devip.c 1991/1029 ## diff -e /n/bootesdump/1991/1025/sys/src/9/port/devip.c /n/bootesdump/1991/1029/sys/src/9/port/devip.c 699a . 209a . 198a . 186a . 179,180c if(cp->stproto != &tcpinfo && cp->stproto != &ilinfo) . ## diffname port/devip.c 1991/1030 ## diff -e /n/bootesdump/1991/1029/sys/src/9/port/devip.c /n/bootesdump/1991/1030/sys/src/9/port/devip.c 707d 689d 685c . 392,393c else if(strcmp(field[0], "announce") == 0 || strcmp(field[0], "reserve") == 0) { . 18,19c int udpsum = 1; . ## diffname port/devip.c 1991/1104 ## diff -e /n/bootesdump/1991/1030/sys/src/9/port/devip.c /n/bootesdump/1991/1104/sys/src/9/port/devip.c 610,620c appendb(&tcb->sndq, bp); tcb->sndcnt += len; . 591a if(bp->type == M_CTL) { PUTNEXT(q, bp); return; } . 586c int len, errnum; . 551a ipc->pdst = 0; ipc->dst = 0; } . 550c if(--ipc->ref == 0) { . 548d 493a if(bp->type == M_CTL) { PUTNEXT(q, bp); return; } . 492c int dlen, ptcllen, newlen; . 407d 391c else if(strcmp(field[0], "announce") == 0) { . ## diffname port/devip.c 1991/1108 ## diff -e /n/bootesdump/1991/1104/sys/src/9/port/devip.c /n/bootesdump/1991/1108/sys/src/9/port/devip.c 237,243c streamopen(c, &ipinfo); pushq(c->stream, new->stproto); new->ref--; return new; . 234,235c c->qid.path = CHDIR|STREAMQID(new-base, ipchanqid); devwalk(c, "ctl", 0, 0, streamgen); . 228,232c new = ipincoming(base); if(new == 0) error(Enodev); . 225c Ipconv *new, *base; . ## diffname port/devip.c 1991/1112 ## diff -e /n/bootesdump/1991/1108/sys/src/9/port/devip.c /n/bootesdump/1991/1112/sys/src/9/port/devip.c 60,63c "listen", {iplistenqid}, 0, 0666, "local", {iplportqid}, 0, 0666, "remote", {iprportqid}, 0, 0666, "status", {ipstatusqid}, 0, 0666, . ## diffname port/devip.c 1991/1114 ## diff -e /n/bootesdump/1991/1112/sys/src/9/port/devip.c /n/bootesdump/1991/1114/sys/src/9/port/devip.c 716,718c s->ref = 0; . 701c return new - base; . 694,699d 691,692d 687,689d 674a connection = STREAMID(c->qid.path); s = &ipconv[c->dev][connection]; base = ipconv[c->dev]; if((s->stproto == &tcpinfo && s->tcpctl.state != LISTEN) || (s->stproto == &ilinfo && s->ilctl.state != Illistening)) errors("not announced"); . 673a Ipconv *s, *base; int connection; Ipconv *cp; . 670,671c int iplisten(Chan *c) . 663a void ipremotefill(Chan *c, char *buf, int len) { int connection; Ipconv *cp; connection = STREAMID(c->qid.path); cp = &ipconv[c->dev][connection]; sprint(buf, "%d.%d.%d.%d %d\n", fmtaddr(cp->dst), cp->pdst); } void iplocalfill(Chan *c, char *buf, int len) { int connection; Ipconv *cp; connection = STREAMID(c->qid.path); cp = &ipconv[c->dev][connection]; sprint(buf, "%d.%d.%d.%d %d\n", fmtaddr(Myip), cp->psrc); } void ipstatusfill(Chan *c, char *buf, int len) { int connection; Ipconv *cp; connection = STREAMID(c->qid.path); cp = &ipconv[c->dev][connection]; if(cp->stproto == &tcpinfo) sprint(buf, "tcp/%d %d %s %s\n", connection, cp->ref, tcpstate[cp->tcpctl.state], cp->tcpctl.flags & CLONE ? "listen" : "connect"); else if(cp->stproto == &ilinfo) sprint(buf, "il/%d %d %s\n", connection, cp->ref, ilstate[cp->ilctl.state]); else sprint(buf, "%s/%d %d\n", cp->stproto->name, connection, cp->ref); } . 652,654c ipc->ref = 1; . 567,569c ipc->ref = 1; . 547,553c ipc->psrc = 0; ipc->pdst = 0; ipc->dst = 0; ipc->ref = 0; . 402a if(cp->stproto == &tcpinfo) tcpstart(cp, TCP_PASSIVE, Streamhi, 0); else if(cp->stproto == &ilinfo) ilstart(cp, IL_PASSIVE, 10); if(cp->backlog == 0) cp->backlog = 3; . 384a if(cp->stproto == &tcpinfo) tcpstart(cp, TCP_ACTIVE, Streamhi, 0); else if(cp->stproto == &ilinfo) ilstart(cp, IL_ACTIVE, 10); . 291,326c return netread(c, a, n, offset, &ipifc[c->dev].net); . 284c if(c->stream) . 255c new->ref = 1; . 231,238c return new - base; . 222c int . 160,219c return netopen(c, omode, &ipifc[c->dev].net); . 149,154c netstat(c, db, &ipifc[c->dev].net); . 140,143c return netwalk(c, name, &ipifc[c->dev].net); . 85,108d 75,76c ipinitifc(&ipifc[i], protocols[i], ipconv[i]); . 69c int i, j; . 59,65d 56,57c for(j = 0; j < conf.ip; j++, cp++) cp->stproto = stproto; ifc->net.name = stproto->name; ifc->net.nconv = conf.ip; ifc->net.devp = &ipinfo; ifc->net.protop = stproto; if(stproto != &udpinfo) ifc->net.listen = iplisten; ifc->net.clone = ipclonecon; 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; } . 49,54c int j; . 47c void ipinitifc(Ipifc *ifc, Qinfo *stproto, Ipconv *cp) . 22d ## diffname port/devip.c 1991/1115 ## diff -e /n/bootesdump/1991/1114/sys/src/9/port/devip.c /n/bootesdump/1991/1115/sys/src/9/port/devip.c 656a netdisown(&s->ipinterface->net, s->index); . 434a netdisown(&ipc->ipinterface->net, ipc->index); . 182c netwstat(c, dp, &ipifc[c->dev].net); . 175a USED(c); . 169a USED(c, name, omode, perm); . 158a ifc = base->ipinterface; if(from) /* copy ownership from listening channel */ netown(&ifc->net, new->index, ifc->net.prot[from->index].owner, 0); else /* current user becomes owner */ netown(&ifc->net, new->index, u->p->user, 0); . 148a Ipifc *ifc; . 146c ipincoming(Ipconv *base, Ipconv *from) . 139c new = ipincoming(base, 0); . 59a ifc->net.prot = (Netprot *)ialloc(sizeof(Netprot) * conf.ip, 0); . 52a cp->ipinterface = ifc; } . 51c for(j = 0; j < conf.ip; j++, cp++){ cp->index = j; . ## diffname port/devip.c 1991/1120 ## diff -e /n/bootesdump/1991/1115/sys/src/9/port/devip.c /n/bootesdump/1991/1120/sys/src/9/port/devip.c 644,645d 544,545d 461d 446d ## diffname port/devip.c 1991/1121 ## diff -e /n/bootesdump/1991/1120/sys/src/9/port/devip.c /n/bootesdump/1991/1121/sys/src/9/port/devip.c 716d 628a print("no newcon\n"); . 618a print("listen wakes\n"); . ## diffname port/devip.c 1991/1124 ## diff -e /n/bootesdump/1991/1121/sys/src/9/port/devip.c /n/bootesdump/1991/1124/sys/src/9/port/devip.c 619d 583,584c sprint(buf, "il/%d %d %s rtt %d ms\n", connection, cp->ref, ilstate[cp->ilctl.state], cp->ilctl.rtt); . 569a . 559a . 271c ilstart(cp, IL_ACTIVE, 20); . ## diffname port/devip.c 1991/1125 ## diff -e /n/bootesdump/1991/1124/sys/src/9/port/devip.c /n/bootesdump/1991/1125/sys/src/9/port/devip.c 368c ifc->pdst = sport; . 359c if(ifc->psrc == dport && ifc->ref && (ifc->pdst == 0 || ifc->pdst == sport)) { . 354a sport = nhgets(uh->udpsport); . 331c Port dport, sport; . 273a else if(strcmp(field[0], "disconnect") == 0) { if(cp->stproto != &udpinfo) error(Eperm); cp->dst = 0; cp->pdst = 0; } . ## diffname port/devip.c 1991/1126 ## diff -e /n/bootesdump/1991/1125/sys/src/9/port/devip.c /n/bootesdump/1991/1126/sys/src/9/port/devip.c 678d 515,516c tcb->sndcnt += blen(bp); if(tcb->sndq == 0) tcb->sndq = bp; else { for(f = tcb->sndq; f->next; f = f->next) ; f->next = bp; } . 489d 486a Block *f; . 457d 209c return netread(c, a, n, offset, ipnet[c->dev]); . 196c netwstat(c, dp, ipnet[c->dev]); . 170c netown(new->net, new->index, u->p->user, 0); . 167c netown(new->net, new->index, new->net->prot[from->index].owner, 0); . 164d 153d 134c return netopen(c, omode, ipnet[c->dev]); . 128c netstat(c, db, ipnet[c->dev]); . 122c return netwalk(c, name, ipnet[c->dev]); . 82c ipnet[i] = (Network *)ialloc(sizeof(Network), 0); ipinitnet(ipnet[i], protocols[i], ipconv[i]); . 61,70c 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; . 56,59c np->name = stproto->name; np->nconv = conf.ip; np->devp = &ipinfo; np->protop = stproto; . 54c cp->net = np; . 47c ipinitnet(Network *np, Qinfo *stproto, Ipconv *cp) . 21a Network *ipnet[Nrprotocol]; /* User level interface for protocol */ . ## diffname port/devip.c 1991/12171 ## diff -e /n/bootesdump/1991/1126/sys/src/9/port/devip.c /n/bootesdump/1991/12171/sys/src/9/port/devip.c 818,819c if(s->psrc == dst) if(s->pdst == src) if(s->dst == dest || dest == 0) . 804c . 801c for(i = base; i < PORTMAX; i++) . 791d 788c for(ifc = ic; ifc < etab; ifc++) . 676c setstate(s, Last_ack); . 673c case Close_wait: . 671c setstate(s, Finwait1); . 667,668c case Syn_received: case Established: . 662,664c case Closed: case Listen: case Syn_sent: . 623c if((s->stproto == &tcpinfo && s->tcpctl.state != Listen) || . 509,512c case Syn_sent: case Syn_received: case Established: case Close_wait: . 507c setstate(s, Syn_sent); . 504c case Listen: . 282c if((cp->stproto == &tcpinfo && cp->tcpctl.state != Closed) || . 240c if((cp->stproto == &tcpinfo && cp->tcpctl.state != Closed) || . 160c (new->stproto == &tcpinfo && new->tcpctl.state != Closed) || . 19,23c 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 */ . ## diffname port/devip.c 1992/0101 ## diff -e /n/bootesdump/1991/12171/sys/src/9/port/devip.c /n/bootesdump/1992/0101/sys/src/9/port/devip.c 738,739d 709,726c x = MIN(len, blen); csum = ptcl_bsum(addr, x); if(odd) hisum += csum; else losum += csum; odd = (odd+x) & 1; len -= x; . 706a if(bp->next == 0) return ~ptcl_bsum(addr, MIN(len, blen)) & 0xffff; losum = 0; hisum = 0; . 693c ulong losum, hisum; . 689a ptcl_bsum(uchar *addr, int len) { ulong losum, hisum, mdsum, x; ulong t1, t2; losum = 0; hisum = 0; mdsum = 0; x = 0; if((ulong)addr & 1) { if(len) { hisum += addr[0]; len--; addr++; } x = 1; } while(len >= 16) { t1 = *(ushort*)(addr+0); t2 = *(ushort*)(addr+2); mdsum += t1; t1 = *(ushort*)(addr+4); mdsum += t2; t2 = *(ushort*)(addr+6); mdsum += t1; t1 = *(ushort*)(addr+8); mdsum += t2; t2 = *(ushort*)(addr+10); mdsum += t1; t1 = *(ushort*)(addr+12); mdsum += t2; t2 = *(ushort*)(addr+14); mdsum += t1; mdsum += t2; len -= 16; addr += 16; } while(len >= 2) { mdsum += *(ushort*)addr; len -= 2; addr += 2; } if(x) { if(len) losum += addr[0]; if(LITTLE) losum += mdsum; else hisum += mdsum; } else { if(len) hisum += addr[0]; if(LITTLE) hisum += mdsum; else losum += mdsum; } losum += hisum >> 8; losum += (hisum & 0xff) << 8; while(hisum = losum>>16) losum = hisum + (losum & 0xffff); return losum & 0xffff; } ushort . 686,688c static short endian = 1; static char* aendian = (char*)&endian; #define LITTLE *aendian . ## diffname port/devip.c 1992/0106 ## diff -e /n/bootesdump/1992/0101/sys/src/9/port/devip.c /n/bootesdump/1992/0106/sys/src/9/port/devip.c 431a uh->frag[0] = 0; uh->frag[1] = 0; . ## diffname port/devip.c 1992/0111 ## diff -e /n/bootesdump/1992/0106/sys/src/9/port/devip.c /n/bootesdump/1992/0111/sys/src/9/port/devip.c 284c error(Enetbusy); . 242c error(Enetbusy); . 237c error(Ebadarg); . 6c #include "../port/error.h" . ## diffname port/devip.c 1992/0112 ## diff -e /n/bootesdump/1992/0111/sys/src/9/port/devip.c /n/bootesdump/1992/0112/sys/src/9/port/devip.c 627c error(Enolisten); . ## diffname port/devip.c 1992/0128 ## diff -e /n/bootesdump/1992/0112/sys/src/9/port/devip.c /n/bootesdump/1992/0128/sys/src/9/port/devip.c 862c return(*p = i); for(i = base ; i <= *p; i++) if(!portused(ic, i)) return(*p = i); . 860c if(priv){ base = PRIVPORTALLOC; max = PORTALLOC; p = &lastport[1]; } else { base = PORTALLOC; max = PORTMAX; p = &lastport[0]; } for(i = *p + 1; i < max; i++) . 857a Port base; Port max; Port *p; . 856c nextport(Ipconv *ic, int priv) . 854a static Port lastport[2] = { PORTALLOC-1, PRIVPORTALLOC-1 }; . 559a ipc->err = 0; . 265c cp->psrc = nextport(ipconv[c->dev], priv); . 256c priv = 1; . 251c priv = 0; . 217c Port port; . 215c int m, backlog, type, priv; . ## diffname port/devip.c 1992/0213 ## diff -e /n/bootesdump/1992/0128/sys/src/9/port/devip.c /n/bootesdump/1992/0213/sys/src/9/port/devip.c 586c sprint(buf, "%d.%d.%d.%d %d\n", fmtaddr(Myip[Myself]), cp->psrc); . 436c hnputl(uh->udpsrc, Myip[Myself]); . ## diffname port/devip.c 1992/0219 ## diff -e /n/bootesdump/1992/0213/sys/src/9/port/devip.c /n/bootesdump/1992/0219/sys/src/9/port/devip.c 102a /* fail if ip is not yet configured */ if(Ipoutput == 0) error(Enoproto); . ## diffname port/devip.c 1992/0223 ## diff -e /n/bootesdump/1992/0219/sys/src/9/port/devip.c /n/bootesdump/1992/0223/sys/src/9/port/devip.c 666a qunlock(s); . 665a qlock(s); . ## diffname port/devip.c 1992/0306 ## diff -e /n/bootesdump/1992/0223/sys/src/9/port/devip.c /n/bootesdump/1992/0306/sys/src/9/port/devip.c 646a qunlock(s); . 645a qlock(s); . 175a new->newcon = 0; . ## diffname port/devip.c 1992/0307 ## diff -e /n/bootesdump/1992/0306/sys/src/9/port/devip.c /n/bootesdump/1992/0307/sys/src/9/port/devip.c 655c print("iplisten: no newcon\n"); . 607,608c sprint(buf, "il/%d %d %s rtt %d ms %d csum\n", connection, cp->ref, ilstate[cp->ilctl.state], cp->ilctl.rtt, cp->ipinterface ? cp->ipinterface->chkerrs : 0); . ## diffname port/devip.c 1992/0313 ## diff -e /n/bootesdump/1992/0307/sys/src/9/port/devip.c /n/bootesdump/1992/0313/sys/src/9/port/devip.c 685a . 679a . 635a if(s->stproto == &ilinfo) if(s->ilctl.state != Illistening) error(Enolisten); . 632,633c if(s->stproto == &tcpinfo) if(s->tcpctl.state != Listen) . 532a . 514a . 372,373c if(ifc->ref) if(ifc->psrc == dport) if(ifc->pdst == 0 || ifc->pdst == sport) { . 328a if(cp->stproto == &ilinfo) if(cp->ilctl.state != Ilclosed) return 1; return 0; } . 327a int ipconbusy(Ipconv *cp) { if(cp->stproto == &tcpinfo) if(cp->tcpctl.state != Closed) return 1; . 287,289c if(ipconbusy(cp)) error(Enetbusy); . 245,247c if(ipconbusy(cp)) error(Enetbusy); . 174a . 171c netown(new->net, new->index, new->net->prot[from->index].owner, 0); . 163,165c if(new->ref || ipconbusy(new)) { . ## diffname port/devip.c 1992/0318 ## diff -e /n/bootesdump/1992/0313/sys/src/9/port/devip.c /n/bootesdump/1992/0318/sys/src/9/port/devip.c 171,172c else /* current user becomes owner */ . 167,168c if(from) /* copy ownership from listening channel */ . 41c Qinfo tcpinfo = { tcpstiput, tcpstoput, tcpstopen, tcpstclose, "tcp", 0, 1 }; . 14,15c Nrprotocol = 3, /* Number of protocols supported by this driver */ Nipsubdir = 4, /* Number of subdirectory entries per connection */ . ## diffname port/devip.c 1992/0319 ## diff -e /n/bootesdump/1992/0318/sys/src/9/port/devip.c /n/bootesdump/1992/0319/sys/src/9/port/devip.c 532a print("q %d\n", blen(bp)); . ## diffname port/devip.c 1992/0320 ## diff -e /n/bootesdump/1992/0319/sys/src/9/port/devip.c /n/bootesdump/1992/0320/sys/src/9/port/devip.c 533d ## diffname port/devip.c 1992/0321 ## diff -e /n/bootesdump/1992/0320/sys/src/9/port/devip.c /n/bootesdump/1992/0321/sys/src/9/port/devip.c 2c #include "../port/lib.h" . ## diffname port/devip.c 1992/0322 ## diff -e /n/bootesdump/1992/0321/sys/src/9/port/devip.c /n/bootesdump/1992/0322/sys/src/9/port/devip.c 710a poperror(); . 709a if(waserror()) { qunlock(tcb); nexterror(); } . 541a poperror(); . 531a if(waserror()) { qunlock(tcb); nexterror(); } . ## diffname port/devip.c 1992/0406 ## diff -e /n/bootesdump/1992/0322/sys/src/9/port/devip.c /n/bootesdump/1992/0406/sys/src/9/port/devip.c 885a if(port == 0) return 0; . ## diffname port/devip.c 1992/0414 ## diff -e /n/bootesdump/1992/0406/sys/src/9/port/devip.c /n/bootesdump/1992/0414/sys/src/9/port/devip.c 676a qunlock(&s->listenq); . 668c if(new->newcon == s) { . 663a qlock(&s->listenq); /* single thread for the sleep */ if(waserror()) { qunlock(&s->listenq); nexterror(); } . 657,662d ## diffname port/devip.c 1992/0416 ## diff -e /n/bootesdump/1992/0414/sys/src/9/port/devip.c /n/bootesdump/1992/0416/sys/src/9/port/devip.c 699a qunlock(tcb); . 698a qlock(tcb); . 697a /* * reset any incoming calls to this listener */ qlock(s); s->backlog = 0; s->curlog = 0; etab = &tcpbase[conf.ip]; for(ifc = tcpbase; ifc < etab; ifc++){ if(ifc->newcon == s) { ifc->newcon = 0; tcpflushincoming(ifc); } } qunlock(s); qlock(tcb); close_self(s, 0); qunlock(tcb); break; case Closed: . 696d 684a Ipconv *etab, *ifc; . 586a /* pass any waiting data upstream */ tcb = &ipc->tcpctl; qlock(tcb); while(bp = getb(&tcb->rcvq)) PUTNEXT(ipc->readq, bp); qunlock(tcb); . 575a if(tcpbase == 0) tcpbase = ipconv[s->dev]; . 559a Tcpctl *tcb; Block *bp; . 292,298c if(port){ qlock(&ipalloc); if(portused(ipconv[c->dev], port)) { qunlock(&ipalloc); error(Einuse); } cp->psrc = port; qunlock(&ipalloc); } else if(*field[1] != '*'){ qlock(&ipalloc); cp->psrc = nextport(ipconv[c->dev], 0); qunlock(&ipalloc); } else cp->psrc = 0; . 268c qunlock(&ipalloc); } . 265,266c if(cp->psrc == 0){ qlock(&ipalloc); . 174d 23a Ipconv *tcpbase; /* Base tcp connection */ . ## diffname port/devip.c 1992/0520 ## diff -e /n/bootesdump/1992/0416/sys/src/9/port/devip.c /n/bootesdump/1992/0520/sys/src/9/port/devip.c 697a return -1; /* not reached */ . 117a return 0; /* not reached */ . ## diffname port/devip.c 1992/0528 ## diff -e /n/bootesdump/1992/0520/sys/src/9/port/devip.c /n/bootesdump/1992/0528/sys/src/9/port/devip.c 252c error(Eneedservice); . ## diffname port/devip.c 1992/0529 ## diff -e /n/bootesdump/1992/0528/sys/src/9/port/devip.c /n/bootesdump/1992/0529/sys/src/9/port/devip.c 987a } /* * Fuck me sideways with a bargepole!!! -- philw * * BSD authentication protocol, used on ports 512, 513, & 514. * This makes sure that a user can only write the REAL user id. * * q->ptr is number of nulls seen */ void bsdopen(Queue *q, Stream *s) { RD(q)->ptr = q; WR(q)->ptr = q; } void bsdclose(Queue *q) { Block *bp; bp = allocb(0); bp->type = M_HANGUP; PUTNEXT(q->other, bp); } void bsdiput(Queue *q, Block *bp) { PUTNEXT(q, bp); } void bsdoput(Queue *q, Block *bp) { uchar *luser; uchar *p; Block *nbp; int n; /* just pass it on if we've done authentication */ if(q->ptr == 0 || bp->type != M_DATA){ PUTNEXT(q, bp); return; } /* collect into a single block */ lock(q); if(q->first == 0) q->first = pullup(bp, blen(bp)); else{ nbp = q->first; nbp->next = bp; q->first = pullup(nbp, blen(nbp)); } bp = q->first; if(bp == 0){ unlock(q); bsdclose(q); return; } /* look for 2 nulls to indicate stderr port and local user */ luser = memchr(bp->rptr, 0, BLEN(bp)); if(luser == 0){ unlock(q); return; } luser++; if(memchr(luser, 0, bp->wptr - luser) == 0){ unlock(q); return; } /* if luser is a lie, hangup */ if(memcmp(luser, u->p->user, strlen(u->p->user)+1) != 0) bsdclose(q); /* mark queue as authenticated and pass data to remote side */ q->ptr = 0; q->first = 0; bp->flags |= S_DELIM; PUTNEXT(q, bp); unlock(q); . 276a /* * stupid hack for BSD port's 512, 513, & 514 * to make it harder for user to lie about his * identity. -- presotto */ switch(cp->pdst){ case 512: case 513: case 514: pushq(c->stream, &bsdinfo); break; } . 44a Qinfo bsdinfo = { bsdiput, bsdoput, bsdopen, bsdclose, "bsd", 0, 1 }; . 40a /* BSD authentication Protocol checker */ void bsdiput(Queue *, Block *); void bsdoput(Queue *, Block *); void bsdopen(Queue *, Stream *); void bsdclose(Queue *); . ## diffname port/devip.c 1992/0602 ## diff -e /n/bootesdump/1992/0529/sys/src/9/port/devip.c /n/bootesdump/1992/0602/sys/src/9/port/devip.c 1087c qunlock(&q->rlock); . 1074c qunlock(&q->rlock); . 1069c qunlock(&q->rlock); . 1061c qunlock(&q->rlock); . 1051c qlock(&q->rlock); . ## diffname port/devip.c 1992/0619 ## diff -e /n/bootesdump/1992/0602/sys/src/9/port/devip.c /n/bootesdump/1992/0619/sys/src/9/port/devip.c 96d ## diffname port/devip.c 1992/0622 ## diff -e /n/bootesdump/1992/0619/sys/src/9/port/devip.c /n/bootesdump/1992/0622/sys/src/9/port/devip.c 89,90c ipconv[i] = (Ipconv *)xalloc(sizeof(Ipconv) * conf.ip); ipnet[i] = (Network *)xalloc(sizeof(Network)); . 86c ipifc = (Ipifc *)xalloc(sizeof(Ipifc) * conf.ip); . 71c np->prot = (Netprot *)xalloc(sizeof(Netprot) * conf.ip); . ## diffname port/devip.c 1992/0623 ## diff -e /n/bootesdump/1992/0622/sys/src/9/port/devip.c /n/bootesdump/1992/0623/sys/src/9/port/devip.c 178c netown(new, u->p->user, 0); . 175,176c netown(new, from->owner, 0); . 71d 62a netadd(np, cp, j); . 60d ## diffname port/devip.c 1992/0625 ## diff -e /n/bootesdump/1992/0623/sys/src/9/port/devip.c /n/bootesdump/1992/0625/sys/src/9/port/devip.c 26,45c Streamput udpstiput, udpstoput, tcpstiput, tcpstoput, iliput, iloput, bsdiput, bsdoput; Streamopen udpstopen, tcpstopen, ilopen, bsdopen; Streamclose udpstclose, tcpstclose, ilclose, bsdclose; . ## diffname port/devip.c 1992/0626 ## diff -e /n/bootesdump/1992/0625/sys/src/9/port/devip.c /n/bootesdump/1992/0626/sys/src/9/port/devip.c 977,978c etab = &ifc->conv[Nipconv]; for(p = ifc->conv; p < etab; p++) { s = *p; if(s == 0) break; . 974c Ipconv **p, *s, **etab; . 971,972c Ipconv* ip_conn(Ipifc *ifc, Port dst, Port src, Ipaddr dest, char proto) . 963c if(!portused(ifc, i)) . 960c if(!portused(ifc, i)) . 942c nextport(Ipifc *ifc, int priv) . 931,934c etab = &ifc->conv[Nipconv]; for(p = ifc->conv; p < etab; p++){ cp = *p; if(cp == 0) break; if(cp->psrc == port) return cp; } . 926c Ipconv **p, **etab; Ipconv *cp; . 924c portused(Ipifc *ifc, Port port) . 723,727c etab = &tcpbase[Nipconv]; for(p = tcpbase; p < etab && *p; p++){ if((*p)->newcon == s) { (*p)->newcon = 0; tcpflushincoming(*p); . 704c Ipconv **etab, **p; . 691c return new->id; . 683,684c etab = &ipifc[c->dev]->conv[Nipconv]; for(p = ipifc[c->dev]->conv; p < etab; p++) { new = *p; if(new == 0) break; . 671c if(s->ifc->protop == &ilinfo) . 667c if(s->ifc->protop == &tcpinfo) . 664,665c s = ipcreateconv(ipifc[c->dev], connection); . 658,659c Ipconv **p, **etab, *new; Ipconv *s; . 646c sprint(buf, "%s/%d %d\n", cp->ifc->protop->name, connection, cp->ref); . 644c cp->ifc ? cp->ifc->chkerrs : 0); . 641c else if(cp->ifc->protop == &ilinfo) . 636,637c cp = ipcreateconv(ipifc[c->dev], connection); if(cp->ifc->protop == &tcpinfo) . 624,625c cp = ipcreateconv(ipifc[c->dev], STREAMID(c->qid.path)); . 621d 613,614c cp = ipcreateconv(ipifc[c->dev], STREAMID(c->qid.path)); . 610d 596c WR(q)->next->ptr = (void *)ipc->ifc; . 586,589c tcpbase = ipifc[s->dev]->conv; ifc = ipifc[s->dev]; initipifc(ifc, IP_TCPPROTO, tcp_input, 1500, 512, ETHER_HDR, "TCP"); ipc = ipcreateconv(ifc, s->id); . 581c kproc("tcpflow", tcpflow, ipifc[s->dev]); . 566a Ipifc *ifc; . 494c WR(q)->next->ptr = (void *)ipc->ifc; . 488,490c ipc = ipcreateconv(ipifc[s->dev], s->id); initipifc(ipifc[s->dev], IP_UDPPROTO, udprcvmsg, 1500, 512, ETHER_HDR, "UDP"); . 479,480d 398,400c cp->dst = addr; cp->pdst = sport; PUTNEXT(cp->readq, bp); . 386,390c etab = &ifc->conv[Nipconv]; for(p = ifc->conv; p < etab; p++) { cp = *p; if(cp == 0) break; if(cp->ref) if(cp->psrc == dport) if(cp->pdst == 0 || cp->pdst == sport) { . 357c Ipconv *cp, **p, **etab; . 355c udprcvmsg(Ipifc *ifc, Block *bp) . 338c if(cp->ifc->protop == &ilinfo) . 334c if(cp->ifc->protop == &tcpinfo) . 309c else if(cp->ifc->protop == &ilinfo) . 307c if(cp->ifc->protop == &tcpinfo) . 302c cp->psrc = nextport(ipifc[c->dev], 0); . 294c if(portused(ipifc[c->dev], port)) { . 277c if(cp->ifc->protop != &udpinfo) . 260c else if(cp->ifc->protop == &ilinfo) . 258c if(cp->ifc->protop == &tcpinfo) . 254c cp->psrc = nextport(ipifc[c->dev], priv); . 217c cp = ipcreateconv(ipifc[c->dev], STREAMID(c->qid.path)); . 199c return netread(c, a, n, offset, ipifc[c->dev]); . 186c netwstat(c, dp, ipifc[c->dev]); . 166c /* create one */ qlock(ifc); etab = &ifc->conv[Nipconv]; for(p = ifc->conv; ; p++){ if(p == etab){ qunlock(ifc); return 0; } if(*p == 0) break; } if(waserror()){ qunlock(ifc); nexterror(); } new = smalloc(sizeof(Ipconv)); new->ifc = ifc; netadd(ifc, new, p - ifc->conv); qlock(new); *p = new; qunlock(ifc); if(from) /* copy ownership from listening channel */ netown(new, from->owner, 0); else /* current user becomes owner */ netown(new, u->p->user, 0); new->ref = 1; qunlock(new); return new; . 149,150c p = &ifc->conv[id]; if(*p) return *p; qlock(ifc); p = &ifc->conv[id]; if(*p){ qunlock(ifc); return *p; } if(waserror()){ qunlock(ifc); nexterror(); } new = smalloc(sizeof(Ipconv)); new->ifc = ifc; netadd(ifc, new, p - ifc->conv); new->ref = 1; *p = new; qunlock(ifc); poperror(); return new; } /* * allocate a conversation structure. */ Ipconv* ipincoming(Ipifc *ifc, Ipconv *from) { Ipconv **p, **etab; Ipconv *new; /* look for an unused existing conversation */ etab = &ifc->conv[Nipconv]; for(p = ifc->conv; p < etab; p++) { new = *p; if(new == 0) break; . 147c Ipconv **p; Ipconv *new; . 144,145c /* * create a new conversation structure if none exists for this conversation slot */ Ipconv* ipcreateconv(Ipifc *ifc, int id) . 141c return new->id; . 137,138c new = ipincoming(ipifc[c->dev], 0); . 135c Ipconv *new; . 129c return netopen(c, omode, ipifc[c->dev]); . 123c netstat(c, db, ipifc[c->dev]); . 117c return netwalk(c, name, ipifc[c->dev]); . 77c initfrag(Nfrag); . 71,73c ipifc[i] = xalloc(sizeof(Ipifc)); ipinitifc(ipifc[i], protocols[i]); . 68,69d 66c int i; . 52,60c ifc->listen = iplisten; ifc->clone = ipclonecon; ifc->ninfo = 3; ifc->info[0].name = "remote"; ifc->info[0].fill = ipremotefill; ifc->info[1].name = "local"; ifc->info[1].fill = iplocalfill; ifc->info[2].name = "status"; ifc->info[2].fill = ipstatusfill; ifc->name = stproto->name; . 42,50c ifc->conv = xalloc(Nipconv * sizeof(Ipconv*)); ifc->protop = stproto; ifc->nconv = Nipconv; ifc->devp = &ipinfo; . 38c ipinitifc(Ipifc *ifc, Qinfo *stproto) . 24c Ipconv **tcpbase; . 20,22c Ipifc *ipifc[Nrprotocol+1]; . 15a Nfrag = 32, /* Ip reassembly queue entries */ Nifc = 4, /* max interfaces */ . ## diffname port/devip.c 1992/0627 ## diff -e /n/bootesdump/1992/0626/sys/src/9/port/devip.c /n/bootesdump/1992/0627/sys/src/9/port/devip.c 538a ipc->headers = 0; . 522,523c hnputs(uh->udpsport, cp->psrc); if(cp->headers){ hnputl(uh->udpdst, addr); hnputs(uh->udpdport, port); } else { hnputl(uh->udpdst, cp->dst); hnputs(uh->udpdport, cp->pdst); } . 520d 498a /* * if we're in header mode, rip off the first 64 bytes as the * destination. The destination is in ascii in the form * %d.%d.%d.%d!%d */ if(cp->headers){ /* get user specified addresses */ bp = pullup(bp, Udphdrsize); if(bp == 0){ freeb(bp); error(Emsgsize); } addr = nhgetl(bp->rptr); bp->rptr += 4; port = nhgets(bp->rptr); bp->rptr += 2; } else addr = port = 0; . 483,485c cp = (Ipconv *)(q->ptr); if(cp->psrc == 0) . 476a Ipaddr addr; Port port; . 474c Ipconv *cp; . 460,462c if(cp->headers){ /* pass the src address to the stream head */ nbp = allocb(Udphdrsize); nbp->next = bp; bp = nbp; hnputl(bp->wptr, addr); bp->wptr += 4; hnputs(bp->wptr, sport); bp->wptr += 2; } else { /* save the src address in the conversation struct */ cp->dst = addr; cp->pdst = sport; } . 421a Block *nbp; . 384a else if(strcmp(field[0], "headers") == 0) { cp->headers = 1; /* include addr/port in user packet */ } . ## diffname port/devip.c 1992/0711 ## diff -e /n/bootesdump/1992/0627/sys/src/9/port/devip.c /n/bootesdump/1992/0711/sys/src/9/port/devip.c 1130d 1128d 1106a USED(s); . 1077c ip_conn(Ipifc *ifc, Port dst, Port src, Ipaddr dest) . 759d 732a if(len < 64) error(Ebadarg); . 722a if(len < 24) error(Ebadarg); . 713a if(len < 24) error(Ebadarg); . 690c initipifc(ifc, IP_TCPPROTO, tcp_input, 1500, 512, ETHER_HDR); . 610d 591c initipifc(ipifc[s->dev], IP_UDPPROTO, udprcvmsg, 1500, 512, ETHER_HDR); . 269a USED(offset); . 40,41d ## diffname port/devip.c 1992/0717 ## diff -e /n/bootesdump/1992/0711/sys/src/9/port/devip.c /n/bootesdump/1992/0717/sys/src/9/port/devip.c 726c sprint(buf, "%d.%d.%d.%d!%d\n", fmtaddr(Myip[Myself]), cp->psrc); . 715c sprint(buf, "%d.%d.%d.%d!%d\n", fmtaddr(cp->dst), cp->pdst); . ## diffname port/devip.c 1992/0720 ## diff -e /n/bootesdump/1992/0717/sys/src/9/port/devip.c /n/bootesdump/1992/0720/sys/src/9/port/devip.c 748c sprint(buf, "%s/%d %d Datagram\n", cp->ifc->protop->name, connection, cp->ref); . ## diffname port/devip.c 1992/0728 ## diff -e /n/bootesdump/1992/0720/sys/src/9/port/devip.c /n/bootesdump/1992/0728/sys/src/9/port/devip.c 217a poperror(); . ## diffname port/devip.c 1992/0826 ## diff -e /n/bootesdump/1992/0728/sys/src/9/port/devip.c /n/bootesdump/1992/0826/sys/src/9/port/devip.c 845c localclose(s, 0); . 838c localclose(s, 0); . ## diffname port/devip.c 1992/0903 ## diff -e /n/bootesdump/1992/0826/sys/src/9/port/devip.c /n/bootesdump/1992/0903/sys/src/9/port/devip.c 866c tcpoutput(s); . 859c tcpsetstate(s, Last_ack); . 853c tcpsetstate(s, Finwait1); . 764a Ipconv **p, **etab, *new; . 762d 734a int connection; . 733d 689c initipifc(ifc, IP_TCPPROTO, tcpinput, 1500, 512, ETHER_HDR); . 652c tcpoutput(s); . 637a /* * Push data */ . 630,631c tcpsndsyn(tcb); tcpsetstate(s, Syn_sent); . 560c } else { . 557c if(cp->headers) { . 173a Ipconv **p, **etab; . 172d 80a Chan *c; . 79d 26,28c Streamput udpstiput, udpstoput, tcpstiput, tcpstoput; Streamput iliput, iloput, bsdiput, bsdoput; Streamopen udpstopen, tcpstopen, ilopen, bsdopen; Streamclose udpstclose, tcpstclose, ilclose, bsdclose; . ## diffname port/devip.c 1992/12051 ## diff -e /n/bootesdump/1992/0903/sys/src/9/port/devip.c /n/bootesdump/1992/12051/sys/src/9/port/devip.c 1066c max = UNPRIVPORTALLOC; . ## diffname port/devip.c 1992/1221 ## diff -e /n/bootesdump/1992/12051/sys/src/9/port/devip.c /n/bootesdump/1992/1221/sys/src/9/port/devip.c 648a if(tcb->sndcnt > Streamhi) tcb->sndfull = 1; . 640a * Process flow control */ if(tcb->sndfull){ qlock(&tcb->sndrlock); if(waserror()) { qunlock(&tcb->sndrlock); nexterror(); } sleep(&tcb->sndr, tcproominq, tcb); poperror(); qunlock(&tcb->sndrlock); } /* . 606a tcproominq(void *a) { return !((Tcpctl *)a)->sndfull; } . ## diffname port/devip.c 1993/0314 ## diff -e /n/bootesdump/1992/1221/sys/src/9/port/devip.c /n/bootesdump/1993/0314/sys/src/9/port/devip.c 769c cp->tcpctl.flags & CLONE ? "listen" : "connect", cp->tcpctl.srtt, cp->tcpctl.mdev); . 767c sprint(buf, "tcp/%d %d %s %s %d+%d\n", connection, cp->ref, . ## diffname port/devip.c 1993/0501 ## diff -e /n/bootesdump/1993/0314/sys/src/9/port/devip.c /n/fornaxdump/1993/0501/sys/src/brazil/port/devip.c 1198c if(memcmp(luser, up->user, strlen(up->user)+1) != 0) . 769,770c cp->tcpctl.flags & CLONE ? "listen" : "connect"); . 767c sprint(buf, "tcp/%d %d %s %s\n", connection, cp->ref, . 750,751c if(len < 32) error(Etoosmall); . 739,740c if(len < 32) error(Etoosmall); . 223c netown(new, up->user, 0); . 190c netown(new, up->user, 0); . ## diffname port/devip.c 1993/0804 # deleted ## diff -e /n/fornaxdump/1993/0501/sys/src/brazil/port/devip.c /n/fornaxdump/1993/0804/sys/src/brazil/port/devip.c 1,1206d