From 3f79300e37d02b1d5df4de97089e89927d1063a2 Mon Sep 17 00:00:00 2001
From: Glenn L McGrath
Date: Fri, 5 Mar 2004 14:25:49 +0000
Subject: Patch by Andrew Victor, 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 | 6 +++---
 networking/udhcp/arpping.h | 9 +++++++--
 2 files changed, 10 insertions(+), 5 deletions(-)

(limited to 'networking')

diff --git a/networking/udhcp/arpping.c b/networking/udhcp/arpping.c
index f2e3768..23c7d46 100644
--- a/networking/udhcp/arpping.c
+++ b/networking/udhcp/arpping.c
@@ -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 */
diff --git a/networking/udhcp/arpping.h b/networking/udhcp/arpping.h
index 99413aa..6cbd297 100644
--- a/networking/udhcp/arpping.h
+++ b/networking/udhcp/arpping.h
@@ -11,7 +11,12 @@
 #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);
-- 
cgit v1.1