From 2d576e2a220e28fe815ea02c38c9bfe9195406c2 Mon Sep 17 00:00:00 2001
From: Johannes Stezenbach <js@sig21.net>
Date: Mon, 28 Oct 2013 23:27:37 +0100
Subject: udhcpc: make DHCP packets to have at least 300 DHCP bytes

Commit b8b72f02 removed all padding from DHCP packets
to fix operation with buggy servers which can't handle
maximum sized packets.  But it introduced a regression
with buggy routers which drop DHCP packets smaller
than 300 bytes (i.e. 342 byte ethernet packets).
Add back some padding to work around.

function                                             old     new   delta
udhcp_send_kernel_packet                             268     292     +24
udhcp_send_raw_packet                                462     473     +11
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 35/0)               Total: 35 bytes

Signed-off-by: Johannes Stezenbach <js@sig21.net>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
---
 networking/udhcp/packet.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/networking/udhcp/packet.c b/networking/udhcp/packet.c
index 33c9585cf..148f52551 100644
--- a/networking/udhcp/packet.c
+++ b/networking/udhcp/packet.c
@@ -143,8 +143,15 @@ int FAST_FUNC udhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt,
 	 *
 	 * In order to work with those buggy servers,
 	 * we truncate packets after end option byte.
+	 *
+	 * However, RFC 1542 says "The IP Total Length and UDP Length
+	 * must be large enough to contain the minimal BOOTP header of 300 octets".
+	 * Thus, we retain enough padding to not go below 300 BOOTP bytes.
+	 * Some devices have filters which drop DHCP packets shorter than that.
 	 */
 	padding = DHCP_OPTIONS_BUFSIZE - 1 - udhcp_end_option(packet.data.options);
+	if (padding > DHCP_SIZE - 300)
+		padding = DHCP_SIZE - 300;
 
 	packet.ip.protocol = IPPROTO_UDP;
 	packet.ip.saddr = source_nip;
@@ -215,6 +222,8 @@ int FAST_FUNC udhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt,
 
 	udhcp_dump_packet(dhcp_pkt);
 	padding = DHCP_OPTIONS_BUFSIZE - 1 - udhcp_end_option(dhcp_pkt->options);
+	if (padding > DHCP_SIZE - 300)
+		padding = DHCP_SIZE - 300;
 	result = safe_write(fd, dhcp_pkt, DHCP_SIZE - padding);
 	msg = "write";
  ret_close:
-- 
cgit v1.2.3