## 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
|