[BusyBox] udhcp patches

Rainer Weikusat rainer.weikusat at sncag.com
Sat Jan 29 03:13:13 UTC 2005


This is the first of a series of patches to the busybox dhcp
code. Final motivation is to get 'force renew' support into the dhcp
client, correct code at least on the relevant paths for that and being
somewhat less generous with system ressources.

This patch
	- uses sendto for all packets that are sent, avoiding the need
          to connect(2) in kernel_packet

        - doesn't zero out sockaddr_in values that are overwritten
          subsequently in any case

	- doesn't bind the raw socket to the link layer destination
          address

	- uses sizeof(variable) instead of sizeof(type)

        - calls the socket functions with the correct socket address
          lengths

        - treats output errors consistently for both socket types

        - renames the sockaddr_in structure in kernel_packet so the
          code is less confusing for a casual reader

Index: busybox//networking/udhcp/packet.c
===================================================================
RCS file: /data/repo/busybox/networking/udhcp/packet.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- busybox//networking/udhcp/packet.c	1 Dec 2004 21:35:53 -0000	1.2
+++ busybox//networking/udhcp/packet.c	29 Jan 2005 03:02:52 -0000	1.3
@@ -19,7 +19,6 @@
 #include "options.h"
 #include "common.h"
 
-
 void init_header(struct dhcpMessage *packet, char type)
 {
 	memset(packet, 0, sizeof(struct dhcpMessage));
@@ -122,6 +121,15 @@
 	return ~sum;
 }
 
+static int do_sendto(int fd, void const *msg, ssize_t msg_len,
+		     struct sockaddr *dest, socklen_t d_len)
+{
+    int rc;
+
+    rc = sendto(fd, msg, msg_len, 0, dest, d_len);
+    if (rc == -1) syslog(LOG_ERR, "sendto failed: %m");
+    return rc;
+}
 
 /* Construct a ip/udp header for a packet, and specify the source and dest hardware address */
 int raw_packet(struct dhcpMessage *payload, uint32_t source_ip, int source_port,
@@ -137,52 +145,42 @@
 		return -1;
 	}
 
-	memset(&dest, 0, sizeof(dest));
 	memset(&packet, 0, sizeof(packet));
 
-	dest.sll_family = AF_PACKET;
-	dest.sll_protocol = htons(ETH_P_IP);
-	dest.sll_ifindex = ifindex;
-	dest.sll_halen = 6;
-	memcpy(dest.sll_addr, dest_arp, 6);
-	if (bind(fd, (struct sockaddr *)&dest, sizeof(struct sockaddr_ll)) < 0) {
-		DEBUG(LOG_ERR, "bind call failed: %m");
-		close(fd);
-		return -1;
-	}
-
 	packet.ip.protocol = IPPROTO_UDP;
 	packet.ip.saddr = source_ip;
 	packet.ip.daddr = dest_ip;
 	packet.udp.source = htons(source_port);
 	packet.udp.dest = htons(dest_port);
-	packet.udp.len = htons(sizeof(packet.udp) + sizeof(struct dhcpMessage)); /* cheat on the psuedo-header */
+	packet.udp.len = htons(sizeof(packet.udp) + sizeof(*payload)); /* cheat on the psuedo-header */
 	packet.ip.tot_len = packet.udp.len;
-	memcpy(&(packet.data), payload, sizeof(struct dhcpMessage));
-	packet.udp.check = checksum(&packet, sizeof(struct udp_dhcp_packet));
+	memcpy(&(packet.data), payload, sizeof(*payload));
+	packet.udp.check = checksum(&packet, sizeof(packet));
 
-	packet.ip.tot_len = htons(sizeof(struct udp_dhcp_packet));
+	packet.ip.tot_len = htons(sizeof(packet));
 	packet.ip.ihl = sizeof(packet.ip) >> 2;
 	packet.ip.version = IPVERSION;
 	packet.ip.ttl = IPDEFTTL;
-	packet.ip.check = checksum(&(packet.ip), sizeof(packet.ip));
+	packet.ip.check = checksum(&packet.ip, sizeof(packet.ip));
 
-	result = sendto(fd, &packet, sizeof(struct udp_dhcp_packet), 0, (struct sockaddr *) &dest, sizeof(dest));
-	if (result <= 0) {
-		DEBUG(LOG_ERR, "write on socket failed: %m");
-	}
+	dest.sll_family = AF_PACKET;
+	dest.sll_protocol = htons(ETH_P_IP);
+	dest.sll_ifindex = ifindex;
+	dest.sll_halen = 6;
+	memcpy(dest.sll_addr, dest_arp, 6);
+	result = do_sendto(fd, &packet, sizeof(packet), (struct sockaddr *)&dest,
+			   sizeof(dest));
 	close(fd);
 	return result;
 }
 
-
 /* Let the kernel do all the work for packet generation */
 int kernel_packet(struct dhcpMessage *payload, uint32_t source_ip, int source_port,
 		   uint32_t dest_ip, int dest_port)
 {
 	int n = 1;
 	int fd, result;
-	struct sockaddr_in client;
+	struct sockaddr_in sa;
 
 	if ((fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
 		return -1;
@@ -190,23 +188,16 @@
 	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &n, sizeof(n)) == -1)
 		return -1;
 
-	memset(&client, 0, sizeof(client));
-	client.sin_family = AF_INET;
-	client.sin_port = htons(source_port);
-	client.sin_addr.s_addr = source_ip;
-
-	if (bind(fd, (struct sockaddr *)&client, sizeof(struct sockaddr)) == -1)
-		return -1;
-
-	memset(&client, 0, sizeof(client));
-	client.sin_family = AF_INET;
-	client.sin_port = htons(dest_port);
-	client.sin_addr.s_addr = dest_ip;
-
-	if (connect(fd, (struct sockaddr *)&client, sizeof(struct sockaddr)) == -1)
-		return -1;
-
-	result = write(fd, payload, sizeof(struct dhcpMessage));
+	sa.sin_family = AF_INET;
+	sa.sin_port = htons(source_port);
+	sa.sin_addr.s_addr = source_ip;
+	if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) return -1;
+
+	sa.sin_family = AF_INET;
+	sa.sin_port = htons(dest_port);
+	sa.sin_addr.s_addr = dest_ip;
+	result = do_sendto(fd, payload, sizeof(*payload), (struct sockaddr *)&sa,
+			   sizeof(sa));
 	close(fd);
 	return result;
 }



More information about the busybox mailing list