Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/external/bsd/dhcpcd/dist Handle truncated DHCP messages, pro...



details:   https://anonhg.NetBSD.org/src/rev/8d63a9a45993
branches:  trunk
changeset: 345426:8d63a9a45993
user:      prlw1 <prlw1%NetBSD.org@localhost>
date:      Thu May 26 09:09:47 2016 +0000

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

diffstat:

 external/bsd/dhcpcd/dist/dhcp.c |  27 +++++++++++++++++++++------
 external/bsd/dhcpcd/dist/dhcp.h |   5 +----
 2 files changed, 22 insertions(+), 10 deletions(-)

diffs (74 lines):

diff -r 8db28206d2d2 -r 8d63a9a45993 external/bsd/dhcpcd/dist/dhcp.c
--- a/external/bsd/dhcpcd/dist/dhcp.c   Thu May 26 07:45:51 2016 +0000
+++ b/external/bsd/dhcpcd/dist/dhcp.c   Thu May 26 09:09:47 2016 +0000
@@ -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 @@
        *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 @@
                            "%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;
diff -r 8db28206d2d2 -r 8d63a9a45993 external/bsd/dhcpcd/dist/dhcp.h
--- a/external/bsd/dhcpcd/dist/dhcp.h   Thu May 26 07:45:51 2016 +0000
+++ b/external/bsd/dhcpcd/dist/dhcp.h   Thu May 26 09:09:47 2016 +0000
@@ -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 @@
        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)



Home | Main Index | Thread Index | Old Index