]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Use static buffers for ARP and move the send code to arp.c. Also, move the hwaddr...
authorRoy Marples <roy@marples.name>
Thu, 4 Sep 2008 08:31:00 +0000 (08:31 +0000)
committerRoy Marples <roy@marples.name>
Thu, 4 Sep 2008 08:31:00 +0000 (08:31 +0000)
arp.c
net.c
net.h

diff --git a/arp.c b/arp.c
index 8935ea65e71e16e54c684ba6e936582c4615553f..9cf6b8998deadb57415d8104709e087baf39e364 100644 (file)
--- a/arp.c
+++ b/arp.c
 #include "logger.h"
 #include "net.h"
 
+#define ARP_LEN \
+       (sizeof(struct arphdr) + (2 * sizeof(uint32_t)) + (2 * HWADDR_LEN))
+
+static uint8_t arp_buffer[ARP_LEN];
+
+static int
+send_arp(const struct interface *iface, int op, in_addr_t sip, in_addr_t tip)
+{
+       struct arphdr ar;
+       size_t len;
+       uint8_t *p;
+       int retval;
+
+       ar.ar_hrd = htons(iface->family);
+       ar.ar_pro = htons(ETHERTYPE_IP);
+       ar.ar_hln = iface->hwlen;
+       ar.ar_pln = sizeof(sip);
+       ar.ar_op = htons(op);
+       p = arp_buffer;
+       p += sizeof(ar);
+       memcpy(p, iface->hwaddr, iface->hwlen);
+       p += iface->hwlen;
+       memcpy(p, &sip, sizeof(sip));
+       p += sizeof(sip);
+       /* ARP requests should ignore this */
+       retval = iface->hwlen;
+       while (retval--)
+               *p++ = '\0';
+       memcpy(p, &tip, sizeof(tip));
+       p += sizeof(tip);
+       len = sizeof(ar) + 2 * iface->hwlen + 2 * sizeof(sip);
+       retval = send_raw_packet(iface, ETHERTYPE_ARP, arp_buffer, len);
+       return retval;
+}
+
 static void
 handle_arp_failure(struct interface *iface)
 {
@@ -56,10 +91,9 @@ static void
 handle_arp_packet(void *arg)
 {
        struct interface *iface = arg;
-       struct arphdr reply;
+       struct arphdr ar;
        uint32_t reply_s;
        uint32_t reply_t;
-       uint8_t arp_reply[sizeof(reply) + 2 * sizeof(reply_s) + 2 * HWADDR_LEN];
        uint8_t *hw_s, *hw_t;
        ssize_t bytes;
        struct if_state *state = iface->state;
@@ -67,36 +101,36 @@ handle_arp_packet(void *arg)
        state->fail.s_addr = 0;
        for(;;) {
                bytes = get_raw_packet(iface, ETHERTYPE_ARP,
-                                      arp_reply, sizeof(arp_reply));
+                                      arp_buffer, sizeof(arp_buffer));
                if (bytes == 0 || bytes == -1)
                        return;
                /* We must have a full ARP header */
-               if ((size_t)bytes < sizeof(reply))
+               if ((size_t)bytes < sizeof(ar))
                        continue;
-               memcpy(&reply, arp_reply, sizeof(reply));
+               memcpy(&ar, arp_buffer, sizeof(ar));
                /* Protocol must be IP. */
-               if (reply.ar_pro != htons(ETHERTYPE_IP))
+               if (ar.ar_pro != htons(ETHERTYPE_IP))
                        continue;
-               if (reply.ar_pln != sizeof(reply_s))
+               if (ar.ar_pln != sizeof(reply_s))
                        continue;
                /* Only these types are recognised */
-               if (reply.ar_op != htons(ARPOP_REPLY) &&
-                   reply.ar_op != htons(ARPOP_REQUEST))
+               if (ar.ar_op != htons(ARPOP_REPLY) &&
+                   ar.ar_op != htons(ARPOP_REQUEST))
                        continue;
 
                /* Get pointers to the hardware addreses */
-               hw_s = arp_reply + sizeof(reply);
-               hw_t = hw_s + reply.ar_hln + reply.ar_pln;
+               hw_s = arp_buffer + sizeof(ar);
+               hw_t = hw_s + ar.ar_hln + ar.ar_pln;
                /* Ensure we got all the data */
-               if ((hw_t + reply.ar_hln + reply.ar_pln) - arp_reply > bytes)
+               if ((hw_t + ar.ar_hln + ar.ar_pln) - arp_buffer > bytes)
                        continue;
                /* Ignore messages from ourself */
-               if (reply.ar_hln == iface->hwlen &&
+               if (ar.ar_hln == iface->hwlen &&
                    memcmp(hw_s, iface->hwaddr, iface->hwlen) == 0)
                        continue;
                /* Copy out the IP addresses */
-               memcpy(&reply_s, hw_s + reply.ar_hln, reply.ar_pln);
-               memcpy(&reply_t, hw_t + reply.ar_hln, reply.ar_pln);
+               memcpy(&reply_s, hw_s + ar.ar_hln, ar.ar_pln);
+               memcpy(&reply_t, hw_t + ar.ar_hln, ar.ar_pln);
 
                /* Check for conflict */
                if (state->offer && 
@@ -114,7 +148,7 @@ handle_arp_packet(void *arg)
                        logger(LOG_ERR, "%s: hardware address %s claims %s",
                               iface->name,
                               hwaddr_ntoa((unsigned char *)hw_s,
-                                          (size_t)reply.ar_hln),
+                                          (size_t)ar.ar_hln),
                               inet_ntoa(state->fail));
                        errno = EEXIST;
                        handle_arp_failure(iface);
@@ -205,3 +239,4 @@ send_arp_probe(void *arg)
        if (send_arp(iface, ARPOP_REQUEST, 0, state->offer->yiaddr) == -1)
                logger(LOG_ERR, "send_arp: %s", strerror(errno));
 }
+
diff --git a/net.c b/net.c
index 53db602ee07fb1256c1be8bbb9c3f7c3d97a108f..81e2eee4570aeded340825dc996032e12d90106c 100644 (file)
--- a/net.c
+++ b/net.c
@@ -75,6 +75,8 @@
 #include "net.h"
 #include "signals.h"
 
+static char hwaddr_buffer[(HWADDR_LEN * 3) + 1];
+
 int
 inet_ntocidr(struct in_addr address)
 {
@@ -132,8 +134,7 @@ get_netmask(uint32_t addr)
 char *
 hwaddr_ntoa(const unsigned char *hwaddr, size_t hwlen)
 {
-       static char buffer[(HWADDR_LEN * 3) + 1];
-       char *p = buffer;
+       char *p = hwaddr_buffer;
        size_t i;
 
        for (i = 0; i < hwlen && i < HWADDR_LEN; i++) {
@@ -144,7 +145,7 @@ hwaddr_ntoa(const unsigned char *hwaddr, size_t hwlen)
 
        *p ++= '\0';
 
-       return buffer;
+       return hwaddr_buffer;
 }
 
 size_t
@@ -553,10 +554,7 @@ int
 open_udp_socket(struct interface *iface)
 {
        int s;
-       union sockunion {
-               struct sockaddr sa;
-               struct sockaddr_in sin;
-       } su;
+       struct sockaddr_in sin;
        int n;
 #ifdef SO_BINDTODEVICE
        struct ifreq ifr;
@@ -579,11 +577,11 @@ open_udp_socket(struct interface *iface)
        n = 1;
        if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n)) == -1)
                goto eexit;
-       memset(&su, 0, sizeof(su));
-       su.sin.sin_family = AF_INET;
-       su.sin.sin_port = htons(DHCP_CLIENT_PORT);
-       su.sin.sin_addr.s_addr = iface->addr.s_addr;
-       if (bind(s, &su.sa, sizeof(su)) == -1)
+       memset(&sin, 0, sizeof(sin));
+       sin.sin_family = AF_INET;
+       sin.sin_port = htons(DHCP_CLIENT_PORT);
+       sin.sin_addr.s_addr = iface->addr.s_addr;
+       if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) == -1)
                goto eexit;
 
        iface->udp_fd = s;
@@ -599,17 +597,14 @@ ssize_t
 send_packet(const struct interface *iface, struct in_addr to,
            const uint8_t *data, ssize_t len)
 {
-       union sockunion {
-               struct sockaddr sa;
-               struct sockaddr_in sin;
-       } su;
-
-       memset(&su, 0, sizeof(su));
-       su.sin.sin_family = AF_INET;
-       su.sin.sin_addr.s_addr = to.s_addr;
-       su.sin.sin_port = htons(DHCP_SERVER_PORT);
-
-       return sendto(iface->udp_fd, data, len, 0, &su.sa, sizeof(su));
+       struct sockaddr_in sin;
+
+       memset(&sin, 0, sizeof(sin));
+       sin.sin_family = AF_INET;
+       sin.sin_addr.s_addr = to.s_addr;
+       sin.sin_port = htons(DHCP_SERVER_PORT);
+       return sendto(iface->udp_fd, data, len, 0,
+                     (struct sockaddr *)&sin, sizeof(sin));
 }
 
 struct udp_dhcp_packet
@@ -745,34 +740,3 @@ valid_udp_packet(const uint8_t *data)
        return retval;
 }
 
-int
-send_arp(const struct interface *iface, int op, in_addr_t sip, in_addr_t tip)
-{
-       struct arphdr *arp;
-       size_t arpsize;
-       uint8_t *p;
-       int retval;
-
-       arpsize = sizeof(*arp) + 2 * iface->hwlen + 2 * sizeof(sip);
-       arp = xmalloc(arpsize);
-       arp->ar_hrd = htons(iface->family);
-       arp->ar_pro = htons(ETHERTYPE_IP);
-       arp->ar_hln = iface->hwlen;
-       arp->ar_pln = sizeof(sip);
-       arp->ar_op = htons(op);
-       p = (uint8_t *)arp;
-       p += sizeof(*arp);
-       memcpy(p, iface->hwaddr, iface->hwlen);
-       p += iface->hwlen;
-       memcpy(p, &sip, sizeof(sip));
-       p += sizeof(sip);
-       /* ARP requests should ignore this */
-       retval = iface->hwlen;
-       while (retval--)
-               *p++ = '\0';
-       memcpy(p, &tip, sizeof(tip));
-       p += sizeof(tip);
-       retval = send_raw_packet(iface, ETHERTYPE_ARP, arp, arpsize);
-       free(arp);
-       return retval;
-}
diff --git a/net.h b/net.h
index fd96f692c55299565b9df435064a3ecff33f3b45..bf8e4ba5aa4821cedb42276e515d609cb7f3fced 100644 (file)
--- a/net.h
+++ b/net.h
@@ -148,8 +148,6 @@ ssize_t send_raw_packet(const struct interface *, int,
                        const void *, ssize_t);
 ssize_t get_raw_packet(struct interface *, int, void *, ssize_t);
 
-int send_arp(const struct interface *, int, in_addr_t, in_addr_t);
-
 int open_link_socket(void);
 int link_changed(int, const struct interface *);
 int carrier_status(const char *);