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

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


## diffname port/devarp.c 1991/0424
## diff -e /dev/null /n/bootesdump/1991/0424/sys/src/9/port/devarp.c
0a
#include	"u.h"
#include	"lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"errno.h"
#include	"arp.h"
#include 	"ipdat.h"

#include	"devtab.h"

Arpcache 	*arp;
Arpcache	**arphash;
Arpstats	arpstats;
Queue		*Servq;

#define ARP_ENTRYLEN	50
char *padstr = "                                           ";


extern Arpcache *arplruhead;
extern Arpcache *arplrutail;

enum{
	arpdirqid,
	arpstatqid,
	arpctlqid,
	arpdataqid,
};

Dirtab arptab[]={
	"stats",	{arpstatqid},		0,	0600,
	"ctl",		{arpctlqid},		0,	0600,
	"data",		{arpdataqid},		0,	0600,
};
#define Narptab (sizeof(arptab)/sizeof(Dirtab))

void
arpreset(void)
{
	Arpcache *ap, *ep;

	arp = (Arpcache *)ialloc(sizeof(Arpcache) * conf.arp, 0);
	arphash = (Arpcache **)ialloc(sizeof(Arpcache *) * Arphashsize, 0);

	ep = &arp[conf.arp];
	for(ap = arp; ap < ep; ap++) {
		ap->frwd = ap+1;
		ap->prev = ap-1;
		ap->type = ARP_FREE;
		ap->status = ARP_TEMP;
	}

	arp[0].prev = 0;
	arplruhead = arp;
	ap = &arp[conf.arp-1];
	ap->frwd = 0;
	arplrutail = ap;
}

void
arpinit(void)
{
}

Chan *
arpattach(char *spec)
{
	return devattach('a', spec);
}

Chan *
arpclone(Chan *c, Chan *nc)
{
	return devclone(c, nc);
}

int
arpwalk(Chan *c, char *name)
{
	return devwalk(c, name, arptab, (long)Narptab, devgen);
}

Chan*
arpclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

void
arpstat(Chan *c, char *db)
{
	devstat(c, db, arptab, (long)Narptab, devgen);
}

Chan *
arpopen(Chan *c, int omode)
{

	if(c->qid.path == CHDIR){
		if(omode != OREAD)
			error(Eperm);
	}

	switch(STREAMTYPE(c->qid.path)) {
	case arpdataqid:
		break;
	case arpstatqid:
		if(omode != OREAD)
			error(Ebadarg);
		break;
	case arpctlqid:
		break;
	}


	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	return c;
}

void
arpcreate(Chan *c, char *name, int omode, ulong perm)
{
	error(Eperm);
}

void
arpremove(Chan *c)
{
	error(Eperm);
}

void
arpwstat(Chan *c, char *dp)
{
	error(Eperm);
}

void
arpclose(Chan *c)
{
	streamclose(c);
}

long
arpread(Chan *c, void *a, long n, ulong offset)
{
	char	 buf[100];
	Arpcache *ap, *ep;
	int	 part, bytes, size;
	char	 *ptr, *ststr;

	switch((int)(c->qid.path&~CHDIR)){
	case arpdirqid:
		return devdirread(c, a, n, arptab, Narptab, devgen);
	case arpdataqid:
		bytes = c->offset;
		while(bytes < conf.arp*ARP_ENTRYLEN && n) {
			ap = &arp[bytes/ARP_ENTRYLEN];
			part = bytes%ARP_ENTRYLEN;

			if(ap->status != ARP_OK)
				ststr = "invalid";
			else
				ststr = (ap->type == ARP_TEMP ? "temp" : "perm");

			sprint(buf,"%d.%d.%d.%d to %.2x:%.2x:%.2x:%.2x:%.2x:%.2x %s%s",
				ap->eip[0], ap->eip[1], ap->eip[2], ap->eip[3],
				ap->et[0], ap->et[1], ap->et[2], ap->et[3],
				ap->et[4], ap->et[5],
				ststr, padstr); 
			
			buf[ARP_ENTRYLEN-1] = '\n';

			size = ARP_ENTRYLEN - part;
			size = MIN(n, size);
			memmove(a, buf+part, size);

			a = (void *)((int)a + size);
			n -= size;
			bytes += size;
		}
		return bytes - c->offset;
		break;
	case arpstatqid:
		sprint(buf, "hits: %d miss: %d failed: %d\n",
			arpstats.hit, arpstats.miss, arpstats.failed);

		return stringread(c, a, n, buf, offset);
	default:
		n=0;
		break;
	}
	return n;
}

long
arpwrite(Chan *c, char *a, long n, ulong offset)
{
	Arpentry entry;
	char	 buf[20], *field[5];
	int 	 m;

	switch(STREAMTYPE(c->qid.path)) {
	case arpctlqid:

		strncpy(buf, a, sizeof buf);
		m = getfields(buf, field, 5, ' ');

		if(strncmp(field[0], "flush", 5) == 0)
			arp_flush();
		else if(strcmp(field[0], "delete") == 0) {
			if(m != 2)
				error(Ebadarg);

			if(arp_delete(field[1]) < 0)
				error(Eaddrnotfound);
		}
	case arpdataqid:
		if(n != sizeof(Arpentry))
			error(Emsgsize);
		memmove(&entry, a, sizeof(Arpentry));
		arp_enter(&entry, ARP_TEMP);
		break;
	default:
		error(Ebadusefd);
	}

	return n;
}

.
## diffname port/devarp.c 1991/0427
## diff -e /n/bootesdump/1991/0424/sys/src/9/port/devarp.c /n/bootesdump/1991/0427/sys/src/9/port/devarp.c
84,89d
## diffname port/devarp.c 1991/1026
## diff -e /n/bootesdump/1991/0427/sys/src/9/port/devarp.c /n/bootesdump/1991/1026/sys/src/9/port/devarp.c
20d
## diffname port/devarp.c 1991/1027
## diff -e /n/bootesdump/1991/1026/sys/src/9/port/devarp.c /n/bootesdump/1991/1027/sys/src/9/port/devarp.c
226a

void
arpopn(Queue *q, Stream *s)
{
	if(!Servq)
		Servq = RD(q);
}

void
arpcls(Queue *q)
{
	if(q == Servq)
		Servq = 0;
}

void
arpiput(Queue *q, Block *bp)
{
	PUTNEXT(q, bp);
}

void
arpoput(Queue *q, Block *bp)
{
	PUTNEXT(q, bp);
}

int
arplookup(uchar *ip, uchar *et)
{
	Arpcache *ap;

	lock(&arpalloc.hash);
	for(ap = ARPHASH(ip); ap; ap = ap->hash) {
		if(ap->status == ARP_OK && memcmp(ap->eip, ip, sizeof(ap->eip)) == 0) {
			memmove(et, ap->et, sizeof(ap->et));
			arplinkhead(ap);
			unlock(&arpalloc.hash);
			arpstats.hit++;
			return 1;
		}
	}
	unlock(&arpalloc.hash);
	return 0;
}

void
arpsendpkt(uchar *unroutedip, uchar *ether, Queue *put, Block *bp)
{
	Arpq *aq;
	Block *nbp;
	uchar ip[4];

	if(!Servq) {
		print("arp: No server\n");
		freeb(bp);
		return;
	}

	iproute(unroutedip, ip);
	if(arplookup(ip, ether)) {
		PUTNEXT(put, bp);
		return;
	}

	/* Send the request out to the user level arp daemon */
	nbp = allocb(sizeof(ip));
	memmove(nbp->rptr, ip, sizeof(ip));
	nbp->wptr += sizeof(ip);
	nbp->flags |= S_DELIM;
	PUTNEXT(Servq, nbp);
	arpstats.miss++;

	lock(&arpalloc);
	if(aq = arpalloc.free)
		arpalloc.free = aq->next;
	unlock(&arpalloc);

	if(aq == 0) {
		freeb(bp);
		return;
	}

	/* Stash the work away until the arp completes or times out */
	memmove(aq->ip, ip, sizeof(aq->ip));
	aq->etheraddr = ether;
	aq->bp = bp;
	aq->put = put;
	aq->time = MACHP(0)->ticks;

	lock(&arpalloc.list);
	if(arpalloc.head)  {
		arpalloc.tail->next = aq;
		arpalloc.tail = aq;
	}
	else {
		arpalloc.tail = aq;
		arpalloc.head = aq;
	}
	aq->next = 0;
	unlock(&arpalloc.list);
}

void
arpflush(void)
{
	Arpcache *ap;

	for(ap = arplruhead; ap; ap = ap->frwd)
		ap->status = ARP_FREE;
}

void
arpenter(Arpentry *ape, int type)
{
	Arpcache *ap, **l, *d;


	/* Update an entry if we have one already */
	l = &ARPHASH(ape->ipaddr);
	lock(&arpalloc.hash);
	for(ap = *l; ap; ap = ap->hash) {
		if(ap->status == ARP_OK && memcmp(ap->eip, ape->ipaddr, sizeof(ap->eip)) == 0) {
			if(ap->type != ARP_PERM) {
				ap->type = type;
				memmove(ap->et, ape->etaddr, sizeof(ap->et));
				ap->status = ARP_OK;
			}
			unlock(&arpalloc.hash);
			return;
		}
	}

	/* Find an entry to replace */
	for(ap = arplrutail; ap && ap->type == ARP_PERM; ap = ap->prev)
		;

	if(!ap) {
		print("arp: too many permanent entries\n");
		unlock(&arpalloc.hash);
		return;
	}

	if(ap->hashhd) {
		for(d = *ap->hashhd; d; d = d->hash) {
			if(d == ap) {
				*(ap->hashhd) = ap->hash;
				break;
			}
			ap->hashhd = &d->hash;
		}
	}

	ap->type = type;
	ap->status = ARP_OK;
	memmove(ap->eip, ape->ipaddr, sizeof(ape->ipaddr));
	memmove(ap->et, ape->etaddr, sizeof(ape->etaddr));
	ap->ip = nhgetl(ap->eip);
	ap->hashhd = l;
	ap->hash = *l;
	*l = ap;
	arplinkhead(ap);
	unlock(&arpalloc.hash);
	pusharpq();
}

void
pusharpq(void)
{
	int sent;
	Arpq *aq, *prev;

loop:	prev = 0;
	lock(&arpalloc.list);
	for(aq = arpalloc.head; aq; aq = aq->next) {
		if(arplookup(aq->ip, aq->etheraddr)) {
			if(prev)
				prev->next = aq->next;
			else
				arpalloc.head = 0;
			if(aq->next == 0)
				arpalloc.tail = prev;
			unlock(&arpalloc.list);
			PUTNEXT(aq->put, aq->bp);

			lock(&arpalloc);
			aq->next = arpalloc.free;
			arpalloc.free = aq;
			unlock(&arpalloc);
			goto loop;
		}
		prev = aq;
	}
	unlock(&arpalloc.list);
}

int
arpdelete(char *addr)
{
	Arpcache *ap;
	char enetaddr[6], buf[20], *ptr;
	int i;

	ptr = buf + 2;
	strncpy(ptr, addr, (sizeof buf) - 2);

	for(i = 0; i < 6 && addr != (char *)1; i++) {
		ptr[-2] = '0';
		ptr[-1] = 'x';
		enetaddr[i] = atoi(ptr-2);
		ptr = strchr(ptr, ':')+1;
	}

	lock(&arpalloc.hash);
	for(ap = arplruhead; ap; ap = ap->frwd) {
		if(memcmp(ap->et, ptr, sizeof(ap->et)) == 0) {
			ap->status = ARP_FREE;
			break;
		}
	}
	unlock(&arpalloc.hash);
}

void
arplinkhead(Arpcache *ap)
{
	if(ap != arplruhead) {
		if(ap->prev)
			ap->prev->frwd = ap->frwd;
		else
			arplruhead = ap->frwd;
	
		if(ap->frwd)
			ap->frwd->prev = ap->prev;
		else
			arplrutail = ap->prev;
		
		ap->frwd = arplruhead;
		ap->prev = 0;
		arplruhead = ap;
	}
}
.
218c
		arpenter(&entry, ARP_TEMP);
.
211c
			if(arpdelete(field[1]) < 0)
.
206c
			arpflush();
.
57a
	newqinfo(&arpinfo);
.
20,22d
16a
typedef struct Arpq Arpq;
struct Arpq
{
	uchar	ip[4];
	uchar	*etheraddr;
	Block	*bp;
	Queue	*put;
	ulong	time;
	Arpq	*next;
};

struct arpalloc
{
	Lock;
	Lock	list;
	Lock	hash;
	Arpq	*free;
	Arpq	*head;
	Arpq	*tail;
}arpalloc;

void		arpiput(Queue *, Block *);
void		arpoput(Queue *, Block *);
void		arpopn(Queue *, Stream *);
void		arpcls(Queue *);
Qinfo arpinfo = { arpiput, arpoput, arpopn, arpcls, "arp" };

.
14a
Arpcache 	*arplruhead, *arplrutail;
Arpcache 	*arp, **arphash;
.
12,13d
## diffname port/devarp.c 1991/1028
## diff -e /n/bootesdump/1991/1027/sys/src/9/port/devarp.c /n/bootesdump/1991/1028/sys/src/9/port/devarp.c
315a
print("miss %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
.
312a
print("hit %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
.
## diffname port/devarp.c 1991/1029
## diff -e /n/bootesdump/1991/1028/sys/src/9/port/devarp.c /n/bootesdump/1991/1029/sys/src/9/port/devarp.c
474c
	unlock(&larphash);
.
467c
	lock(&larphash);
.
420,449d
416,417c
	unlock(&larphash);
.
411d
393c
		unlock(&larphash);
.
382c
			unlock(&larphash);
.
374c
	lock(&larphash);
.
299,357d
294c
	arpstats.miss++;
	unlock(&larphash);
.
289c
			unlock(&larphash);
.
284c
	lock(&larphash);
.
276c
	uchar ip[4];
	Etherhdr *eh;

	if(bp->type != M_DATA) {
		if(Servq == 0 && streamparse("arpd", bp)) {
print("setting arp channel\n");
			Servq = RD(q);
			freeb(bp);
		}
		else
			PUTNEXT(q, bp);
		return;
	}

	if(!Servq) {
		print("arp: No server, packet dropped\n");
		freeb(bp);
		return;
	}

	eh = (Etherhdr *)bp->rptr;
	iproute(eh->dst, ip);

	/* Send downstream to the ethernet */
	if(arplookup(ip, eh->d)) {
print("arp hit %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
		PUTNEXT(q, bp);
		return;
	}
print("arp miss %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);

	/* Return the packet to the arp server for address resolution */
	memmove(eh->d, ip, sizeof(ip));
	PUTNEXT(Servq, bp);
.
256,257d
28,41d
17,26c
void	arpiput(Queue *, Block *);
void	arpoput(Queue *, Block *);
void	arpopn(Queue *, Stream *);
void	arpcls(Queue *);
void	arpenter(Arpentry*, int);
void	arpflush(void);
int	arpdelete(char*);
void	arplinkhead(Arpcache*);
int	arplookup(uchar*, uchar*);
.
15a
Lock		larphash;
.
11a
#define ARP_FREE	0
#define ARP_OK		1
#define ARP_ASKED	2
#define ARP_TEMP	0
#define ARP_PERM	1
#define Arphashsize	32
#define ARPHASH(p)	arphash[((p[2]^p[3])%Arphashsize)]

typedef struct Arpcache Arpcache;
struct Arpcache {
	uchar	status;
	uchar	type;
	uchar	eip[4];
	uchar	et[6];
	Arpcache *hash;
	Arpcache **hashhd;
	Arpcache *frwd;
	Arpcache *prev;
};

.
## diffname port/devarp.c 1991/1030
## diff -e /n/bootesdump/1991/1029/sys/src/9/port/devarp.c /n/bootesdump/1991/1030/sys/src/9/port/devarp.c
311c
	/* Push the packet up to the arp server for address resolution */
.
309d
305d
300a
	if(nhgets(eh->type) != ET_IP) {
		PUTNEXT(q, bp);	
		return;
	}

.
285d
## diffname port/devarp.c 1991/1112
## diff -e /n/bootesdump/1991/1030/sys/src/9/port/devarp.c /n/bootesdump/1991/1112/sys/src/9/port/devarp.c
61,63c
	"stats",	{arpstatqid},		0,	0666,
	"ctl",		{arpctlqid},		0,	0666,
	"data",		{arpdataqid},		0,	0666,
.
## diffname port/devarp.c 1991/1115
## diff -e /n/bootesdump/1991/1112/sys/src/9/port/devarp.c /n/bootesdump/1991/1115/sys/src/9/port/devarp.c
261a
	USED(q, s);
.
258d
215c
		return stringread(a, n, buf, offset);
.
161a
	USED(c, dp);
.
155a
	USED(c);
.
149a
	USED(c, name, omode, perm);
.
## diffname port/devarp.c 1991/1203
## diff -e /n/bootesdump/1991/1115/sys/src/9/port/devarp.c /n/bootesdump/1991/1203/sys/src/9/port/devarp.c
21c
struct Arpcache
{
.
## diffname port/devarp.c 1992/0111
## diff -e /n/bootesdump/1991/1203/sys/src/9/port/devarp.c /n/bootesdump/1992/0111/sys/src/9/port/devarp.c
6c
#include	"../port/error.h"
.
## diffname port/devarp.c 1992/0112
## diff -e /n/bootesdump/1992/0111/sys/src/9/port/devarp.c /n/bootesdump/1992/0112/sys/src/9/port/devarp.c
247c
				error(Ebadaddr);
.
## diffname port/devarp.c 1992/0114
## diff -e /n/bootesdump/1992/0112/sys/src/9/port/devarp.c /n/bootesdump/1992/0114/sys/src/9/port/devarp.c
247c
				error(Enetaddr);
.
## diffname port/devarp.c 1992/0213
## diff -e /n/bootesdump/1992/0114/sys/src/9/port/devarp.c /n/bootesdump/1992/0213/sys/src/9/port/devarp.c
445a

.
316a
	/* if ip broadcast, use ether bcast address */
	addr = nhgetl(eh->dst);
	if(addr == Myip[Mybcast] || addr == Myip[Mynet] || addr == Myip[Mysubnet]){
		memset(eh->d, 0xff, sizeof(eh->d));
		PUTNEXT(q, bp);
		return;
	}

.
311c
	/* if a known ip addr, send downstream to the ethernet */
.
298c
		if((dropped++ % 1000) == 0)
			print("arp: No server, packet dropped\n");
.
285a
	Ipaddr addr;
	static int dropped;
.
185c
		return devdirread(c, a, n, 0, 0, arpgen);
.
118c
	devstat(c, db, 0, 0, arpgen);
.
112c
	return devwalk(c, name, 0, 0, arpgen);
.
67a
/*
 *  create a 2-level directory
 */
int
arpgen(Chan *c, void *vp, int ntab, int i, Dir *dp)
{
	Qid q;

	q.vers = 0;

	/* top level directory contains the directory arp */
	if(c->qid.path == CHDIR){
		if(i)
			return -1;
		q.path = CHDIR | arpdir2qid;
		devdir(c, q, "arp", 0, eve, 0555, dp);
		return 1;
	}

	/* next level uses table */
	return devgen(c, arptab, Narptab, i, dp);
}

.
62,64c
	"stats",	{arpstatqid},		0,	0444,
	"ctl",		{arpctlqid},		0,	0664,
	"data",		{arpdataqid},		0,	0664,
.
55a
	arpdir2qid,
.
## diffname port/devarp.c 1992/0214
## diff -e /n/bootesdump/1992/0213/sys/src/9/port/devarp.c /n/bootesdump/1992/0214/sys/src/9/port/devarp.c
351,352d
344,348c
	/* Push the packet up to the arp server for address resolution */
	if(!Servq) {
		if((dropped++ % 1000) == 0)
			print("arp: No server, packet dropped %d.%d.%d.%d\n",
				eh->dst[0], eh->dst[1], eh->dst[2], eh->dst[3]);
		freeb(bp);
.
335a
	/* if ip broadcast, use ether bcast address */
	addr = nhgetl(eh->dst);
	if(addr == Myip[Mybcast] || addr == Myip[Mynet] || addr == Myip[Mysubnet]){
		memset(eh->d, 0xff, sizeof(eh->d));
		PUTNEXT(q, bp);
		return;
	}

.
323,329d
## diffname port/devarp.c 1992/0304
## diff -e /n/bootesdump/1992/0214/sys/src/9/port/devarp.c /n/bootesdump/1992/0304/sys/src/9/port/devarp.c
331c
	if(addr == Myip[Mybcast] || addr == Myip[Mynet]
	|| ((addr & Mymask) == Myip[Mynet+1] && (addr & ~Mynetmask) == ~Mynetmask)){
.
## diffname port/devarp.c 1992/0319
## diff -e /n/bootesdump/1992/0304/sys/src/9/port/devarp.c /n/bootesdump/1992/0319/sys/src/9/port/devarp.c
288a
	if(Myip[Myself])
		error(Einuse);
.
## diffname port/devarp.c 1992/0320
## diff -e /n/bootesdump/1992/0319/sys/src/9/port/devarp.c /n/bootesdump/1992/0320/sys/src/9/port/devarp.c
289,290d
278a

.
272a
		break;

.
266c
		else
		if(strcmp(field[0], "delete") == 0) {
.
## diffname port/devarp.c 1992/0321
## diff -e /n/bootesdump/1992/0320/sys/src/9/port/devarp.c /n/bootesdump/1992/0321/sys/src/9/port/devarp.c
2c
#include	"../port/lib.h"
.
## diffname port/devarp.c 1992/0325
## diff -e /n/bootesdump/1992/0321/sys/src/9/port/devarp.c /n/bootesdump/1992/0325/sys/src/9/port/devarp.c
486d
462c
		if(memcmp(ap->eip, ip, sizeof(ap->eip)) == 0) {
.
450,459c
	i = ipparse(addr);
	hnputl(ip, i);	
.
447,448c
	uchar ip[4];
	Ipaddr i;
.
387c
	ep = &arp[conf.arp];
	for(ap = arp; ap < ep; ap++)
.
385c
	Arpcache *ap, *ep;
.
## diffname port/devarp.c 1992/0520
## diff -e /n/bootesdump/1992/0325/sys/src/9/port/devarp.c /n/bootesdump/1992/0520/sys/src/9/port/devarp.c
460a
	return rv;
.
456a
			rv = 0;
.
450a
	rv = -1;
.
449a
	int rv;
.
## diffname port/devarp.c 1992/0619
## diff -e /n/bootesdump/1992/0520/sys/src/9/port/devarp.c /n/bootesdump/1992/0619/sys/src/9/port/devarp.c
335c
	if(Myip[Myself] == 0 || addr == Myip[Mybcast] || addr == Myip[Mynet]
.
## diffname port/devarp.c 1992/0620
## diff -e /n/bootesdump/1992/0619/sys/src/9/port/devarp.c /n/bootesdump/1992/0620/sys/src/9/port/devarp.c
97,98c
	arp = xalloc(sizeof(Arpcache) * conf.arp);
	arphash = (Arpcache **)xalloc(sizeof(Arpcache *) * Arphashsize);
.
## diffname port/devarp.c 1992/0623
## diff -e /n/bootesdump/1992/0620/sys/src/9/port/devarp.c /n/bootesdump/1992/0623/sys/src/9/port/devarp.c
243c
		return readstr(offset, a, n, buf);
.
## diffname port/devarp.c 1992/0711
## diff -e /n/bootesdump/1992/0623/sys/src/9/port/devarp.c /n/bootesdump/1992/0711/sys/src/9/port/devarp.c
256a

	USED(offset);
.
205c
	char	 *ststr;
.
203c
	Arpcache *ap;
.
76a
	USED(vp);
	USED(ntab);

.
## diffname port/devarp.c 1992/0819
## diff -e /n/bootesdump/1992/0711/sys/src/9/port/devarp.c /n/bootesdump/1992/0819/sys/src/9/port/devarp.c
211,212d
209a
	if(c->qid.path&CHDIR)
		return devdirread(c, a, n, arptab, Narptab, arpgen);

.
168d
151,152c
	if(c->qid.path&CHDIR){
.
## diffname port/devarp.c 1993/0206
## diff -e /n/bootesdump/1992/0819/sys/src/9/port/devarp.c /n/bootesdump/1993/0206/sys/src/9/port/devarp.c
391c
	ep = &arp[Narp];
.
214c
		while(bytes < Narp*ARP_ENTRYLEN && n) {
.
113c
	ap = &arp[Narp-1];
.
103c
	ep = &arp[Narp];
.
100c
	arp = xalloc(sizeof(Arpcache) * Narp);
.
68a
enum
{
	Narp=	64,	/* size of arp cache */
};

.
## diffname port/devarp.c 1993/0501
## diff -e /n/bootesdump/1993/0206/sys/src/9/port/devarp.c /n/fornaxdump/1993/0501/sys/src/brazil/port/devarp.c
396c
	ep = &arp[conf.arp];
.
219c
		while(bytes < conf.arp*ARP_ENTRYLEN && n) {
.
118c
	ap = &arp[conf.arp-1];
.
108c
	ep = &arp[conf.arp];
.
105c
	arp = xalloc(sizeof(Arpcache) * conf.arp);
.
69,73d
## diffname port/devarp.c 1993/0804 # deleted
## diff -e /n/fornaxdump/1993/0501/sys/src/brazil/port/devarp.c /n/fornaxdump/1993/0804/sys/src/brazil/port/devarp.c
1,489d

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.