1 From f01a29a90269c98a86accb0923d65aecf5f59b44 Mon Sep 17 00:00:00 2001
2 From: Pavel Zhukov <pzhukov@redhat.com>
3 Date: Thu, 28 Feb 2019 16:40:38 +0100
4 Subject: [PATCH 23/28] option 97 - pxe-client-id
6 Bug-url: https://bugzilla.redhat.com/1058674
9 common/options.c | 27 ++++++++++++++++++++-------
10 common/tables.c | 3 ++-
12 server/dhcp.c | 19 +++++++++++++++++++
13 server/dhcpd.conf.5 | 9 ++++++---
14 server/dhcpleasequery.c | 18 +++++++++++++++---
15 server/failover.c | 3 +++
16 server/mdb.c | 5 +++--
17 8 files changed, 69 insertions(+), 16 deletions(-)
19 diff --git a/common/options.c b/common/options.c
20 index 66433c4..4e26094 100644
21 --- a/common/options.c
22 +++ b/common/options.c
23 @@ -4551,13 +4551,26 @@ int validate_packet(struct packet *packet)
24 "a future version of ISC DHCP will reject this");
28 - * If hlen is 0 we don't have any identifier, we warn the user
29 - * but continue processing the packet as we can.
31 - if (packet->raw->hlen == 0) {
32 - log_debug("Received DHCPv4 packet without client-id"
33 - " option and empty hlen field.");
34 + oc = lookup_option (&dhcp_universe, packet->options,
37 + /* Let's check if pxe-client-id is sane */
38 + if ((oc->data.len < 2) ||
39 + (oc->data.data[0] == '\0' &&
40 + oc->data.len != 17)) {
41 + log_debug("Dropped DHCPv4 packet with wrong "
42 + "(len == %d) pxe-client-id", oc->data.len);
47 + * If hlen is 0 we don't have any identifier, we warn the user
48 + * but continue processing the packet as we can.
50 + if (packet->raw->hlen == 0) {
51 + log_debug("Received DHCPv4 packet without client-id"
52 + " option and empty hlen field.");
57 diff --git a/common/tables.c b/common/tables.c
58 index 96521a6..8034d94 100644
61 @@ -200,8 +200,9 @@ static struct option dhcp_options[] = {
62 /* Defined by RFC 4578 */
63 { "pxe-system-type", "Sa", &dhcp_universe, 93, 1 },
64 { "pxe-interface-id", "BBB", &dhcp_universe, 94, 1 },
65 - { "pxe-client-id", "BX", &dhcp_universe, 97, 1 },
67 + { "pxe-client-id", "BX", &dhcp_universe, 97, 1 },
69 { "uap-servers", "t", &dhcp_universe, 98, 1 },
70 #if defined(RFC4776_OPTIONS)
71 { "geoconf-civic", "X", &dhcp_universe, 99, 1 },
72 diff --git a/includes/dhcp.h b/includes/dhcp.h
73 index 7202f1d..4ad3874 100644
76 @@ -158,6 +158,7 @@ struct dhcp_packet {
77 #define DHO_AUTHENTICATE 90 /* RFC3118, was 210 */
78 #define DHO_CLIENT_LAST_TRANSACTION_TIME 91
79 #define DHO_ASSOCIATED_IP 92
80 +#define DHO_PXE_CLIENT_ID 97 /* RFC4578 */
81 #define DHO_V6_ONLY_PREFERRED 108 /* RFC8925 */
82 #define DHO_SUBNET_SELECTION 118 /* RFC3011! */
83 #define DHO_DOMAIN_SEARCH 119 /* RFC3397 */
84 diff --git a/server/dhcp.c b/server/dhcp.c
85 index 8363840..29d9c69 100644
88 @@ -228,6 +228,10 @@ dhcp (struct packet *packet) {
89 if (lease -> uid_len) {
90 oc = lookup_option (&dhcp_universe, packet -> options,
91 DHO_DHCP_CLIENT_IDENTIFIER);
93 + oc = lookup_option (&dhcp_universe,
99 @@ -826,6 +830,9 @@ void dhcprelease (packet, ms_nulltp)
101 oc = lookup_option (&dhcp_universe, packet -> options,
102 DHO_DHCP_CLIENT_IDENTIFIER);
104 + oc = lookup_option (&dhcp_universe, packet -> options,
105 + DHO_PXE_CLIENT_ID);
106 memset (&data, 0, sizeof data);
108 evaluate_option_cache (&data, packet, (struct lease *)0,
109 @@ -1338,6 +1345,9 @@ void dhcpinform (packet, ms_nulltp)
111 oc = lookup_option(&dhcp_universe, packet->options,
112 DHO_DHCP_CLIENT_IDENTIFIER);
114 + oc = lookup_option (&dhcp_universe, packet -> options,
115 + DHO_PXE_CLIENT_ID);
116 memset(&d1, 0, sizeof(d1));
118 evaluate_option_cache(&d1, packet, NULL, NULL,
119 @@ -2448,6 +2458,9 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
121 oc = lookup_option (&dhcp_universe, packet -> options,
122 DHO_DHCP_CLIENT_IDENTIFIER);
124 + oc = lookup_option (&dhcp_universe, packet -> options,
125 + DHO_PXE_CLIENT_ID);
127 evaluate_option_cache (&d1, packet, lease,
128 (struct client_state *)0,
129 @@ -3040,6 +3053,9 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
130 /* Record the uid, if given... */
131 oc = lookup_option (&dhcp_universe, packet -> options,
132 DHO_DHCP_CLIENT_IDENTIFIER);
134 + oc = lookup_option (&dhcp_universe, packet -> options,
135 + DHO_PXE_CLIENT_ID);
137 evaluate_option_cache(&d1, packet, lease, NULL,
138 packet->options, state->options,
139 @@ -4258,6 +4274,9 @@ int find_lease (struct lease **lp,
140 specified unique client identifier. */
141 oc = lookup_option (&dhcp_universe, packet -> options,
142 DHO_DHCP_CLIENT_IDENTIFIER);
144 + oc = lookup_option (&dhcp_universe, packet -> options,
145 + DHO_PXE_CLIENT_ID);
146 memset (&client_identifier, 0, sizeof client_identifier);
148 evaluate_option_cache (&client_identifier,
149 diff --git a/server/dhcpd.conf.5 b/server/dhcpd.conf.5
150 index b7e79ea..2354b1d 100644
151 --- a/server/dhcpd.conf.5
152 +++ b/server/dhcpd.conf.5
153 @@ -1664,10 +1664,12 @@ should be a name identifying the host. If a \fIhostname\fR option is
154 not specified for the host, \fIhostname\fR is used.
156 \fIHost\fR declarations are matched to actual DHCP or BOOTP clients
157 -by matching the \fRdhcp-client-identifier\fR option specified in the
158 +by matching the \fIdhcp-client-identifier\fR or \fIpxe-client-id\fR
159 +options specified in the
160 \fIhost\fR declaration to the one supplied by the client, or, if the
161 \fIhost\fR declaration or the client does not provide a
162 -\fRdhcp-client-identifier\fR option, by matching the \fIhardware\fR
163 +\fIdhcp-client-identifier\fR or \fIpxe-client-id\fR options,
164 +by matching the \fIhardware\fR
165 parameter in the \fIhost\fR declaration to the network hardware
166 address supplied by the client. BOOTP clients do not normally
167 provide a \fIdhcp-client-identifier\fR, so the hardware address must
168 @@ -1679,7 +1681,8 @@ to identify hosts.
172 -the \fIdhcp-client-identifier\fR option and the hardware address can be
173 +the \fIdhcp-client-identifier\fR and \fIpxe-client-id\fR
174 +options and the hardware address can be
175 used to match a host declaration, or the \fIhost-identifier option\fR
176 parameter for DHCPv6 servers. For example, it is not possible to
177 match a host declaration to a \fIhost-name\fR option. This is
178 diff --git a/server/dhcpleasequery.c b/server/dhcpleasequery.c
179 index 0f1d4f7..dae4ae7 100644
180 --- a/server/dhcpleasequery.c
181 +++ b/server/dhcpleasequery.c
182 @@ -276,7 +276,7 @@ dhcpleasequery(struct packet *packet, int ms_nulltp) {
185 memset(&uid, 0, sizeof(uid));
186 - if (get_option(&uid,
187 + i = get_option(&uid,
191 @@ -286,8 +286,20 @@ dhcpleasequery(struct packet *packet, int ms_nulltp) {
194 DHO_DHCP_CLIENT_IDENTIFIER,
199 + i = get_option(&uid,
214 diff --git a/server/failover.c b/server/failover.c
215 index 5b36d3a..a641e86 100644
216 --- a/server/failover.c
217 +++ b/server/failover.c
218 @@ -5988,6 +5988,9 @@ int load_balance_mine (struct packet *packet, dhcp_failover_state_t *state)
220 oc = lookup_option(&dhcp_universe, packet->options,
221 DHO_DHCP_CLIENT_IDENTIFIER);
223 + oc = lookup_option(&dhcp_universe, packet -> options,
224 + DHO_PXE_CLIENT_ID);
225 memset(&ds, 0, sizeof ds);
227 evaluate_option_cache(&ds, packet, NULL, NULL,
228 diff --git a/server/mdb.c b/server/mdb.c
229 index 60a40e1..2cd5605 100644
232 @@ -129,8 +129,9 @@ static int find_uid_statement (struct executable_statement *esp,
233 esp -> data.option &&
234 (esp -> data.option -> option -> universe ==
236 - (esp -> data.option -> option -> code ==
237 - DHO_DHCP_CLIENT_IDENTIFIER)) {
238 + ((esp -> data.option -> option -> code ==
239 + DHO_DHCP_CLIENT_IDENTIFIER) ||
240 + (esp -> data.option -> option -> code == DHO_PXE_CLIENT_ID))) {
242 log_error ("dhcp client identifier may not be %s",
243 "specified conditionally.");