Module Name:    src
Committed By:   prlw1
Date:           Thu May 26 09:09:47 UTC 2016

Modified Files:
        src/external/bsd/dhcpcd/dist: dhcp.c dhcp.h

Log Message:
Handle truncated DHCP messages, provided only the BOOTP vendor area
is truncated.  [3fd740f3ed]
OK from roy@


To generate a diff of this commit:
cvs rdiff -u -r1.41 -r1.42 src/external/bsd/dhcpcd/dist/dhcp.c
cvs rdiff -u -r1.15 -r1.16 src/external/bsd/dhcpcd/dist/dhcp.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/external/bsd/dhcpcd/dist/dhcp.c
diff -u src/external/bsd/dhcpcd/dist/dhcp.c:1.41 src/external/bsd/dhcpcd/dist/dhcp.c:1.42
--- src/external/bsd/dhcpcd/dist/dhcp.c:1.41	Mon May  9 20:28:08 2016
+++ src/external/bsd/dhcpcd/dist/dhcp.c	Thu May 26 09:09:47 2016
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcp.c,v 1.41 2016/05/09 20:28:08 martin Exp $");
+ __RCSID("$NetBSD: dhcp.c,v 1.42 2016/05/26 09:09:47 prlw1 Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -1087,9 +1087,12 @@ make_message(struct bootp **bootpm, cons
 	*p++ = DHO_END;
 	len = (size_t)(p - (uint8_t *)bootp);
 
-	/* Pad out to the BOOTP minimum message length.
-	 * Some DHCP servers incorrectly require this. */
-	while (len < BOOTP_MESSAGE_LENTH_MIN) {
+	/* Pad out to the BOOTP message length.
+	 * Even if we send a DHCP packet with a variable length vendor area,
+	 * some servers / relay agents don't like packets smaller than
+	 * a BOOTP message which is fine because that's stipulated
+	 * in RFC1542 section 2.1. */
+	while (len < sizeof(*bootp)) {
 		*p++ = DHO_PAD;
 		len++;
 	}
@@ -3139,14 +3142,26 @@ dhcp_handlepacket(void *arg)
 			    "%s: server %s is not destination",
 			    ifp->name, inet_ntoa(from));
 		}
-
+		/*
+		 * DHCP has a variable option area rather than a fixed
+		 * vendor area.
+		 * Because DHCP uses the BOOTP protocol it should
+		 * still send BOOTP sized packets to be RFC compliant.
+		 * However some servers send a truncated vendor area.
+		 * dhcpcd can work fine without the vendor area being sent.
+		 */
 		bytes = get_udp_data(&bootp, buf);
-		if (bytes < sizeof(struct bootp)) {
+		if (bytes < offsetof(struct bootp, vend)) {
 			logger(ifp->ctx, LOG_ERR,
 			    "%s: truncated packet (%zu) from %s",
 			    ifp->name, bytes, inet_ntoa(from));
 			continue;
 		}
+		/* But to make our IS_DHCP macro easy, ensure the vendor
+		 * area has at least 4 octets. */
+		while (bytes < offsetof(struct bootp, vend) + 4)
+			bootp[bytes++] = '\0';
+
 		dhcp_handledhcp(ifp, (struct bootp *)bootp, bytes, &from);
 		if (state->raw_fd == -1)
 			break;

Index: src/external/bsd/dhcpcd/dist/dhcp.h
diff -u src/external/bsd/dhcpcd/dist/dhcp.h:1.15 src/external/bsd/dhcpcd/dist/dhcp.h:1.16
--- src/external/bsd/dhcpcd/dist/dhcp.h:1.15	Mon May  9 10:15:59 2016
+++ src/external/bsd/dhcpcd/dist/dhcp.h	Thu May 26 09:09:47 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: dhcp.h,v 1.15 2016/05/09 10:15:59 roy Exp $ */
+/* $NetBSD: dhcp.h,v 1.16 2016/05/26 09:09:47 prlw1 Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -133,9 +133,6 @@ enum FQDN {
 	FQDN_BOTH       = 0x31
 };
 
-/* Some crappy DHCP servers require the BOOTP minimum length */
-#define BOOTP_MESSAGE_LENTH_MIN 300
-
 /* Don't import common.h as that defines __unused which causes problems
  * on some Linux systems which define it as part of a structure */
 #if __GNUC__ > 2 || defined(__INTEL_COMPILER)

Reply via email to