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

1998/0313/ip/ethermedium.c (diff list | history)

1998/0307/sys/src/9/ip/ethermedium.c:22,281998/0313/sys/src/9/ip/ethermedium.c:22,28 (short | long | prev | next)
1998/0306    
static void	etherbwrite(Ipifc *ifc, Block *bp, int version, uchar *ip); 
static void	etheraddmulti(Ipifc *ifc, uchar *a, uchar *ia); 
static void	etherremmulti(Ipifc *ifc, uchar *a, uchar *ia); 
static Block*	multicastarp(Arpent *a, uchar *mac); 
1998/0313    
static Block*	multicastarp(Fs *f, Arpent *a, uchar *mac); 
1998/0306    
static void	sendarp(Ipifc *ifc, Arpent *a); 
static int	multicastea(uchar *ea, uchar *ip); 
static void	recvarpproc(Ipifc *ifc); 
1998/0307/sys/src/9/ip/ethermedium.c:51,561998/0313/sys/src/9/ip/ethermedium.c:51,57
1998/0306    
typedef struct	Etherrock Etherrock; 
struct Etherrock 
{ 
1998/0313    
	Fs	*f;		/* file system we belong to */ 
1998/0306    
	Proc	*arpp;		/* arp process */ 
	Proc	*readp;		/* reading process */ 
	Chan	*mchan;		/* Data channel */ 
1998/0307/sys/src/9/ip/ethermedium.c:128,1351998/0313/sys/src/9/ip/ethermedium.c:129,136
1998/0306    
	fd = kdial(addr, nil, dir, &cfd); 
	if(fd < 0) 
		error("dial 0x800 failed"); 
	mchan = fdtochan(fd, ORDWR, 0, 1); 
	cchan = fdtochan(cfd, ORDWR, 0, 1); 
1998/0313    
	mchan = commonfdtochan(fd, ORDWR, 0, 1); 
	cchan = commonfdtochan(cfd, ORDWR, 0, 1); 
1998/0306    
	kclose(fd); 
	kclose(cfd); 
 
1998/0307/sys/src/9/ip/ethermedium.c:162,1681998/0313/sys/src/9/ip/ethermedium.c:163,169
1998/0306    
	fd = kdial(addr, nil, nil, nil); 
	if(fd < 0) 
		error("dial 0x806 failed"); 
	achan = fdtochan(fd, ORDWR, 0, 1); 
1998/0313    
	achan = commonfdtochan(fd, ORDWR, 0, 1); 
1998/0306    
	kclose(fd); 
 
	er = smalloc(sizeof(*er)); 
1998/0307/sys/src/9/ip/ethermedium.c:169,1741998/0313/sys/src/9/ip/ethermedium.c:170,176
1998/0306    
	er->mchan = mchan; 
	er->cchan = cchan; 
	er->achan = achan; 
1998/0313    
	er->f = ifc->conv->p->f; 
1998/0306    
	ifc->arg = er; 
 
	free(buf); 
1998/0307/sys/src/9/ip/ethermedium.c:217,2261998/0313/sys/src/9/ip/ethermedium.c:219,228
1998/0306    
	Etherrock *er = ifc->arg; 
 
	/* get mac address of destination */ 
	a = arpget(bp, version, ðermedium, ip, mac); 
1998/0313    
	a = arpget(er->f->arp, bp, version, ðermedium, ip, mac); 
1998/0306    
	if(a){ 
		/* check for broadcast or multicast */ 
		bp = multicastarp(a, mac); 
1998/0313    
		bp = multicastarp(er->f, a, mac); 
1998/0306    
		if(bp == nil){ 
			sendarp(ifc, a); 
1998/0307    
			return; 
1998/0307/sys/src/9/ip/ethermedium.c:281,2871998/0313/sys/src/9/ip/ethermedium.c:283,289
1998/0306    
		if(ifc->lifc == nil) 
			freeb(bp); 
		else 
			ipiput(ifc->lifc->local, bp); 
1998/0313    
			ipiput(er->f, ifc->lifc->local, bp); 
1998/0307    
		runlock(ifc);	locked = 0;	USED(locked); 
 
1998/0306    
	} 
1998/0307/sys/src/9/ip/ethermedium.c:325,3311998/0313/sys/src/9/ip/ethermedium.c:327,333
1998/0306    
 
	/* don't do anything if it's been less than a second since the last */ 
	if(msec - a->time < 1000){ 
		arprelease(a); 
1998/0313    
		arprelease(er->f->arp, a); 
1998/0306    
		return; 
	} 
 
1998/0307/sys/src/9/ip/ethermedium.c:339,3451998/0313/sys/src/9/ip/ethermedium.c:341,347
1998/0306    
 
	/* try to keep it around for a second more */ 
	a->time = msec; 
	arprelease(a); 
1998/0313    
	arprelease(er->f->arp, a); 
1998/0306    
 
	n = sizeof(Etherarp); 
	if(n < a->type->minmtu) 
1998/0307/sys/src/9/ip/ethermedium.c:387,3931998/0313/sys/src/9/ip/ethermedium.c:389,395
1998/0306    
		break; 
 
	case ARPREPLY: 
		arpenter(ifc, V4, e->spa, e->sha, ðermedium, 0); 
1998/0313    
		arpenter(er->f->arp, ifc, V4, e->spa, e->sha, ðermedium, 0); 
1998/0306    
		break; 
 
	case ARPREQUEST: 
1998/0307/sys/src/9/ip/ethermedium.c:408,4191998/0313/sys/src/9/ip/ethermedium.c:410,421
1998/0306    
		} 
 
		/* refresh what we know about sender */ 
		arpenter(ifc, V4, e->spa, e->sha, ðermedium, 1); 
1998/0313    
		arpenter(er->f->arp, ifc, V4, e->spa, e->sha, ðermedium, 1); 
1998/0306    
 
		/* answer only requests for our address or systems we're proxying for */ 
		v4tov6(ip, e->tpa); 
		if(!iplocalonifc(ifc, ip)) 
		if(ipproxyifc(ifc, ip) == 0) 
1998/0313    
		if(ipproxyifc(er->f, ifc, ip) == 0) 
1998/0306    
			break; 
 
/* print("arp: rem %I %E (for %I)\n", e->spa, e->sha, e->tpa); /**/ 
1998/0307/sys/src/9/ip/ethermedium.c:490,5041998/0313/sys/src/9/ip/ethermedium.c:492,506
1998/0306    
 *  addresses 
 */ 
static Block* 
multicastarp(Arpent *a, uchar *mac) 
1998/0313    
multicastarp(Fs *f, Arpent *a, uchar *mac) 
1998/0306    
{ 
	/* is it broadcast? */ 
	switch(ipforme(a->ip)){ 
1998/0313    
	switch(ipforme(f, a->ip)){ 
1998/0306    
	case Runi: 
		return nil; 
	case Rbcast: 
		memset(mac, 0xff, 6); 
		return arpresolve(a, ðermedium, mac); 
1998/0313    
		return arpresolve(f->arp, a, ðermedium, mac); 
1998/0306    
	default: 
		break; 
	} 
1998/0307/sys/src/9/ip/ethermedium.c:507,5131998/0313/sys/src/9/ip/ethermedium.c:509,515
1998/0306    
	switch(multicastea(mac, a->ip)){ 
	case V4: 
	case V6: 
		return arpresolve(a, ðermedium, mac); 
1998/0313    
		return arpresolve(f->arp, a, ðermedium, mac); 
1998/0306    
	} 
 
	/* let arp take care of it */ 


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