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)