plan 9 kernel history: overview | file list | diff list

1992/0720/port/devip.c (diff list | history)

1991/0424/sys/src/9/port/devip.c:135,1461991/0427/sys/src/9/port/devip.c:135,140 (short | long)
1991/0424    
		return devwalk(c, name, ipsubdir, Nipsubdir, streamgen); 
} 
 
Chan* 
ipclwalk(Chan *c, char *name) 
{ 
	return devclwalk(c, name); 
} 
                 
void 
ipstat(Chan *c, char *db) 
{ 
1991/0427/sys/src/9/port/devip.c:595,6061991/0430/sys/src/9/port/devip.c:595,612 (short | long)
1991/0424    
tcpstopen(Queue *q, Stream *s) 
{ 
	Ipconv *ipc; 
1991/0430    
	static int donekproc; 
1991/0424    
 
	/* Start tcp service processes */ 
	if(!Tcpoutput) { 
		Tcpoutput = WR(q); 
1991/0430    
		/* This never goes away - we use this queue to send acks/rejects */ 
		s->opens++; 
 
		/* Flow control and tcp timer processes */ 
1991/0424    
		kproc("tcpack", tcpackproc, 0); 
		kproc("tcpflow", tcpflow, &ipconv[s->dev]); 
1991/0430    
 
1991/0424    
	} 
 
	ipc = &ipconv[s->dev][s->id]; 
1991/0430/sys/src/9/port/devip.c:602,6081991/0504/sys/src/9/port/devip.c:602,608 (short | long)
1991/0424    
		Tcpoutput = WR(q); 
1991/0430    
		/* This never goes away - we use this queue to send acks/rejects */ 
		s->opens++; 
                 
1991/0504    
		s->inuse++; 
1991/0430    
		/* Flow control and tcp timer processes */ 
1991/0424    
		kproc("tcpack", tcpackproc, 0); 
		kproc("tcpflow", tcpflow, &ipconv[s->dev]); 
1991/0504/sys/src/9/port/devip.c:297,3031991/0516/sys/src/9/port/devip.c:297,303 (short | long)
1991/0424    
		return stringread(c, a, n, buf, offset); 
	} 
 
	return Eperm; 
1991/0516    
	error(Eperm); 
1991/0424    
} 
 
long 
1991/0504/sys/src/9/port/devip.c:314,3381991/0516/sys/src/9/port/devip.c:314,340
1991/0424    
 
	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) { 
1991/0516    
			if(cp->stproto == &tcpinfo && 
			   cp->tcpctl.state != CLOSED) 
				error(Edevbusy); 
 
1991/0424    
			if(m != 2) 
				return Ebadarg; 
1991/0516    
				error(Ebadarg); 
1991/0424    
 
			switch(getfields(field[1], field, 5, '!')) { 
			default: 
				return Ebadarg; 
1991/0516    
				error(Ebadarg); 
1991/0424    
			case 2: 
				base = PORTALLOC; 
				break; 
			case 3: 
				if(strcmp(field[2], "r") != 0) 
					return Eperm; 
1991/0516    
					error(Eperm); 
1991/0424    
				base = PRIVPORTALLOC; 
				break; 
			} 
1991/0504/sys/src/9/port/devip.c:348,3611991/0516/sys/src/9/port/devip.c:350,367
1991/0424    
		} 
		else if(strcmp(field[0], "announce") == 0 || 
			strcmp(field[0], "reserve") == 0) { 
1991/0516    
				if(cp->stproto == &tcpinfo && 
				   cp->tcpctl.state != CLOSED) 
					error(Edevbusy); 
 
1991/0424    
			if(m != 2) 
				return Ebadarg; 
1991/0516    
				error(Ebadarg); 
1991/0424    
			port = atoi(field[1]); 
 
			qlock(&ipalloc); 
			if(portused(ipconv[c->dev], port)) { 
				qunlock(&ipalloc);	 
				return Einuse; 
1991/0516    
				error(Einuse); 
1991/0424    
			} 
			cp->psrc = port; 
			cp->ptype = *field[0]; 
1991/0504/sys/src/9/port/devip.c:363,3721991/0516/sys/src/9/port/devip.c:369,378
1991/0424    
		} 
		else if(strcmp(field[0], "backlog") == 0) { 
			if(m != 2) 
				return Ebadarg; 
1991/0516    
				error(Ebadarg); 
1991/0424    
			backlog = atoi(field[1]); 
			if(backlog == 0) 
				return Ebadarg; 
1991/0516    
				error(Ebadarg); 
1991/0424    
			if(backlog > 5) 
				backlog = 5; 
			cp->backlog = backlog; 
1991/0504/sys/src/9/port/devip.c:377,3831991/0516/sys/src/9/port/devip.c:383,389
1991/0424    
		return n; 
	} 
 
	return Eperm; 
1991/0516    
	error(Eperm); 
1991/0424    
} 
 
 
1991/0504/sys/src/9/port/devip.c:384,3931991/0516/sys/src/9/port/devip.c:390,396
1991/0424    
void 
udpstiput(Queue *q, Block *bp) 
{ 
	if(bp->type == M_CTL) 
		PUTNEXT(q, bp); 
	else 
		panic("udpstiput: Why am I here"); 
1991/0516    
	PUTNEXT(q, bp); 
1991/0424    
} 
 
/* 
1991/0504/sys/src/9/port/devip.c:535,5441991/0516/sys/src/9/port/devip.c:538,544
1991/0424    
void 
tcpstiput(Queue *q, Block *bp) 
{ 
	if(bp->type == M_CTL) 
		PUTNEXT(q, bp); 
	else 
		panic("tcpstiput: Why am I here"); 
1991/0516    
	PUTNEXT(q, bp); 
1991/0424    
} 
 
void 
1991/0516/sys/src/9/port/devip.c:71,761991/0705/sys/src/9/port/devip.c:71,77 (short | long)
1991/0424    
	} 
 
	initfrag(conf.frag); 
1991/0705    
	tcpinit(); 
1991/0424    
} 
 
void 
1991/0705/sys/src/9/port/devip.c:708,7441991/0723/sys/src/9/port/devip.c:708,713 (short | long)
1991/0424    
	} 
} 
 
/* 
 * 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 
1991/0723/sys/src/9/port/devip.c:9,171991/1012/sys/src/9/port/devip.c:9,19 (short | long)
1991/0424    
 
#include	"devtab.h" 
 
enum{ 
	Nrprotocol = 2, /* Number of protocols supported by this driver */ 
	Nipsubdir = 4,	/* Number of subdirectory entries per connection */ 
1991/1012    
 
enum 
{ 
	Nrprotocol	= 3,		/* Number of protocols supported by this driver */ 
	Nipsubdir	= 4,		/* Number of subdirectory entries per connection */ 
1991/0424    
}; 
 
int udpsum = 1; 
1991/0723/sys/src/9/port/devip.c:32,441991/1012/sys/src/9/port/devip.c:34,53
1991/0424    
void	tcpstoput(Queue *, Block *); 
void	tcpstopen(Queue *, Stream *); 
void	tcpstclose(Queue *); 
1991/1012    
/* Plan9 Reliable Datagram Protocol */ 
void	iliput(Queue *, Block *); 
void	iloput(Queue *, Block *); 
void	ilopen(Queue *, Stream *); 
void	ilclose(Queue *); 
1991/0424    
 
Qinfo tcpinfo = { tcpstiput, tcpstoput, tcpstopen, tcpstclose, "tcp" }; 
Qinfo udpinfo = { udpstiput, udpstoput, udpstopen, udpstclose, "udp" }; 
1991/1012    
Qinfo ilinfo  = { iliput,    iloput,    ilopen,    ilclose,    "il"  }; 
1991/0424    
 
Qinfo *protocols[] = { &tcpinfo, &udpinfo, 0 }; 
1991/1012    
Qinfo *protocols[] = { &tcpinfo, &udpinfo, &ilinfo, 0 }; 
1991/0424    
 
enum{ 
1991/1012    
enum 
{ 
1991/0424    
	ipdirqid, 
	iplistenqid, 
	iplportqid, 
1991/0723/sys/src/9/port/devip.c:63,691991/1012/sys/src/9/port/devip.c:72,78
1991/0424    
 
	ipifc = (Ipifc *)ialloc(sizeof(Ipifc) * conf.ip, 0); 
 
	for(i = 0; i < Nrprotocol; i++) { 
1991/1012    
	for(i = 0; protocols[i]; i++) { 
1991/0424    
		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]); 
1991/1012/sys/src/9/port/devip.c:9,151991/1013/sys/src/9/port/devip.c:9,14 (short | long)
1991/0424    
 
#include	"devtab.h" 
 
1991/1012    
                 
enum 
{ 
	Nrprotocol	= 3,		/* Number of protocols supported by this driver */ 
1991/1012/sys/src/9/port/devip.c:605,6111991/1013/sys/src/9/port/devip.c:604,609
1991/0424    
tcpstopen(Queue *q, Stream *s) 
{ 
	Ipconv *ipc; 
1991/0430    
	static int donekproc; 
1991/0424    
 
	/* Start tcp service processes */ 
	if(!Tcpoutput) { 
1991/1012/sys/src/9/port/devip.c:719,7251991/1013/sys/src/9/port/devip.c:717,723
1991/0424    
 
 
/*  
 * ptcl_csum - protcol cecksum routine 
1991/1013    
 * ptcl_csum - protcol checksum routine 
1991/0424    
 */ 
ushort 
ptcl_csum(Block *bp, int offset, int len) 
1991/1012/sys/src/9/port/devip.c:858,8611991/1013/sys/src/9/port/devip.c:856,858
1991/0424    
 
	return 0; 
} 
                 
1991/1013/sys/src/9/port/devip.c:187,1941991/1014/sys/src/9/port/devip.c:187,196 (short | long)
1991/0424    
			pushq(c->stream, cp->stproto); 
 
		if(cp->stproto == &tcpinfo) 
			open_tcp(cp, TCP_PASSIVE, Streamhi, 0); 
	                 
1991/1014    
			tcpstart(cp, TCP_PASSIVE, Streamhi, 0); 
		else if(cp->stproto == &ilinfo) 
			ilstart(cp, IL_PASSIVE, 10); 
 
1991/0424    
		iplisten(c, cp, ipconv[c->dev]); 
		break; 
	case Sdataqid: 
1991/1013/sys/src/9/port/devip.c:197,2031991/1014/sys/src/9/port/devip.c:199,208
1991/0424    
			pushq(c->stream, cp->stproto); 
 
		if(cp->stproto == &tcpinfo) 
			open_tcp(cp, TCP_ACTIVE, Streamhi, 0); 
1991/1014    
			tcpstart(cp, TCP_ACTIVE, Streamhi, 0); 
		else if(cp->stproto == &ilinfo) 
			ilstart(cp, IL_ACTIVE, 10); 
 
1991/0424    
		break; 
	case Sctlqid: 
		streamopen(c, &ipinfo); 
1991/1014/sys/src/9/port/devip.c:176,1821991/1015/sys/src/9/port/devip.c:176,183 (short | long)
1991/0424    
			error(Ebadarg); 
		break; 
	case iplistenqid: 
		if(cp->stproto != &tcpinfo) 
1991/1015    
		if(cp->stproto != &tcpinfo && 
		   cp->stproto != &ilinfo) 
1991/0424    
			error(Eprotonosup); 
 
		if(cp->backlog == 0) 
1991/1014/sys/src/9/port/devip.c:227,2341991/1015/sys/src/9/port/devip.c:228,235
1991/0424    
	for(new = base; new < etab; new++) { 
		if(new->ref == 0 && canqlock(new)) { 
			if(new->ref || 
		          (new->stproto == &tcpinfo && 
			   new->tcpctl.state != CLOSED)) { 
1991/1015    
		          (new->stproto == &tcpinfo && new->tcpctl.state != CLOSED) || 
			  (new->stproto == &ilinfo && new->ilctl.state != Ilclosed)) { 
1991/0424    
				qunlock(new); 
				continue; 
			} 
1991/1014/sys/src/9/port/devip.c:299,3121991/1015/sys/src/9/port/devip.c:300,312
1991/0424    
		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], 
1991/1015    
		if(cp->stproto == &tcpinfo) 
			sprint(buf, "tcp/%d %d %s %s\n", connection, cp->ref, tcpstate[cp->tcpctl.state], 
1991/0424    
				cp->tcpctl.flags & CLONE ? "listen" : "connect"); 
		} 
1991/1015    
		else if(cp->stproto == &ilinfo) 
			sprint(buf, "il/%d %d %s\n", connection, cp->ref, ilstate[cp->ilctl.state]); 
1991/0424    
		else 
			sprint(buf, "%s/%d %d\n", cp->stproto->name,  
				connection, cp->ref); 
1991/1015    
			sprint(buf, "%s/%d %d\n", cp->stproto->name, connection, cp->ref); 
1991/0424    
 
		return stringread(c, a, n, buf, offset); 
	} 
1991/1014/sys/src/9/port/devip.c:333,3411991/1015/sys/src/9/port/devip.c:333,341
1991/0424    
		m = getfields(buf, field, 5, ' '); 
 
		if(strcmp(field[0], "connect") == 0) { 
1991/0516    
			if(cp->stproto == &tcpinfo && 
			   cp->tcpctl.state != CLOSED) 
				error(Edevbusy); 
1991/1015    
			if((cp->stproto == &tcpinfo && cp->tcpctl.state != CLOSED) || 
			   (cp->stproto == &ilinfo && cp->ilctl.state != Ilclosed)) 
					error(Edevbusy); 
1991/0516    
 
1991/0424    
			if(m != 2) 
1991/0516    
				error(Ebadarg); 
1991/1014/sys/src/9/port/devip.c:364,3711991/1015/sys/src/9/port/devip.c:364,371
1991/0424    
		} 
		else if(strcmp(field[0], "announce") == 0 || 
			strcmp(field[0], "reserve") == 0) { 
1991/0516    
				if(cp->stproto == &tcpinfo && 
				   cp->tcpctl.state != CLOSED) 
1991/1015    
			if((cp->stproto == &tcpinfo && cp->tcpctl.state != CLOSED) || 
			   (cp->stproto == &ilinfo && cp->ilctl.state != Ilclosed)) 
1991/0516    
					error(Edevbusy); 
 
1991/0424    
			if(m != 2) 
1991/1015/sys/src/9/port/devip.c:17,231991/1019/sys/src/9/port/devip.c:17,23 (short | long)
1991/0424    
 
int udpsum = 1; 
 
Queue	*Tcpoutput;		/* Tcp to lance output channel */ 
1991/1019    
Queue	*Ipoutput;		/* Control message stream for tcp/il */ 
1991/0424    
Ipifc	*ipifc;			/* IP protocol interfaces for stip */ 
Ipconv	*ipconv[Nrprotocol];	/* Connections for each protocol */ 
Dirtab  *ipdir[Nrprotocol];	/* Connection directory structures */ 
1991/1015/sys/src/9/port/devip.c:609,6221991/1019/sys/src/9/port/devip.c:609,625
1991/0424    
tcpstopen(Queue *q, Stream *s) 
{ 
	Ipconv *ipc; 
1991/1019    
	static int tcpkprocs; 
1991/0424    
 
	/* Start tcp service processes */ 
	if(!Tcpoutput) { 
		Tcpoutput = WR(q); 
1991/0430    
		/* This never goes away - we use this queue to send acks/rejects */ 
1991/1019    
	if(!Ipoutput) { 
		Ipoutput = WR(q); 
1991/0430    
		s->opens++; 
1991/0504    
		s->inuse++; 
1991/0430    
		/* Flow control and tcp timer processes */ 
1991/1019    
	} 
 
	/* Flow control and tcp timer processes */ 
	if(tcpkprocs == 0) { 
		tcpkprocs = 1; 
1991/0424    
		kproc("tcpack", tcpackproc, 0); 
		kproc("tcpflow", tcpflow, &ipconv[s->dev]); 
1991/0430    
 
1991/1019/sys/src/9/port/devip.c:226,2311991/1023/sys/src/9/port/devip.c:226,255 (short | long)
1991/0424    
	base = ipconv[c->dev]; 
	etab = &base[conf.ip]; 
	for(new = base; new < etab; new++) { 
1991/1023    
		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++) { 
1991/0424    
		if(new->ref == 0 && canqlock(new)) { 
			if(new->ref || 
1991/1015    
		          (new->stproto == &tcpinfo && new->tcpctl.state != CLOSED) || 
1991/1019/sys/src/9/port/devip.c:234,2511991/1023/sys/src/9/port/devip.c:258,268
1991/0424    
				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); 
1991/1023    
	return 0; 
1991/0424    
} 
 
void 
1991/1019/sys/src/9/port/devip.c:642,6481991/1023/sys/src/9/port/devip.c:659,665
1991/0424    
} 
 
int 
tcp_havecon(Ipconv *s) 
1991/1023    
iphavecon(Ipconv *s) 
1991/0424    
{ 
	return s->curlog; 
} 
1991/1019/sys/src/9/port/devip.c:655,6821991/1023/sys/src/9/port/devip.c:672,696
1991/0424    
	qlock(&s->listenq); 
 
	for(;;) { 
		sleep(&s->listenr, tcp_havecon, s); 
1991/1023    
		sleep(&s->listenr, iphavecon, s); 
1991/0424    
 
		/* 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++; 
                 
1991/1023    
		new = base; 
 		for(etab = &base[conf.ip]; new < etab; new++) { 
			if(new->newcon) { 
1991/0424    
				/* Remove the listen channel reference */ 
				streamclose(c); 
 
				s->curlog--; 
1991/1023    
 
1991/0424    
				/* Attach the control channel to the new connection */ 
1991/1023    
				new->newcon = 0; 
1991/0424    
				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); 
1991/1023    
 
1991/0424    
				return; 
			} 
		} 
1991/1023/sys/src/9/port/devip.c:181,1871991/1024/sys/src/9/port/devip.c:181,187 (short | long)
1991/0424    
			error(Eprotonosup); 
 
		if(cp->backlog == 0) 
			cp->backlog = 1; 
1991/1024    
			cp->backlog = 3; 
1991/0424    
 
		streamopen(c, &ipinfo); 
		if(c->stream->devq->next->info != cp->stproto) 
1991/1023/sys/src/9/port/devip.c:226,2321991/1024/sys/src/9/port/devip.c:226,232
1991/0424    
	base = ipconv[c->dev]; 
	etab = &base[conf.ip]; 
	for(new = base; new < etab; new++) { 
1991/1023    
		new = ipincoming(c->dev); 
1991/1024    
		new = ipincoming(base); 
1991/1023    
		if(new == 0) 
			error(Enodev); 
 
1991/1023/sys/src/9/port/devip.c:243,2531991/1024/sys/src/9/port/devip.c:243,252
1991/1023    
} 
 
Ipconv * 
ipincoming(int dev) 
1991/1024    
ipincoming(Ipconv *base) 
1991/1023    
{ 
	Ipconv *base, *new, *etab; 
1991/1024    
	Ipconv *new, *etab; 
1991/1023    
 
	base = ipconv[dev]; 
	etab = &base[conf.ip]; 
	for(new = base; new < etab; new++) { 
1991/0424    
		if(new->ref == 0 && canqlock(new)) { 
1991/1023/sys/src/9/port/devip.c:335,4201991/1024/sys/src/9/port/devip.c:334,426
1991/0424    
ipwrite(Chan *c, char *a, long n, ulong offset) 
{ 
	int 	m, backlog, type; 
	char 	*field[5], buf[256]; 
	Ipconv  *cp; 
1991/1024    
	char 	*field[5], *ctlarg[5], buf[256]; 
1991/0424    
	Port	port, base; 
1991/1024    
	Ipconv  *cp; 
1991/0424    
 
	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)]; 
1991/1024    
	if (type != Sctlqid) 
		error(Eperm); 
1991/0424    
 
		strncpy(buf, a, sizeof buf); 
		m = getfields(buf, field, 5, ' '); 
1991/1024    
	cp = &ipconv[c->dev][STREAMID(c->qid.path)]; 
1991/0424    
 
		if(strcmp(field[0], "connect") == 0) { 
1991/1015    
			if((cp->stproto == &tcpinfo && cp->tcpctl.state != CLOSED) || 
			   (cp->stproto == &ilinfo && cp->ilctl.state != Ilclosed)) 
					error(Edevbusy); 
1991/1024    
	m = n; 
	if(m > sizeof(buf)-1) 
		m = sizeof(buf)-1; 
	strncpy(buf, a, m); 
	buf[m] = '\0'; 
1991/0516    
 
1991/0424    
			if(m != 2) 
1991/0516    
				error(Ebadarg); 
1991/1024    
	m = getfields(buf, field, 5, ' '); 
	if(m < 1) 
		errors("bad ip control"); 
1991/0424    
 
			switch(getfields(field[1], field, 5, '!')) { 
			default: 
1991/0516    
				error(Ebadarg); 
1991/0424    
			case 2: 
				base = PORTALLOC; 
				break; 
			case 3: 
				if(strcmp(field[2], "r") != 0) 
1991/0516    
					error(Eperm); 
1991/0424    
				base = PRIVPORTALLOC; 
				break; 
			} 
			cp->dst = ipparse(field[0]); 
			cp->pdst = atoi(field[1]); 
1991/1024    
	if(strcmp(field[0], "connect") == 0) { 
		if((cp->stproto == &tcpinfo && cp->tcpctl.state != CLOSED) || 
		   (cp->stproto == &ilinfo && cp->ilctl.state != Ilclosed)) 
				error(Edevbusy); 
1991/0424    
 
			/* If we have no local port assign one */ 
			qlock(&ipalloc); 
			if(cp->psrc == 0) 
				cp->psrc = nextport(ipconv[c->dev], base); 
			qunlock(&ipalloc); 
1991/1024    
		if(m != 2) 
			error(Ebadarg); 
1991/0424    
 
1991/1024    
		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; 
1991/0424    
		} 
		else if(strcmp(field[0], "announce") == 0 || 
			strcmp(field[0], "reserve") == 0) { 
1991/1015    
			if((cp->stproto == &tcpinfo && cp->tcpctl.state != CLOSED) || 
			   (cp->stproto == &ilinfo && cp->ilctl.state != Ilclosed)) 
1991/0516    
					error(Edevbusy); 
1991/1024    
		cp->dst = ipparse(ctlarg[0]); 
		cp->pdst = atoi(ctlarg[1]); 
1991/0516    
 
1991/0424    
			if(m != 2) 
1991/0516    
				error(Ebadarg); 
1991/0424    
			port = atoi(field[1]); 
1991/1024    
		/* If we have no local port assign one */ 
		qlock(&ipalloc); 
		if(cp->psrc == 0) 
			cp->psrc = nextport(ipconv[c->dev], base); 
		qunlock(&ipalloc); 
1991/0424    
 
			qlock(&ipalloc); 
			if(portused(ipconv[c->dev], port)) { 
				qunlock(&ipalloc);	 
1991/0516    
				error(Einuse); 
1991/0424    
			} 
			cp->psrc = port; 
			cp->ptype = *field[0]; 
			qunlock(&ipalloc); 
		} 
		else if(strcmp(field[0], "backlog") == 0) { 
			if(m != 2) 
1991/0516    
				error(Ebadarg); 
1991/0424    
			backlog = atoi(field[1]); 
			if(backlog == 0) 
1991/0516    
				error(Ebadarg); 
1991/0424    
			if(backlog > 5) 
				backlog = 5; 
			cp->backlog = backlog; 
		} 
		else 
			return streamwrite(c, a, n, 0); 
1991/1024    
	} 
	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); 
1991/0424    
 
		return n; 
1991/1024    
		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); 
1991/0424    
	} 
1991/1024    
	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); 
1991/0424    
 
1991/0516    
	error(Eperm); 
1991/1024    
	return n; 
1991/0424    
} 
 
 
1991/1023/sys/src/9/port/devip.c:690,6961991/1024/sys/src/9/port/devip.c:696,702
1991/0424    
				pushq(c->stream, new->stproto); 
				new->ref--; 
				qunlock(&s->listenq); 
1991/1023    
                 
1991/1024    
print("ip listener!\n"); 
1991/0424    
				return; 
			} 
		} 
1991/1024/sys/src/9/port/devip.c:365,3711991/1025/sys/src/9/port/devip.c:365,371 (short | long)
1991/1024    
		if(m != 2) 
			error(Ebadarg); 
1991/0424    
 
1991/1024    
		switch(m = getfields(field[1], ctlarg, 5, '!')) { 
1991/1025    
		switch(getfields(field[1], ctlarg, 5, '!')) { 
1991/1024    
		default: 
			error(Ebadarg); 
		case 2: 
1991/1024/sys/src/9/port/devip.c:676,6851991/1025/sys/src/9/port/devip.c:676,690
1991/0424    
	Ipconv *etab, *new; 
 
	qlock(&s->listenq); 
                 
1991/1025    
	if(waserror()) { 
		qunlock(&s->listenq); 
		nexterror(); 
	} 
print("listener on %lux R 0x%lux\n", s, &s->listenr); 
1991/0424    
	for(;;) { 
1991/1023    
		sleep(&s->listenr, iphavecon, s); 
1991/0424    
                 
1991/1025    
		poperror(); 
print("listen awoke\n"); 
1991/1023    
		new = base; 
 		for(etab = &base[conf.ip]; new < etab; new++) { 
			if(new->newcon) { 
1991/1025/sys/src/9/port/devip.c:176,1831991/1029/sys/src/9/port/devip.c:176,182 (short | long)
1991/0424    
			error(Ebadarg); 
		break; 
	case iplistenqid: 
1991/1015    
		if(cp->stproto != &tcpinfo && 
		   cp->stproto != &ilinfo) 
1991/1029    
		if(cp->stproto != &tcpinfo && cp->stproto != &ilinfo) 
1991/0424    
			error(Eprotonosup); 
 
		if(cp->backlog == 0) 
1991/1025/sys/src/9/port/devip.c:184,1891991/1029/sys/src/9/port/devip.c:183,189
1991/1024    
			cp->backlog = 3; 
1991/0424    
 
		streamopen(c, &ipinfo); 
1991/1029    
 
1991/0424    
		if(c->stream->devq->next->info != cp->stproto) 
			pushq(c->stream, cp->stproto); 
 
1991/1025/sys/src/9/port/devip.c:196,2011991/1029/sys/src/9/port/devip.c:196,202
1991/0424    
		break; 
	case Sdataqid: 
		streamopen(c, &ipinfo); 
1991/1029    
 
1991/0424    
		if(c->stream->devq->next->info != cp->stproto) 
			pushq(c->stream, cp->stproto); 
 
1991/1025/sys/src/9/port/devip.c:207,2121991/1029/sys/src/9/port/devip.c:208,214
1991/0424    
		break; 
	case Sctlqid: 
		streamopen(c, &ipinfo); 
1991/1029    
 
1991/0424    
		if(c->stream->devq->next->info != cp->stproto) 
			pushq(c->stream, cp->stproto); 
		break; 
1991/1025/sys/src/9/port/devip.c:697,7021991/1029/sys/src/9/port/devip.c:699,705
1991/1023    
				new->newcon = 0; 
1991/0424    
				c->qid.path = CHDIR|STREAMQID(new-base, ipchanqid); 
				devwalk(c, "ctl", 0, 0, streamgen); 
1991/1029    
 
1991/0424    
				streamopen(c, &ipinfo); 
				pushq(c->stream, new->stproto); 
				new->ref--; 
1991/1029/sys/src/9/port/devip.c:15,221991/1030/sys/src/9/port/devip.c:15,21 (short | long)
1991/1012    
	Nipsubdir	= 4,		/* Number of subdirectory entries per connection */ 
1991/0424    
}; 
 
int udpsum = 1; 
                 
1991/1030    
int 	udpsum = 1; 
1991/1019    
Queue	*Ipoutput;		/* Control message stream for tcp/il */ 
1991/0424    
Ipifc	*ipifc;			/* IP protocol interfaces for stip */ 
Ipconv	*ipconv[Nrprotocol];	/* Connections for each protocol */ 
1991/1029/sys/src/9/port/devip.c:389,3961991/1030/sys/src/9/port/devip.c:388,394
1991/1024    
		qunlock(&ipalloc); 
1991/0424    
 
1991/1024    
	} 
	else if(strcmp(field[0], "announce") == 0 || 
		strcmp(field[0], "reserve") == 0) { 
1991/1030    
	else if(strcmp(field[0], "announce") == 0 || strcmp(field[0], "reserve") == 0) { 
1991/1024    
		if((cp->stproto == &tcpinfo && cp->tcpctl.state != CLOSED) || 
		   (cp->stproto == &ilinfo && cp->ilctl.state != Ilclosed)) 
				error(Edevbusy); 
1991/1029/sys/src/9/port/devip.c:682,6921991/1030/sys/src/9/port/devip.c:680,689
1991/1025    
		qunlock(&s->listenq); 
		nexterror(); 
	} 
print("listener on %lux R 0x%lux\n", s, &s->listenr); 
1991/1030    
 
1991/0424    
	for(;;) { 
1991/1023    
		sleep(&s->listenr, iphavecon, s); 
1991/1025    
		poperror(); 
print("listen awoke\n"); 
1991/1023    
		new = base; 
 		for(etab = &base[conf.ip]; new < etab; new++) { 
			if(new->newcon) { 
1991/1029/sys/src/9/port/devip.c:704,7101991/1030/sys/src/9/port/devip.c:701,706
1991/0424    
				pushq(c->stream, new->stproto); 
				new->ref--; 
				qunlock(&s->listenq); 
1991/1024    
print("ip listener!\n"); 
1991/0424    
				return; 
			} 
		} 
1991/1030/sys/src/9/port/devip.c:388,3941991/1104/sys/src/9/port/devip.c:388,394 (short | long)
1991/1024    
		qunlock(&ipalloc); 
1991/0424    
 
1991/1024    
	} 
1991/1030    
	else if(strcmp(field[0], "announce") == 0 || strcmp(field[0], "reserve") == 0) { 
1991/1104    
	else if(strcmp(field[0], "announce") == 0) { 
1991/1024    
		if((cp->stproto == &tcpinfo && cp->tcpctl.state != CLOSED) || 
		   (cp->stproto == &ilinfo && cp->ilctl.state != Ilclosed)) 
				error(Edevbusy); 
1991/1030/sys/src/9/port/devip.c:404,4101991/1104/sys/src/9/port/devip.c:404,409
1991/1024    
			error(Einuse); 
		} 
		cp->psrc = port; 
		cp->ptype = *field[0]; 
		qunlock(&ipalloc); 
1991/0424    
	} 
1991/1024    
	else if(strcmp(field[0], "backlog") == 0) { 
1991/1030/sys/src/9/port/devip.c:489,4961991/1104/sys/src/9/port/devip.c:488,500
1991/0424    
{ 
	Ipconv *ipc; 
	Udphdr *uh; 
	int	dlen, ptcllen, newlen; 
1991/1104    
	int dlen, ptcllen, newlen; 
1991/0424    
 
1991/1104    
	if(bp->type == M_CTL) { 
		PUTNEXT(q, bp); 
		return; 
	} 
 
1991/0424    
	/* Prepend udp header to packet and pass on to ip layer */ 
	ipc = (Ipconv *)(q->ptr); 
	if(ipc->psrc == 0) 
1991/1030/sys/src/9/port/devip.c:545,5541991/1104/sys/src/9/port/devip.c:549,560
1991/0424    
 
	ipc = (Ipconv *)(q->ptr); 
 
	/* If the port was bound rather than reserved, clear the allocation */ 
	qlock(ipc); 
	if(--ipc->ref == 0 && ipc->ptype == 'b') 
1991/1104    
	if(--ipc->ref == 0) { 
1991/0424    
		ipc->psrc = 0; 
1991/1104    
		ipc->pdst = 0; 
		ipc->dst = 0; 
	} 
1991/0424    
	qunlock(ipc); 
 
	closeipifc(ipc->ipinterface); 
1991/1030/sys/src/9/port/devip.c:583,5941991/1104/sys/src/9/port/devip.c:589,605
1991/0424    
{ 
	Ipconv *s; 
	Tcpctl *tcb;  
	int len, errnum, oob = 0; 
1991/1104    
	int len, errnum; 
1991/0424    
 
	s = (Ipconv *)(q->ptr); 
	len = blen(bp); 
	tcb = &s->tcpctl; 
 
1991/1104    
	if(bp->type == M_CTL) { 
		PUTNEXT(q, bp); 
		return; 
	} 
 
1991/0424    
	if(s->psrc == 0) 
		error(Enoport); 
 
1991/1030/sys/src/9/port/devip.c:607,6231991/1104/sys/src/9/port/devip.c:618,625
1991/0424    
	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; 
		} 
                 
1991/1104    
		appendb(&tcb->sndq, bp); 
		tcb->sndcnt += len; 
1991/0424    
		tcprcvwin(s); 
		tcp_output(s); 
		qunlock(tcb); 
1991/1104/sys/src/9/port/devip.c:222,2461991/1108/sys/src/9/port/devip.c:222,241 (short | long)
1991/0424    
Ipconv * 
ipclonecon(Chan *c) 
{ 
	Ipconv *base, *new, *etab; 
1991/1108    
	Ipconv *new, *base; 
1991/0424    
 
	base = ipconv[c->dev]; 
	etab = &base[conf.ip]; 
	for(new = base; new < etab; new++) { 
1991/1024    
		new = ipincoming(base); 
1991/1023    
		if(new == 0) 
			error(Enodev); 
1991/1108    
	new = ipincoming(base); 
	if(new == 0) 
		error(Enodev); 
1991/1023    
 
		c->qid.path = CHDIR|STREAMQID(new-base, ipchanqid); 
		devwalk(c, "ctl", 0, 0, streamgen); 
1991/1108    
	c->qid.path = CHDIR|STREAMQID(new-base, ipchanqid); 
	devwalk(c, "ctl", 0, 0, streamgen); 
1991/1023    
 
		streamopen(c, &ipinfo); 
		pushq(c->stream, new->stproto); 
		new->ref--; 
		return new; 
	} 
                 
	error(Enodev); 
1991/1108    
	streamopen(c, &ipinfo); 
	pushq(c->stream, new->stproto); 
	new->ref--; 
	return new; 
1991/1023    
} 
 
Ipconv * 
1991/1108/sys/src/9/port/devip.c:57,661991/1112/sys/src/9/port/devip.c:57,66 (short | long)
1991/0424    
}; 
 
Dirtab ipsubdir[]={ 
	"listen",	{iplistenqid},		0,	0600, 
	"local",	{iplportqid},		0,	0600, 
	"remote",	{iprportqid},		0,	0600, 
	"status",	{ipstatusqid},		0,	0600, 
1991/1112    
	"listen",	{iplistenqid},		0,	0666, 
	"local",	{iplportqid},		0,	0666, 
	"remote",	{iprportqid},		0,	0666, 
	"status",	{ipstatusqid},		0,	0666, 
1991/0424    
}; 
 
void 
1991/1112/sys/src/9/port/devip.c:19,251991/1114/sys/src/9/port/devip.c:19,24 (short | long)
1991/1019    
Queue	*Ipoutput;		/* Control message stream for tcp/il */ 
1991/0424    
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 */ 
1991/1112/sys/src/9/port/devip.c:44,791991/1114/sys/src/9/port/devip.c:43,81
1991/0424    
 
1991/1012    
Qinfo *protocols[] = { &tcpinfo, &udpinfo, &ilinfo, 0 }; 
1991/0424    
 
1991/1012    
enum 
1991/1114    
void 
ipinitifc(Ipifc *ifc, Qinfo *stproto, Ipconv *cp) 
1991/1012    
{ 
1991/0424    
	ipdirqid, 
	iplistenqid, 
	iplportqid, 
	iprportqid, 
	ipstatusqid, 
	ipchanqid, 
1991/1114    
	int j; 
1991/0424    
 
	ipcloneqid 
}; 
1991/1114    
	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; 
} 
1991/0424    
 
Dirtab ipsubdir[]={ 
1991/1112    
	"listen",	{iplistenqid},		0,	0666, 
	"local",	{iplportqid},		0,	0666, 
	"remote",	{iprportqid},		0,	0666, 
	"status",	{ipstatusqid},		0,	0666, 
1991/0424    
}; 
                 
void 
ipreset(void) 
{ 
	int i; 
1991/1114    
	int i, j; 
1991/0424    
 
	ipifc = (Ipifc *)ialloc(sizeof(Ipifc) * conf.ip, 0); 
 
1991/1012    
	for(i = 0; protocols[i]; i++) { 
1991/0424    
		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]); 
1991/1114    
		ipinitifc(&ipifc[i], protocols[i], ipconv[i]); 
1991/0424    
		newqinfo(protocols[i]); 
	} 
 
1991/1112/sys/src/9/port/devip.c:82,1111991/1114/sys/src/9/port/devip.c:84,89
1991/0424    
} 
 
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) 
{ 
} 
1991/1112/sys/src/9/port/devip.c:137,2251991/1114/sys/src/9/port/devip.c:115,136
1991/0424    
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); 
1991/1114    
	return netwalk(c, name, &ipifc[c->dev].net); 
1991/0424    
} 
 
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); 
1991/1114    
	netstat(c, db, &ipifc[c->dev].net); 
1991/0424    
} 
 
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: 
1991/1029    
		if(cp->stproto != &tcpinfo && cp->stproto != &ilinfo) 
1991/0424    
			error(Eprotonosup); 
                 
		if(cp->backlog == 0) 
1991/1024    
			cp->backlog = 3; 
1991/0424    
                 
		streamopen(c, &ipinfo); 
1991/1029    
                 
1991/0424    
		if(c->stream->devq->next->info != cp->stproto) 
			pushq(c->stream, cp->stproto); 
                 
		if(cp->stproto == &tcpinfo) 
1991/1014    
			tcpstart(cp, TCP_PASSIVE, Streamhi, 0); 
		else if(cp->stproto == &ilinfo) 
			ilstart(cp, IL_PASSIVE, 10); 
                 
1991/0424    
		iplisten(c, cp, ipconv[c->dev]); 
		break; 
	case Sdataqid: 
		streamopen(c, &ipinfo); 
1991/1029    
                 
1991/0424    
		if(c->stream->devq->next->info != cp->stproto) 
			pushq(c->stream, cp->stproto); 
                 
		if(cp->stproto == &tcpinfo) 
1991/1014    
			tcpstart(cp, TCP_ACTIVE, Streamhi, 0); 
		else if(cp->stproto == &ilinfo) 
			ilstart(cp, IL_ACTIVE, 10); 
                 
1991/0424    
		break; 
	case Sctlqid: 
		streamopen(c, &ipinfo); 
1991/1029    
                 
1991/0424    
		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; 
1991/1114    
	return netopen(c, omode, &ipifc[c->dev].net); 
1991/0424    
} 
 
Ipconv * 
1991/1114    
int 
1991/0424    
ipclonecon(Chan *c) 
{ 
1991/1108    
	Ipconv *new, *base; 
1991/1112/sys/src/9/port/devip.c:228,2411991/1114/sys/src/9/port/devip.c:139,145
1991/1108    
	new = ipincoming(base); 
	if(new == 0) 
		error(Enodev); 
1991/1023    
                 
1991/1108    
	c->qid.path = CHDIR|STREAMQID(new-base, ipchanqid); 
	devwalk(c, "ctl", 0, 0, streamgen); 
1991/1023    
                 
1991/1108    
	streamopen(c, &ipinfo); 
	pushq(c->stream, new->stproto); 
	new->ref--; 
	return new; 
1991/1114    
	return new - base; 
1991/1023    
} 
 
Ipconv * 
1991/1112/sys/src/9/port/devip.c:252,2581991/1114/sys/src/9/port/devip.c:156,162
1991/0424    
				qunlock(new); 
				continue; 
			} 
			new->ref++; 
1991/1114    
			new->ref = 1; 
1991/0424    
			qunlock(new); 
			return new; 
		}	 
1991/1112/sys/src/9/port/devip.c:281,2871991/1114/sys/src/9/port/devip.c:185,191
1991/0424    
void 
ipclose(Chan *c) 
{ 
	if(c->qid.path != CHDIR) 
1991/1114    
	if(c->stream) 
1991/0424    
		streamclose(c); 
} 
 
1991/1112/sys/src/9/port/devip.c:288,3291991/1114/sys/src/9/port/devip.c:192,198
1991/0424    
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: 
1991/1015    
		if(cp->stproto == &tcpinfo) 
			sprint(buf, "tcp/%d %d %s %s\n", connection, cp->ref, tcpstate[cp->tcpctl.state], 
1991/0424    
				cp->tcpctl.flags & CLONE ? "listen" : "connect"); 
1991/1015    
		else if(cp->stproto == &ilinfo) 
			sprint(buf, "il/%d %d %s\n", connection, cp->ref, ilstate[cp->ilctl.state]); 
1991/0424    
		else 
1991/1015    
			sprint(buf, "%s/%d %d\n", cp->stproto->name, connection, cp->ref); 
1991/0424    
                 
		return stringread(c, a, n, buf, offset); 
	} 
                 
1991/0516    
	error(Eperm); 
1991/1114    
	return netread(c, a, n, offset,  &ipifc[c->dev].net); 
1991/0424    
} 
 
long 
1991/1112/sys/src/9/port/devip.c:382,3871991/1114/sys/src/9/port/devip.c:251,261
1991/1024    
			cp->psrc = nextport(ipconv[c->dev], base); 
		qunlock(&ipalloc); 
1991/0424    
 
1991/1114    
		if(cp->stproto == &tcpinfo) 
			tcpstart(cp, TCP_ACTIVE, Streamhi, 0); 
		else if(cp->stproto == &ilinfo) 
			ilstart(cp, IL_ACTIVE, 10); 
 
1991/1024    
	} 
1991/1104    
	else if(strcmp(field[0], "announce") == 0) { 
1991/1024    
		if((cp->stproto == &tcpinfo && cp->tcpctl.state != CLOSED) || 
1991/1112/sys/src/9/port/devip.c:400,4051991/1114/sys/src/9/port/devip.c:274,287
1991/1024    
		} 
		cp->psrc = port; 
		qunlock(&ipalloc); 
1991/1114    
 
		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; 
1991/0424    
	} 
1991/1024    
	else if(strcmp(field[0], "backlog") == 0) { 
		if(m != 2) 
1991/1112/sys/src/9/port/devip.c:544,5561991/1114/sys/src/9/port/devip.c:426,435
1991/0424    
 
	ipc = (Ipconv *)(q->ptr); 
 
	qlock(ipc); 
1991/1104    
	if(--ipc->ref == 0) { 
1991/0424    
		ipc->psrc = 0; 
1991/1104    
		ipc->pdst = 0; 
		ipc->dst = 0; 
	} 
1991/0424    
	qunlock(ipc); 
1991/1114    
	ipc->psrc = 0; 
	ipc->pdst = 0; 
	ipc->dst = 0; 
	ipc->ref = 0; 
1991/0424    
 
	closeipifc(ipc->ipinterface); 
} 
1991/1112/sys/src/9/port/devip.c:564,5721991/1114/sys/src/9/port/devip.c:443,449
1991/0424    
	ipc->ipinterface = newipifc(IP_UDPPROTO, udprcvmsg, ipconv[s->dev], 
			            1500, 512, ETHER_HDR, "UDP"); 
 
	qlock(ipc); 
	ipc->ref++; 
	qunlock(ipc); 
1991/1114    
	ipc->ref = 1; 
1991/0424    
	ipc->readq = RD(q);	 
	RD(q)->ptr = (void *)ipc; 
	WR(q)->next->ptr = (void *)ipc->ipinterface; 
1991/1112/sys/src/9/port/devip.c:649,6571991/1114/sys/src/9/port/devip.c:526,532
1991/0424    
	ipc->ipinterface = newipifc(IP_TCPPROTO, tcp_input, ipconv[s->dev],  
			            1500, 512, ETHER_HDR, "TCP"); 
 
	qlock(ipc); 
	ipc->ref++; 
	qunlock(ipc); 
1991/1114    
	ipc->ref = 1; 
1991/0424    
 
	ipc->readq = RD(q); 
	ipc->readq->rp = &tcpflowr; 
1991/1112/sys/src/9/port/devip.c:661,6661991/1114/sys/src/9/port/devip.c:536,580
1991/0424    
	WR(q)->ptr = (void *)ipc; 
} 
 
1991/1114    
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); 
} 
 
1991/0424    
int 
1991/1023    
iphavecon(Ipconv *s) 
1991/0424    
{ 
1991/1112/sys/src/9/port/devip.c:667,6771991/1114/sys/src/9/port/devip.c:581,602
1991/0424    
	return s->curlog; 
} 
 
void 
iplisten(Chan *c, Ipconv *s, Ipconv *base) 
1991/1114    
int 
iplisten(Chan *c) 
1991/0424    
{ 
	Ipconv *etab, *new; 
1991/1114    
	Ipconv *s, *base; 
	int connection; 
	Ipconv *cp; 
1991/0424    
 
1991/1114    
	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"); 
 
1991/0424    
	qlock(&s->listenq); 
1991/1025    
	if(waserror()) { 
		qunlock(&s->listenq); 
1991/1112/sys/src/9/port/devip.c:684,7041991/1114/sys/src/9/port/devip.c:609,618
1991/1023    
		new = base; 
 		for(etab = &base[conf.ip]; new < etab; new++) { 
			if(new->newcon) { 
1991/0424    
				/* Remove the listen channel reference */ 
				streamclose(c); 
                 
				s->curlog--; 
1991/1023    
                 
1991/0424    
				/* Attach the control channel to the new connection */ 
1991/1023    
				new->newcon = 0; 
1991/0424    
				c->qid.path = CHDIR|STREAMQID(new-base, ipchanqid); 
				devwalk(c, "ctl", 0, 0, streamgen); 
1991/1029    
                 
1991/0424    
				streamopen(c, &ipinfo); 
				pushq(c->stream, new->stproto); 
				new->ref--; 
				qunlock(&s->listenq); 
				return; 
1991/1114    
				return new - base; 
1991/0424    
			} 
		} 
	} 
1991/1112/sys/src/9/port/devip.c:713,7211991/1114/sys/src/9/port/devip.c:627,633
1991/0424    
	s = (Ipconv *)(q->ptr); 
	tcb = &s->tcpctl; 
 
	qlock(s); 
	s->ref--; 
	qunlock(s); 
1991/1114    
	s->ref = 0; 
1991/0424    
 
	/* Not interested in data anymore */ 
	s->readq = 0; 
1991/1114/sys/src/9/port/devip.c:48,551991/1115/sys/src/9/port/devip.c:48,58 (short | long)
1991/1012    
{ 
1991/1114    
	int j; 
1991/0424    
 
1991/1114    
	for(j = 0; j < conf.ip; j++, cp++) 
1991/1115    
	for(j = 0; j < conf.ip; j++, cp++){ 
		cp->index = j; 
1991/1114    
		cp->stproto = stproto; 
1991/1115    
		cp->ipinterface = ifc; 
	} 
1991/1114    
	ifc->net.name = stproto->name; 
	ifc->net.nconv = conf.ip; 
	ifc->net.devp = &ipinfo; 
1991/1114/sys/src/9/port/devip.c:57,621991/1115/sys/src/9/port/devip.c:60,66
1991/1114    
	if(stproto != &udpinfo) 
		ifc->net.listen = iplisten; 
	ifc->net.clone = ipclonecon; 
1991/1115    
	ifc->net.prot = (Netprot *)ialloc(sizeof(Netprot) * conf.ip, 0); 
1991/1114    
	ifc->net.ninfo = 3; 
	ifc->net.info[0].name = "remote"; 
	ifc->net.info[0].fill = ipremotefill; 
1991/1114/sys/src/9/port/devip.c:136,1421991/1115/sys/src/9/port/devip.c:140,146
1991/1108    
	Ipconv *new, *base; 
1991/0424    
 
	base = ipconv[c->dev]; 
1991/1108    
	new = ipincoming(base); 
1991/1115    
	new = ipincoming(base, 0); 
1991/1108    
	if(new == 0) 
		error(Enodev); 
1991/1114    
	return new - base; 
1991/1114/sys/src/9/port/devip.c:143,1511991/1115/sys/src/9/port/devip.c:147,156
1991/1023    
} 
 
Ipconv * 
1991/1024    
ipincoming(Ipconv *base) 
1991/1115    
ipincoming(Ipconv *base, Ipconv *from) 
1991/1023    
{ 
1991/1024    
	Ipconv *new, *etab; 
1991/1115    
	Ipifc *ifc; 
1991/1023    
 
	etab = &base[conf.ip]; 
	for(new = base; new < etab; new++) { 
1991/1114/sys/src/9/port/devip.c:156,1611991/1115/sys/src/9/port/devip.c:161,173
1991/0424    
				qunlock(new); 
				continue; 
			} 
1991/1115    
			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); 
1991/1114    
			new->ref = 1; 
1991/0424    
			qunlock(new); 
			return new; 
1991/1114/sys/src/9/port/devip.c:167,1721991/1115/sys/src/9/port/devip.c:179,185
1991/0424    
void 
ipcreate(Chan *c, char *name, int omode, ulong perm) 
{ 
1991/1115    
	USED(c, name, omode, perm); 
1991/0424    
	error(Eperm); 
} 
 
1991/1114/sys/src/9/port/devip.c:173,1781991/1115/sys/src/9/port/devip.c:186,192
1991/0424    
void 
ipremove(Chan *c) 
{ 
1991/1115    
	USED(c); 
1991/0424    
	error(Eperm); 
} 
 
1991/1114/sys/src/9/port/devip.c:179,1851991/1115/sys/src/9/port/devip.c:193,199
1991/0424    
void 
ipwstat(Chan *c, char *dp) 
{ 
	error(Eperm); 
1991/1115    
	netwstat(c, dp, &ipifc[c->dev].net); 
1991/0424    
} 
 
void 
1991/1114/sys/src/9/port/devip.c:432,4371991/1115/sys/src/9/port/devip.c:446,452
1991/1114    
	ipc->ref = 0; 
1991/0424    
 
	closeipifc(ipc->ipinterface); 
1991/1115    
	netdisown(&ipc->ipinterface->net, ipc->index); 
1991/0424    
} 
 
void 
1991/1114/sys/src/9/port/devip.c:654,6591991/1115/sys/src/9/port/devip.c:669,675
1991/0424    
		qunlock(tcb); 
		break; 
	} 
1991/1115    
	netdisown(&s->ipinterface->net, s->index); 
1991/0424    
} 
 
 
1991/1115/sys/src/9/port/devip.c:443,4491991/1120/sys/src/9/port/devip.c:443,448 (short | long)
1991/1114    
	ipc->psrc = 0; 
	ipc->pdst = 0; 
	ipc->dst = 0; 
	ipc->ref = 0; 
1991/0424    
 
	closeipifc(ipc->ipinterface); 
1991/1115    
	netdisown(&ipc->ipinterface->net, ipc->index); 
1991/1115/sys/src/9/port/devip.c:458,4641991/1120/sys/src/9/port/devip.c:457,462
1991/0424    
	ipc->ipinterface = newipifc(IP_UDPPROTO, udprcvmsg, ipconv[s->dev], 
			            1500, 512, ETHER_HDR, "UDP"); 
 
1991/1114    
	ipc->ref = 1; 
1991/0424    
	ipc->readq = RD(q);	 
	RD(q)->ptr = (void *)ipc; 
	WR(q)->next->ptr = (void *)ipc->ipinterface; 
1991/1115/sys/src/9/port/devip.c:541,5481991/1120/sys/src/9/port/devip.c:539,544
1991/0424    
	ipc->ipinterface = newipifc(IP_TCPPROTO, tcp_input, ipconv[s->dev],  
			            1500, 512, ETHER_HDR, "TCP"); 
 
1991/1114    
	ipc->ref = 1; 
1991/0424    
                 
	ipc->readq = RD(q); 
	ipc->readq->rp = &tcpflowr; 
 
1991/1115/sys/src/9/port/devip.c:641,6481991/1120/sys/src/9/port/devip.c:637,642
1991/0424    
 
	s = (Ipconv *)(q->ptr); 
	tcb = &s->tcpctl; 
                 
1991/1114    
	s->ref = 0; 
1991/0424    
 
	/* Not interested in data anymore */ 
	s->readq = 0; 
1991/1120/sys/src/9/port/devip.c:616,6211991/1121/sys/src/9/port/devip.c:616,622 (short | long)
1991/1030    
 
1991/0424    
	for(;;) { 
1991/1023    
		sleep(&s->listenr, iphavecon, s); 
1991/1121    
		print("listen wakes\n"); 
1991/1025    
		poperror(); 
1991/1023    
		new = base; 
 		for(etab = &base[conf.ip]; new < etab; new++) { 
1991/1120/sys/src/9/port/devip.c:626,6311991/1121/sys/src/9/port/devip.c:627,633
1991/1114    
				return new - base; 
1991/0424    
			} 
		} 
1991/1121    
		print("no newcon\n"); 
1991/0424    
	} 
} 
 
1991/1120/sys/src/9/port/devip.c:713,7191991/1121/sys/src/9/port/devip.c:715,720
1991/0424    
			break; 
		blen = BLEN(bp); 
		addr = bp->rptr; 
                 
	} 
 
	losum += hisum>>8; 
1991/1121/sys/src/9/port/devip.c:268,2741991/1124/sys/src/9/port/devip.c:268,274 (short | long)
1991/1114    
		if(cp->stproto == &tcpinfo) 
			tcpstart(cp, TCP_ACTIVE, Streamhi, 0); 
		else if(cp->stproto == &ilinfo) 
			ilstart(cp, IL_ACTIVE, 10); 
1991/1124    
			ilstart(cp, IL_ACTIVE, 20); 
1991/1114    
 
1991/1024    
	} 
1991/1104    
	else if(strcmp(field[0], "announce") == 0) { 
1991/1121/sys/src/9/port/devip.c:557,5621991/1124/sys/src/9/port/devip.c:557,563
1991/1114    
	cp = &ipconv[c->dev][connection]; 
	sprint(buf, "%d.%d.%d.%d %d\n", fmtaddr(cp->dst), cp->pdst); 
} 
1991/1124    
 
1991/1114    
void 
iplocalfill(Chan *c, char *buf, int len) 
{ 
1991/1121/sys/src/9/port/devip.c:567,5721991/1124/sys/src/9/port/devip.c:568,574
1991/1114    
	cp = &ipconv[c->dev][connection]; 
	sprint(buf, "%d.%d.%d.%d %d\n", fmtaddr(Myip), cp->psrc); 
} 
1991/1124    
 
1991/1114    
void 
ipstatusfill(Chan *c, char *buf, int len) 
{ 
1991/1121/sys/src/9/port/devip.c:580,5871991/1124/sys/src/9/port/devip.c:582,589
1991/1114    
			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]); 
1991/1124    
		sprint(buf, "il/%d %d %s rtt %d ms\n", connection, cp->ref, 
			ilstate[cp->ilctl.state], cp->ilctl.rtt); 
1991/1114    
	else 
		sprint(buf, "%s/%d %d\n", cp->stproto->name, connection, cp->ref); 
} 
1991/1121/sys/src/9/port/devip.c:616,6221991/1124/sys/src/9/port/devip.c:618,623
1991/1030    
 
1991/0424    
	for(;;) { 
1991/1023    
		sleep(&s->listenr, iphavecon, s); 
1991/1121    
		print("listen wakes\n"); 
1991/1025    
		poperror(); 
1991/1023    
		new = base; 
 		for(etab = &base[conf.ip]; new < etab; new++) { 
1991/1124/sys/src/9/port/devip.c:271,2761991/1125/sys/src/9/port/devip.c:271,283 (short | long)
1991/1124    
			ilstart(cp, IL_ACTIVE, 20); 
1991/1114    
 
1991/1024    
	} 
1991/1125    
	else if(strcmp(field[0], "disconnect") == 0) { 
		if(cp->stproto != &udpinfo) 
			error(Eperm); 
 
		cp->dst = 0; 
		cp->pdst = 0; 
	} 
1991/1104    
	else if(strcmp(field[0], "announce") == 0) { 
1991/1024    
		if((cp->stproto == &tcpinfo && cp->tcpctl.state != CLOSED) || 
		   (cp->stproto == &ilinfo && cp->ilctl.state != Ilclosed)) 
1991/1124/sys/src/9/port/devip.c:328,3341991/1125/sys/src/9/port/devip.c:335,341
1991/0424    
{ 
	Ipconv *ifc, *etab; 
	Udphdr *uh; 
	Port   dport; 
1991/1125    
	Port   dport, sport; 
1991/0424    
	ushort sum, len; 
	Ipaddr addr; 
 
1991/1124/sys/src/9/port/devip.c:352,3621991/1125/sys/src/9/port/devip.c:359,371
1991/0424    
	} 
 
	dport = nhgets(uh->udpdport); 
1991/1125    
	sport = nhgets(uh->udpsport); 
1991/0424    
 
	/* Look for a conversation structure for this port */ 
	etab = &muxed[conf.ip]; 
	for(ifc = muxed; ifc < etab; ifc++) { 
		if(ifc->psrc == dport && ifc->ref) { 
1991/1125    
		if(ifc->psrc == dport && ifc->ref && 
		   (ifc->pdst == 0 || ifc->pdst == sport)) { 
1991/0424    
			/* Trim the packet down to data size */ 
			len = len - (UDP_HDRSIZE-UDP_PHDRSIZE); 
			bp = btrim(bp, UDP_EHSIZE+UDP_HDRSIZE, len); 
1991/1124/sys/src/9/port/devip.c:365,3711991/1125/sys/src/9/port/devip.c:374,380
1991/0424    
 
			/* Stuff the src address into the remote file */ 
		 	ifc->dst = addr; 
			ifc->pdst = nhgets(uh->udpsport); 
1991/1125    
			ifc->pdst = sport; 
1991/0424    
			PUTNEXT(ifc->readq, bp); 
			return; 
		} 
Too many diffs (26 > 25). Stopping.


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)