Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/ip/arp.c

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


## diffname ip/arp.c 1998/0306
## diff -e /dev/null /n/emeliedump/1998/0306/sys/src/brazil/ip/arp.c
0a
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "../port/error.h"

#include "ip.h"

/*
 *  address resolution tables
 */

enum
{
	NHASH		= (1<<6),
	NCACHE		= 256,

	AOK		= 1,
	AWAIT		= 2,
};

char *arpstate[] =
{
	"UNUSED",
	"OK",
	"WAIT",
};

typedef struct Arpcache Arpcache;
struct Arpcache
{
	QLock;
	Arpent*	hash[NHASH];
	Arpent	cache[NCACHE];
};

Arpcache	arp;

char *Ebadarp = "bad arp";

#define haship(s) ((s)[IPaddrlen-1]%NHASH)

static Arpent*
newarp(uchar *ip, Medium *m)
{
	uint t;
	Block *next, *xp;
	Arpent *a, *e, *f, **l;

	/* find oldest entry */
	e = &arp.cache[NCACHE];
	a = arp.cache;
	t = a->used;
	for(f = a; f < e; f++){
		if(f->used < t){
			t = f->used;
			a = f;
		}
	}

	/* dump waiting packets */
	xp = a->hold;
	a->hold = nil;
	while(xp){
		next = xp->list;
		freeblist(xp);
		xp = next;
	}

	/* take out of current chain */
	l = &arp.hash[haship(a->ip)];
	for(f = *l; f; f = f->hash){
		if(f == a) {
			*l = a->hash;
			break;
		}
		l = &f->hash;
	}

	/* insert into new chain */
	l = &arp.hash[haship(ip)];
	a->hash = *l;
	*l = a;
	memmove(a->ip, ip, sizeof(a->ip));
	a->used = msec;
	a->time = 0;
	a->type = m;

	return a;
}

Arpent*
arpget(Block *bp, int version, Medium *type, uchar *ip, uchar *mac)
{
	int hash;
	Arpent *a;
	uchar v6ip[IPaddrlen];

	if(version == V4) {
		v4tov6(v6ip, ip);
		ip = v6ip;
	}

	qlock(&arp);
	hash = haship(ip);
	for(a = arp.hash[hash]; a; a = a->hash) {
		if(memcmp(ip, a->ip, sizeof(a->ip)) == 0)
		if(type == a->type)
			break;
	}

	if(a == nil){
		a = newarp(ip, type);
		a->state = AWAIT;
	}
	a->used = msec;
	if(a->state == AWAIT){
		if(a->hold)
			a->last->list = bp;
		else
			a->hold = bp;
		a->last = bp;
		bp->list = nil; 
		return a;		/* return with arp qlocked */
	}

	memmove(mac, a->mac, a->type->maclen);
	qunlock(&arp);
	return nil;
}

/*
 * called with arp locked
 */
void
arprelease(Arpent*)
{
	qunlock(&arp);
}

/*
 * called with arp locked
 */
Block*
arpresolve(Arpent *a, Medium *type, uchar *mac)
{
	Block *bp;

	memmove(a->mac, mac, type->maclen);
	a->type = type;
	a->state = AOK;
	a->used = msec;
	bp = a->hold;
	a->hold = nil;
	qunlock(&arp);

	return bp;
}

void
arpenter(Ipifc *ifc, int version, uchar *ip, uchar *mac, Medium *type, int refresh)
{
	Arpent *a;
	Block *bp, *next;
	uchar v6ip[IPaddrlen];

	if(version == V4){
		v4tov6(v6ip, ip);
		ip = v6ip;
	}

	qlock(&arp);
	for(a = arp.hash[haship(ip)]; a; a = a->hash) {
		if(a->type != type || (a->state != AWAIT && a->state != AOK))
			continue;

		if(ipcmp(a->ip, ip) == 0) {
			a->state = AOK;
			memmove(a->mac, mac, type->maclen);
			bp = a->hold;
			a->hold = nil;
			if(version == V4)
				ip += IPv4off;
			qunlock(&arp);
			while(bp) {
				next = bp->list;
				if(ifc != nil){
					if(waserror()){
						runlock(ifc);
						nexterror();
					}
					rlock(ifc);
					if(ifc->m != nil)
						ifc->m->bwrite(ifc, bp, version, ip);
					else
						freeb(bp);
					runlock(ifc);
					poperror();
				} else
					freeb(bp);
				bp = next;
			}
			a->used = msec;
			return;
		}
	}

	/* if nil, we're adding a new entry */
	if(refresh == 0){
		a = newarp(ip, type);
		a->state = AOK;
		a->type = type;
		memmove(a->mac, mac, type->maclen);
	}

	qunlock(&arp);
}

int
arpwrite(char *s, int len)
{
	int n;
	Block *bp;
	Arpent *a;
	char *f[4], buf[256];
	uchar ip[], mac[MAClen];
	Medium *m;

	if(len == 0)
		error(Ebadarp);
	if(len >= sizeof(buf))
		len = sizeof(buf)-1;
	strncpy(buf, s, len);
	buf[len] = 0;
	if(len > 0 && buf[len-1] == '\n')
		buf[len-1] = 0;

	n = parsefields(buf, f, 4, " ");
	if(strcmp(f[0], "flush") == 0){
		qlock(&arp);
		for(a = arp.cache; a < &arp.cache[NCACHE]; a++){
			memset(a->ip, 0, sizeof(a->ip));
			memset(a->mac, 0, sizeof(a->mac));
			a->hash = nil;
			a->state = 0;
			a->used = 0;
			while(a->hold != nil) {
				bp = a->hold->list;
				freeblist(a->hold);
				a->hold = bp;
			}
		}
		memset(arp.hash, 0, sizeof(arp.hash));
		qunlock(&arp);
	} else if(strcmp(f[0], "add") == 0){
		if(n != 4)
			error(Ebadarp);
		m = ipfindmedium(f[1]);
		if(m == nil)
			error(Ebadarp);
		parseip(ip, f[2]);
		parsemac(mac, f[3], m->maclen);
		arpenter(nil, V6, ip, mac, m, 0);
	} else
		error(Ebadarp);

	return len;
}

enum
{
	Alinelen=	66,
};

char *aformat = "%-6.6s %-8.8s %-16.16I %-32.32s\n";

static void
convmac(char *p, uchar *mac, int n)
{
	while(n-- > 0)
		p += sprint(p, "%2.2ux", *mac++);
}

int
arpread(char *p, ulong offset, int len)
{
	Arpent *a;
	int n;
	char mac[2*MAClen+1];

	if(offset % Alinelen)
		return 0;

	offset = offset/Alinelen;
	len = len/Alinelen;

	n = 0;
	for(a = arp.cache; len > 0 && a < &arp.cache[NCACHE]; a++){
		if(a->state == 0)
			continue;
		if(offset > 0){
			offset--;
			continue;
		}
		len--;
		qlock(&arp);
		convmac(mac, a->mac, a->type->maclen);
		n += sprint(p+n, aformat, a->type->name, arpstate[a->state], a->ip, mac);
		qunlock(&arp);
	}

	return n;
}
.
## diffname ip/arp.c 1998/0313
## diff -e /n/emeliedump/1998/0306/sys/src/brazil/ip/arp.c /n/emeliedump/1998/0313/sys/src/brazil/ip/arp.c
310c
		qunlock(arp);
.
307c
		qlock(arp);
.
299c
	for(a = arp->cache; len > 0 && a < &arp->cache[NCACHE]; a++){
.
286c
arpread(Arp *arp, char *p, ulong offset, int len)
.
264c
		arpenter(arp, nil, V6, ip, mac, m, 0);
.
254,255c
		memset(arp->hash, 0, sizeof(arp->hash));
		qunlock(arp);
.
241,242c
		qlock(arp);
		for(a = arp->cache; a < &arp->cache[NCACHE]; a++){
.
221c
arpwrite(Arp *arp, char *s, int len)
.
217c
	qunlock(arp);
.
211c
		a = newarp(arp, ip, type);
.
209d
185c
			qunlock(arp);
.
173,174c
	qlock(arp);
	for(a = arp->hash[haship(ip)]; a; a = a->hash) {
.
162c
arpenter(Arp *arp, Ipifc *ifc, int version, uchar *ip, uchar *mac, Medium *type, int refresh)
.
156c
	qunlock(arp);
.
146c
arpresolve(Arp *arp, Arpent *a, Medium *type, uchar *mac)
.
139c
	qunlock(arp);
.
137c
arprelease(Arp *arp, Arpent*)
.
129c
	qunlock(arp);
.
114c
		a = newarp(arp, ip, type);
.
107c
	for(a = arp->hash[hash]; a; a = a->hash) {
.
105c
	qlock(arp);
.
94c
arpget(Arp *arp, Block *bp, int version, Medium *type, uchar *ip, uchar *mac)
.
82c
	l = &arp->hash[haship(ip)];
.
72c
	l = &arp->hash[haship(a->ip)];
.
52,53c
	e = &arp->cache[NCACHE];
	a = arp->cache;
.
45c
newarp(Arp *arp, uchar *ip, Medium *m)
.
43a
void
arpinit(Fs *f)
{
	f->arp = smalloc(sizeof(Arp));
	f->arp->f = f;
}

.
38,39d
34c
	Fs	*f;
	Arpent	*hash[NHASH];
.
30,31c
/*
 *  one per Fs
 */
struct Arp
.
## diffname ip/arp.c 1998/0320
## diff -e /n/emeliedump/1998/0313/sys/src/brazil/ip/arp.c /n/emeliedump/1998/0320/sys/src/brazil/ip/arp.c
234c
	uchar ip[IPaddrlen], mac[MAClen];
.
## diffname ip/arp.c 1998/0630
## diff -e /n/emeliedump/1998/0320/sys/src/brazil/ip/arp.c /n/emeliedump/1998/0630/sys/src/brazil/ip/arp.c
266,271c

		m->ares(fs, V6, ip, mac, n, 0);
.
263,264c
	} else if(strcmp(f[0], "add") == 0) {
		switch(n) {
		default:
			error(Ebadarg);
		case 3:
			parseip(ip, f[1]);
			r = v4lookup(fs, ip+IPv4off);
			if(r == nil)
				error("Destination unreachable");
			m = r->ifc->m;
			n = parsemac(mac, f[2], m->maclen);
			break;
		case 4:
			m = ipfindmedium(f[1]);
			if(m == nil)
				error(Ebadarp);
			parseip(ip, f[2]);
			n = parsemac(mac, f[3], m->maclen);
			break;
		}

		if(m->ares == nil)
.
236a
	arp = fs->arp;

.
235d
232a
	Medium *m;
.
230a
	Route *r;
	Arp *arp;
.
228c
arpwrite(Fs *fs, char *s, int len)
.
180a
	if(r == nil) {
		print("arp: no route for entry\n");
		return;
	}

	ifc = r->ifc;
	type = ifc->m;

.
179a
	else
		r = v6lookup(fs, ip);
.
176c
	arp = fs->arp;

	if(n != 6) {
print("arp: len = %d\n", n);
		return;
	}

	if(version == V4) {
		r = v4lookup(fs, ip);
.
172a
	Ipifc *ifc;
	Medium *type;
.
171a
	Arp *arp;
	Route *r;
.
170c
arpenter(Fs *fs, int version, uchar *ip, uchar *mac, int n, int refresh)
.
## diffname ip/arp.c 1999/0731
## diff -e /n/emeliedump/1998/0630/sys/src/brazil/ip/arp.c /n/emeliedump/1999/0731/sys/src/brazil/ip/arp.c
127,132c
		if(bp != nil){
			if(a->hold)
				a->last->list = bp;
			else
				a->hold = bp;
			a->last = bp;
			bp->list = nil; 
		}
.
## diffname ip/arp.c 2000/0212
## diff -e /n/emeliedump/1999/0731/sys/src/brazil/ip/arp.c /n/emeliedump/2000/0212/sys/src/9/ip/arp.c
198c
//		print("arp: no route for entry\n");
.
## diffname ip/arp.c 2000/0225
## diff -e /n/emeliedump/2000/0212/sys/src/9/ip/arp.c /n/emeliedump/2000/0225/sys/src/9/ip/arp.c
185c
//		print("arp: len = %d\n", n);
.
## diffname ip/arp.c 2000/0308
## diff -e /n/emeliedump/2000/0225/sys/src/9/ip/arp.c /n/emeliedump/2000/0308/sys/src/9/ip/arp.c
274c
	n = getfields(buf, f, 4, 1, " ");
.
## diffname ip/arp.c 2001/1117
## diff -e /n/emeliedump/2000/0308/sys/src/9/ip/arp.c /n/emeliedump/2001/1117/sys/src/9/ip/arp.c
274c
	n = tokenize(buf, f, 4);
.
## diffname ip/arp.c 2001/1120
## diff -e /n/emeliedump/2001/1117/sys/src/9/ip/arp.c /n/emeliedump/2001/1120/sys/src/9/ip/arp.c
318a
	case CMflush:
		qlock(arp);
		for(a = arp->cache; a < &arp->cache[NCACHE]; a++){
			memset(a->ip, 0, sizeof(a->ip));
			memset(a->mac, 0, sizeof(a->mac));
			a->hash = nil;
			a->state = 0;
			a->used = 0;
			while(a->hold != nil) {
				bp = a->hold->list;
				freeblist(a->hold);
				a->hold = bp;
			}
		}
		memset(arp->hash, 0, sizeof(arp->hash));
		qunlock(arp);
		break;
	}

	poperror();
	free(cb);
.
316,317c
		break;
.
307,308c
			parseip(ip, cb->f[2]);
			n = parsemac(mac, cb->f[3], m->maclen);
.
304c
			m = ipfindmedium(cb->f[1]);
.
301c
			n = parsemac(mac, cb->f[2], m->maclen);
.
299c
				error("destination unreachable");
.
296c
			parseip(ip, cb->f[1]);
.
294c
			cmderror(cb, Ecmdargs);
.
274,292c
	ct = lookupcmd(cb, arpcmd, nelem(arpcmd));

	switch(ct->index){
	case CMadd:
		switch(cb->nf) {
.
265,272c
	cb = parsecmd(s, len);
	if(waserror()){
		free(cb);
		nexterror();
	}
.
260d
258a
	Cmdbuf *cb;
	Cmdtab *ct;
.
40a
static
Cmdtab arpcmd[] =
{
	CMadd,	"add",	0,
	CMflush,	"flush",	1,
};

.
29a
enum
{
	CMadd,
	CMflush,
};

.
## diffname ip/arp.c 2002/0507
## diff -e /n/emeliedump/2001/1120/sys/src/9/ip/arp.c /n/emeliedump/2002/0507/sys/src/9/ip/arp.c
382a

extern int
rxmitsols(Arp *arp)
{
	uint sflag;
	Block *next, *xp;
	Arpent *a, *b, **l;
	Fs *f;
	uchar ipsrc[IPaddrlen];
	Ipifc *ifc = nil;
	long nrxt;

	qlock(arp);
	f = arp->f;

	a = arp->rxmt;
	if(a==nil){
		nrxt = 0;
		goto dodrops; 		//return nrxt;
	}
	nrxt = a->rxtat - msec;
	if(nrxt > 3*ReTransTimer/4) 
		goto dodrops; 		//return nrxt;

	for(; a; a = a->nextrxt){
		ifc = a->ifc;
		assert(ifc != nil);
		if((a->rxtsrem <= 0) || !(canrlock(ifc)) || (a->ifcid != ifc->ifcid)){
			xp = a->hold;
			a->hold = nil;

			if(xp){
				if(arp->dropl == nil) 
					arp->dropf = xp;
				else
					arp->dropl->list = xp;
			}

			cleanarpent(arp, a);
		}
		else
			break;
	}

	 /* need to unlock arp, else will deadlock when icmpns 
	  * wants to lock arp later.
	  */
	
	qunlock(arp);

	if(a == nil) 
		goto dodrops; 		// return 0;

	if(sflag = ipv6anylocal(ifc, ipsrc)) 
		icmpns(f, ipsrc, sflag, a->ip, TARG_MULTI, ifc->mac); 

	runlock(ifc);

	/* grab lock on arp again */

	qlock(arp);	

	/* put to the end of re-transmit chain */
	l = &arp->rxmt;
	for(b = *l; b; b = b->nextrxt){
		if(b == a){
			*l = a->nextrxt;
			break;
		}
		l = &b->nextrxt;
	}
	for(b = *l; b; b = b->nextrxt){
		l = &b->nextrxt;
	}
	*l = a;
	a->rxtsrem--;
	a->nextrxt = nil;
	a->time = msec;
	a->rxtat = msec + ReTransTimer;

	a = arp->rxmt;
	if(a==nil)
		nrxt = 0;
	else 
		nrxt = a->rxtat - msec;

dodrops:
	xp = arp->dropf;
	arp->dropf = nil;
	arp->dropl = nil;
	qunlock(arp);

	for(; xp; xp = next){
		next = xp->list;
		icmphostunr(f, ifc, xp, icmp6_adr_unreach, 1);
	}

	return nrxt;

}

static int
rxready(void *v)
{
	Arp *arp = (Arp *) v;
	int x;

	x = ((arp->rxmt != nil) || (arp->dropf != nil));

	return x;
}

static void
rxmitproc(void *v)
{
	Arp *arp = v;
	long wakeupat;

	arp->rxmitp = up;
	print("arp rxmitproc started\n");
	if(waserror()){
		arp->rxmitp = 0;
		pexit("hangup", 1);
	}
	for(;;){
		wakeupat = rxmitsols(arp);
		if(wakeupat == 0) 
			sleep(&arp->rxmtq, rxready, v); 
		else if(wakeupat > ReTransTimer/4) 
			tsleep(&arp->rxmtq, return0, 0, wakeupat); 
	}
}

.
344c
char *aformat = "%-6.6s %-8.8s %-40.40I %-32.32s\n";
.
341c
	Alinelen=	90,
.
315,335d
313c
	} else
		error(Ebadarp);
.
304,305c
			parseip(ip, f[2]);
			n = parsemac(mac, f[3], m->maclen);
.
301c
			m = ipfindmedium(f[1]);
.
298c
			n = parsemac(mac, f[2], m->maclen);
.
296c
				error("Destination unreachable");
.
293,294c
			parseip(ip, f[1]);
			if(isv4(ip))
				r = v4lookup(fs, ip+IPv4off);
			else
				r = v6lookup(fs, ip);
.
291c
			error(Ebadarg);
.
285,289c
	n = getfields(buf, f, 4, 1, " ");
	if(strcmp(f[0], "flush") == 0){
		qlock(arp);
		for(a = arp->cache; a < &arp->cache[NCACHE]; a++){
			memset(a->ip, 0, sizeof(a->ip));
			memset(a->mac, 0, sizeof(a->mac));
			a->hash = nil;
			a->state = 0;
			a->used = 0;
			while(a->hold != nil){
				bp = a->hold->list;
				freeblist(a->hold);
				a->hold = bp;
			}
		}
		memset(arp->hash, 0, sizeof(arp->hash));
// clear all pkts on these lists (rxmt, dropf/l)
		arp->rxmt = nil;
		arp->dropf = nil;
		arp->dropl = nil;
		qunlock(arp);
	} else if(strcmp(f[0], "add") == 0){
		switch(n){
.
279,283c
	if(len == 0)
		error(Ebadarp);
	if(len >= sizeof(buf))
		len = sizeof(buf)-1;
	strncpy(buf, s, len);
	buf[len] = 0;
	if(len > 0 && buf[len-1] == '\n')
		buf[len-1] = 0;
.
274a
	char *f[4], buf[256];
.
272,273d
255c
		//a = newarp6(arp, ip, ifc, 0);
		if(version == 4)
			a = newarp(arp, ip, type);
		else 
			a = newarp6(arp, ip, ifc, 0);

.
231c
			while(bp){
.
225a

			if(version == V6){
				/* take out of re-transmit chain */
				l = &arp->rxmt;
				for(f = *l; f; f = f->nextrxt){
					if(f == a){
						*l = a->nextrxt;
						break;
					}
					l = &f->nextrxt;
				}
			}

			a->hold = nil;
			a->ifc = ifc;
			a->ifcid = ifc->ifcid;
.
223c
		if(ipcmp(a->ip, ip) == 0){
.
219c
	for(a = arp->hash[haship(ip)]; a; a = a->hash){
.
210c
	if(r == nil){
.
202c
	if(version == V4){
.
197c
	if(n != 6){
.
189c
	Arpent *a, *f, **l;
.
172a
	if(!isv4(a->ip)){
		l = &arp->rxmt;
		for(f = *l; f; f = f->nextrxt){
			if(f == a){
				*l = a->nextrxt;
				break;
			}
			l = &f->nextrxt;
		}
	}

.
171a
	Arpent *f, **l;
.
135c
		//a = newarp6(arp, ip, ifc, (version != V4));
		if(version == V4)
			a = newarp(arp, ip, type);
		else 
			a = newarp6(arp, ip, ifc, 1);
.
128c
	for(a = arp->hash[hash]; a; a = a->hash){
.
121c
	if(version == V4){
.
118a
	Medium *type = ifc->m;
.
115c
arpget(Arp *arp, Block *bp, int version, Ipifc *ifc, uchar *ip, uchar *mac)
.
113a
static Arpent*
newarp6(Arp *arp, uchar *ip, Ipifc *ifc, int addrxt)
{
	uint t;
	Block *next, *xp;
	Arpent *a, *e, *f, **l;
	Medium *m = ifc->m;
	int empty;

	/* find oldest entry */
	e = &arp->cache[NCACHE];
	a = arp->cache;
	t = a->used;
	for(f = a; f < e; f++){
		if(f->used < t){
			t = f->used;
			a = f;
		}
	}

	/* dump waiting packets */
	xp = a->hold;
	a->hold = nil;

	if(isv4(a->ip)){
		while(xp){
			next = xp->list;
			freeblist(xp);
			xp = next;
		}
	}
	else {	// queue icmp unreachable for rxmitproc later on, w/o arp lock
		if(xp){
			if(arp->dropl == nil) 
				arp->dropf = xp;
			else
				arp->dropl->list = xp;

			for(next = xp->list; next; next = next->list)
				xp = next;
			arp->dropl = xp;
			wakeup(&arp->rxmtq);
		}
	}

	/* take out of current chain */
	l = &arp->hash[haship(a->ip)];
	for(f = *l; f; f = f->hash){
		if(f == a){
			*l = a->hash;
			break;
		}
		l = &f->hash;
	}

	/* insert into new chain */
	l = &arp->hash[haship(ip)];
	a->hash = *l;
	*l = a;

	memmove(a->ip, ip, sizeof(a->ip));
	a->used = msec;
	a->time = 0;
	a->type = m;

	a->rxtat = msec + ReTransTimer;
	a->rxtsrem = MAX_MULTICAST_SOLICIT;
	a->ifc = ifc;
	a->ifcid = ifc->ifcid;

	/* put to the end of re-transmit chain; addrxt is 0 when isv4(a->ip) */
	if(!ipismulticast(a->ip) && addrxt){
		l = &arp->rxmt;
		empty = (*l==nil);

		for(f = *l; f; f = f->nextrxt){
			if(f == a){
				*l = a->nextrxt;
				break;
			}
			l = &f->nextrxt;
		}
		for(f = *l; f; f = f->nextrxt){
			l = &f->nextrxt;
		}
		*l = a;
		if(empty) 
			wakeup(&arp->rxmtq);
	}

	a->nextrxt = nil;

	return a;
}

/* called with arp qlocked */

void
cleanarpent(Arp *arp, Arpent *a)
{
	Arpent *f, **l;

	a->used = 0;
	a->time = 0;
	a->type = 0;
	a->state = 0;
	
	/* take out of current chain */
	l = &arp->hash[haship(a->ip)];
	for(f = *l; f; f = f->hash){
		if(f == a){
			*l = a->hash;
			break;
		}
		l = &f->hash;
	}

	/* take out of re-transmit chain */
	l = &arp->rxmt;
	for(f = *l; f; f = f->nextrxt){
		if(f == a){
			*l = a->nextrxt;
			break;
		}
		l = &f->nextrxt;
	}
	a->nextrxt = nil;
	a->hash = nil;
	a->hold = nil;
	a->last = nil;
	a->ifc = nil;
}

.
95c
		if(f == a){
.
85a

.
62a
	f->arp->rxmt = nil;
	f->arp->dropf = f->arp->dropl = nil;
	kproc("rxmitproc", rxmitproc, f->arp);
.
57a
extern int 	ReTransTimer = RETRANS_TIMER;
static void 	rxmitproc(void *v);

.
47,53d
44a
	Arpent	*rxmt;
	Proc	*rxmitp;	/* neib sol re-transmit proc */
	Rendez	rxmtq;
	Block 	*dropf, *dropl;
.
30,35d
8a
#include "ipv6.h"
.
## diffname ip/arp.c 2002/0601
## diff -e /n/emeliedump/2002/0507/sys/src/9/ip/arp.c /n/emeliedump/2002/0601/sys/src/9/ip/arp.c
675c
	//print("arp rxmitproc started\n");
.
420,425c
		a = newarp6(arp, ip, ifc, 0);
.
357a
		break;
	default:
		panic("arpenter: version %d", version);
		return;	/* to supress warnings */
	}
.
355,356c
		break;
	case V6:
.
351c
	switch(version){
	case V4:
.
302a
 * Copy out the mac address from the Arpent.  Return the
 * block waiting to get sent to this mac address.
 *
.
268,272c
		a = newarp6(arp, ip, ifc, (version != V4));
.
245a
/*
 *  fill in the media address if we have it.  Otherwise return an
 *  Arpent that represents the state of the address resolution FSM
 *  for ip.  Add the packet to be sent onto the list of packets
 *  waiting for ip->mac to be resolved.
 */
.
64,113d
62a
/*
 *  create a new arp entry for an ip address.
 */
.
## diffname ip/arp.c 2002/0710
## diff -e /n/emeliedump/2002/0601/sys/src/9/ip/arp.c /n/emeliedump/2002/0710/sys/src/9/ip/arp.c
599c
		nrxt = a->rxtat - NOW;
.
592,593c
	a->time = NOW;
	a->rxtat = NOW + ReTransTimer;
.
535c
	nrxt = a->rxtat - NOW;
.
378c
			a->used = NOW;
.
283c
	a->used = NOW;
.
230c
	a->used = NOW;
.
131c
	a->rxtat = NOW + ReTransTimer;
.
127c
	a->used = NOW;
.
## diffname ip/arp.c 2003/0308
## diff -e /n/emeliedump/2002/0710/sys/src/9/ip/arp.c /n/emeliedump/2003/0308/sys/src/9/ip/arp.c
446c
				r = v6lookup(fs, ip, nil);
.
444c
				r = v4lookup(fs, ip+IPv4off, nil);
.
316c
		r = v6lookup(fs, ip, nil);
.
311c
		r = v4lookup(fs, ip, nil);
.
## diffname ip/arp.c 2003/0310
## diff -e /n/emeliedump/2003/0308/sys/src/9/ip/arp.c /n/emeliedump/2003/0310/sys/src/9/ip/arp.c
599c
		nrxt = a->rtime - NOW;
.
592,593c
	a->rtime = NOW + ReTransTimer;
.
535c
	nrxt = a->rtime - NOW;
.
424c
			a->utime = 0;
.
378c
			a->utime = NOW;
			a->ctime = a->utime;
.
283c
	a->utime = NOW;
.
243a

	/* remove old entries */
	if(NOW - a->ctime > 15*60*1000)
		cleanarpent(arp, a);

.
230c
	a->utime = NOW;
.
168,169c
	a->utime = 0;
	a->ctime = 0;
.
131c
	a->rtime = NOW + ReTransTimer;
.
127,128c
	a->utime = NOW;
	a->ctime = a->utime;
.
80,81c
		if(f->utime < t){
			t = f->utime;
.
78c
	t = a->utime;
.
## diffname ip/arp.c 2003/0313
## diff -e /n/emeliedump/2003/0310/sys/src/9/ip/arp.c /n/emeliedump/2003/0313/sys/src/9/ip/arp.c
392a
		a->ctime = NOW;
.
## diffname ip/arp.c 2003/0318
## diff -e /n/emeliedump/2003/0313/sys/src/9/ip/arp.c /n/emeliedump/2003/0318/sys/src/9/ip/arp.c
383,384d
364a

.
363a
			a->utime = NOW;
			a->ctime = a->utime;
.
357d
128c
	a->ctime = 0;
.

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

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