summaryrefslogtreecommitdiff
path: root/usr/src/boot/lib/libstand/arp.c
diff options
context:
space:
mode:
authorToomas Soome <tsoome@me.com>2017-03-19 22:42:08 +0200
committerRichard Lowe <richlowe@richlowe.net>2017-10-16 09:34:42 -0400
commit859472da62d5df230117a53edc3cfcc61d5896ac (patch)
treebb650fc10b6dc1a02a539e7e4f200f185e0af861 /usr/src/boot/lib/libstand/arp.c
parent9276b3991ba20d5a5660887ba81b0bc7bed25a0c (diff)
downloadillumos-joyent-859472da62d5df230117a53edc3cfcc61d5896ac.tar.gz
8140 loader: network read rework
Reviewed by: Robert Mustacchi <rm@joyent.com> Approved by: Richard Lowe <richlowe@richlowe.net>
Diffstat (limited to 'usr/src/boot/lib/libstand/arp.c')
-rw-r--r--usr/src/boot/lib/libstand/arp.c56
1 files changed, 25 insertions, 31 deletions
diff --git a/usr/src/boot/lib/libstand/arp.c b/usr/src/boot/lib/libstand/arp.c
index e6175325f3..22bd028df1 100644
--- a/usr/src/boot/lib/libstand/arp.c
+++ b/usr/src/boot/lib/libstand/arp.c
@@ -36,7 +36,6 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/socket.h>
@@ -65,17 +64,16 @@ int arp_num = 1;
/* Local forwards */
static ssize_t arpsend(struct iodesc *, void *, size_t);
-static ssize_t arprecv(struct iodesc *, void *, size_t, time_t);
+static ssize_t arprecv(struct iodesc *, void **, void **, time_t);
/* Broadcast an ARP packet, asking who has addr on interface d */
u_char *
-arpwhohas(d, addr)
- struct iodesc *d;
- struct in_addr addr;
+arpwhohas(struct iodesc *d, struct in_addr addr)
{
int i;
struct ether_arp *ah;
struct arp_list *al;
+ void *pkt;
struct {
struct ether_header eh;
struct {
@@ -83,13 +81,6 @@ arpwhohas(d, addr)
u_char pad[18]; /* 60 - sizeof(...) */
} data;
} wbuf;
- struct {
- struct ether_header eh;
- struct {
- struct ether_arp arp;
- u_char pad[24]; /* extra space */
- } data;
- } rbuf;
/* Try for cached answer first */
for (i = 0, al = arp_list; i < arp_num; ++i, ++al)
@@ -122,35 +113,36 @@ arpwhohas(d, addr)
/* Store ip address in cache (incomplete entry). */
al->addr = addr;
+ pkt = NULL;
+ ah = NULL;
i = sendrecv(d,
arpsend, &wbuf.data, sizeof(wbuf.data),
- arprecv, &rbuf.data, sizeof(rbuf.data));
+ arprecv, &pkt, (void **)&ah);
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) {
+ struct ether_header *eh;
+
+ eh = (struct ether_header *)((uintptr_t)pkt + ETHER_ALIGN);
printf("arp: response from %s\n",
- ether_sprintf(rbuf.eh.ether_shost));
+ ether_sprintf(eh->ether_shost));
printf("arp: cacheing %s --> %s\n",
inet_ntoa(addr), ether_sprintf(ah->arp_sha));
}
#endif
MACPY(ah->arp_sha, al->ea);
++arp_num;
-
+ free(pkt);
return (al->ea);
}
static ssize_t
-arpsend(d, pkt, len)
- struct iodesc *d;
- void *pkt;
- size_t len;
+arpsend(struct iodesc *d, void *pkt, size_t len)
{
#ifdef ARP_DEBUG
@@ -166,28 +158,27 @@ arpsend(d, pkt, len)
* else -1 (and errno == 0)
*/
static ssize_t
-arprecv(d, pkt, len, tleft)
- struct iodesc *d;
- void *pkt;
- size_t len;
- time_t tleft;
+arprecv(struct iodesc *d, void **pkt, void **payload, time_t tleft)
{
ssize_t n;
struct ether_arp *ah;
u_int16_t etype; /* host order */
+ void *ptr;
#ifdef ARP_DEBUG
if (debug)
printf("arprecv: ");
#endif
- n = readether(d, pkt, len, tleft, &etype);
+ ptr = NULL;
+ n = readether(d, &ptr, (void **)&ah, tleft, &etype);
errno = 0; /* XXX */
if (n == -1 || n < sizeof(struct ether_arp)) {
#ifdef ARP_DEBUG
if (debug)
printf("bad len=%d\n", n);
#endif
+ free(ptr);
return (-1);
}
@@ -196,12 +187,11 @@ arprecv(d, pkt, len, tleft)
if (debug)
printf("not arp type=%d\n", etype);
#endif
+ free(ptr);
return (-1);
}
/* Ethernet address now checked in readether() */
-
- ah = (struct ether_arp *)pkt;
if (ah->arp_hrd != htons(ARPHRD_ETHER) ||
ah->arp_pro != htons(ETHERTYPE_IP) ||
ah->arp_hln != sizeof(ah->arp_sha) ||
@@ -211,6 +201,7 @@ arprecv(d, pkt, len, tleft)
if (debug)
printf("bad hrd/pro/hln/pln\n");
#endif
+ free(ptr);
return (-1);
}
@@ -220,6 +211,7 @@ arprecv(d, pkt, len, tleft)
printf("is request\n");
#endif
arp_reply(d, ah);
+ free(ptr);
return (-1);
}
@@ -228,6 +220,7 @@ arprecv(d, pkt, len, tleft)
if (debug)
printf("not ARP reply\n");
#endif
+ free(ptr);
return (-1);
}
@@ -239,6 +232,7 @@ arprecv(d, pkt, len, tleft)
if (debug)
printf("unwanted address\n");
#endif
+ free(ptr);
return (-1);
}
/* We don't care who the reply was sent to. */
@@ -248,6 +242,8 @@ arprecv(d, pkt, len, tleft)
if (debug)
printf("got it\n");
#endif
+ *pkt = ptr;
+ *payload = ah;
return (n);
}
@@ -256,9 +252,7 @@ arprecv(d, pkt, len, tleft)
* Notes: Re-uses buffer. Pad to length = 46.
*/
void
-arp_reply(d, pkt)
- struct iodesc *d;
- void *pkt; /* the request */
+arp_reply(struct iodesc *d, void *pkt)
{
struct ether_arp *arp = pkt;