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

2001/0922/ip/devip.c (diff list | history)

1997/0327/sys/src/9/ip/devip.c:648,6631997/0403/sys/src/9/ip/devip.c:648,658 (short | long)
1997/0327    
				qunlock(&c->car); 
				nexterror(); 
			} 
			switch(nfield){ 
			default: 
				error("bad args to announce"); 
			case 2: 
				setladdrport(c, fields[1]); 
				break; 
			} 
			c->state = Announcing; 
			c->cerr[0] = '\0'; 
			x->announce(c); 
1997/0403    
			p = x->announce(c, fields, nfield); 
			if(p != nil) 
				error(p); 
1997/0327    
			sleep(&c->cr, announced, c); 
			if(c->cerr[0] != '\0') 
				error(c->cerr); 
1997/0327/sys/src/9/ip/devip.c:934,9391997/0403/sys/src/9/ip/devip.c:929,947
1997/0327    
			return p; 
		setladdr(c); 
		c->lport = atoi(argv[2]); 
1997/0403    
		break; 
	} 
	return nil; 
} 
 
char* 
Fsstdannounce(Conv* c, char* argv[], int argc) 
{ 
	switch(argc){ 
	default: 
		return "bad args to announce"; 
	case 2: 
		setladdrport(c, argv[1]); 
1997/0327    
		break; 
	} 
	return nil; 
1997/0403/sys/src/9/ip/devip.c:712,7171997/0408/sys/src/9/ip/devip.c:712,720 (short | long)
1997/0327    
} 
 
Dev ipdevtab = { 
1997/0408    
	'I', 
	"ip", 
 
1997/0327    
	ipreset, 
	ipinit, 
	ipattach, 
1997/0408/sys/src/9/ip/devip.c:137,1421997/0423/sys/src/9/ip/devip.c:137,144 (short | long)
1997/0327    
	switch(TYPE(c->qid)) { 
	case Qtopdir: 
		if(s < fs.np) { 
1997/0423    
			if(fs.p[s]->connect == nil) 
				return 0;	/* protocol with no user interface */ 
1997/0327    
			q = (Qid){QID(s, 0, Qprotodir)|CHDIR, 0}; 
			devdir(c, q, fs.p[s]->name, 0, network, CHDIR|0555, dp); 
			return 1; 
1997/0408/sys/src/9/ip/devip.c:270,2751997/0423/sys/src/9/ip/devip.c:272,280
1997/0327    
	switch(TYPE(c->qid)) { 
	default: 
		break; 
1997/0423    
	case Qipifc: 
		c->aux = newifcconv(); 
		break; 
1997/0327    
	case Qlog: 
		netlogopen(); 
		break; 
1997/0408/sys/src/9/ip/devip.c:402,4071997/0423/sys/src/9/ip/devip.c:407,416
1997/0327    
	switch(TYPE(c->qid)) { 
	default: 
		break; 
1997/0423    
	case Qipifc: 
		closeifcconv(c->aux); 
		c->aux = nil; 
		break; 
1997/0327    
	case Qlog: 
		netlogclose(); 
		break; 
1997/0408/sys/src/9/ip/devip.c:530,5361997/0423/sys/src/9/ip/devip.c:539,546
1997/0327    
static void 
setladdrport(Conv* c, char* str) 
{ 
	char *p, addr[4]; 
1997/0423    
	char *p; 
	uchar addr[Ipaddrlen]; 
1997/0327    
 
	p = strchr(str, '!'); 
	if(p == nil) { 
1997/0408/sys/src/9/ip/devip.c:540,5461997/0423/sys/src/9/ip/devip.c:550,556
1997/0327    
	else { 
		*p++ = 0; 
		parseip(addr, str); 
		c->laddr = nhgetl((byte*)addr); 
1997/0423    
		c->laddr = nhgetl(addr); 
1997/0327    
	} 
	if(*p == '*') 
		c->lport = 0; 
1997/0408/sys/src/9/ip/devip.c:554,5601997/0423/sys/src/9/ip/devip.c:564,571
1997/0327    
static char* 
setraddrport(Conv* c, char* str) 
{ 
	char *p, addr[4]; 
1997/0423    
	char *p; 
	uchar addr[Ipaddrlen]; 
1997/0327    
 
	p = strchr(str, '!'); 
	if(p == nil) 
1997/0408/sys/src/9/ip/devip.c:561,5671997/0423/sys/src/9/ip/devip.c:572,578
1997/0327    
		return "malformed address"; 
	*p++ = 0; 
	parseip(addr, str); 
	c->raddr = nhgetl((byte*)addr); 
1997/0423    
	c->raddr = nhgetl(addr); 
1997/0327    
	c->rport = atoi(p); 
	p = strchr(p, '!'); 
	if(p){ 
1997/0408/sys/src/9/ip/devip.c:600,6061997/0423/sys/src/9/ip/devip.c:611,617
1997/0327    
			error(p); 
		return n; 
	case Qipifc: 
		p = Mediaifcwrite(a, n); 
1997/0423    
		p = Mediaifcwrite(ch->aux, a, n); 
1997/0327    
		if(p != nil) 
			error(p); 
		return n; 
1997/0423/sys/src/9/ip/devip.c:500,5131997/0508/sys/src/9/ip/devip.c:500,505 (short | long)
1997/0327    
	int x, found; 
 
	p = c->p; 
	/* 
	 * For compatibility with old Plan9/Brazil systems restrict 
	 * the port number for now such that it can't sign-extend on 
	 * the other end. 
	 */ 
	while(p->nextport < 5000 || p->nextport >= (1<<15)) 
		p->nextport = nrand(1<<16); 
                 
	if(c->restricted) 
		pp = &p->nextrport; 
	else 
1997/0423/sys/src/9/ip/devip.c:514,5251997/0508/sys/src/9/ip/devip.c:506,526
1997/0327    
		pp = &p->nextport; 
	lock(p); 
	for(;;(*pp)++){ 
		if(*pp == 0 || *pp >= (1<<15)) {	/* BSD hack */ 
			if(c->restricted) 
1997/0508    
		/* 
		 * Fsproto initialises p->nextport to 0 and the restricted 
		 * ports (p->nextrport) to 600. 
		 * Restricted ports must lie between 600 and 1024. 
		 * For the initial condition or if the unrestricted port number 
		 * has wrapped round, select a random port between 5000 and 1<<16 
		 * to start at. 
		 */ 
		if(c->restricted){ 
			if(*pp >= 1024) 
1997/0327    
				*pp = 600; 
			else 
				*pp = 5000; 
		} 
1997/0508    
		else while(*pp < 5000) 
			*pp = nrand(1<<16); 
 
1997/0327    
		found = 0; 
		for(x = 0; x < p->nc; x++){ 
			if(p->conv[x] == nil) 
1997/0508/sys/src/9/ip/devip.c:408,4141997/0531/sys/src/9/ip/devip.c:408,415 (short | long)
1997/0327    
	default: 
		break; 
1997/0423    
	case Qipifc: 
		closeifcconv(c->aux); 
1997/0531    
		if(c->flag & COPEN) 
			closeifcconv(c->aux); 
1997/0423    
		c->aux = nil; 
		break; 
1997/0327    
	case Qlog: 
1997/0531/sys/src/9/ip/devip.c:918,9261997/0806/sys/src/9/ip/devip.c:918,926 (short | long)
1997/0327    
	n = 0; 
	for(p = fs.p; *p; p++) 
		n += snprint(buf + n, len - n, 
			"%s: csum %d hlen %d len %d order %d rexmit %d\n", 
1997/0806    
			"%s: csum %d hlen %d len %d order %d rexmit %d wc %d\n", 
1997/0327    
			(*p)->name, (*p)->csumerr, (*p)->hlenerr, (*p)->lenerr, 
			(*p)->order, (*p)->rexmit); 
1997/0806    
			(*p)->order, (*p)->rexmit, (*p)->wclosed); 
1997/0327    
	return n; 
} 
 
1997/0806/sys/src/9/ip/devip.c:512,5181997/0811/sys/src/9/ip/devip.c:512,518 (short | long)
1997/0508    
		 * ports (p->nextrport) to 600. 
		 * Restricted ports must lie between 600 and 1024. 
		 * For the initial condition or if the unrestricted port number 
		 * has wrapped round, select a random port between 5000 and 1<<16 
1997/0811    
		 * has wrapped round, select a random port between 5000 and 1<<15 
1997/0508    
		 * to start at. 
		 */ 
		if(c->restricted){ 
1997/0806/sys/src/9/ip/devip.c:520,5261997/0811/sys/src/9/ip/devip.c:520,526
1997/0327    
				*pp = 600; 
		} 
1997/0508    
		else while(*pp < 5000) 
			*pp = nrand(1<<16); 
1997/0811    
			*pp = nrand(1<<15); 
1997/0508    
 
1997/0327    
		found = 0; 
		for(x = 0; x < p->nc; x++){ 
1997/0811/sys/src/9/ip/devip.c:542,5481997/0815/sys/src/9/ip/devip.c:542,548 (short | long)
1997/0327    
setladdrport(Conv* c, char* str) 
{ 
1997/0423    
	char *p; 
	uchar addr[Ipaddrlen]; 
1997/0815    
	uchar addr[IPaddrlen]; 
1997/0327    
 
	p = strchr(str, '!'); 
	if(p == nil) { 
1997/0811/sys/src/9/ip/devip.c:567,5731997/0815/sys/src/9/ip/devip.c:567,573
1997/0327    
setraddrport(Conv* c, char* str) 
{ 
1997/0423    
	char *p; 
	uchar addr[Ipaddrlen]; 
1997/0815    
	uchar addr[IPaddrlen]; 
1997/0327    
 
	p = strchr(str, '!'); 
	if(p == nil) 
1997/0815/sys/src/9/ip/devip.c:224,2301997/0823/sys/src/9/ip/devip.c:224,230 (short | long)
1997/0327    
			c->qid = (Qid){QID(0, 0, Qtopdir)|CHDIR, 0}; 
			break; 
		case Qconvdir: 
			c->qid = (Qid){QID(0, 0, Qprotodir)|CHDIR, 0}; 
1997/0823    
			c->qid = (Qid){QID(PROTO(c->qid), 0, Qprotodir)|CHDIR, 0}; 
1997/0327    
			break; 
		default: 
			panic("ipwalk %lux", c->qid.path); 
1997/0823/sys/src/9/ip/devip.c:916,9261997/0916/sys/src/9/ip/devip.c:916,929 (short | long)
1997/0327    
	int n; 
 
	n = 0; 
	for(p = fs.p; *p; p++) 
1997/0916    
	for(p = fs.p; *p; p++){ 
1997/0327    
		n += snprint(buf + n, len - n, 
1997/0806    
			"%s: csum %d hlen %d len %d order %d rexmit %d wc %d\n", 
1997/0916    
			"%s: csum %d hlen %d len %d order %d rexmit %d\n", 
1997/0327    
			(*p)->name, (*p)->csumerr, (*p)->hlenerr, (*p)->lenerr, 
1997/0806    
			(*p)->order, (*p)->rexmit, (*p)->wclosed); 
1997/0916    
			(*p)->order, (*p)->rexmit); 
		if((*p)->stats) 
			n += (*(*p)->stats)(buf + n, len - n); 
	} 
1997/0327    
	return n; 
} 
 
1997/0916/sys/src/9/ip/devip.c:539,5451997/1030/sys/src/9/ip/devip.c:539,545 (short | long)
1997/0327    
} 
 
static void 
setladdrport(Conv* c, char* str) 
1997/1030    
setladdrport(Conv* c, char* str, int nodefault) 
1997/0327    
{ 
1997/0423    
	char *p; 
1997/0815    
	uchar addr[IPaddrlen]; 
1997/0916/sys/src/9/ip/devip.c:547,5531997/1030/sys/src/9/ip/devip.c:547,556
1997/0327    
	p = strchr(str, '!'); 
	if(p == nil) { 
		p = str; 
		c->laddr = 0; 
1997/1030    
		if(nodefault) 
			setladdr(c); 
		else 
			c->laddr = 0; 
1997/0327    
	} 
	else { 
		*p++ = 0; 
1997/0916/sys/src/9/ip/devip.c:946,9531997/1030/sys/src/9/ip/devip.c:949,955
1997/0327    
		p = setraddrport(c, argv[1]); 
		if(p != nil) 
			return p; 
		setladdr(c); 
		c->lport = atoi(argv[2]); 
1997/1030    
		setladdrport(c, argv[2], 1); 
1997/0403    
		break; 
	} 
	return nil; 
1997/0916/sys/src/9/ip/devip.c:960,9661997/1030/sys/src/9/ip/devip.c:962,968
1997/0403    
	default: 
		return "bad args to announce"; 
	case 2: 
		setladdrport(c, argv[1]); 
1997/1030    
		setladdrport(c, argv[1], 0); 
1997/0327    
		break; 
	} 
	return nil; 
1997/1030/sys/src/9/ip/devip.c:470,4771997/1104/sys/src/9/ip/devip.c:470,483 (short | long)
1997/0327    
		sprint(buf, "%s/%d %d %s \n", c->p->name, c->x, c->inuse, statename); 
		return readstr(offset, p, n, buf); 
	case Qdata: 
1997/1104    
{int xxx; 
poot("ipread 1", 0); 
1997/0327    
		c = fs.p[PROTO(ch->qid)]->conv[CONV(ch->qid)]; 
		return qread(c->rq, a, n); 
1997/1104    
//		return qread(c->rq, a, n); 
		xxx = qread(c->rq, a, n); 
poot("ipread 2", 0); 
		return xxx; 
} 
1997/0327    
	case Qerr: 
		c = fs.p[PROTO(ch->qid)]->conv[CONV(ch->qid)]; 
		return qread(c->eq, a, n); 
1997/1030/sys/src/9/ip/devip.c:807,8121997/1104/sys/src/9/ip/devip.c:813,819
1997/0327    
			c->x = pp - p->conv; 
			c->ptcl = malloc(p->ptclsize); 
			if(c->ptcl == nil) { 
1997/1104    
				unlock(c); 
1997/0327    
				free(c); 
				error(Enomem); 
			} 
1997/1104/sys/src/9/ip/devip.c:470,4831997/1105/sys/src/9/ip/devip.c:470,478 (short | long)
1997/0327    
		sprint(buf, "%s/%d %d %s \n", c->p->name, c->x, c->inuse, statename); 
		return readstr(offset, p, n, buf); 
	case Qdata: 
1997/1104    
{int xxx; 
poot("ipread 1", 0); 
1997/0327    
		c = fs.p[PROTO(ch->qid)]->conv[CONV(ch->qid)]; 
1997/1104    
//		return qread(c->rq, a, n); 
		xxx = qread(c->rq, a, n); 
poot("ipread 2", 0); 
		return xxx; 
} 
1997/1105    
		return qread(c->rq, a, n); 
 
1997/0327    
	case Qerr: 
		c = fs.p[PROTO(ch->qid)]->conv[CONV(ch->qid)]; 
		return qread(c->eq, a, n); 
1997/1105/sys/src/9/ip/devip.c:545,5521997/1128/sys/src/9/ip/devip.c:545,556 (short | long)
1997/0423    
	char *p; 
1997/0815    
	uchar addr[IPaddrlen]; 
1997/0327    
 
1997/1128    
	/* 
	 *  ignore restricted part if it exists.  it's 
	 *  meaningless on local ports. 
	 */ 
1997/0327    
	p = strchr(str, '!'); 
	if(p == nil) { 
1997/1128    
	if(p == nil || strcmp(p, "!r") == 0) { 
1997/0327    
		p = str; 
1997/1030    
		if(nodefault) 
			setladdr(c); 
1997/1128/sys/src/9/ip/devip.c:14,261998/0306/sys/src/9/ip/devip.c:14,27 (short | long)
1997/0327    
	Qtopdir=	1,		/* top level directory */ 
	Qtopbase, 
	Qarp=		Qtopbase, 
	Qipifc, 
	Qiproute, 
1998/0306    
	Qiprouter, 
1997/0327    
	Qlog, 
 
	Qprotodir,			/* directory for a protocol */ 
	Qprotobase, 
	Qclone=		Qprotobase, 
1998/0306    
	Qstats, 
1997/0327    
 
	Qconvdir,			/* directory for a conversation */ 
	Qconvbase, 
1997/1128/sys/src/9/ip/devip.c:79,851998/0306/sys/src/9/ip/devip.c:80,86
1997/0327    
		q = (Qid){QID(PROTO(c->qid), CONV(c->qid), Qstatus), 0}; 
		break; 
	} 
	devdir(c, q, p, 0, cv->owner, 0444, dp); 
1998/0306    
	devdir(c, q, p, 0, cv->owner, 0666, dp); 
1997/0327    
	return 1; 
} 
 
1997/1128/sys/src/9/ip/devip.c:91,981998/0306/sys/src/9/ip/devip.c:92,103
1997/0327    
	switch(i) { 
	case Qclone: 
		q = (Qid){QID(PROTO(c->qid), 0, Qclone), 0}; 
		devdir(c, q, "clone", 0, network, 0444, dp); 
1998/0306    
		devdir(c, q, "clone", 0, network, 0666, dp); 
1997/0327    
		return 1; 
1998/0306    
	case Qstats: 
		q = (Qid){QID(PROTO(c->qid), 0, Qstats), 0}; 
		devdir(c, q, "stats", 0, network, 0444, dp); 
		return 1; 
1997/0327    
	}	 
	return -1; 
} 
1997/1128/sys/src/9/ip/devip.c:110,1291998/0306/sys/src/9/ip/devip.c:115,134
1997/0327    
		p = "arp"; 
		q = (Qid){QID(0, 0, Qarp), 0}; 
		break; 
	case Qipifc: 
		p = "ipifc"; 
		q = (Qid){QID(0, 0, Qipifc), 0}; 
		break; 
	case Qiproute: 
		p = "iproute"; 
		q = (Qid){QID(0, 0, Qiproute), 0}; 
		break; 
1998/0306    
	case Qiprouter: 
		p = "iprouter"; 
		q = (Qid){QID(0, 0, Qiprouter), 0}; 
		break; 
1997/0327    
	case Qlog: 
		p = "log"; 
		q = (Qid){QID(0, 0, Qlog), 0}; 
		break; 
	} 
	devdir(c, q, p, 0, network, 0444, dp); 
1998/0306    
	devdir(c, q, p, 0, network, 0666, dp); 
1997/0327    
	return 1; 
} 
 
1997/1128/sys/src/9/ip/devip.c:146,1541998/0306/sys/src/9/ip/devip.c:151,159
1997/0327    
		s -= fs.np; 
		return ip1gen(c, s+Qtopbase, dp); 
	case Qarp: 
	case Qipifc: 
	case Qlog: 
	case Qiproute: 
1998/0306    
	case Qiprouter: 
1997/0327    
		return ip1gen(c, TYPE(c->qid), dp); 
	case Qprotodir: 
		if(s < fs.p[PROTO(c->qid)]->ac) { 
1997/1128/sys/src/9/ip/devip.c:161,1661998/0306/sys/src/9/ip/devip.c:166,172
1997/0327    
		s -= fs.p[PROTO(c->qid)]->ac; 
		return ip2gen(c, s+Qprotobase, dp); 
	case Qclone: 
1998/0306    
	case Qstats: 
1997/0327    
		return ip2gen(c, TYPE(c->qid), dp); 
	case Qconvdir: 
		return ip3gen(c, s+Qconvbase, dp); 
1997/1128/sys/src/9/ip/devip.c:193,1981998/0306/sys/src/9/ip/devip.c:199,206
1997/0327    
	fmtinstall('i', eipconv); 
	fmtinstall('I', eipconv); 
	fmtinstall('E', eipconv); 
1998/0306    
	fmtinstall('V', eipconv); 
	fmtinstall('M', eipconv); 
1997/0327    
} 
 
static Chan* 
1997/1128/sys/src/9/ip/devip.c:217,2411998/0306/sys/src/9/ip/devip.c:225,248
1997/0327    
{ 
	Path *op; 
 
	if(strcmp(name, "..") == 0){ 
		switch(TYPE(c->qid)){ 
		case Qtopdir: 
		case Qprotodir: 
			c->qid = (Qid){QID(0, 0, Qtopdir)|CHDIR, 0}; 
			break; 
		case Qconvdir: 
1997/0823    
			c->qid = (Qid){QID(PROTO(c->qid), 0, Qprotodir)|CHDIR, 0}; 
1997/0327    
			break; 
		default: 
			panic("ipwalk %lux", c->qid.path); 
		} 
		op = c->path; 
		c->path = ptenter(&syspt, op, name); 
		decref(op); 
		return 1; 
	} 
1998/0306    
	if(strcmp(name, "..") != 0) 
		return devwalk(c, name, nil, 0, ipgen); 
1997/0327    
 
	return devwalk(c, name, nil, 0, ipgen); 
1998/0306    
	switch(TYPE(c->qid)){ 
	case Qtopdir: 
	case Qprotodir: 
		c->qid = (Qid){QID(0, 0, Qtopdir)|CHDIR, 0}; 
		break; 
	case Qconvdir: 
		c->qid = (Qid){QID(PROTO(c->qid), 0, Qprotodir)|CHDIR, 0}; 
		break; 
	default: 
		panic("ipwalk %lux", c->qid.path); 
	} 
	op = c->path; 
	c->path = ptenter(&syspt, op, name); 
	decref(op); 
	return 1; 
1997/0327    
} 
 
static void 
1997/1128/sys/src/9/ip/devip.c:272,2831998/0306/sys/src/9/ip/devip.c:279,293
1997/0327    
	switch(TYPE(c->qid)) { 
	default: 
		break; 
1997/0423    
	case Qipifc: 
		c->aux = newifcconv(); 
		break; 
1997/0327    
	case Qlog: 
		netlogopen(); 
		break; 
1998/0306    
	case Qiprouter: 
		iprouteropen(); 
		break; 
	case Qiproute: 
		memmove(c->tag, "none", sizeof(c->tag)); 
		break; 
1997/0327    
	case Qtopdir: 
	case Qprotodir: 
	case Qconvdir: 
1997/1128/sys/src/9/ip/devip.c:284,2891998/0306/sys/src/9/ip/devip.c:294,300
1997/0327    
	case Qstatus: 
	case Qremote: 
	case Qlocal: 
1998/0306    
	case Qstats: 
1997/0327    
		if(omode != OREAD) 
			error(Eperm); 
		break; 
1997/1128/sys/src/9/ip/devip.c:300,3111998/0306/sys/src/9/ip/devip.c:311,322
1997/0327    
	case Qctl: 
	case Qerr: 
		p = fs.p[PROTO(c->qid)]; 
		lock(p); 
1998/0306    
		qlock(p); 
1997/0327    
		cv = p->conv[CONV(c->qid)]; 
		lock(cv); 
		if(waserror()) { 
			unlock(cv); 
			unlock(p); 
1998/0306    
			qunlock(p); 
1997/0327    
			nexterror(); 
		} 
		if((perm & (cv->perm>>6)) != perm) { 
1997/1128/sys/src/9/ip/devip.c:321,3271998/0306/sys/src/9/ip/devip.c:332,338
1997/0327    
			cv->perm = 0660; 
		} 
		unlock(cv); 
		unlock(p); 
1998/0306    
		qunlock(p); 
1997/0327    
		poperror(); 
		break; 
	case Qlisten: 
1997/1128/sys/src/9/ip/devip.c:381,3881998/0306/sys/src/9/ip/devip.c:392,401
1997/0327    
closeconv(Conv *cv) 
{ 
	Conv *nc; 
1998/0306    
	Ipmulti *mp; 
1997/0327    
 
	lock(cv); 
1998/0306    
 
1997/0327    
	if(--cv->inuse > 0) { 
		unlock(cv); 
		return; 
1997/1128/sys/src/9/ip/devip.c:397,4021998/0306/sys/src/9/ip/devip.c:410,418
1997/0327    
	strcpy(cv->owner, network); 
	cv->perm = 0660; 
 
1998/0306    
	while((mp = cv->multi) != nil) 
		ipifcremmulti(cv, mp->ma, mp->ia); 
 
1997/0327    
	/* The close routine will unlock the conv */ 
	cv->p->close(cv); 
} 
1997/1128/sys/src/9/ip/devip.c:407,4191998/0306/sys/src/9/ip/devip.c:423,435
1997/0327    
	switch(TYPE(c->qid)) { 
	default: 
		break; 
1997/0423    
	case Qipifc: 
1998/0306    
	case Qlog: 
1997/0531    
		if(c->flag & COPEN) 
			closeifcconv(c->aux); 
1997/0423    
		c->aux = nil; 
1998/0306    
			netlogclose(); 
1997/0423    
		break; 
1997/0327    
	case Qlog: 
		netlogclose(); 
1998/0306    
	case Qiprouter: 
		if(c->flag & COPEN) 
			iprouterclose(); 
1997/0327    
		break; 
	case Qdata: 
	case Qctl: 
1997/1128/sys/src/9/ip/devip.c:423,4351998/0306/sys/src/9/ip/devip.c:439,456
1997/0327    
	} 
} 
 
1998/0306    
enum 
{ 
	Statelen=	1024, 
}; 
 
1997/0327    
static long 
ipread(Chan *ch, void *a, long n, ulong offset) 
{ 
	Conv *c; 
	Proto *x; 
	byte ip[4]; 
	char buf[256], *p, *statename; 
1998/0306    
	char *buf, *p; 
	long m, rv; 
1997/0327    
 
	p = a; 
	switch(TYPE(ch->qid)) { 
1997/1128/sys/src/9/ip/devip.c:441,4811998/0306/sys/src/9/ip/devip.c:462,522
1997/0327    
		return devdirread(ch, a, n, 0, 0, ipgen); 
	case Qarp: 
		return arpread(a, offset, n); 
	case Qipifc: 
		return Mediaifcread(a, offset, n); 
	case Qiproute: 
		return routeread(a, offset, n); 
1998/0306    
	case Qiprouter: 
		return iprouterread(a, n); 
1997/0327    
	case Qlog: 
		return netlogread(a, offset, n); 
	case Qctl: 
1998/0306    
		buf = smalloc(16); 
1997/0327    
		sprint(buf, "%d", CONV(ch->qid)); 
		return readstr(offset, p, n, buf); 
1998/0306    
		rv = readstr(offset, p, n, buf); 
		free(buf); 
		return rv; 
1997/0327    
	case Qremote: 
1998/0306    
		buf = smalloc(Statelen); 
1997/0327    
		c = fs.p[PROTO(ch->qid)]->conv[CONV(ch->qid)]; 
		hnputl(ip, c->raddr); 
		sprint(buf, "%I!%d\n", ip, c->rport); 
		return readstr(offset, p, n, buf); 
1998/0306    
		sprint(buf, "%I!%d\n", c->raddr, c->rport); 
		rv = readstr(offset, p, n, buf); 
		free(buf); 
		return rv; 
1997/0327    
	case Qlocal: 
		c = fs.p[PROTO(ch->qid)]->conv[CONV(ch->qid)]; 
		if(media != nil && c->laddr == 0) 
			hnputl(ip, Mediagetaddr(media)); 
		else 
			hnputl(ip, c->laddr); 
		sprint(buf, "%I!%d\n", ip, c->lport); 
		return readstr(offset, p, n, buf); 
1998/0306    
		buf = smalloc(Statelen); 
		x = fs.p[PROTO(ch->qid)]; 
		c = x->conv[CONV(ch->qid)]; 
		if(x->local == nil) { 
			sprint(buf, "%I!%d\n", c->laddr, c->lport); 
		} else { 
			(*x->local)(c, buf, Statelen-2); 
		} 
		rv = readstr(offset, p, n, buf); 
		free(buf); 
		return rv; 
1997/0327    
	case Qstatus: 
1998/0306    
		buf = smalloc(Statelen); 
1997/0327    
		x = fs.p[PROTO(ch->qid)]; 
		c = x->conv[CONV(ch->qid)]; 
		x->state(&statename, c); 
		sprint(buf, "%s/%d %d %s \n", c->p->name, c->x, c->inuse, statename); 
		return readstr(offset, p, n, buf); 
1998/0306    
		m = sprint(buf, "%s/%d %d ", c->p->name, c->x, c->inuse); 
		(*x->state)(c, buf, Statelen-m-2); 
		rv = readstr(offset, p, n, buf); 
		free(buf); 
		return rv; 
1997/0327    
	case Qdata: 
		c = fs.p[PROTO(ch->qid)]->conv[CONV(ch->qid)]; 
1997/1105    
		return qread(c->rq, a, n); 
                 
1997/0327    
	case Qerr: 
		c = fs.p[PROTO(ch->qid)]->conv[CONV(ch->qid)]; 
		return qread(c->eq, a, n); 
1998/0306    
	case Qstats: 
		x = fs.p[PROTO(ch->qid)]; 
		if(x->stats == nil) 
			error("stats not implemented"); 
		buf = smalloc(Statelen); 
		(*x->stats)(buf, Statelen); 
		rv = readstr(offset, p, n, buf); 
		free(buf); 
		return rv; 
1997/0327    
	} 
} 
 
1997/1128/sys/src/9/ip/devip.c:485,4991998/0306/sys/src/9/ip/devip.c:526,543
1997/0327    
	return devbread(c, n, offset); 
} 
 
1998/0306    
/* 
 *  set local address to be that of the ifc closest to remote address 
 */ 
1997/0327    
static void 
setladdr(Conv* c) 
{ 
	byte rem[4]; 
                 
	hnputl(rem, c->raddr); 
	c->laddr = Mediagetsrc(rem); 
1998/0306    
	findlocalip(c->laddr, c->raddr); 
1997/0327    
} 
 
1998/0306    
/* 
 *  pick a local port and set it 
 */ 
1997/0327    
static void 
setlport(Conv* c) 
{ 
1997/1128/sys/src/9/ip/devip.c:506,5121998/0306/sys/src/9/ip/devip.c:550,556
1997/0327    
		pp = &p->nextrport; 
	else 
		pp = &p->nextport; 
	lock(p); 
1998/0306    
	qlock(p); 
1997/0327    
	for(;;(*pp)++){ 
1997/0508    
		/* 
		 * Fsproto initialises p->nextport to 0 and the restricted 
1997/1128/sys/src/9/ip/devip.c:536,5491998/0306/sys/src/9/ip/devip.c:580,600
1997/0327    
			break; 
	} 
	c->lport = (*pp)++; 
	unlock(p); 
1998/0306    
	qunlock(p); 
1997/0327    
} 
 
1998/0306    
/* 
 *  set a local address and port from a string of the form 
 *	address!port 
 *  if address is missing and not announcing, pick one 
 *  if address is missing and announcing, leave address as zero (i.e. matches anything) 
 *  if port is 0, pick a free one 
 *  if port is '*', leave port as zero (i.e. matches anything) 
 */ 
1997/0327    
static void 
1997/1030    
setladdrport(Conv* c, char* str, int nodefault) 
1998/0306    
setladdrport(Conv* c, char* str, int announcing) 
1997/0327    
{ 
1997/0423    
	char *p; 
1997/0815    
	uchar addr[IPaddrlen]; 
1997/0327    
 
1997/1128    
	/* 
	 *  ignore restricted part if it exists.  it's 
1997/1128/sys/src/9/ip/devip.c:552,5701998/0306/sys/src/9/ip/devip.c:603,618
1997/0327    
	p = strchr(str, '!'); 
1997/1128    
	if(p == nil || strcmp(p, "!r") == 0) { 
1997/0327    
		p = str; 
1997/1030    
		if(nodefault) 
1998/0306    
		memset(c->laddr, 0, sizeof(c->laddr)); 
		if(!announcing) 
1997/1030    
			setladdr(c); 
		else 
			c->laddr = 0; 
1997/0327    
	} 
	else { 
1998/0306    
	} else { 
1997/0327    
		*p++ = 0; 
		parseip(addr, str); 
1997/0423    
		c->laddr = nhgetl(addr); 
1998/0306    
		parseip(c->laddr, str); 
1997/0327    
	} 
	if(*p == '*') 
		c->lport = 0; 
	else { 
1998/0306    
 
	c->lport = 0; 
	if(*p != '*'){ 
1997/0327    
		c->lport = atoi(p); 
		if(c->lport == 0) 
			setlport(c); 
1997/1128/sys/src/9/ip/devip.c:575,5881998/0306/sys/src/9/ip/devip.c:623,634
1997/0327    
setraddrport(Conv* c, char* str) 
{ 
1997/0423    
	char *p; 
1997/0815    
	uchar addr[IPaddrlen]; 
1997/0327    
 
	p = strchr(str, '!'); 
	if(p == nil) 
		return "malformed address"; 
	*p++ = 0; 
	parseip(addr, str); 
1997/0423    
	c->raddr = nhgetl(addr); 
1998/0306    
	parseip(c->raddr, str); 
1997/0327    
	c->rport = atoi(p); 
	p = strchr(p, '!'); 
	if(p){ 
1997/1128/sys/src/9/ip/devip.c:592,6351998/0306/sys/src/9/ip/devip.c:638,800
1997/0327    
	return nil; 
} 
 
1998/0306    
/* 
 *  called by protocol connect routine to set addresses 
 */ 
char* 
Fsstdconnect(Conv *c, char *argv[], int argc) 
{ 
	char *p; 
 
	switch(argc) { 
	default: 
		return "bad args to connect"; 
	case 2: 
		p = setraddrport(c, argv[1]); 
		if(p != nil) 
			return p; 
		setladdr(c); 
		setlport(c); 
		break; 
	case 3: 
		p = setraddrport(c, argv[1]); 
		if(p != nil) 
			return p; 
		setladdrport(c, argv[2], 0); 
		break; 
	} 
	return nil; 
} 
/* 
 *  initiate connection and sleep till its set up 
 */ 
1997/0327    
static int 
connected(void* a) 
{ 
	return ((Conv*)a)->state == Connected; 
} 
1998/0306    
static void 
connectctlmsg(Proto *x, Conv *c, Cmdbuf *cb) 
{ 
	char *p; 
1997/0327    
 
1998/0306    
	c->state = Connecting; 
	c->cerr[0] = '\0'; 
	if(x->connect == nil) 
		error("connect not supported"); 
	p = x->connect(c, cb->f, cb->nf); 
	if(p != nil) 
		error(p); 
	sleep(&c->cr, connected, c); 
	if(c->cerr[0] != '\0') 
		error(c->cerr); 
} 
 
/* 
 *  called by protocol announce routine to set addresses 
 */ 
char* 
Fsstdannounce(Conv* c, char* argv[], int argc) 
{ 
	switch(argc){ 
	default: 
		return "bad args to announce"; 
	case 2: 
		setladdrport(c, argv[1], 1); 
		break; 
	} 
	return nil; 
} 
 
/* 
 *  initiate announcement and sleep till its set up 
 */ 
1997/0327    
static int 
announced(void* a) 
{ 
	return ((Conv*)a)->state == Announced; 
} 
1998/0306    
static void 
announcectlmsg(Proto *x, Conv *c, Cmdbuf *cb) 
{ 
	char *p; 
1997/0327    
 
1998/0306    
	c->state = Announcing; 
	c->cerr[0] = '\0'; 
	if(x->announce == nil) 
		error("announce not supported"); 
	p = x->announce(c, cb->f, cb->nf); 
	if(p != nil) 
		error(p); 
	sleep(&c->cr, announced, c); 
	if(c->cerr[0] != '\0') 
		error(c->cerr); 
} 
 
/* 
 *  called by protocol bide routine to set addresses 
 */ 
char* 
Fsstdbind(Conv* c, char* argv[], int argc) 
{ 
	switch(argc){ 
	default: 
		return "bad args to bind"; 
	case 2: 
		setladdrport(c, argv[1], 0); 
		break; 
	} 
	return nil; 
} 
 
static void 
bindctlmsg(Proto *x, Conv *c, Cmdbuf *cb) 
{ 
	char *p; 
 
	if(x->bind == nil) 
		p = Fsstdbind(c, cb->f, cb->nf); 
	else 
		p = x->bind(c, cb->f, cb->nf); 
	if(p != nil) 
		error(p); 
} 
 
static void 
ttlctlmsg(Conv *c, Cmdbuf *cb) 
{ 
	if(cb->nf < 2) 
		c->ttl = MAXTTL; 
	else 
		c->ttl = atoi(cb->f[1]); 
} 
 
1997/0327    
static long 
ipwrite(Chan* ch, char* a, long n, ulong) 
{ 
	Conv *c; 
	Proto *x; 
	int nfield; 
	char *p, *fields[10], buf[128]; 
1998/0306    
	char *p; 
	Cmdbuf *cb; 
	uchar ia[IPaddrlen]; 
1997/0327    
 
	switch(TYPE(ch->qid)){ 
	default: 
		error(Eperm); 
1998/0306    
	case Qdata: 
		x = fs.p[PROTO(ch->qid)]; 
		c = x->conv[CONV(ch->qid)]; 
 
		if(c->wq == nil) 
			error(Eperm); 
 
		qwrite(c->wq, a, n); 
		x->kick(c, n); 
		break; 
1997/0327    
	case Qarp: 
		p = arpwrite(a, n); 
		if(p != nil) 
			error(p); 
		return n; 
	case Qipifc: 
1997/0423    
		p = Mediaifcwrite(ch->aux, a, n); 
1997/0327    
		if(p != nil) 
			error(p); 
		return n; 
1998/0306    
		return arpwrite(a, n); 
1997/0327    
	case Qiproute: 
		p = routewrite(a, n); 
		if(p != nil) 
			error(p); 
		return n; 
1998/0306    
		return routewrite(ch, a, n); 
1997/0327    
	case Qlog: 
		p = netlogctl(a, n); 
		if(p != nil) 
1997/1128/sys/src/9/ip/devip.c:638,7271998/0306/sys/src/9/ip/devip.c:803,850
1997/0327    
	case Qctl: 
		x = fs.p[PROTO(ch->qid)]; 
		c = x->conv[CONV(ch->qid)]; 
		if(n > sizeof(buf)-1) 
			n = sizeof(buf)-1; 
		memmove(buf, a, n); 
		buf[n] = '\0'; 
		nfield = parsefields(buf, fields, 10, " "); 
		if(strcmp(fields[0], "connect") == 0){ 
			if(canqlock(&c->car) == 0) 
				error("connect/announce in progress"); 
			if(waserror()) { 
				qunlock(&c->car); 
				nexterror(); 
			} 
			c->state = Connecting; 
			c->cerr[0] = '\0'; 
			p = x->connect(c, fields, nfield); 
			if(p != nil) 
				error(p); 
			sleep(&c->cr, connected, c); 
			if(c->cerr[0] != '\0') 
				error(c->cerr); 
			qunlock(&c->car); 
			poperror(); 
			return n; 
1998/0306    
		cb = parsecmd(a, n); 
 
		if(canqlock(&c->car) == 0){ 
			free(cb); 
			error("connect/announce in progress"); 
1997/0327    
		} 
		if(strcmp(fields[0], "announce") == 0){ 
			if(canqlock(&c->car) == 0) 
				error("connect/announce in progress"); 
			if(waserror()) { 
				qunlock(&c->car); 
				nexterror(); 
			} 
			c->state = Announcing; 
			c->cerr[0] = '\0'; 
1997/0403    
			p = x->announce(c, fields, nfield); 
			if(p != nil) 
				error(p); 
1997/0327    
			sleep(&c->cr, announced, c); 
			if(c->cerr[0] != '\0') 
				error(c->cerr); 
1998/0306    
		if(waserror()) { 
1997/0327    
			qunlock(&c->car); 
			poperror(); 
			return n; 
1998/0306    
			free(cb); 
			nexterror(); 
1997/0327    
		} 
		if(strcmp(fields[0], "bind") == 0){ 
			if(canqlock(&c->car) == 0) 
				error("connect/announce in progress"); 
			if(waserror()) { 
				qunlock(&c->car); 
				nexterror(); 
			} 
			switch(nfield){ 
			default: 
				error("bad args to bind"); 
			case 2: 
				setladdr(c); 
				c->lport = atoi(fields[1]); 
				if(c->lport == 0) 
					setlport(c); 
				break; 
			} 
			qunlock(&c->car); 
			poperror(); 
			return n; 
		} 
		if(strcmp(fields[0], "ttl") == 0){ 
			if(nfield < 2) 
				c->ttl = MAXTTL; 
			else 
				c->ttl = atoi(fields[1]); 
			return n; 
		} 
		if(x->ctl != nil) { 
			p = x->ctl(c, fields, nfield); 
1998/0306    
		if(strcmp(cb->f[0], "connect") == 0) 
			connectctlmsg(x, c, cb); 
		else if(strcmp(cb->f[0], "announce") == 0) 
			announcectlmsg(x, c, cb); 
		else if(strcmp(cb->f[0], "bind") == 0) 
			bindctlmsg(x, c, cb); 
		else if(strcmp(cb->f[0], "ttl") == 0) 
			ttlctlmsg(c, cb); 
		else if(strcmp(cb->f[0], "addmulti") == 0){ 
			if(cb->nf < 2) 
				error("addmulti needs interface address"); 
			if(!ipismulticast(c->raddr)) 
				error("addmulti for a non multicast address"); 
			parseip(ia, cb->f[1]); 
			ipifcaddmulti(c, c->raddr, ia); 
		} else if(strcmp(cb->f[0], "remmulti") == 0){ 
			if(cb->nf < 2) 
				error("remmulti needs interface address"); 
			if(!ipismulticast(c->raddr)) 
				error("remmulti for a non multicast address"); 
			parseip(ia, cb->f[1]); 
			ipifcremmulti(c, c->raddr, ia); 
		} else if(x->ctl != nil) { 
			p = x->ctl(c, cb->f, cb->nf); 
1997/0327    
			if(p != nil) 
				error(p); 
			return n; 
		} 
		error("unknown control request"); 
	case Qdata: 
		x = fs.p[PROTO(ch->qid)]; 
		c = x->conv[CONV(ch->qid)]; 
                 
		qwrite(c->wq, a, n); 
		x->kick(c, n); 
1998/0306    
		} else 
			error("unknown control request"); 
		qunlock(&c->car); 
		free(cb); 
		poperror(); 
1997/0327    
	} 
	return n; 
} 
1997/1128/sys/src/9/ip/devip.c:782,7881998/0306/sys/src/9/ip/devip.c:905,911
1997/0327    
 *  built in 
 */ 
int 
Fsbuiltinproto(Fs* fs, byte proto) 
1998/0306    
Fsbuiltinproto(Fs* fs, uchar proto) 
1997/0327    
{ 
	return fs->t2p[proto] != nil; 
} 
1997/1128/sys/src/9/ip/devip.c:790,8031998/0306/sys/src/9/ip/devip.c:913,924
1997/0327    
Conv* 
Fsprotoclone(Proto *p, char *user) 
{ 
	char *junk; 
	int unused; 
	Conv *c, **pp, **ep; 
 
	c = nil; 
	lock(p); 
1998/0306    
	qlock(p); 
1997/0327    
	if(waserror()) { 
		unlock(p); 
1998/0306    
		qunlock(p); 
1997/0327    
		nexterror(); 
	} 
	ep = &p->conv[p->nc]; 
1997/1128/sys/src/9/ip/devip.c:812,8181998/0306/sys/src/9/ip/devip.c:933,938
1997/0327    
			c->x = pp - p->conv; 
			c->ptcl = malloc(p->ptclsize); 
			if(c->ptcl == nil) { 
1997/1104    
				unlock(c); 
1997/0327    
				free(c); 
				error(Enomem); 
			} 
1997/1128/sys/src/9/ip/devip.c:823,8301998/0306/sys/src/9/ip/devip.c:943,953
1997/0327    
			break; 
		} 
		if(canlock(c)){ 
			unused = p->state(&junk, c); 
			if(c->inuse == 0 && unused) 
1998/0306    
			/* 
			 *  make sure both processes and protocol 
			 *  are done with this Conv 
			 */ 
			if(c->inuse == 0 && (p->inuse == nil || (*p->inuse)(c) == 0)) 
1997/0327    
				break; 
 
			unlock(c); 
1997/1128/sys/src/9/ip/devip.c:831,8371998/0306/sys/src/9/ip/devip.c:954,960
1997/0327    
		} 
	} 
	if(pp >= ep) { 
		unlock(p); 
1998/0306    
		qunlock(p); 
1997/0327    
		poperror(); 
		return nil; 
	} 
1997/1128/sys/src/9/ip/devip.c:840,8471998/0306/sys/src/9/ip/devip.c:963,970
1997/0327    
	strcpy(c->owner, user); 
	c->perm = 0660; 
	c->state = 0; 
	c->laddr = 0; 
	c->raddr = 0; 
1998/0306    
	ipmove(c->laddr, IPnoaddr); 
	ipmove(c->raddr, IPnoaddr); 
1997/0327    
	c->lport = 0; 
	c->rport = 0; 
	c->restricted = 0; 
1997/1128/sys/src/9/ip/devip.c:851,8571998/0306/sys/src/9/ip/devip.c:974,980
1997/0327    
	qreopen(c->eq); 
 
	unlock(c); 
	unlock(p); 
1998/0306    
	qunlock(p); 
1997/0327    
	poperror(); 
	return c; 
} 
1997/1128/sys/src/9/ip/devip.c:878,8901998/0306/sys/src/9/ip/devip.c:1001,1013
1997/0327    
} 
 
Proto* 
Fsrcvpcol(Fs* fs, byte proto) 
1998/0306    
Fsrcvpcol(Fs* fs, uchar proto) 
1997/0327    
{ 
	return fs->t2p[proto]; 
} 
 
Conv* 
Fsnewcall(Fs*, Conv *c, Ipaddr raddr, ushort rport, Ipaddr laddr, ushort lport) 
1998/0306    
Fsnewcall(Fs*, Conv *c, uchar *raddr, ushort rport, uchar *laddr, ushort lport) 
1997/0327    
{ 
	Conv *nc; 
	Conv **l; 
1997/1128/sys/src/9/ip/devip.c:905,9131998/0306/sys/src/9/ip/devip.c:1028,1036
1997/0327    
		unlock(c); 
		return nil; 
	} 
	nc->raddr = raddr; 
1998/0306    
	ipmove(nc->raddr, raddr); 
1997/0327    
	nc->rport = rport; 
	nc->laddr = laddr; 
1998/0306    
	ipmove(nc->laddr, laddr); 
1997/0327    
	nc->lport = lport; 
	nc->next = nil; 
	*l = nc; 
1997/1128/sys/src/9/ip/devip.c:916,9751998/0306/sys/src/9/ip/devip.c:1039,1042
1997/0327    
	wakeup(&c->listenr); 
 
	return nc; 
} 
                 
int 
Fspcolstats(char *buf, int len) 
{ 
	Proto **p; 
	int n; 
                 
	n = 0; 
1997/0916    
	for(p = fs.p; *p; p++){ 
1997/0327    
		n += snprint(buf + n, len - n, 
1997/0916    
			"%s: csum %d hlen %d len %d order %d rexmit %d\n", 
1997/0327    
			(*p)->name, (*p)->csumerr, (*p)->hlenerr, (*p)->lenerr, 
1997/0916    
			(*p)->order, (*p)->rexmit); 
		if((*p)->stats) 
			n += (*(*p)->stats)(buf + n, len - n); 
	} 
1997/0327    
	return n; 
} 
                 
char* 
Fsstdconnect(Conv *c, char *argv[], int argc) 
{ 
	char *p; 
                 
	switch(argc) { 
	default: 
		return "bad args to connect"; 
	case 2: 
		p = setraddrport(c, argv[1]); 
		if(p != nil) 
			return p; 
		setladdr(c); 
		setlport(c); 
		break; 
	case 3: 
		p = setraddrport(c, argv[1]); 
		if(p != nil) 
			return p; 
1997/1030    
		setladdrport(c, argv[2], 1); 
1997/0403    
		break; 
	} 
	return nil; 
} 
                 
char* 
Fsstdannounce(Conv* c, char* argv[], int argc) 
{ 
	switch(argc){ 
	default: 
		return "bad args to announce"; 
	case 2: 
1997/1030    
		setladdrport(c, argv[1], 0); 
1997/0327    
		break; 
	} 
	return nil; 
} 
1998/0306/sys/src/9/ip/devip.c:16,211998/0310/sys/src/9/ip/devip.c:16,22 (short | long)
1997/0327    
	Qarp=		Qtopbase, 
	Qiproute, 
1998/0306    
	Qiprouter, 
1998/0310    
	Qipselftab, 
1997/0327    
	Qlog, 
 
	Qprotodir,			/* directory for a protocol */ 
1998/0306/sys/src/9/ip/devip.c:107,1131998/0310/sys/src/9/ip/devip.c:108,116
1997/0327    
{ 
	Qid q; 
	char *p; 
1998/0310    
	int prot; 
1997/0327    
 
1998/0310    
	prot = 0666; 
1997/0327    
	switch(i) { 
	default: 
		return -1; 
1998/0306/sys/src/9/ip/devip.c:119,1241998/0310/sys/src/9/ip/devip.c:122,132
1997/0327    
		p = "iproute"; 
		q = (Qid){QID(0, 0, Qiproute), 0}; 
		break; 
1998/0310    
	case Qipselftab: 
		p = "ipselftab"; 
		prot = 0444; 
		q = (Qid){QID(0, 0, Qipselftab), 0}; 
		break; 
1998/0306    
	case Qiprouter: 
		p = "iprouter"; 
		q = (Qid){QID(0, 0, Qiprouter), 0}; 
1998/0306/sys/src/9/ip/devip.c:128,1341998/0310/sys/src/9/ip/devip.c:136,142
1997/0327    
		q = (Qid){QID(0, 0, Qlog), 0}; 
		break; 
	} 
1998/0306    
	devdir(c, q, p, 0, network, 0666, dp); 
1998/0310    
	devdir(c, q, p, 0, network, prot, dp); 
1997/0327    
	return 1; 
} 
 
1998/0306/sys/src/9/ip/devip.c:154,1591998/0310/sys/src/9/ip/devip.c:162,168
1997/0327    
	case Qlog: 
	case Qiproute: 
1998/0306    
	case Qiprouter: 
1998/0310    
	case Qipselftab: 
1997/0327    
		return ip1gen(c, TYPE(c->qid), dp); 
	case Qprotodir: 
		if(s < fs.p[PROTO(c->qid)]->ac) { 
1998/0306/sys/src/9/ip/devip.c:295,3001998/0310/sys/src/9/ip/devip.c:304,310
1997/0327    
	case Qremote: 
	case Qlocal: 
1998/0306    
	case Qstats: 
1998/0310    
	case Qipselftab: 
1997/0327    
		if(omode != OREAD) 
			error(Eperm); 
		break; 
1998/0306/sys/src/9/ip/devip.c:464,4711998/0310/sys/src/9/ip/devip.c:474,481
1997/0327    
		return arpread(a, offset, n); 
	case Qiproute: 
		return routeread(a, offset, n); 
1998/0306    
	case Qiprouter: 
		return iprouterread(a, n); 
1998/0310    
	case Qipselftab: 
		return ipselftabread(a, offset, n); 
1997/0327    
	case Qlog: 
		return netlogread(a, offset, n); 
	case Qctl: 
1998/0310/sys/src/9/ip/devip.c:6,191998/0313/sys/src/9/ip/devip.c:6,17 (short | long)
1997/0327    
#include	"../port/error.h" 
#include	"../ip/ip.h" 
 
Fs fs; 
Queue* qlog; 
                 
enum 
{ 
	Qtopdir=	1,		/* top level directory */ 
	Qtopbase, 
	Qarp=		Qtopbase, 
1998/0313    
	Qbootp, 
1997/0327    
	Qiproute, 
1998/0306    
	Qiprouter, 
1998/0310    
	Qipselftab, 
1998/0310/sys/src/9/ip/devip.c:33,461998/0313/sys/src/9/ip/devip.c:31,59
1997/0327    
	Qlocal, 
	Qremote, 
	Qstatus, 
1998/0313    
 
	Logtype=	5, 
	Masktype=	(1<<Logtype)-1, 
	Logconv=	12, 
	Maskconv=	(1<<Logconv)-1, 
	Shiftconv=	Logtype, 
	Logproto=	8, 
	Maskproto=	(1<<Logproto)-1, 
	Shiftproto=	Logtype + Logconv, 
 
	Nfs=		16, 
1997/0327    
}; 
#define TYPE(x) 	((x).path & 0x1f) 
#define CONV(x) 	(((x).path >> 5)&0xfff) 
#define PROTO(x) 	(((x).path >> 17)&0xff) 
#define QID(p, c, y) 	(((p)<<17) | ((c)<<5) | (y)) 
1998/0313    
#define TYPE(x) 	( (x).path & Masktype ) 
#define CONV(x) 	( ((x).path >> Shiftconv) & Maskconv ) 
#define PROTO(x) 	( ((x).path >> Shiftproto) & Maskproto ) 
#define QID(p, c, y) 	( ((p)<<(Shiftproto)) | ((c)<<Shiftconv) | (y) ) 
1997/0327    
 
static char network[] = "network"; 
 
1998/0313    
QLock	fslock; 
Fs	*ipfs[Nfs];	/* attached fs's */ 
Queue	*qlog; 
 
1997/0327    
static int 
ip3gen(Chan *c, int i, Dir *dp) 
{ 
1998/0310/sys/src/9/ip/devip.c:48,541998/0313/sys/src/9/ip/devip.c:61,67
1997/0327    
	Conv *cv; 
	char *p; 
 
	cv = fs.p[PROTO(c->qid)]->conv[CONV(c->qid)]; 
1998/0313    
	cv = ipfs[c->dev]->p[PROTO(c->qid)]->conv[CONV(c->qid)]; 
1997/0327    
	switch(i) { 
	default: 
		return -1; 
1998/0310/sys/src/9/ip/devip.c:118,1231998/0313/sys/src/9/ip/devip.c:131,140
1997/0327    
		p = "arp"; 
		q = (Qid){QID(0, 0, Qarp), 0}; 
		break; 
1998/0313    
	case Qbootp: 
		p = "bootp"; 
		q = (Qid){QID(0, 0, Qbootp), 0}; 
		break; 
1997/0327    
	case Qiproute: 
		p = "iproute"; 
		q = (Qid){QID(0, 0, Qiproute), 0}; 
1998/0310/sys/src/9/ip/devip.c:146,1641998/0313/sys/src/9/ip/devip.c:163,185
1997/0327    
	Qid q; 
	Conv *cv; 
	char name[16]; 
1998/0313    
	Fs *f; 
1997/0327    
 
1998/0313    
	f = ipfs[c->dev]; 
 
1997/0327    
	switch(TYPE(c->qid)) { 
	case Qtopdir: 
		if(s < fs.np) { 
1997/0423    
			if(fs.p[s]->connect == nil) 
1998/0313    
		if(s < f->np) { 
			if(f->p[s]->connect == nil) 
1997/0423    
				return 0;	/* protocol with no user interface */ 
1997/0327    
			q = (Qid){QID(s, 0, Qprotodir)|CHDIR, 0}; 
			devdir(c, q, fs.p[s]->name, 0, network, CHDIR|0555, dp); 
1998/0313    
			devdir(c, q, f->p[s]->name, 0, network, CHDIR|0555, dp); 
1997/0327    
			return 1; 
		} 
		s -= fs.np; 
1998/0313    
		s -= f->np; 
1997/0327    
		return ip1gen(c, s+Qtopbase, dp); 
	case Qarp: 
1998/0313    
	case Qbootp: 
1997/0327    
	case Qlog: 
	case Qiproute: 
1998/0306    
	case Qiprouter: 
1998/0310/sys/src/9/ip/devip.c:165,1781998/0313/sys/src/9/ip/devip.c:186,199
1998/0310    
	case Qipselftab: 
1997/0327    
		return ip1gen(c, TYPE(c->qid), dp); 
	case Qprotodir: 
		if(s < fs.p[PROTO(c->qid)]->ac) { 
			cv = fs.p[PROTO(c->qid)]->conv[s]; 
1998/0313    
		if(s < f->p[PROTO(c->qid)]->ac) { 
			cv = f->p[PROTO(c->qid)]->conv[s]; 
1997/0327    
			sprint(name, "%d", s); 
			q = (Qid){QID(PROTO(c->qid), s, Qconvdir)|CHDIR, 0}; 
			devdir(c, q, name, 0, cv->owner, CHDIR|0555, dp); 
			return 1; 
		} 
		s -= fs.p[PROTO(c->qid)]->ac; 
1998/0313    
		s -= f->p[PROTO(c->qid)]->ac; 
1997/0327    
		return ip2gen(c, s+Qprotobase, dp); 
	case Qclone: 
1998/0306    
	case Qstats: 
1998/0310/sys/src/9/ip/devip.c:199,2101998/0313/sys/src/9/ip/devip.c:220,225
1997/0327    
static void 
ipinit(void) 
{ 
	int i; 
	extern void (*ipprotoinit[])(Fs*); 
                 
	initfrag(100); 
	for(i = 0; ipprotoinit[i]; i++) 
		ipprotoinit[i](&fs); 
	fmtinstall('i', eipconv); 
	fmtinstall('I', eipconv); 
	fmtinstall('E', eipconv); 
1998/0310/sys/src/9/ip/devip.c:212,2241998/0313/sys/src/9/ip/devip.c:227,271
1998/0306    
	fmtinstall('M', eipconv); 
1997/0327    
} 
 
1998/0313    
static Fs* 
ipgetfs(int dev) 
{ 
	extern void (*ipprotoinit[])(Fs*); 
	Fs *f; 
	int i; 
 
	if(dev >= Nfs) 
		return nil; 
 
	qlock(&fslock); 
	if(ipfs[dev] == nil){ 
		f = smalloc(sizeof(Fs)); 
		ip_init(f); 
		arpinit(f); 
		netloginit(f); 
		for(i = 0; ipprotoinit[i]; i++) 
			ipprotoinit[i](f); 
		ipfs[dev] = f; 
	} 
	qunlock(&fslock); 
 
	return ipfs[dev]; 
} 
 
1997/0327    
static Chan* 
ipattach(char* spec) 
{ 
	Chan *c; 
1998/0313    
	int dev; 
1997/0327    
 
1998/0313    
	dev = atoi(spec); 
	if(dev >= 16) 
		error("bad specification"); 
 
	ipgetfs(dev); 
1997/0327    
	c = devattach('I', spec); 
	c->qid = (Qid){QID(0, 0, Qtopdir)|CHDIR, 0}; 
1998/0313    
	c->dev = dev; 
1997/0327    
 
	return c; 
} 
1998/0310/sys/src/9/ip/devip.c:281,2981998/0313/sys/src/9/ip/devip.c:328,348
1997/0327    
	Conv *cv, *nc; 
	Proto *p; 
	int perm; 
1998/0313    
	Fs *f; 
1997/0327    
 
	omode &= 3; 
	perm = m2p[omode]; 
 
1998/0313    
	f = ipfs[c->dev]; 
 
1997/0327    
	switch(TYPE(c->qid)) { 
	default: 
		break; 
	case Qlog: 
		netlogopen(); 
1998/0313    
		netlogopen(f); 
1997/0327    
		break; 
1998/0306    
	case Qiprouter: 
		iprouteropen(); 
1998/0313    
		iprouteropen(f); 
1998/0306    
		break; 
	case Qiproute: 
		memmove(c->tag, "none", sizeof(c->tag)); 
1998/0310/sys/src/9/ip/devip.c:304,3161998/0313/sys/src/9/ip/devip.c:354,367
1997/0327    
	case Qremote: 
	case Qlocal: 
1998/0306    
	case Qstats: 
1998/0313    
	case Qbootp: 
1998/0310    
	case Qipselftab: 
1997/0327    
		if(omode != OREAD) 
			error(Eperm); 
		break; 
	case Qclone: 
		p = fs.p[PROTO(c->qid)]; 
		cv = Fsprotoclone(p, up->user); 
1998/0313    
		p = f->p[PROTO(c->qid)]; 
		cv = Fsprotoclone(p, commonuser()); 
1997/0327    
		if(cv == nil) { 
			error(Enodev); 
			break; 
1998/0310/sys/src/9/ip/devip.c:320,3261998/0313/sys/src/9/ip/devip.c:371,377
1997/0327    
	case Qdata: 
	case Qctl: 
	case Qerr: 
		p = fs.p[PROTO(c->qid)]; 
1998/0313    
		p = f->p[PROTO(c->qid)]; 
1998/0306    
		qlock(p); 
1997/0327    
		cv = p->conv[CONV(c->qid)]; 
		lock(cv); 
1998/0310/sys/src/9/ip/devip.c:330,3361998/0313/sys/src/9/ip/devip.c:381,387
1997/0327    
			nexterror(); 
		} 
		if((perm & (cv->perm>>6)) != perm) { 
			if(strcmp(up->user, cv->owner) != 0) 
1998/0313    
			if(strcmp(commonuser(), cv->owner) != 0) 
1997/0327    
				error(Eperm); 
		 	if((perm & cv->perm) != perm) 
				error(Eperm);  
1998/0310/sys/src/9/ip/devip.c:338,3441998/0313/sys/src/9/ip/devip.c:389,395
1997/0327    
		} 
		cv->inuse++; 
		if(cv->inuse == 1){ 
			memmove(cv->owner, up->user, NAMELEN); 
1998/0313    
			memmove(cv->owner, commonuser(), NAMELEN); 
1997/0327    
			cv->perm = 0660; 
		} 
		unlock(cv); 
1998/0310/sys/src/9/ip/devip.c:346,3521998/0313/sys/src/9/ip/devip.c:397,403
1997/0327    
		poperror(); 
		break; 
	case Qlisten: 
		cv = fs.p[PROTO(c->qid)]->conv[CONV(c->qid)]; 
1998/0313    
		cv = f->p[PROTO(c->qid)]->conv[CONV(c->qid)]; 
1997/0327    
		if(cv->state != Announced) 
			error("not announced"); 
 
1998/0310/sys/src/9/ip/devip.c:365,3711998/0313/sys/src/9/ip/devip.c:416,422
1997/0327    
			if(nc != nil){ 
				cv->incall = nc->next; 
				c->qid = (Qid){QID(PROTO(c->qid), nc->x, Qctl), 0}; 
				memmove(cv->owner, up->user, NAMELEN); 
1998/0313    
				memmove(cv->owner, commonuser(), NAMELEN); 
1997/0327    
			} 
			unlock(cv); 
 
1998/0310/sys/src/9/ip/devip.c:430,4511998/0313/sys/src/9/ip/devip.c:481,505
1997/0327    
static void 
ipclose(Chan* c) 
{ 
1998/0313    
	Fs *f; 
 
	f = ipfs[c->dev]; 
1997/0327    
	switch(TYPE(c->qid)) { 
	default: 
		break; 
1998/0306    
	case Qlog: 
1997/0531    
		if(c->flag & COPEN) 
1998/0306    
			netlogclose(); 
1998/0313    
			netlogclose(f); 
1997/0423    
		break; 
1998/0306    
	case Qiprouter: 
		if(c->flag & COPEN) 
			iprouterclose(); 
1998/0313    
			iprouterclose(f); 
1997/0327    
		break; 
	case Qdata: 
	case Qctl: 
	case Qerr: 
		if(c->flag & COPEN) 
			closeconv(fs.p[PROTO(c->qid)]->conv[CONV(c->qid)]); 
1998/0313    
			closeconv(f->p[PROTO(c->qid)]->conv[CONV(c->qid)]); 
1997/0327    
	} 
} 
 
1998/0310/sys/src/9/ip/devip.c:461,4671998/0313/sys/src/9/ip/devip.c:515,524
1997/0327    
	Proto *x; 
1998/0306    
	char *buf, *p; 
	long m, rv; 
1998/0313    
	Fs *f; 
1997/0327    
 
1998/0313    
	f = ipfs[ch->dev]; 
 
1997/0327    
	p = a; 
	switch(TYPE(ch->qid)) { 
	default: 
1998/0310/sys/src/9/ip/devip.c:471,4831998/0313/sys/src/9/ip/devip.c:528,542
1997/0327    
	case Qconvdir: 
		return devdirread(ch, a, n, 0, 0, ipgen); 
	case Qarp: 
		return arpread(a, offset, n); 
1998/0313    
		return arpread(f->arp, a, offset, n); 
 	case Qbootp: 
 		return bootpread(a, offset, n); 
1997/0327    
	case Qiproute: 
		return routeread(a, offset, n); 
1998/0313    
		return routeread(f, a, offset, n); 
1998/0310    
	case Qipselftab: 
		return ipselftabread(a, offset, n); 
1998/0313    
		return ipselftabread(f, a, offset, n); 
1997/0327    
	case Qlog: 
		return netlogread(a, offset, n); 
1998/0313    
		return netlogread(f, a, offset, n); 
1997/0327    
	case Qctl: 
1998/0306    
		buf = smalloc(16); 
1997/0327    
		sprint(buf, "%d", CONV(ch->qid)); 
1998/0310/sys/src/9/ip/devip.c:486,4921998/0313/sys/src/9/ip/devip.c:545,551
1998/0306    
		return rv; 
1997/0327    
	case Qremote: 
1998/0306    
		buf = smalloc(Statelen); 
1997/0327    
		c = fs.p[PROTO(ch->qid)]->conv[CONV(ch->qid)]; 
1998/0313    
		c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)]; 
1998/0306    
		sprint(buf, "%I!%d\n", c->raddr, c->rport); 
		rv = readstr(offset, p, n, buf); 
		free(buf); 
1998/0310/sys/src/9/ip/devip.c:493,4991998/0313/sys/src/9/ip/devip.c:552,558
1998/0306    
		return rv; 
1997/0327    
	case Qlocal: 
1998/0306    
		buf = smalloc(Statelen); 
		x = fs.p[PROTO(ch->qid)]; 
1998/0313    
		x = f->p[PROTO(ch->qid)]; 
1998/0306    
		c = x->conv[CONV(ch->qid)]; 
		if(x->local == nil) { 
			sprint(buf, "%I!%d\n", c->laddr, c->lport); 
1998/0310/sys/src/9/ip/devip.c:505,5111998/0313/sys/src/9/ip/devip.c:564,570
1998/0306    
		return rv; 
1997/0327    
	case Qstatus: 
1998/0306    
		buf = smalloc(Statelen); 
1997/0327    
		x = fs.p[PROTO(ch->qid)]; 
1998/0313    
		x = f->p[PROTO(ch->qid)]; 
1997/0327    
		c = x->conv[CONV(ch->qid)]; 
1998/0306    
		m = sprint(buf, "%s/%d %d ", c->p->name, c->x, c->inuse); 
		(*x->state)(c, buf, Statelen-m-2); 
1998/0310/sys/src/9/ip/devip.c:513,5291998/0313/sys/src/9/ip/devip.c:572,588
1998/0306    
		free(buf); 
		return rv; 
1997/0327    
	case Qdata: 
		c = fs.p[PROTO(ch->qid)]->conv[CONV(ch->qid)]; 
1998/0313    
		c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)]; 
1997/1105    
		return qread(c->rq, a, n); 
1997/0327    
	case Qerr: 
		c = fs.p[PROTO(ch->qid)]->conv[CONV(ch->qid)]; 
1998/0313    
		c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)]; 
1997/0327    
		return qread(c->eq, a, n); 
1998/0306    
	case Qstats: 
		x = fs.p[PROTO(ch->qid)]; 
1998/0313    
		x = f->p[PROTO(ch->qid)]; 
1998/0306    
		if(x->stats == nil) 
			error("stats not implemented"); 
		buf = smalloc(Statelen); 
		(*x->stats)(buf, Statelen); 
1998/0313    
		(*x->stats)(x, buf, Statelen); 
1998/0306    
		rv = readstr(offset, p, n, buf); 
		free(buf); 
		return rv; 
1998/0310/sys/src/9/ip/devip.c:542,5481998/0313/sys/src/9/ip/devip.c:601,607
1997/0327    
static void 
setladdr(Conv* c) 
{ 
1998/0306    
	findlocalip(c->laddr, c->raddr); 
1998/0313    
	findlocalip(c->p->f, c->laddr, c->raddr); 
1997/0327    
} 
 
1998/0306    
/* 
1998/0310/sys/src/9/ip/devip.c:787,7981998/0313/sys/src/9/ip/devip.c:846,860
1998/0306    
	char *p; 
	Cmdbuf *cb; 
	uchar ia[IPaddrlen]; 
1998/0313    
	Fs *f; 
1997/0327    
 
1998/0313    
	f = ipfs[ch->dev]; 
 
1997/0327    
	switch(TYPE(ch->qid)){ 
	default: 
		error(Eperm); 
1998/0306    
	case Qdata: 
		x = fs.p[PROTO(ch->qid)]; 
1998/0313    
		x = f->p[PROTO(ch->qid)]; 
1998/0306    
		c = x->conv[CONV(ch->qid)]; 
 
		if(c->wq == nil) 
1998/0310/sys/src/9/ip/devip.c:802,8171998/0313/sys/src/9/ip/devip.c:864,879
1998/0306    
		x->kick(c, n); 
		break; 
1997/0327    
	case Qarp: 
1998/0306    
		return arpwrite(a, n); 
1998/0313    
		return arpwrite(f->arp, a, n); 
1997/0327    
	case Qiproute: 
1998/0306    
		return routewrite(ch, a, n); 
1998/0313    
		return routewrite(f, ch, a, n); 
1997/0327    
	case Qlog: 
		p = netlogctl(a, n); 
1998/0313    
		p = netlogctl(f, a, n); 
1997/0327    
		if(p != nil) 
			error(p); 
		return n; 
	case Qctl: 
		x = fs.p[PROTO(ch->qid)]; 
1998/0313    
		x = f->p[PROTO(ch->qid)]; 
1997/0327    
		c = x->conv[CONV(ch->qid)]; 
1998/0306    
		cb = parsecmd(a, n); 
 
1998/0310/sys/src/9/ip/devip.c:887,9121998/0313/sys/src/9/ip/devip.c:949,977
1997/0327    
}; 
 
int 
Fsproto(Fs *fs, Proto *p) 
1998/0313    
Fsproto(Fs *f, Proto *p) 
1997/0327    
{ 
	if(fs->np >= Maxproto) 
1998/0313    
	if(f->np >= Maxproto) 
1997/0327    
		return -1; 
 
1998/0313    
	p->f = f; 
 
1997/0327    
	if(p->ipproto > 0){ 
		if(fs->t2p[p->ipproto] != nil) 
1998/0313    
		if(f->t2p[p->ipproto] != nil) 
1997/0327    
			return -1; 
		fs->t2p[p->ipproto] = p; 
1998/0313    
		f->t2p[p->ipproto] = p; 
1997/0327    
	} 
 
	p->qid.path = CHDIR|QID(fs->np, 0, Qprotodir); 
1998/0313    
	p->qid.path = CHDIR|QID(f->np, 0, Qprotodir); 
1997/0327    
	p->conv = malloc(sizeof(Conv*)*(p->nc+1)); 
	if(p->conv == nil) 
		panic("Fsproto"); 
 
	p->x = fs->np; 
1998/0313    
	p->x = f->np; 
1997/0327    
	p->nextport = 0; 
	p->nextrport = 600; 
	fs->p[fs->np++] = p; 
1998/0313    
	f->p[f->np++] = p; 
 
1997/0327    
	return 0; 
} 
 
1998/0310/sys/src/9/ip/devip.c:915,9231998/0313/sys/src/9/ip/devip.c:980,988
1997/0327    
 *  built in 
 */ 
int 
1998/0306    
Fsbuiltinproto(Fs* fs, uchar proto) 
1998/0313    
Fsbuiltinproto(Fs* f, uchar proto) 
1997/0327    
{ 
	return fs->t2p[proto] != nil; 
1998/0313    
	return f->t2p[proto] != nil; 
1997/0327    
} 
 
Conv* 
1998/0310/sys/src/9/ip/devip.c:990,9961998/0313/sys/src/9/ip/devip.c:1055,1061
1997/0327    
} 
 
int 
Fsconnected(Fs*, Conv* c, char* msg) 
1998/0313    
Fsconnected(Conv* c, char* msg) 
1997/0327    
{ 
	if(msg != nil && *msg != '\0') 
		strncpy(c->cerr, msg, ERRLEN-1); 
1998/0310/sys/src/9/ip/devip.c:1011,10231998/0313/sys/src/9/ip/devip.c:1076,1088
1997/0327    
} 
 
Proto* 
1998/0306    
Fsrcvpcol(Fs* fs, uchar proto) 
1998/0313    
Fsrcvpcol(Fs* f, uchar proto) 
1997/0327    
{ 
	return fs->t2p[proto]; 
1998/0313    
	return f->t2p[proto]; 
1997/0327    
} 
 
Conv* 
1998/0306    
Fsnewcall(Fs*, Conv *c, uchar *raddr, ushort rport, uchar *laddr, ushort lport) 
1998/0313    
Fsnewcall(Conv *c, uchar *raddr, ushort rport, uchar *laddr, ushort lport) 
1997/0327    
{ 
	Conv *nc; 
	Conv **l; 
1998/0313/sys/src/9/ip/devip.c:509,5151998/0319/sys/src/9/ip/devip.c:509,515 (short | long)
Change dev read and write to use vlong offset.
rsc Fri Mar 4 12:44:25 2005
1998/0306    
}; 
 
1997/0327    
static long 
ipread(Chan *ch, void *a, long n, ulong offset) 
1998/0319    
ipread(Chan *ch, void *a, long n, vlong off) 
1997/0327    
{ 
	Conv *c; 
	Proto *x; 
1998/0313/sys/src/9/ip/devip.c:516,5211998/0319/sys/src/9/ip/devip.c:516,522
1998/0306    
	char *buf, *p; 
	long m, rv; 
1998/0313    
	Fs *f; 
1998/0319    
	ulong offset = off; 
1997/0327    
 
1998/0313    
	f = ipfs[ch->dev]; 
 
1998/0313/sys/src/9/ip/devip.c:839,8451998/0319/sys/src/9/ip/devip.c:840,846
1998/0306    
} 
 
1997/0327    
static long 
ipwrite(Chan* ch, char* a, long n, ulong) 
1998/0319    
ipwrite(Chan* ch, char* a, long n, vlong) 
1997/0327    
{ 
	Conv *c; 
	Proto *x; 
1998/0319/sys/src/9/ip/devip.c:467,4721998/0321/sys/src/9/ip/devip.c:467,473 (short | long)
Bug fix?: zero cv->incall on close.
rsc Fri Mar 4 12:44:25 2005
1997/0327    
		cv->incall = nc->next; 
		closeconv(nc); 
	} 
1998/0321    
	cv->incall = nil; 
1997/0327    
 
	strcpy(cv->owner, network); 
	cv->perm = 0660; 
1998/0321/sys/src/9/ip/devip.c:1080,10861998/0324/sys/src/9/ip/devip.c:1080,1089 (short | long)
Let Fsrcvpcol defer to f->ipmux.
rsc Fri Mar 4 12:44:25 2005
1997/0327    
Proto* 
1998/0313    
Fsrcvpcol(Fs* f, uchar proto) 
1997/0327    
{ 
1998/0313    
	return f->t2p[proto]; 
1998/0324    
	if(f->t2m[proto] && f->ipmux) 
		return f->ipmux; 
	else 
		return f->t2p[proto]; 
1997/0327    
} 
 
Conv* 
1998/0324/sys/src/9/ip/devip.c:1080,10861998/0327/sys/src/9/ip/devip.c:1080,1086 (short | long)
Defer to f->ipmux even wehn f->t2m[proto] isn't there. Bug fix? XXX
rsc Fri Mar 4 12:44:25 2005
1997/0327    
Proto* 
1998/0313    
Fsrcvpcol(Fs* f, uchar proto) 
1997/0327    
{ 
1998/0324    
	if(f->t2m[proto] && f->ipmux) 
1998/0327    
	if(f->ipmux) 
1998/0324    
		return f->ipmux; 
	else 
		return f->t2p[proto]; 
1998/0327/sys/src/9/ip/devip.c:54,591998/0423/sys/src/9/ip/devip.c:54,62 (short | long)
Call nullmediumlink and pktmediumlink so they can register with addipmedium.
rsc Fri Mar 4 12:44:25 2005
1998/0313    
Fs	*ipfs[Nfs];	/* attached fs's */ 
Queue	*qlog; 
 
1998/0423    
extern void nullmediumlink(void); 
extern void pktmediumlink(void); 
 
1997/0327    
static int 
ip3gen(Chan *c, int i, Dir *dp) 
{ 
1998/0327/sys/src/9/ip/devip.c:215,2201998/0423/sys/src/9/ip/devip.c:218,225
1997/0327    
static void 
ipreset(void) 
{ 
1998/0423    
	nullmediumlink(); 
	pktmediumlink(); 
1997/0327    
} 
 
static void 
1998/0423/sys/src/9/ip/devip.c:852,8581998/0502/sys/src/9/ip/devip.c:852,858 (short | long)
Add optional multicast address argument to addmulti control message.
rsc Fri Mar 4 12:44:25 2005
1997/0327    
	Proto *x; 
1998/0306    
	char *p; 
	Cmdbuf *cb; 
	uchar ia[IPaddrlen]; 
1998/0502    
	uchar ia[IPaddrlen], ma[IPaddrlen]; 
1998/0313    
	Fs *f; 
1997/0327    
 
1998/0313    
	f = ipfs[ch->dev]; 
1998/0423/sys/src/9/ip/devip.c:904,9131998/0502/sys/src/9/ip/devip.c:904,921
1998/0306    
		else if(strcmp(cb->f[0], "addmulti") == 0){ 
			if(cb->nf < 2) 
				error("addmulti needs interface address"); 
			if(!ipismulticast(c->raddr)) 
				error("addmulti for a non multicast address"); 
			parseip(ia, cb->f[1]); 
			ipifcaddmulti(c, c->raddr, ia); 
1998/0502    
			if(cb->nf == 2){ 
				if(!ipismulticast(c->raddr)) 
					error("addmulti for a non multicast address"); 
				parseip(ia, cb->f[1]); 
				ipifcaddmulti(c, c->raddr, ia); 
			} else { 
				parseip(ma, cb->f[2]); 
				if(!ipismulticast(ma)) 
					error("addmulti for a non multicast address"); 
				parseip(ia, cb->f[1]); 
				ipifcaddmulti(c, ma, ia); 
			} 
1998/0306    
		} else if(strcmp(cb->f[0], "remmulti") == 0){ 
			if(cb->nf < 2) 
				error("remmulti needs interface address"); 
1998/0502/sys/src/9/ip/devip.c:1099,11041998/0509/sys/src/9/ip/devip.c:1099,1110 (short | long)
Add Fsrcvpcolx, which is Fsrcvpcol but ignores f->ipmux.
rsc Fri Mar 4 12:44:25 2005
1998/0324    
		return f->t2p[proto]; 
1997/0327    
} 
 
1998/0509    
Proto* 
Fsrcvpcolx(Fs *f, uchar proto) 
{ 
	return f->t2p[proto]; 
} 
 
1997/0327    
Conv* 
1998/0313    
Fsnewcall(Conv *c, uchar *raddr, ushort rport, uchar *laddr, ushort lport) 
1997/0327    
{ 
1998/0509/sys/src/9/ip/devip.c:871,8771998/0630/sys/src/9/ip/devip.c:871,877 (short | long)
1998/0306    
		x->kick(c, n); 
		break; 
1997/0327    
	case Qarp: 
1998/0313    
		return arpwrite(f->arp, a, n); 
1998/0630    
		return arpwrite(f, a, n); 
1997/0327    
	case Qiproute: 
1998/0313    
		return routewrite(f, ch, a, n); 
1997/0327    
	case Qlog: 
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)