from gwr:
authorderaadt <deraadt@openbsd.org>
Fri, 15 Dec 1995 08:08:16 +0000 (08:08 +0000)
committerderaadt <deraadt@openbsd.org>
Fri, 15 Dec 1995 08:08:16 +0000 (08:08 +0000)
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.

sys/lib/libsa/arp.c

index de09484..f9c5c95 100644 (file)
@@ -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.
 /* 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;
        }