Patch by Andrew Victor,
authorGlenn L McGrath <bug1@ihug.co.nz>
Fri, 5 Mar 2004 14:25:49 +0000 (14:25 -0000)
committerGlenn L McGrath <bug1@ihug.co.nz>
Fri, 5 Mar 2004 14:25:49 +0000 (14:25 -0000)
In arpping.h, fix structure alignment of "struct arpMsg".
GCC can insert padding in the structure which causes udhcpd to send an
invalid ARP packet on the network.  It will then not receive a valid
reply, which can cause it to assign an IP address that's already in use
on the network.
(With kernels before 2.4.20, the "struct ethhdr" in linux/if_ether.h
wasn't marked as packed.  This is also an issue if your toolchain was
built with a pre-2.4.20 kernel).

networking/udhcp/arpping.c
networking/udhcp/arpping.h

index f2e3768..23c7d46 100644 (file)
@@ -60,9 +60,9 @@ int arpping(uint32_t yiaddr, uint32_t ip, uint8_t *mac, char *interface)
 
        /* send arp request */
        memset(&arp, 0, sizeof(arp));
-       memcpy(arp.ethhdr.h_dest, MAC_BCAST_ADDR, 6);   /* MAC DA */
-       memcpy(arp.ethhdr.h_source, mac, 6);            /* MAC SA */
-       arp.ethhdr.h_proto = htons(ETH_P_ARP);          /* protocol type (Ethernet) */
+       memcpy(arp.h_dest, MAC_BCAST_ADDR, 6);          /* MAC DA */
+       memcpy(arp.h_source, mac, 6);                   /* MAC SA */
+       arp.h_proto = htons(ETH_P_ARP);                 /* protocol type (Ethernet) */
        arp.htype = htons(ARPHRD_ETHER);                /* hardware type */
        arp.ptype = htons(ETH_P_IP);                    /* protocol type (ARP message) */
        arp.hlen = 6;                                   /* hardware address length */
index 99413aa..6cbd297 100644 (file)
 #include <netinet/in.h>
 
 struct arpMsg {
-       struct ethhdr ethhdr;                   /* Ethernet header */
+       /* Ethernet header */
+       u_char   h_dest[6];                     /* destination ether addr */
+       u_char   h_source[6];                   /* source ether addr */
+       u_short  h_proto;                       /* packet type ID field */
+       
+       /* ARP packet */
        uint16_t htype;                         /* hardware type (must be ARPHRD_ETHER) */
        uint16_t ptype;                         /* protocol type (must be ETH_P_IP) */
        uint8_t  hlen;                          /* hardware address length (must be 6) */
@@ -22,7 +27,7 @@ struct arpMsg {
        uint8_t  tHaddr[6];                     /* target's hardware address */
        uint8_t  tInaddr[4];                    /* target's IP address */
        uint8_t  pad[18];                       /* pad for min. Ethernet payload (60 bytes) */
-};
+} __attribute__ ((packed));
 
 /* function prototypes */
 int arpping(uint32_t yiaddr, uint32_t ip, uint8_t *arp, char *interface);