From: Roy Marples Date: Thu, 4 Sep 2008 08:31:00 +0000 (+0000) Subject: Use static buffers for ARP and move the send code to arp.c. Also, move the hwaddr... X-Git-Tag: v5.0.0~306 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f0f4b8b6df73aaa57672c47a7f339b52db23e68f;p=thirdparty%2Fdhcpcd.git Use static buffers for ARP and move the send code to arp.c. Also, move the hwaddr buffer to the top of the file for clarity. --- diff --git a/arp.c b/arp.c index 8935ea65..9cf6b899 100644 --- a/arp.c +++ b/arp.c @@ -40,6 +40,41 @@ #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 53db602e..81e2eee4 100644 --- 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 fd96f692..bf8e4ba5 100644 --- 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 *);