diff -up dhcp-4.3.1/common/options.c.option97 dhcp-4.3.1/common/options.c --- dhcp-4.3.1/common/options.c.option97 2014-12-17 10:49:23.364257702 +0100 +++ dhcp-4.3.1/common/options.c 2014-12-17 10:49:23.458256518 +0100 @@ -4270,13 +4270,26 @@ int validate_packet(struct packet *packe "a future version of ISC DHCP will reject this"); } } else { - /* - * If hlen is 0 we don't have any identifier, we warn the user - * but continue processing the packet as we can. - */ - if (packet->raw->hlen == 0) { - log_debug("Received DHCPv4 packet without client-id" - " option and empty hlen field."); + oc = lookup_option (&dhcp_universe, packet->options, + DHO_PXE_CLIENT_ID); + if (oc) { + /* Let's check if pxe-client-id is sane */ + if ((oc->data.len < 2) || + (oc->data.data[0] == '\0' && + oc->data.len != 17)) { + log_debug("Dropped DHCPv4 packet with wrong " + "(len == %d) pxe-client-id", oc->data.len); + return (0); + } + } else { + /* + * If hlen is 0 we don't have any identifier, we warn the user + * but continue processing the packet as we can. + */ + if (packet->raw->hlen == 0) { + log_debug("Received DHCPv4 packet without client-id" + " option and empty hlen field."); + } } } diff -up dhcp-4.3.1/common/tables.c.option97 dhcp-4.3.1/common/tables.c --- dhcp-4.3.1/common/tables.c.option97 2014-12-17 10:49:23.365257689 +0100 +++ dhcp-4.3.1/common/tables.c 2014-12-17 10:49:23.459256505 +0100 @@ -197,8 +197,9 @@ static struct option dhcp_options[] = { /* Defined by RFC 4578 */ { "pxe-system-type", "S", &dhcp_universe, 93, 1 }, { "pxe-interface-id", "BBB", &dhcp_universe, 94, 1 }, - { "pxe-client-id", "BX", &dhcp_universe, 97, 1 }, #endif + { "pxe-client-id", "BX", &dhcp_universe, 97, 1 }, + { "uap-servers", "t", &dhcp_universe, 98, 1 }, #if defined(RFC4776_OPTIONS) { "geoconf-civic", "X", &dhcp_universe, 99, 1 }, diff -up dhcp-4.3.1/includes/dhcp.h.option97 dhcp-4.3.1/includes/dhcp.h --- dhcp-4.3.1/includes/dhcp.h.option97 2014-12-17 10:49:23.377257538 +0100 +++ dhcp-4.3.1/includes/dhcp.h 2014-12-17 10:49:23.459256505 +0100 @@ -159,6 +159,7 @@ struct dhcp_packet { #define DHO_AUTHENTICATE 90 /* RFC3118, was 210 */ #define DHO_CLIENT_LAST_TRANSACTION_TIME 91 #define DHO_ASSOCIATED_IP 92 +#define DHO_PXE_CLIENT_ID 97 /* RFC4578 */ #define DHO_SUBNET_SELECTION 118 /* RFC3011! */ #define DHO_DOMAIN_SEARCH 119 /* RFC3397 */ #define DHO_CLASSLESS_STATIC_ROUTES 121 /* RFC3442 */ diff -up dhcp-4.3.1/server/dhcp.c.option97 dhcp-4.3.1/server/dhcp.c --- dhcp-4.3.1/server/dhcp.c.option97 2014-12-17 10:49:23.409257135 +0100 +++ dhcp-4.3.1/server/dhcp.c 2014-12-17 10:49:23.460256492 +0100 @@ -196,6 +196,10 @@ dhcp (struct packet *packet) { oc = lookup_option (&dhcp_universe, packet -> options, DHO_DHCP_CLIENT_IDENTIFIER); if (!oc) + oc = lookup_option (&dhcp_universe, + packet -> options, + DHO_PXE_CLIENT_ID); + if (!oc) goto nolease; memset (&data, 0, sizeof data); @@ -764,6 +768,9 @@ void dhcprelease (packet, ms_nulltp) oc = lookup_option (&dhcp_universe, packet -> options, DHO_DHCP_CLIENT_IDENTIFIER); + if (!oc) + oc = lookup_option (&dhcp_universe, packet -> options, + DHO_PXE_CLIENT_ID); memset (&data, 0, sizeof data); if (oc && evaluate_option_cache (&data, packet, (struct lease *)0, @@ -1191,6 +1198,9 @@ void dhcpinform (packet, ms_nulltp) */ oc = lookup_option(&dhcp_universe, packet->options, DHO_DHCP_CLIENT_IDENTIFIER); + if (!oc) + oc = lookup_option (&dhcp_universe, packet -> options, + DHO_PXE_CLIENT_ID); memset(&d1, 0, sizeof(d1)); if (oc && evaluate_option_cache(&d1, packet, NULL, NULL, @@ -2144,6 +2154,9 @@ void ack_lease (packet, lease, offer, wh can be used. */ oc = lookup_option (&dhcp_universe, packet -> options, DHO_DHCP_CLIENT_IDENTIFIER); + if (!oc) + oc = lookup_option (&dhcp_universe, packet -> options, + DHO_PXE_CLIENT_ID); if (oc && evaluate_option_cache (&d1, packet, lease, (struct client_state *)0, @@ -2715,6 +2728,9 @@ void ack_lease (packet, lease, offer, wh /* Record the uid, if given... */ oc = lookup_option (&dhcp_universe, packet -> options, DHO_DHCP_CLIENT_IDENTIFIER); + if (!oc) + oc = lookup_option (&dhcp_universe, packet -> options, + DHO_PXE_CLIENT_ID); if (oc && evaluate_option_cache(&d1, packet, lease, NULL, packet->options, state->options, @@ -3812,6 +3828,9 @@ int find_lease (struct lease **lp, specified unique client identifier. */ oc = lookup_option (&dhcp_universe, packet -> options, DHO_DHCP_CLIENT_IDENTIFIER); + if (!oc) + oc = lookup_option (&dhcp_universe, packet -> options, + DHO_PXE_CLIENT_ID); memset (&client_identifier, 0, sizeof client_identifier); if (oc && evaluate_option_cache (&client_identifier, diff -up dhcp-4.3.1/server/dhcpd.conf.5.option97 dhcp-4.3.1/server/dhcpd.conf.5 --- dhcp-4.3.1/server/dhcpd.conf.5.option97 2014-12-17 10:49:23.325258193 +0100 +++ dhcp-4.3.1/server/dhcpd.conf.5 2014-12-17 10:49:23.461256480 +0100 @@ -1559,10 +1559,12 @@ should be a name identifying the host. not specified for the host, \fIhostname\fR is used. .PP \fIHost\fR declarations are matched to actual DHCP or BOOTP clients -by matching the \fRdhcp-client-identifier\fR option specified in the +by matching the \fIdhcp-client-identifier\fR or \fIpxe-client-id\fR +options specified in the \fIhost\fR declaration to the one supplied by the client, or, if the \fIhost\fR declaration or the client does not provide a -\fRdhcp-client-identifier\fR option, by matching the \fIhardware\fR +\fIdhcp-client-identifier\fR or \fIpxe-client-id\fR options, +by matching the \fIhardware\fR parameter in the \fIhost\fR declaration to the network hardware address supplied by the client. BOOTP clients do not normally provide a \fIdhcp-client-identifier\fR, so the hardware address must @@ -1574,7 +1576,8 @@ to identify hosts. .PP Please be aware that .B only -the \fIdhcp-client-identifier\fR option and the hardware address can be +the \fIdhcp-client-identifier\fR and \fIpxe-client-id\fR +options and the hardware address can be used to match a host declaration, or the \fIhost-identifier option\fR parameter for DHCPv6 servers. For example, it is not possible to match a host declaration to a \fIhost-name\fR option. This is diff -up dhcp-4.3.1/server/dhcpleasequery.c.option97 dhcp-4.3.1/server/dhcpleasequery.c --- dhcp-4.3.1/server/dhcpleasequery.c.option97 2014-08-07 00:35:02.000000000 +0200 +++ dhcp-4.3.1/server/dhcpleasequery.c 2014-12-17 10:49:23.457256530 +0100 @@ -269,7 +269,7 @@ dhcpleasequery(struct packet *packet, in */ memset(&uid, 0, sizeof(uid)); - if (get_option(&uid, + i = get_option(&uid, &dhcp_universe, packet, NULL, @@ -279,8 +279,20 @@ dhcpleasequery(struct packet *packet, in packet->options, &global_scope, DHO_DHCP_CLIENT_IDENTIFIER, - MDL)) { - + MDL); + if (!i) + i = get_option(&uid, + &dhcp_universe, + packet, + NULL, + NULL, + packet->options, + NULL, + packet->options, + &global_scope, + DHO_PXE_CLIENT_ID, + MDL); + if (i) { snprintf(dbg_info, sizeof(dbg_info), "client-id %s", diff -up dhcp-4.3.1/server/failover.c.option97 dhcp-4.3.1/server/failover.c --- dhcp-4.3.1/server/failover.c.option97 2014-12-17 10:49:23.413257085 +0100 +++ dhcp-4.3.1/server/failover.c 2014-12-17 10:49:23.462256467 +0100 @@ -5878,6 +5878,9 @@ int load_balance_mine (struct packet *pa oc = lookup_option(&dhcp_universe, packet->options, DHO_DHCP_CLIENT_IDENTIFIER); + if (!oc) + oc = lookup_option(&dhcp_universe, packet -> options, + DHO_PXE_CLIENT_ID); memset(&ds, 0, sizeof ds); if (oc && evaluate_option_cache(&ds, packet, NULL, NULL, diff -up dhcp-4.3.1/server/mdb.c.option97 dhcp-4.3.1/server/mdb.c --- dhcp-4.3.1/server/mdb.c.option97 2014-08-07 00:35:03.000000000 +0200 +++ dhcp-4.3.1/server/mdb.c 2014-12-17 10:49:23.463256455 +0100 @@ -130,8 +130,9 @@ static int find_uid_statement (struct ex esp -> data.option && (esp -> data.option -> option -> universe == &dhcp_universe) && - (esp -> data.option -> option -> code == - DHO_DHCP_CLIENT_IDENTIFIER)) { + ((esp -> data.option -> option -> code == + DHO_DHCP_CLIENT_IDENTIFIER) || + (esp -> data.option -> option -> code == DHO_PXE_CLIENT_ID))) { if (condp) { log_error ("dhcp client identifier may not be %s", "specified conditionally.");