7a016a6
diff -up dhcp-4.3.5b1/common/options.c.option97 dhcp-4.3.5b1/common/options.c
7a016a6
--- dhcp-4.3.5b1/common/options.c.option97	2016-09-12 17:17:13.972691041 +0200
7a016a6
+++ dhcp-4.3.5b1/common/options.c	2016-09-12 17:19:17.706790276 +0200
7a016a6
@@ -4434,13 +4434,26 @@ int validate_packet(struct packet *packe
5d40954
 				"a future version of ISC DHCP will reject this");
5d40954
 		}
5d40954
 	} else {
7a016a6
-		/*
5d40954
-		 * If hlen is 0 we don't have any identifier, we warn the user
5d40954
-		 * but continue processing the packet as we can.
5d40954
-		 */
5d40954
-		if (packet->raw->hlen == 0) {
5d40954
-			log_debug("Received DHCPv4 packet without client-id"
5d40954
-				  " option and empty hlen field.");
5d40954
+		oc = lookup_option (&dhcp_universe, packet->options,
5d40954
+				    DHO_PXE_CLIENT_ID);
5d40954
+		if (oc) {
5d40954
+			/* Let's check if pxe-client-id is sane */
5d40954
+			if ((oc->data.len < 2) ||
5d40954
+			    (oc->data.data[0] == '\0' &&
5d40954
+			     oc->data.len != 17)) {
5d40954
+				log_debug("Dropped DHCPv4 packet with wrong "
5d40954
+				    "(len == %d) pxe-client-id", oc->data.len);
5d40954
+				return (0);
5d40954
+			}
5d40954
+		} else {
5d40954
+			/*
5d40954
+			 * If hlen is 0 we don't have any identifier, we warn the user
5d40954
+			 * but continue processing the packet as we can.
5d40954
+			 */
5d40954
+			if (packet->raw->hlen == 0) {
5d40954
+				log_debug("Received DHCPv4 packet without client-id"
5d40954
+						" option and empty hlen field.");
5d40954
+			}
5d40954
 		}
5d40954
 	}
5d40954
 
7a016a6
diff -up dhcp-4.3.5b1/common/tables.c.option97 dhcp-4.3.5b1/common/tables.c
7a016a6
--- dhcp-4.3.5b1/common/tables.c.option97	2016-09-12 17:17:13.927691005 +0200
7a016a6
+++ dhcp-4.3.5b1/common/tables.c	2016-09-12 17:17:13.972691041 +0200
7a016a6
@@ -196,8 +196,9 @@ static struct option dhcp_options[] = {
5d40954
 	/* Defined by RFC 4578 */
5d40954
 	{ "pxe-system-type", "S",		&dhcp_universe,  93, 1 },
5d40954
 	{ "pxe-interface-id", "BBB",		&dhcp_universe,  94, 1 },
5d40954
-	{ "pxe-client-id", "BX",		&dhcp_universe,  97, 1 },
5d40954
 #endif
5d40954
+	{ "pxe-client-id", "BX",		&dhcp_universe,  97, 1 },
5d40954
+
5d40954
 	{ "uap-servers", "t",			&dhcp_universe,  98, 1 },
5d40954
 #if defined(RFC4776_OPTIONS)
5d40954
         { "geoconf-civic", "X",                 &dhcp_universe, 99, 1 },
7a016a6
diff -up dhcp-4.3.5b1/includes/dhcp.h.option97 dhcp-4.3.5b1/includes/dhcp.h
7a016a6
--- dhcp-4.3.5b1/includes/dhcp.h.option97	2016-09-12 17:17:13.936691013 +0200
7a016a6
+++ dhcp-4.3.5b1/includes/dhcp.h	2016-09-12 17:17:13.972691041 +0200
5d40954
@@ -159,6 +159,7 @@ struct dhcp_packet {
5d40954
 #define DHO_AUTHENTICATE			90  /* RFC3118, was 210 */
5d40954
 #define DHO_CLIENT_LAST_TRANSACTION_TIME	91
5d40954
 #define DHO_ASSOCIATED_IP			92
5d40954
+#define DHO_PXE_CLIENT_ID			97  /* RFC4578 */
5d40954
 #define DHO_SUBNET_SELECTION			118 /* RFC3011! */
5d40954
 #define DHO_DOMAIN_SEARCH			119 /* RFC3397 */
5d40954
 #define DHO_CLASSLESS_STATIC_ROUTES		121 /* RFC3442 */
7a016a6
diff -up dhcp-4.3.5b1/server/dhcp.c.option97 dhcp-4.3.5b1/server/dhcp.c
7a016a6
--- dhcp-4.3.5b1/server/dhcp.c.option97	2016-09-12 17:17:13.947691021 +0200
7a016a6
+++ dhcp-4.3.5b1/server/dhcp.c	2016-09-12 17:17:13.973691042 +0200
7a016a6
@@ -221,6 +221,10 @@ dhcp (struct packet *packet) {
5d40954
 			oc = lookup_option (&dhcp_universe, packet -> options,
5d40954
 					    DHO_DHCP_CLIENT_IDENTIFIER);
5d40954
 			if (!oc)
5d40954
+				oc = lookup_option (&dhcp_universe,
5d40954
+						    packet -> options,
5d40954
+						    DHO_PXE_CLIENT_ID);
5d40954
+			if (!oc)
5d40954
 				goto nolease;
5d40954
 
5d40954
 			memset (&data, 0, sizeof data);
7a016a6
@@ -818,6 +822,9 @@ void dhcprelease (packet, ms_nulltp)
5d40954
 
5d40954
 	oc = lookup_option (&dhcp_universe, packet -> options,
5d40954
 			    DHO_DHCP_CLIENT_IDENTIFIER);
5d40954
+	if (!oc)
5d40954
+		oc = lookup_option (&dhcp_universe, packet -> options,
5d40954
+				    DHO_PXE_CLIENT_ID);
5d40954
 	memset (&data, 0, sizeof data);
5d40954
 	if (oc &&
5d40954
 	    evaluate_option_cache (&data, packet, (struct lease *)0,
7a016a6
@@ -1286,6 +1293,9 @@ void dhcpinform (packet, ms_nulltp)
5d40954
          */
5d40954
 	oc = lookup_option(&dhcp_universe, packet->options,
5d40954
 			   DHO_DHCP_CLIENT_IDENTIFIER);
5d40954
+	if (!oc)
5d40954
+		oc = lookup_option (&dhcp_universe, packet -> options,
5d40954
+				    DHO_PXE_CLIENT_ID);
5d40954
 	memset(&d1, 0, sizeof(d1));
5d40954
 	if (oc &&
5d40954
 	    evaluate_option_cache(&d1, packet, NULL, NULL,
7a016a6
@@ -2381,6 +2391,9 @@ void ack_lease (packet, lease, offer, wh
5d40954
 		   can be used. */
5d40954
 		oc = lookup_option (&dhcp_universe, packet -> options,
5d40954
 				    DHO_DHCP_CLIENT_IDENTIFIER);
5d40954
+		if (!oc)
5d40954
+			oc = lookup_option (&dhcp_universe, packet -> options,
5d40954
+					    DHO_PXE_CLIENT_ID);
5d40954
 		if (oc &&
5d40954
 		    evaluate_option_cache (&d1, packet, lease,
5d40954
 					   (struct client_state *)0,
7a016a6
@@ -2962,6 +2975,9 @@ void ack_lease (packet, lease, offer, wh
5d40954
 		/* Record the uid, if given... */
5d40954
 		oc = lookup_option (&dhcp_universe, packet -> options,
5d40954
 				    DHO_DHCP_CLIENT_IDENTIFIER);
5d40954
+		if (!oc)
5d40954
+			oc = lookup_option (&dhcp_universe, packet -> options,
5d40954
+					    DHO_PXE_CLIENT_ID);
5d40954
 		if (oc &&
5d40954
 		    evaluate_option_cache(&d1, packet, lease, NULL,
5d40954
 					  packet->options, state->options,
7a016a6
@@ -4068,6 +4084,9 @@ int find_lease (struct lease **lp,
5d40954
 	   specified unique client identifier. */
5d40954
 	oc = lookup_option (&dhcp_universe, packet -> options,
5d40954
 			    DHO_DHCP_CLIENT_IDENTIFIER);
5d40954
+	if (!oc)
5d40954
+		oc = lookup_option (&dhcp_universe, packet -> options,
5d40954
+				    DHO_PXE_CLIENT_ID);
5d40954
 	memset (&client_identifier, 0, sizeof client_identifier);
5d40954
 	if (oc &&
5d40954
 	    evaluate_option_cache (&client_identifier,
7a016a6
diff -up dhcp-4.3.5b1/server/dhcpd.conf.5.option97 dhcp-4.3.5b1/server/dhcpd.conf.5
7a016a6
--- dhcp-4.3.5b1/server/dhcpd.conf.5.option97	2016-09-12 17:17:13.885690972 +0200
7a016a6
+++ dhcp-4.3.5b1/server/dhcpd.conf.5	2016-09-12 17:17:13.974691043 +0200
7a016a6
@@ -1587,10 +1587,12 @@ should be a name identifying the host.
5d40954
 not specified for the host, \fIhostname\fR is used.
5d40954
 .PP
5d40954
 \fIHost\fR declarations are matched to actual DHCP or BOOTP clients
5d40954
-by matching the \fRdhcp-client-identifier\fR option specified in the
5d40954
+by matching the \fIdhcp-client-identifier\fR or \fIpxe-client-id\fR
5d40954
+options specified in the
5d40954
 \fIhost\fR declaration to the one supplied by the client, or, if the
5d40954
 \fIhost\fR declaration or the client does not provide a
5d40954
-\fRdhcp-client-identifier\fR option, by matching the \fIhardware\fR
5d40954
+\fIdhcp-client-identifier\fR or \fIpxe-client-id\fR options,
5d40954
+by matching the \fIhardware\fR
5d40954
 parameter in the \fIhost\fR declaration to the network hardware
5d40954
 address supplied by the client.  BOOTP clients do not normally
5d40954
 provide a \fIdhcp-client-identifier\fR, so the hardware address must
7a016a6
@@ -1602,7 +1604,8 @@ to identify hosts.
5d40954
 .PP
5d40954
 Please be aware that
5d40954
 .B only
5d40954
-the \fIdhcp-client-identifier\fR option and the hardware address can be
5d40954
+the \fIdhcp-client-identifier\fR and \fIpxe-client-id\fR
5d40954
+options and the hardware address can be
5d40954
 used to match a host declaration, or the \fIhost-identifier option\fR
5d40954
 parameter for DHCPv6 servers.  For example, it is not possible to
5d40954
 match a host declaration to a \fIhost-name\fR option.  This is
7a016a6
diff -up dhcp-4.3.5b1/server/dhcpleasequery.c.option97 dhcp-4.3.5b1/server/dhcpleasequery.c
7a016a6
--- dhcp-4.3.5b1/server/dhcpleasequery.c.option97	2016-08-26 20:19:53.000000000 +0200
7a016a6
+++ dhcp-4.3.5b1/server/dhcpleasequery.c	2016-09-12 17:17:13.974691043 +0200
7a016a6
@@ -273,7 +273,7 @@ dhcpleasequery(struct packet *packet, in
5d40954
 		 */
5d40954
 
5d40954
 		memset(&uid, 0, sizeof(uid));
5d40954
-		if (get_option(&uid, 
5d40954
+		i = get_option(&uid,
5d40954
 			       &dhcp_universe,
5d40954
 			       packet,
5d40954
 			       NULL,
7a016a6
@@ -283,8 +283,20 @@ dhcpleasequery(struct packet *packet, in
5d40954
 			       packet->options, 
5d40954
 			       &global_scope,
5d40954
 			       DHO_DHCP_CLIENT_IDENTIFIER,
5d40954
-			       MDL)) {
5d40954
-
5d40954
+			       MDL);
5d40954
+		if (!i)
5d40954
+			i = get_option(&uid,
5d40954
+				       &dhcp_universe,
5d40954
+				       packet,
5d40954
+				       NULL,
5d40954
+				       NULL,
5d40954
+				       packet->options,
5d40954
+				       NULL,
5d40954
+				       packet->options,
5d40954
+				       &global_scope,
5d40954
+				       DHO_PXE_CLIENT_ID,
5d40954
+				       MDL);
5d40954
+		if (i) {
5d40954
 			snprintf(dbg_info, 
5d40954
 				 sizeof(dbg_info), 
5d40954
 				 "client-id %s",
7a016a6
diff -up dhcp-4.3.5b1/server/failover.c.option97 dhcp-4.3.5b1/server/failover.c
7a016a6
--- dhcp-4.3.5b1/server/failover.c.option97	2016-08-26 20:19:53.000000000 +0200
7a016a6
+++ dhcp-4.3.5b1/server/failover.c	2016-09-12 17:17:13.975691044 +0200
7a016a6
@@ -5957,6 +5957,9 @@ int load_balance_mine (struct packet *pa
5d40954
 
5d40954
 	oc = lookup_option(&dhcp_universe, packet->options,
5d40954
 			   DHO_DHCP_CLIENT_IDENTIFIER);
5d40954
+	if (!oc)
5d40954
+		oc = lookup_option(&dhcp_universe, packet -> options,
5d40954
+				    DHO_PXE_CLIENT_ID);
5d40954
 	memset(&ds, 0, sizeof ds);
5d40954
 	if (oc &&
5d40954
 	    evaluate_option_cache(&ds, packet, NULL, NULL,
7a016a6
diff -up dhcp-4.3.5b1/server/mdb.c.option97 dhcp-4.3.5b1/server/mdb.c
7a016a6
--- dhcp-4.3.5b1/server/mdb.c.option97	2016-08-26 20:19:53.000000000 +0200
7a016a6
+++ dhcp-4.3.5b1/server/mdb.c	2016-09-12 17:17:13.975691044 +0200
7a016a6
@@ -129,8 +129,9 @@ static int find_uid_statement (struct ex
5d40954
 	    esp -> data.option &&
5d40954
 	    (esp -> data.option -> option -> universe ==
5d40954
 	     &dhcp_universe) &&
5d40954
-	    (esp -> data.option -> option -> code ==
5d40954
-	     DHO_DHCP_CLIENT_IDENTIFIER)) {
5d40954
+	    ((esp -> data.option -> option -> code ==
5d40954
+						DHO_DHCP_CLIENT_IDENTIFIER) ||
5d40954
+	     (esp -> data.option -> option -> code == DHO_PXE_CLIENT_ID))) {
5d40954
 		if (condp) {
5d40954
 			log_error ("dhcp client identifier may not be %s",
5d40954
 				   "specified conditionally.");