diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-12-15 08:08:17 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-12-15 08:08:17 +0000 |
commit | 528844d42adf10780bac465ed1aa6b7a4ec555d8 (patch) | |
tree | deae185116fa223ef93c2a01249e922e9f60fa33 | |
parent | 3c25d6481132b470fe85e545e66fd506d285e5f4 (diff) |
from gwr:
Check return value from sendrecv so that ARP timeout does not cause
garbage to be entered into the ARP table. Also fix ARP_DEBUG code.
-rw-r--r-- | sys/lib/libsa/arp.c | 46 |
1 files changed, 26 insertions, 20 deletions
diff --git a/sys/lib/libsa/arp.c b/sys/lib/libsa/arp.c index de09484106b..f9c5c95e7be 100644 --- a/sys/lib/libsa/arp.c +++ b/sys/lib/libsa/arp.c @@ -1,4 +1,4 @@ -/* $NetBSD: arp.c,v 1.12 1995/09/27 23:14:57 pk Exp $ */ +/* $NetBSD: arp.c,v 1.13 1995/12/08 04:12:53 gwr Exp $ */ /* * Copyright (c) 1992 Regents of the University of California. @@ -55,14 +55,14 @@ /* Cache stuff */ #define ARP_NUM 8 /* need at most 3 arp entries */ -static struct arp_list { +struct arp_list { struct in_addr addr; u_char ea[6]; } arp_list[ARP_NUM] = { /* XXX - net order `INADDR_BROADCAST' must be a constant */ { {0xffffffff}, BA } }; -static int arp_num = 1; +int arp_num = 1; /* Local forwards */ static ssize_t arpsend __P((struct iodesc *, void *, size_t)); @@ -78,36 +78,34 @@ arpwhohas(d, addr) register struct ether_arp *ah; register struct arp_list *al; struct { - u_char header[ETHER_SIZE]; + struct ether_header eh; struct { struct ether_arp arp; - u_char pad[18]; /* 60 - sizeof(arp) */ + u_char pad[18]; /* 60 - sizeof(...) */ } data; } wbuf; struct { - u_char header[ETHER_SIZE]; + struct ether_header eh; struct { struct ether_arp arp; u_char pad[24]; /* extra space */ } data; } rbuf; -#ifdef ARP_DEBUG - if (debug) - printf("arpwhohas: called for %s\n", inet_ntoa(addr)); -#endif /* Try for cached answer first */ for (i = 0, al = arp_list; i < arp_num; ++i, ++al) if (addr.s_addr == al->addr.s_addr) return (al->ea); /* Don't overflow cache */ - if (arp_num > ARP_NUM - 1) - panic("arpwhohas: overflowed arp_list!"); + if (arp_num > ARP_NUM - 1) { + arp_num = 1; /* recycle */ + printf("arpwhohas: overflowed arp_list!\n"); + } #ifdef ARP_DEBUG if (debug) - printf("arpwhohas: not cached\n"); + printf("arpwhohas: send request for %s\n", inet_ntoa(addr)); #endif bzero((char*)&wbuf.data, sizeof(wbuf.data)); @@ -119,22 +117,30 @@ arpwhohas(d, addr) ah->arp_op = htons(ARPOP_REQUEST); MACPY(d->myea, ah->arp_sha); bcopy(&d->myip, ah->arp_spa, sizeof(ah->arp_spa)); + /* Leave zeros in arp_tha */ bcopy(&addr, ah->arp_tpa, sizeof(ah->arp_tpa)); - /* Store ip address in cache */ + /* Store ip address in cache (incomplete entry). */ al->addr = addr; - (void)sendrecv(d, + i = sendrecv(d, arpsend, &wbuf.data, sizeof(wbuf.data), arprecv, &rbuf.data, sizeof(rbuf.data)); + if (i == -1) { + panic("arp: no response for %s\n", + inet_ntoa(addr)); + } /* Store ethernet address in cache */ ah = &rbuf.data.arp; #ifdef ARP_DEBUG - if (debug) + if (debug) { + printf("arp: response from %s\n", + ether_sprintf(rbuf.eh.ether_shost)); printf("arp: cacheing %s --> %s\n", - intoa(ah->arp_spa), + inet_ntoa(addr), ether_sprintf(ah->arp_sha)); + } #endif MACPY(ah->arp_sha, al->ea); ++arp_num; @@ -205,7 +211,7 @@ arprecv(d, pkt, len, tleft) { #ifdef ARP_DEBUG if (debug) - printf("bad hrd/pro/hln/pln\n") + printf("bad hrd/pro/hln/pln\n"); #endif return (-1); } @@ -213,7 +219,7 @@ arprecv(d, pkt, len, tleft) if (ah->arp_op == htons(ARPOP_REQUEST)) { #ifdef ARP_DEBUG if (debug) - printf("is request\n") + printf("is request\n"); #endif arp_reply(d, ah); return (-1); @@ -265,7 +271,7 @@ arp_reply(d, pkt) { #ifdef ARP_DEBUG if (debug) - printf("arp_reply: bad hrd/pro/hln/pln\n") + printf("arp_reply: bad hrd/pro/hln/pln\n"); #endif return; } |