Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/port/devip.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


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

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.