## 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
|