]> git.ipfire.org Git - thirdparty/dhcp.git/blame - server/dhcp.c
[master] Add abandon-lease-time parameter
[thirdparty/dhcp.git] / server / dhcp.c
CommitLineData
d7837182
TL
1/* dhcp.c
2
b88e8e15 3 DHCP Protocol engine. */
d7837182
TL
4
5/*
606f2720 6 * Copyright (c) 2004-2016 by Internet Systems Consortium, Inc. ("ISC")
98311e4b 7 * Copyright (c) 1995-2003 by Internet Software Consortium
d7837182 8 *
98311e4b
DH
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
d7837182 12 *
98311e4b
DH
13 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
d7837182 20 *
98311e4b
DH
21 * Internet Systems Consortium, Inc.
22 * 950 Charter Street
23 * Redwood City, CA 94063
24 * <info@isc.org>
2c85ac9b 25 * https://www.isc.org/
49733f31 26 *
d7837182
TL
27 */
28
d7837182 29#include "dhcpd.h"
fe5b0fdd
DH
30#include <errno.h>
31#include <limits.h>
f8cbf390
DH
32#include <sys/time.h>
33
a1308b64
DH
34static void maybe_return_agent_options(struct packet *packet,
35 struct option_state *options);
f3a44c10
TM
36static int reuse_lease (struct packet* packet, struct lease* new_lease,
37 struct lease* lease, struct lease_state *state,
38 int offer);
785c1a51
FD
39#if defined(DHCPv6) && defined(DHCP4o6)
40static int locate_network6(struct packet *packet);
41#endif
d7837182 42
4b7df707
TL
43int outstanding_pings;
44
e422b8c7
TM
45#if defined(DELAYED_ACK)
46static void delayed_ack_enqueue(struct lease *);
47static void delayed_acks_timer(void *);
48
49
6368a1bd
DH
50struct leasequeue *ackqueue_head, *ackqueue_tail;
51static struct leasequeue *free_ackqueue;
0585235c
SR
52static struct timeval max_fsync;
53
6368a1bd
DH
54int outstanding_acks;
55int max_outstanding_acks = DEFAULT_DELAYED_ACK;
f8cbf390
DH
56int max_ack_delay_secs = DEFAULT_ACK_DELAY_SECS;
57int max_ack_delay_usecs = DEFAULT_ACK_DELAY_USECS;
0585235c 58int min_ack_delay_usecs = DEFAULT_MIN_ACK_DELAY_USECS;
e422b8c7 59#endif
6368a1bd 60
a7822eac 61static char dhcp_message [256];
2c9bf1f4
DH
62static int site_code_min;
63
64static int find_min_site_code(struct universe *);
65static isc_result_t lowest_site_code(const void *, unsigned, void *);
b88e8e15 66
d758ad8c
TL
67static const char *dhcp_type_names [] = {
68 "DHCPDISCOVER",
69 "DHCPOFFER",
70 "DHCPREQUEST",
71 "DHCPDECLINE",
72 "DHCPACK",
73 "DHCPNAK",
74 "DHCPRELEASE",
6d103865 75 "DHCPINFORM",
51e7687f 76 "type 9",
6d103865
SK
77 "DHCPLEASEQUERY",
78 "DHCPLEASEUNASSIGNED",
79 "DHCPLEASEUNKNOWN",
80 "DHCPLEASEACTIVE"
d758ad8c
TL
81};
82const int dhcp_type_name_max = ((sizeof dhcp_type_names) / sizeof (char *));
83
27e90ede
TL
84#if defined (TRACING)
85# define send_packet trace_packet_send
86#endif
87
51e7687f
EH
88void
89dhcp (struct packet *packet) {
5bc2e1f2 90 int ms_nulltp = 0;
c99a6692 91 struct option_cache *oc;
51e7687f 92 struct lease *lease = NULL;
9e383163
TL
93 const char *errmsg;
94 struct data_string data;
5bc2e1f2 95
51e7687f
EH
96 if (!locate_network(packet) &&
97 packet->packet_type != DHCPREQUEST &&
98 packet->packet_type != DHCPINFORM &&
99 packet->packet_type != DHCPLEASEQUERY) {
9e383163 100 const char *s;
51e7687f 101 char typebuf[32];
9e383163
TL
102 errmsg = "unknown network segment";
103 bad_packet:
104
51e7687f
EH
105 if (packet->packet_type > 0 &&
106 packet->packet_type <= dhcp_type_name_max) {
107 s = dhcp_type_names[packet->packet_type - 1];
9e383163 108 } else {
98311e4b 109 /* %Audit% Cannot exceed 28 bytes. %2004.06.17,Safe% */
51e7687f 110 sprintf(typebuf, "type %d", packet->packet_type);
9e383163
TL
111 s = typebuf;
112 }
113
785c1a51
FD
114#if defined(DHCPv6) && defined(DHCP4o6)
115 if (dhcpv4_over_dhcpv6 && (packet->dhcp4o6_response != NULL)) {
116 log_info("DHCP4o6 %s from %s via %s: %s", s,
117 (packet->raw->htype
118 ? print_hw_addr(packet->raw->htype,
119 packet->raw->hlen,
120 packet->raw->chaddr)
121 : "<no identifier>"),
122 piaddr(packet->client_addr),
123 errmsg);
124 goto out;
125 }
126#endif
127
51e7687f
EH
128 log_info("%s from %s via %s: %s", s,
129 (packet->raw->htype
130 ? print_hw_addr(packet->raw->htype,
131 packet->raw->hlen,
132 packet->raw->chaddr)
133 : "<no identifier>"),
134 packet->raw->giaddr.s_addr
135 ? inet_ntoa(packet->raw->giaddr)
136 : packet->interface->name, errmsg);
9e383163
TL
137 goto out;
138 }
139
140 /* There is a problem with the relay agent information option,
9aa3f3a5
DH
141 * which is that in order for a normal relay agent to append
142 * this option, the relay agent has to have been involved in
143 * getting the packet from the client to the server. Note
144 * that this is the software entity known as the relay agent,
145 * _not_ the hardware entity known as a router in which the
146 * relay agent may be running, so the fact that a router has
147 * forwarded a packet does not mean that the relay agent in
148 * the router was involved.
149 *
150 * So when the client broadcasts (DHCPDISCOVER, or giaddr is set),
151 * we can be sure that there are either agent options in the
152 * packet, or there aren't supposed to be. When the giaddr is not
153 * set, it's still possible that the client is on a directly
154 * attached subnet, and agent options are being appended by an l2
155 * device that has no address, and so sets no giaddr.
156 *
157 * But in either case it's possible that the packets we receive
158 * from the client in RENEW state may not include the agent options,
159 * so if they are not in the packet we must "pretend" the last values
160 * we observed were provided.
161 */
162 if (packet->packet_type == DHCPREQUEST &&
163 packet->raw->ciaddr.s_addr && !packet->raw->giaddr.s_addr &&
164 (packet->options->universe_count <= agent_universe.index ||
165 packet->options->universes[agent_universe.index] == NULL))
9e383163
TL
166 {
167 struct iaddr cip;
168
169 cip.len = sizeof packet -> raw -> ciaddr;
170 memcpy (cip.iabuf, &packet -> raw -> ciaddr,
171 sizeof packet -> raw -> ciaddr);
172 if (!find_lease_by_ip_addr (&lease, cip, MDL))
173 goto nolease;
174
175 /* If there are no agent options on the lease, it's not
176 interesting. */
177 if (!lease -> agent_options)
178 goto nolease;
179
180 /* The client should not be unicasting a renewal if its lease
181 has expired, so make it go through the process of getting
182 its agent options legally. */
183 if (lease -> ends < cur_time)
184 goto nolease;
185
186 if (lease -> uid_len) {
187 oc = lookup_option (&dhcp_universe, packet -> options,
188 DHO_DHCP_CLIENT_IDENTIFIER);
189 if (!oc)
190 goto nolease;
191
192 memset (&data, 0, sizeof data);
193 if (!evaluate_option_cache (&data,
194 packet, (struct lease *)0,
195 (struct client_state *)0,
196 packet -> options,
197 (struct option_state *)0,
198 &global_scope, oc, MDL))
199 goto nolease;
200 if (lease -> uid_len != data.len ||
201 memcmp (lease -> uid, data.data, data.len)) {
202 data_string_forget (&data, MDL);
203 goto nolease;
204 }
205 data_string_forget (&data, MDL);
206 } else
207 if ((lease -> hardware_addr.hbuf [0] !=
208 packet -> raw -> htype) ||
209 (lease -> hardware_addr.hlen - 1 !=
210 packet -> raw -> hlen) ||
211 memcmp (&lease -> hardware_addr.hbuf [1],
212 packet -> raw -> chaddr,
213 packet -> raw -> hlen))
214 goto nolease;
215
216 /* Okay, so we found a lease that matches the client. */
bfe2d221
TL
217 option_chain_head_reference ((struct option_chain_head **)
218 &(packet -> options -> universes
219 [agent_universe.index]),
220 lease -> agent_options, MDL);
9aa3f3a5
DH
221
222 if (packet->options->universe_count <= agent_universe.index)
223 packet->options->universe_count =
224 agent_universe.index + 1;
225
226 packet->agent_options_stashed = ISC_TRUE;
9e383163
TL
227 }
228 nolease:
3a581108 229
88cd8aca
DH
230 /* If a client null terminates options it sends, it probably
231 * expects the server to reciprocate.
232 */
5bc2e1f2
TL
233 if ((oc = lookup_option (&dhcp_universe, packet -> options,
234 DHO_HOST_NAME))) {
235 if (!oc -> expression)
88cd8aca 236 ms_nulltp = oc->flags & OPTION_HAD_NULLS;
5bc2e1f2
TL
237 }
238
88cd8aca 239 /* Classify the client. */
b3f15965
TL
240 classify_client (packet);
241
ed8bcd8f
TL
242 switch (packet -> packet_type) {
243 case DHCPDISCOVER:
5bc2e1f2 244 dhcpdiscover (packet, ms_nulltp);
ed8bcd8f 245 break;
97ca1699 246
ed8bcd8f 247 case DHCPREQUEST:
9e383163 248 dhcprequest (packet, ms_nulltp, lease);
ed8bcd8f 249 break;
97ca1699 250
ed8bcd8f 251 case DHCPRELEASE:
5bc2e1f2 252 dhcprelease (packet, ms_nulltp);
ed8bcd8f 253 break;
97ca1699 254
b88e8e15 255 case DHCPDECLINE:
5bc2e1f2 256 dhcpdecline (packet, ms_nulltp);
b88e8e15
TL
257 break;
258
259 case DHCPINFORM:
5bc2e1f2 260 dhcpinform (packet, ms_nulltp);
b88e8e15
TL
261 break;
262
6d103865
SK
263 case DHCPLEASEQUERY:
264 dhcpleasequery(packet, ms_nulltp);
265 break;
9e383163
TL
266
267 case DHCPACK:
268 case DHCPOFFER:
269 case DHCPNAK:
6d103865
SK
270 case DHCPLEASEUNASSIGNED:
271 case DHCPLEASEUNKNOWN:
272 case DHCPLEASEACTIVE:
ed8bcd8f 273 break;
9e383163
TL
274
275 default:
276 errmsg = "unknown packet type";
277 goto bad_packet;
97ca1699 278 }
9e383163
TL
279 out:
280 if (lease)
281 lease_dereference (&lease, MDL);
ed8bcd8f 282}
97ca1699 283
5bc2e1f2 284void dhcpdiscover (packet, ms_nulltp)
ed8bcd8f 285 struct packet *packet;
5bc2e1f2 286 int ms_nulltp;
ed8bcd8f 287{
20916cae 288 struct lease *lease = (struct lease *)0;
d9eefc5d 289 char msgbuf [1024]; /* XXX */
ffdcd127 290 TIME when;
98311e4b 291 const char *s;
33225687
TL
292 int peer_has_leases = 0;
293#if defined (FAILOVER_PROTOCOL)
294 dhcp_failover_state_t *peer;
295#endif
a8b53b42 296
bb0b00a5 297 find_lease (&lease, packet, packet -> shared_network,
88cd8aca 298 0, &peer_has_leases, (struct lease *)0, MDL);
5941275a 299
98311e4b
DH
300 if (lease && lease -> client_hostname) {
301 if ((strlen (lease -> client_hostname) <= 64) &&
28868515 302 db_printable((unsigned char *)lease->client_hostname))
98311e4b
DH
303 s = lease -> client_hostname;
304 else
305 s = "Hostname Unsuitable for Printing";
306 } else
d9eefc5d
TL
307 s = (char *)0;
308
98311e4b
DH
309 /* %Audit% This is log output. %2004.06.17,Safe%
310 * If we truncate we hope the user can get a hint from the log.
311 */
785c1a51
FD
312#if defined(DHCPv6) && defined(DHCP4o6)
313 if (dhcpv4_over_dhcpv6 && (packet->dhcp4o6_response != NULL)) {
314 snprintf (msgbuf, sizeof msgbuf,
315 "DHCP4o6 DHCPDISCOVER from %s %s%s%svia %s",
316 (packet -> raw -> htype
317 ? print_hw_addr (packet -> raw -> htype,
318 packet -> raw -> hlen,
319 packet -> raw -> chaddr)
320 : (lease
321 ? print_hex_1(lease->uid_len, lease->uid, 60)
322 : "<no identifier>")),
323 s ? "(" : "", s ? s : "", s ? ") " : "",
324 piaddr(packet->client_addr));
325 } else
326#endif
98311e4b 327 snprintf (msgbuf, sizeof msgbuf, "DHCPDISCOVER from %s %s%s%svia %s",
d9eefc5d
TL
328 (packet -> raw -> htype
329 ? print_hw_addr (packet -> raw -> htype,
330 packet -> raw -> hlen,
fdd46b53 331 packet -> raw -> chaddr)
d9eefc5d 332 : (lease
6d103865 333 ? print_hex_1(lease->uid_len, lease->uid, 60)
d9eefc5d
TL
334 : "<no identifier>")),
335 s ? "(" : "", s ? s : "", s ? ") " : "",
336 packet -> raw -> giaddr.s_addr
337 ? inet_ntoa (packet -> raw -> giaddr)
338 : packet -> interface -> name);
339
15c00bba
TL
340 /* Sourceless packets don't make sense here. */
341 if (!packet -> shared_network) {
785c1a51
FD
342#if defined(DHCPv6) && defined(DHCP4o6)
343 if (dhcpv4_over_dhcpv6 && (packet->dhcp4o6_response != NULL)) {
344 log_info ("DHCP4o6 packet from unknown subnet: %s",
345 piaddr(packet->client_addr));
346 } else
347#endif
8ae2d595 348 log_info ("Packet from unknown subnet: %s",
15c00bba 349 inet_ntoa (packet -> raw -> giaddr));
20916cae 350 goto out;
15c00bba
TL
351 }
352
d758ad8c
TL
353#if defined (FAILOVER_PROTOCOL)
354 if (lease && lease -> pool && lease -> pool -> failover_peer) {
355 peer = lease -> pool -> failover_peer;
356
fdfebedf
DH
357 /*
358 * If the lease is ours to (re)allocate, then allocate it.
359 *
2426234f 360 * If the lease is active, it belongs to the client. This
88cd8aca 361 * is the right lease, if we are to offer one. We decide
98bd7ca0 362 * whether or not to offer later on.
fdfebedf
DH
363 *
364 * If the lease was last active, and we've reached this
365 * point, then it was last active with the same client. We
366 * can safely re-activate the lease with this client.
88cd8aca 367 */
2426234f 368 if (lease->binding_state == FTS_ACTIVE ||
fdfebedf 369 lease->rewind_binding_state == FTS_ACTIVE ||
2426234f 370 lease_mine_to_reallocate(lease)) {
88cd8aca 371 ; /* This space intentionally left blank. */
d758ad8c
TL
372
373 /* Otherwise, we can't let the client have this lease. */
88cd8aca 374 } else {
d758ad8c
TL
375#if defined (DEBUG_FIND_LEASE)
376 log_debug ("discarding %s - %s",
377 piaddr (lease -> ip_addr),
378 binding_state_print (lease -> binding_state));
379#endif
380 lease_dereference (&lease, MDL);
381 }
382 }
383#endif
384
97ca1699
TL
385 /* If we didn't find a lease, try to allocate one... */
386 if (!lease) {
20916cae
TL
387 if (!allocate_lease (&lease, packet,
388 packet -> shared_network -> pools,
389 &peer_has_leases)) {
33225687 390 if (peer_has_leases)
98311e4b
DH
391 log_error ("%s: peer holds all free leases",
392 msgbuf);
33225687 393 else
98311e4b
DH
394 log_error ("%s: network %s: no free leases",
395 msgbuf,
396 packet -> shared_network -> name);
97ca1699
TL
397 return;
398 }
97ca1699
TL
399 }
400
150cedd0 401#if defined (FAILOVER_PROTOCOL)
f8f34940
TL
402 if (lease && lease -> pool && lease -> pool -> failover_peer) {
403 peer = lease -> pool -> failover_peer;
404 if (peer -> service_state == not_responding ||
405 peer -> service_state == service_startup) {
406 log_info ("%s: not responding%s",
407 msgbuf, peer -> nrr);
408 goto out;
409 }
410 } else
411 peer = (dhcp_failover_state_t *)0;
412
150cedd0 413 /* Do load balancing if configured. */
88cd8aca 414 if (peer && (peer -> service_state == cooperating) &&
98311e4b 415 !load_balance_mine (packet, peer)) {
88cd8aca 416 if (peer_has_leases) {
98311e4b
DH
417 log_debug ("%s: load balance to peer %s",
418 msgbuf, peer -> name);
419 goto out;
420 } else {
88cd8aca
DH
421 log_debug ("%s: cancel load balance to peer %s - %s",
422 msgbuf, peer -> name, "no free leases");
33225687 423 }
150cedd0
TL
424 }
425#endif
426
12c9957e 427 /* If it's an expired lease, get rid of any bindings. */
6ceb9118
TL
428 if (lease -> ends < cur_time && lease -> scope)
429 binding_scope_dereference (&lease -> scope, MDL);
12c9957e 430
ffdcd127
TL
431 /* Set the lease to really expire in 2 minutes, unless it has
432 not yet expired, in which case leave its expiry time alone. */
433 when = cur_time + 120;
434 if (when < lease -> ends)
435 when = lease -> ends;
436
c75473d8
DH
437 ack_lease (packet, lease, DHCPOFFER, when, msgbuf, ms_nulltp,
438 (struct host_decl *)0);
20916cae
TL
439 out:
440 if (lease)
441 lease_dereference (&lease, MDL);
ed8bcd8f
TL
442}
443
9e383163 444void dhcprequest (packet, ms_nulltp, ip_lease)
ed8bcd8f 445 struct packet *packet;
5bc2e1f2 446 int ms_nulltp;
9e383163 447 struct lease *ip_lease;
ed8bcd8f 448{
15c00bba 449 struct lease *lease;
b88e8e15 450 struct iaddr cip;
4f767627 451 struct iaddr sip;
7a049f2c 452 struct subnet *subnet;
fa97acc1 453 int ours = 0;
5d25508c
TL
454 struct option_cache *oc;
455 struct data_string data;
d9eefc5d 456 char msgbuf [1024]; /* XXX */
98311e4b 457 const char *s;
4f767627 458 char smbuf [19];
bb0b00a5
TL
459#if defined (FAILOVER_PROTOCOL)
460 dhcp_failover_state_t *peer;
461#endif
27e90ede 462 int have_requested_addr = 0;
5d25508c 463
951323fe 464 oc = lookup_option (&dhcp_universe, packet -> options,
5d25508c
TL
465 DHO_DHCP_REQUESTED_ADDRESS);
466 memset (&data, 0, sizeof data);
467 if (oc &&
ca1c700e 468 evaluate_option_cache (&data, packet, (struct lease *)0,
9e383163 469 (struct client_state *)0,
ca1c700e 470 packet -> options, (struct option_state *)0,
12c9957e 471 &global_scope, oc, MDL)) {
b88e8e15 472 cip.len = 4;
5d25508c 473 memcpy (cip.iabuf, data.data, 4);
4bd8800e 474 data_string_forget (&data, MDL);
27e90ede 475 have_requested_addr = 1;
a8b53b42 476 } else {
5d25508c 477 oc = (struct option_cache *)0;
a8b53b42
TL
478 cip.len = 4;
479 memcpy (cip.iabuf, &packet -> raw -> ciaddr.s_addr, 4);
480 }
481
15c00bba
TL
482 /* Find the lease that matches the address requested by the
483 client. */
44b2e3ad 484
20916cae
TL
485 subnet = (struct subnet *)0;
486 lease = (struct lease *)0;
487 if (find_subnet (&subnet, cip, MDL))
488 find_lease (&lease, packet,
9e383163 489 subnet -> shared_network, &ours, 0, ip_lease, MDL);
007e3ee4 490
98311e4b
DH
491 if (lease && lease -> client_hostname) {
492 if ((strlen (lease -> client_hostname) <= 64) &&
28868515 493 db_printable((unsigned char *)lease->client_hostname))
98311e4b
DH
494 s = lease -> client_hostname;
495 else
496 s = "Hostname Unsuitable for Printing";
497 } else
d9eefc5d
TL
498 s = (char *)0;
499
4f767627
TL
500 oc = lookup_option (&dhcp_universe, packet -> options,
501 DHO_DHCP_SERVER_IDENTIFIER);
502 memset (&data, 0, sizeof data);
503 if (oc &&
504 evaluate_option_cache (&data, packet, (struct lease *)0,
505 (struct client_state *)0,
506 packet -> options, (struct option_state *)0,
507 &global_scope, oc, MDL)) {
508 sip.len = 4;
509 memcpy (sip.iabuf, data.data, 4);
510 data_string_forget (&data, MDL);
98311e4b
DH
511 /* piaddr() should not return more than a 15 byte string.
512 * safe.
513 */
4f767627 514 sprintf (smbuf, " (%s)", piaddr (sip));
f8380d3f 515 } else {
4f767627 516 smbuf [0] = 0;
f8380d3f
SR
517 sip.len = 0;
518 }
4f767627 519
98311e4b
DH
520 /* %Audit% This is log output. %2004.06.17,Safe%
521 * If we truncate we hope the user can get a hint from the log.
522 */
785c1a51
FD
523#if defined(DHCPv6) && defined(DHCP4o6)
524 if (dhcpv4_over_dhcpv6 && (packet->dhcp4o6_response != NULL)) {
525 snprintf (msgbuf, sizeof msgbuf,
526 "DHCP4o6 DHCPREQUEST for %s%s from %s %s%s%svia %s",
527 piaddr (cip), smbuf,
528 (packet -> raw -> htype
529 ? print_hw_addr (packet -> raw -> htype,
530 packet -> raw -> hlen,
531 packet -> raw -> chaddr)
532 : (lease
533 ? print_hex_1(lease->uid_len, lease->uid, 60)
534 : "<no identifier>")),
535 s ? "(" : "", s ? s : "", s ? ") " : "",
536 piaddr(packet->client_addr));
537 } else
538#endif
98311e4b
DH
539 snprintf (msgbuf, sizeof msgbuf,
540 "DHCPREQUEST for %s%s from %s %s%s%svia %s",
4f767627 541 piaddr (cip), smbuf,
d9eefc5d
TL
542 (packet -> raw -> htype
543 ? print_hw_addr (packet -> raw -> htype,
544 packet -> raw -> hlen,
fdd46b53 545 packet -> raw -> chaddr)
d9eefc5d 546 : (lease
6d103865 547 ? print_hex_1(lease->uid_len, lease->uid, 60)
d9eefc5d
TL
548 : "<no identifier>")),
549 s ? "(" : "", s ? s : "", s ? ") " : "",
550 packet -> raw -> giaddr.s_addr
c4924529 551 ? inet_ntoa (packet -> raw -> giaddr)
d9eefc5d 552 : packet -> interface -> name);
a69f4fd3 553
007e3ee4 554#if defined (FAILOVER_PROTOCOL)
bb0b00a5
TL
555 if (lease && lease -> pool && lease -> pool -> failover_peer) {
556 peer = lease -> pool -> failover_peer;
557 if (peer -> service_state == not_responding ||
558 peer -> service_state == service_startup) {
559 log_info ("%s: not responding%s",
f8f34940 560 msgbuf, peer -> nrr);
bb0b00a5
TL
561 goto out;
562 }
31bbee78 563
98311e4b
DH
564 /* "load balance to peer" - is not done at all for request.
565 *
566 * If it's RENEWING, we are the only server to hear it, so
567 * we have to serve it. If it's REBINDING, it's out of
568 * communication with the other server, so there's no point
569 * in waiting to serve it. However, if the lease we're
570 * offering is not a free lease, then we may be the only
571 * server that can offer it, so we can't load balance if
572 * the lease isn't in the free or backup state. If it is
573 * in the free or backup state, then that state is what
574 * mandates one server or the other should perform the
575 * allocation, not the LBA...we know the peer cannot
576 * allocate a request for an address in our free state.
577 *
578 * So our only compass is lease_mine_to_reallocate(). This
579 * effects both load balancing, and a sanity-check that we
580 * are not going to try to allocate a lease that isn't ours.
581 */
d758ad8c
TL
582 if ((lease -> binding_state == FTS_FREE ||
583 lease -> binding_state == FTS_BACKUP) &&
584 !lease_mine_to_reallocate (lease)) {
585 log_debug ("%s: lease owned by peer", msgbuf);
31bbee78
TL
586 goto out;
587 }
d758ad8c 588
fdfebedf
DH
589 /*
590 * If the lease is in a transitional state, we can't
591 * renew it unless we can rewind it to a non-transitional
592 * state (active, free, or backup). lease_mine_to_reallocate()
593 * checks for free/backup, so we only need to check for active.
594 */
595 if ((lease->binding_state == FTS_RELEASED ||
596 lease->binding_state == FTS_EXPIRED) &&
597 lease->rewind_binding_state != FTS_ACTIVE &&
598 !lease_mine_to_reallocate(lease)) {
599 log_debug("%s: lease in transition state %s", msgbuf,
600 (lease->binding_state == FTS_RELEASED)
98311e4b
DH
601 ? "released" : "expired");
602 goto out;
603 }
604
605 /* It's actually very unlikely that we'll ever get here,
606 but if we do, tell the client to stop using the lease,
607 because the administrator reset it. */
608 if (lease -> binding_state == FTS_RESET &&
609 !lease_mine_to_reallocate (lease)) {
610 log_debug ("%s: lease reset by administrator", msgbuf);
e046c826 611 nak_lease (packet, &cip, lease->subnet->group);
98311e4b
DH
612 goto out;
613 }
614
7116a34f
TM
615 /* If server-id-check is enabled, verify that the client's
616 * server source address (sip from incoming packet) is ours.
617 * To avoid problems with confused clients we do some sanity
618 * checks to verify sip's length and that it isn't all zeros.
619 * We then get the server id we would likely use for this
620 * packet and compare them. If they don't match it we assume
621 * we didn't send the offer and so we don't process the
622 * request. */
623 if ((server_id_check == 1) && (sip.len == 4) &&
f8380d3f
SR
624 (memcmp(sip.iabuf, "\0\0\0\0", sip.len) != 0)) {
625 struct in_addr from;
e046c826
TM
626 struct option_state *eval_options = NULL;
627
628 eval_network_statements(&eval_options, packet, NULL);
7116a34f
TM
629 get_server_source_address(&from, eval_options,
630 NULL, packet);
e046c826 631 option_state_dereference (&eval_options, MDL);
f8380d3f
SR
632 if (memcmp(sip.iabuf, &from, sip.len) != 0) {
633 log_debug("%s: not our server id", msgbuf);
634 goto out;
635 }
636 }
f8380d3f 637
d758ad8c
TL
638 /* At this point it's possible that we will get a broadcast
639 DHCPREQUEST for a lease that we didn't offer, because
640 both we and the peer are in a position to offer it.
641 In that case, we probably shouldn't answer. In order
642 to not answer, we would have to compare the server
643 identifier sent by the client with the list of possible
644 server identifiers we can send, and if the client's
645 identifier isn't on the list, drop the DHCPREQUEST.
646 We aren't currently doing that for two reasons - first,
647 it's not clear that all clients do the right thing
648 with respect to sending the client identifier, which
649 could mean that we might simply not respond to a client
650 that is depending on us to respond. Secondly, we allow
651 the user to specify the server identifier to send, and
652 we don't enforce that the server identifier should be
653 one of our IP addresses. This is probably not a big
654 deal, but it's theoretically an issue.
655
656 The reason we care about this is that if both servers
657 send a DHCPACK to the DHCPREQUEST, they are then going
658 to send dueling BNDUPD messages, which could cause
659 trouble. I think it causes no harm, but it seems
660 wrong. */
bb0b00a5
TL
661 } else
662 peer = (dhcp_failover_state_t *)0;
007e3ee4
TL
663#endif
664
44b2e3ad
TL
665 /* If a client on a given network REQUESTs a lease on an
666 address on a different network, NAK it. If the Requested
667 Address option was used, the protocol says that it must
668 have been broadcast, so we can trust the source network
669 information.
15c00bba
TL
670
671 If ciaddr was specified and Requested Address was not, then
672 we really only know for sure what network a packet came from
673 if it came through a BOOTP gateway - if it came through an
3d789c23 674 IP router, we'll just have to assume that it's cool.
15c00bba 675
44b2e3ad
TL
676 If we don't think we know where the packet came from, it
677 came through a gateway from an unknown network, so it's not
678 from a RENEWING client. If we recognize the network it
679 *thinks* it's on, we can NAK it even though we don't
680 recognize the network it's *actually* on; otherwise we just
681 have to ignore it.
682
683 We don't currently try to take advantage of access to the
684 raw packet, because it's not available on all platforms.
685 So a packet that was unicast to us through a router from a
686 RENEWING client is going to look exactly like a packet that
687 was broadcast to us from an INIT-REBOOT client.
688
689 Since we can't tell the difference between these two kinds
690 of packets, if the packet appears to have come in off the
691 local wire, we have to treat it as if it's a RENEWING
692 client. This means that we can't NAK a RENEWING client on
693 the local wire that has a bogus address. The good news is
694 that we won't ACK it either, so it should revert to INIT
695 state and send us a DHCPDISCOVER, which we *can* work with.
696
697 Because we can't detect that a RENEWING client is on the
698 wrong wire, it's going to sit there trying to renew until
699 it gets to the REBIND state, when we *can* NAK it because
700 the packet will get to us through a BOOTP gateway. We
701 shouldn't actually see DHCPREQUEST packets from RENEWING
702 clients on the wrong wire anyway, since their idea of their
703 local router will be wrong. In any case, the protocol
704 doesn't really allow us to NAK a DHCPREQUEST from a
705 RENEWING client, so we can punt on this issue. */
706
707 if (!packet -> shared_network ||
1d8b8d99
TL
708 (packet -> raw -> ciaddr.s_addr &&
709 packet -> raw -> giaddr.s_addr) ||
27e90ede 710 (have_requested_addr && !packet -> raw -> ciaddr.s_addr)) {
15c00bba
TL
711
712 /* If we don't know where it came from but we do know
713 where it claims to have come from, it didn't come
3d789c23 714 from there. */
15c00bba 715 if (!packet -> shared_network) {
027f46cb 716 if (subnet && subnet -> group -> authoritative) {
8ae2d595 717 log_info ("%s: wrong network.", msgbuf);
e046c826 718 nak_lease (packet, &cip, NULL);
3d789c23 719 goto out;
15c00bba 720 }
4fbcd991 721 /* Otherwise, ignore it. */
797d58b3
TL
722 log_info ("%s: ignored (%s).", msgbuf,
723 (subnet
724 ? "not authoritative" : "unknown subnet"));
20916cae 725 goto out;
b88e8e15 726 }
15c00bba 727
44b2e3ad
TL
728 /* If we do know where it came from and it asked for an
729 address that is not on that shared network, nak it. */
20916cae
TL
730 if (subnet)
731 subnet_dereference (&subnet, MDL);
732 if (!find_grouped_subnet (&subnet, packet -> shared_network,
733 cip, MDL)) {
027f46cb
TL
734 if (packet -> shared_network -> group -> authoritative)
735 {
8ae2d595 736 log_info ("%s: wrong network.", msgbuf);
e046c826 737 nak_lease (packet, &cip, NULL);
3d789c23 738 goto out;
027f46cb 739 }
e89a5afe 740 log_info ("%s: ignored (not authoritative).", msgbuf);
b88e8e15
TL
741 return;
742 }
743 }
ed8bcd8f 744
0c11afbc 745 /* If the address the client asked for is ours, but it wasn't
65cf86d7 746 available for the client, NAK it. */
0c11afbc 747 if (!lease && ours) {
8ae2d595 748 log_info ("%s: lease %s unavailable.", msgbuf, piaddr (cip));
e046c826 749 nak_lease (packet, &cip, (subnet ? subnet->group : NULL));
20916cae 750 goto out;
0c11afbc
TL
751 }
752
6dadd610 753 /* Otherwise, send the lease to the client if we found one. */
eeea1395 754 if (lease) {
c75473d8
DH
755 ack_lease (packet, lease, DHCPACK, 0, msgbuf, ms_nulltp,
756 (struct host_decl *)0);
eeea1395 757 } else
74f45f96 758 log_info ("%s: unknown lease %s.", msgbuf, piaddr (cip));
20916cae
TL
759
760 out:
761 if (subnet)
762 subnet_dereference (&subnet, MDL);
763 if (lease)
764 lease_dereference (&lease, MDL);
765 return;
ed8bcd8f
TL
766}
767
5bc2e1f2 768void dhcprelease (packet, ms_nulltp)
ed8bcd8f 769 struct packet *packet;
5bc2e1f2 770 int ms_nulltp;
ed8bcd8f 771{
cb8176c4 772 struct lease *lease = (struct lease *)0, *next = (struct lease *)0;
2b260752 773 struct iaddr cip;
5d25508c
TL
774 struct option_cache *oc;
775 struct data_string data;
98311e4b
DH
776 const char *s;
777 char msgbuf [1024], cstr[16]; /* XXX */
fa97acc1 778
bb0b00a5 779
2ba8b7cd 780 /* DHCPRELEASE must not specify address in requested-address
65cf86d7
EH
781 option, but old protocol specs weren't explicit about this,
782 so let it go. */
951323fe 783 if ((oc = lookup_option (&dhcp_universe, packet -> options,
5d25508c 784 DHO_DHCP_REQUESTED_ADDRESS))) {
8ae2d595 785 log_info ("DHCPRELEASE from %s specified requested-address.",
2ba8b7cd
TL
786 print_hw_addr (packet -> raw -> htype,
787 packet -> raw -> hlen,
788 packet -> raw -> chaddr));
fa97acc1
TL
789 }
790
951323fe 791 oc = lookup_option (&dhcp_universe, packet -> options,
5d25508c
TL
792 DHO_DHCP_CLIENT_IDENTIFIER);
793 memset (&data, 0, sizeof data);
794 if (oc &&
ca1c700e 795 evaluate_option_cache (&data, packet, (struct lease *)0,
9e383163 796 (struct client_state *)0,
ca1c700e 797 packet -> options, (struct option_state *)0,
12c9957e 798 &global_scope, oc, MDL)) {
20916cae 799 find_lease_by_uid (&lease, data.data, data.len, MDL);
4bd8800e 800 data_string_forget (&data, MDL);
ed8bcd8f 801
73a4b6e5
TL
802 /* See if we can find a lease that matches the IP address
803 the client is claiming. */
b7d47627 804 while (lease) {
cb8176c4
TL
805 if (lease -> n_uid)
806 lease_reference (&next, lease -> n_uid, MDL);
73a4b6e5
TL
807 if (!memcmp (&packet -> raw -> ciaddr,
808 lease -> ip_addr.iabuf, 4)) {
809 break;
810 }
cb8176c4
TL
811 lease_dereference (&lease, MDL);
812 if (next) {
813 lease_reference (&lease, next, MDL);
814 lease_dereference (&next, MDL);
815 }
73a4b6e5 816 }
cb8176c4
TL
817 if (next)
818 lease_dereference (&next, MDL);
20916cae 819 }
12c9957e
TL
820
821 /* The client is supposed to pass a valid client-identifier,
822 but the spec on this has changed historically, so try the
823 IP address in ciaddr if the client-identifier fails. */
824 if (!lease) {
db2ed553
TL
825 cip.len = 4;
826 memcpy (cip.iabuf, &packet -> raw -> ciaddr, 4);
20916cae 827 find_lease_by_ip_addr (&lease, cip, MDL);
2ba8b7cd
TL
828 }
829
830
98311e4b
DH
831 /* If the hardware address doesn't match, don't do the release. */
832 if (lease &&
833 (lease -> hardware_addr.hlen != packet -> raw -> hlen + 1 ||
834 lease -> hardware_addr.hbuf [0] != packet -> raw -> htype ||
835 memcmp (&lease -> hardware_addr.hbuf [1],
836 packet -> raw -> chaddr, packet -> raw -> hlen)))
837 lease_dereference (&lease, MDL);
838
839 if (lease && lease -> client_hostname) {
840 if ((strlen (lease -> client_hostname) <= 64) &&
28868515 841 db_printable((unsigned char *)lease->client_hostname))
98311e4b
DH
842 s = lease -> client_hostname;
843 else
844 s = "Hostname Unsuitable for Printing";
845 } else
d9eefc5d
TL
846 s = (char *)0;
847
98311e4b
DH
848 /* %Audit% Cannot exceed 16 bytes. %2004.06.17,Safe%
849 * We copy this out to stack because we actually want to log two
850 * inet_ntoa()'s in this message.
851 */
852 strncpy(cstr, inet_ntoa (packet -> raw -> ciaddr), 15);
853 cstr[15] = '\0';
854
855 /* %Audit% This is log output. %2004.06.17,Safe%
856 * If we truncate we hope the user can get a hint from the log.
857 */
785c1a51
FD
858#if defined(DHCPv6) && defined(DHCP4o6)
859 if (dhcpv4_over_dhcpv6 && (packet->dhcp4o6_response != NULL)) {
860 snprintf (msgbuf, sizeof msgbuf,
861 "DHCP4o6 DHCPRELEASE of %s from %s %s%s%svia "
862 "%s (%sfound)",
863 cstr,
864 (packet -> raw -> htype
865 ? print_hw_addr (packet -> raw -> htype,
866 packet -> raw -> hlen,
867 packet -> raw -> chaddr)
868 : (lease
869 ? print_hex_1(lease->uid_len, lease->uid, 60)
870 : "<no identifier>")),
871 s ? "(" : "", s ? s : "", s ? ") " : "",
872 piaddr(packet->client_addr),
873 lease ? "" : "not ");
874 } else
875#endif
98311e4b 876 snprintf (msgbuf, sizeof msgbuf,
007e3ee4 877 "DHCPRELEASE of %s from %s %s%s%svia %s (%sfound)",
98311e4b 878 cstr,
007e3ee4
TL
879 (packet -> raw -> htype
880 ? print_hw_addr (packet -> raw -> htype,
881 packet -> raw -> hlen,
882 packet -> raw -> chaddr)
883 : (lease
6d103865 884 ? print_hex_1(lease->uid_len, lease->uid, 60)
007e3ee4
TL
885 : "<no identifier>")),
886 s ? "(" : "", s ? s : "", s ? ") " : "",
887 packet -> raw -> giaddr.s_addr
888 ? inet_ntoa (packet -> raw -> giaddr)
889 : packet -> interface -> name,
890 lease ? "" : "not ");
891
892#if defined (FAILOVER_PROTOCOL)
bb0b00a5
TL
893 if (lease && lease -> pool && lease -> pool -> failover_peer) {
894 dhcp_failover_state_t *peer = lease -> pool -> failover_peer;
895 if (peer -> service_state == not_responding ||
896 peer -> service_state == service_startup) {
897 log_info ("%s: ignored%s",
898 peer -> name, peer -> nrr);
899 goto out;
900 }
901
007e3ee4
TL
902 /* DHCPRELEASE messages are unicast, so if the client
903 sent the DHCPRELEASE to us, it's not going to send it
904 to the peer. Not sure why this would happen, and
905 if it does happen I think we still have to change the
bb0b00a5 906 lease state, so that's what we're doing.
007e3ee4 907 XXX See what it says in the draft about this. */
007e3ee4
TL
908 }
909#endif
a8b53b42 910
b88e8e15 911 /* If we found a lease, release it. */
20916cae 912 if (lease && lease -> ends > cur_time) {
43f23dcc 913 release_lease (lease, packet);
6c608437
TL
914 }
915 log_info ("%s", msgbuf);
66cebfcb 916#if defined(FAILOVER_PROTOCOL)
007e3ee4 917 out:
66cebfcb 918#endif
007e3ee4
TL
919 if (lease)
920 lease_dereference (&lease, MDL);
ed8bcd8f
TL
921}
922
5bc2e1f2 923void dhcpdecline (packet, ms_nulltp)
b88e8e15 924 struct packet *packet;
5bc2e1f2 925 int ms_nulltp;
b88e8e15 926{
20916cae 927 struct lease *lease = (struct lease *)0;
19654922 928 struct option_state *options = (struct option_state *)0;
bb0b00a5 929 int ignorep = 0;
19654922
TL
930 int i;
931 const char *status;
98311e4b 932 const char *s;
007e3ee4 933 char msgbuf [1024]; /* XXX */
9e383163
TL
934 struct iaddr cip;
935 struct option_cache *oc;
936 struct data_string data;
a8b53b42 937
fa97acc1 938 /* DHCPDECLINE must specify address. */
951323fe 939 if (!(oc = lookup_option (&dhcp_universe, packet -> options,
5d25508c
TL
940 DHO_DHCP_REQUESTED_ADDRESS)))
941 return;
942 memset (&data, 0, sizeof data);
ca1c700e 943 if (!evaluate_option_cache (&data, packet, (struct lease *)0,
9e383163 944 (struct client_state *)0,
ca1c700e
TL
945 packet -> options,
946 (struct option_state *)0,
12c9957e 947 &global_scope, oc, MDL))
fa97acc1 948 return;
a8b53b42 949
fa97acc1 950 cip.len = 4;
5d25508c 951 memcpy (cip.iabuf, data.data, 4);
4bd8800e 952 data_string_forget (&data, MDL);
20916cae 953 find_lease_by_ip_addr (&lease, cip, MDL);
fa97acc1 954
98311e4b
DH
955 if (lease && lease -> client_hostname) {
956 if ((strlen (lease -> client_hostname) <= 64) &&
28868515 957 db_printable((unsigned char *)lease->client_hostname))
98311e4b
DH
958 s = lease -> client_hostname;
959 else
960 s = "Hostname Unsuitable for Printing";
961 } else
007e3ee4
TL
962 s = (char *)0;
963
98311e4b
DH
964 /* %Audit% This is log output. %2004.06.17,Safe%
965 * If we truncate we hope the user can get a hint from the log.
966 */
785c1a51
FD
967#if defined(DHCPv6) && defined(DHCP4o6)
968 if (dhcpv4_over_dhcpv6 && (packet->dhcp4o6_response != NULL)) {
969 snprintf (msgbuf, sizeof msgbuf,
970 "DHCP4o6 DHCPDECLINE of %s from %s %s%s%svia %s",
971 piaddr (cip),
972 (packet -> raw -> htype
973 ? print_hw_addr (packet -> raw -> htype,
974 packet -> raw -> hlen,
975 packet -> raw -> chaddr)
976 : (lease
977 ? print_hex_1(lease->uid_len, lease->uid, 60)
978 : "<no identifier>")),
979 s ? "(" : "", s ? s : "", s ? ") " : "",
980 piaddr(packet->client_addr));
981 } else
982#endif
98311e4b
DH
983 snprintf (msgbuf, sizeof msgbuf,
984 "DHCPDECLINE of %s from %s %s%s%svia %s",
007e3ee4
TL
985 piaddr (cip),
986 (packet -> raw -> htype
987 ? print_hw_addr (packet -> raw -> htype,
988 packet -> raw -> hlen,
989 packet -> raw -> chaddr)
990 : (lease
6d103865 991 ? print_hex_1(lease->uid_len, lease->uid, 60)
007e3ee4
TL
992 : "<no identifier>")),
993 s ? "(" : "", s ? s : "", s ? ") " : "",
994 packet -> raw -> giaddr.s_addr
995 ? inet_ntoa (packet -> raw -> giaddr)
996 : packet -> interface -> name);
997
4bd8800e 998 option_state_allocate (&options, MDL);
a69f4fd3 999
19654922
TL
1000 /* Execute statements in scope starting with the subnet scope. */
1001 if (lease)
a7341359
SR
1002 execute_statements_in_scope(NULL, packet, NULL, NULL,
1003 packet->options, options,
1004 &global_scope,
1005 lease->subnet->group,
1006 NULL, NULL);
19654922
TL
1007
1008 /* Execute statements in the class scopes. */
1009 for (i = packet -> class_count; i > 0; i--) {
1010 execute_statements_in_scope
a7341359
SR
1011 (NULL, packet, NULL, NULL, packet->options, options,
1012 &global_scope, packet->classes[i - 1]->group,
1013 lease ? lease->subnet->group : NULL, NULL);
b88e8e15 1014 }
19654922
TL
1015
1016 /* Drop the request if dhcpdeclines are being ignored. */
1017 oc = lookup_option (&server_universe, options, SV_DECLINES);
1018 if (!oc ||
12c9957e 1019 evaluate_boolean_option_cache (&ignorep, packet, lease,
9e383163 1020 (struct client_state *)0,
12c9957e
TL
1021 packet -> options, options,
1022 &lease -> scope, oc, MDL)) {
bb0b00a5
TL
1023 /* If we found a lease, mark it as unusable and complain. */
1024 if (lease) {
1025#if defined (FAILOVER_PROTOCOL)
1026 if (lease -> pool && lease -> pool -> failover_peer) {
1027 dhcp_failover_state_t *peer =
1028 lease -> pool -> failover_peer;
1029 if (peer -> service_state == not_responding ||
1030 peer -> service_state == service_startup) {
1031 if (!ignorep)
1032 log_info ("%s: ignored%s",
1033 peer -> name, peer -> nrr);
1034 goto out;
1035 }
1036
1037 /* DHCPDECLINE messages are broadcast, so we can safely
1038 ignore the DHCPDECLINE if the peer has the lease.
1039 XXX Of course, at this point that information has been
1040 lost. */
19654922 1041 }
bb0b00a5
TL
1042#endif
1043
1044 abandon_lease (lease, "declined.");
1045 status = "abandoned";
a4ffedd1
DH
1046 } else {
1047 status = "not found";
bb0b00a5 1048 }
19654922 1049 } else
bb0b00a5 1050 status = "ignored";
19654922 1051
007e3ee4
TL
1052 if (!ignorep)
1053 log_info ("%s: %s", msgbuf, status);
66cebfcb
DH
1054
1055#if defined(FAILOVER_PROTOCOL)
007e3ee4 1056 out:
66cebfcb 1057#endif
007e3ee4
TL
1058 if (options)
1059 option_state_dereference (&options, MDL);
20916cae
TL
1060 if (lease)
1061 lease_dereference (&lease, MDL);
b88e8e15
TL
1062}
1063
5bc2e1f2 1064void dhcpinform (packet, ms_nulltp)
b88e8e15 1065 struct packet *packet;
5bc2e1f2 1066 int ms_nulltp;
b88e8e15 1067{
4d079f0e
SR
1068 char msgbuf[1024], *addr_type;
1069 struct data_string d1, prl, fixed_addr;
e77892f5 1070 struct option_cache *oc;
4d079f0e 1071 struct option_state *options = NULL;
e77892f5
TL
1072 struct dhcp_packet raw;
1073 struct packet outgoing;
3175ee90 1074 unsigned char dhcpack = DHCPACK;
49f61135 1075 struct subnet *subnet = NULL;
4d079f0e 1076 struct iaddr cip, gip, sip;
28868515 1077 unsigned i;
b1b7b521 1078 int nulltp;
e77892f5
TL
1079 struct sockaddr_in to;
1080 struct in_addr from;
49f61135 1081 isc_boolean_t zeroed_ciaddr;
dd9237c3 1082 struct interface_info *interface;
4d079f0e
SR
1083 int result, h_m_client_ip = 0;
1084 struct host_decl *host = NULL, *hp = NULL, *h;
1085#if defined (DEBUG_INFORM_HOST)
1086 int h_w_fixed_addr = 0;
1087#endif
49f61135 1088
cdc336ab
TL
1089 /* The client should set ciaddr to its IP address, but apparently
1090 it's common for clients not to do this, so we'll use their IP
1091 source address if they didn't set ciaddr. */
4d079f0e 1092 if (!packet->raw->ciaddr.s_addr) {
49f61135 1093 zeroed_ciaddr = ISC_TRUE;
785c1a51
FD
1094 /* With DHCPv4-over-DHCPv6 it can be an IPv6 address
1095 so we check its length. */
1096 if (packet->client_addr.len == 4) {
1097 cip.len = 4;
1098 memcpy(cip.iabuf, &packet->client_addr.iabuf, 4);
1099 addr_type = "source";
1100 } else {
1101 cip.len = 0;
1102 memset(cip.iabuf, 0, 4);
1103 addr_type = "v4o6";
1104 }
cdc336ab 1105 } else {
49f61135 1106 zeroed_ciaddr = ISC_FALSE;
cdc336ab 1107 cip.len = 4;
4d079f0e
SR
1108 memcpy(cip.iabuf, &packet->raw->ciaddr, 4);
1109 addr_type = "client";
cdc336ab 1110 }
4d079f0e
SR
1111 sip.len = 4;
1112 memcpy(sip.iabuf, cip.iabuf, 4);
cdc336ab 1113
88cd8aca
DH
1114 if (packet->raw->giaddr.s_addr) {
1115 gip.len = 4;
1116 memcpy(gip.iabuf, &packet->raw->giaddr, 4);
4d079f0e
SR
1117 if (zeroed_ciaddr == ISC_TRUE) {
1118 addr_type = "relay";
1119 memcpy(sip.iabuf, gip.iabuf, 4);
1120 }
88cd8aca
DH
1121 } else
1122 gip.len = 0;
1123
98311e4b
DH
1124 /* %Audit% This is log output. %2004.06.17,Safe%
1125 * If we truncate we hope the user can get a hint from the log.
1126 */
785c1a51
FD
1127#if defined(DHCPv6) && defined(DHCP4o6)
1128 if (dhcpv4_over_dhcpv6 && (packet->dhcp4o6_response != NULL)) {
1129 snprintf(msgbuf, sizeof(msgbuf),
1130 "DHCP4o6 DHCPINFORM from %s via %s",
1131 piaddr(cip),
1132 piaddr(packet->client_addr));
1133 } else
1134#endif
4d079f0e
SR
1135 snprintf(msgbuf, sizeof(msgbuf), "DHCPINFORM from %s via %s",
1136 piaddr(cip),
1137 packet->raw->giaddr.s_addr ?
1138 inet_ntoa(packet->raw->giaddr) :
1139 packet->interface->name);
cdc336ab
TL
1140
1141 /* If the IP source address is zero, don't respond. */
4d079f0e
SR
1142 if (!memcmp(cip.iabuf, "\0\0\0", 4)) {
1143 log_info("%s: ignored (null source address).", msgbuf);
cdc336ab
TL
1144 return;
1145 }
e77892f5 1146
4d079f0e
SR
1147 /* Find the subnet that the client is on.
1148 * CC: Do the link selection / subnet selection
1149 */
1150
1151 option_state_allocate(&options, MDL);
1152
1153 if ((oc = lookup_option(&agent_universe, packet->options,
1154 RAI_LINK_SELECT)) == NULL)
1155 oc = lookup_option(&dhcp_universe, packet->options,
1156 DHO_SUBNET_SELECTION);
49f61135 1157
4d079f0e
SR
1158 memset(&d1, 0, sizeof d1);
1159 if (oc && evaluate_option_cache(&d1, packet, NULL, NULL,
1160 packet->options, NULL,
1161 &global_scope, oc, MDL)) {
1162 struct option_cache *noc = NULL;
1163
1164 if (d1.len != 4) {
1165 log_info("%s: ignored (invalid subnet selection option).", msgbuf);
1166 option_state_dereference(&options, MDL);
49f61135
DH
1167 return;
1168 }
e77892f5 1169
4d079f0e
SR
1170 memcpy(sip.iabuf, d1.data, 4);
1171 data_string_forget(&d1, MDL);
1172
1173 /* Make a copy of the data. */
1174 if (option_cache_allocate(&noc, MDL)) {
1175 if (oc->data.len)
1176 data_string_copy(&noc->data, &oc->data, MDL);
1177 if (oc->expression)
1178 expression_reference(&noc->expression,
1179 oc->expression, MDL);
1180 if (oc->option)
1181 option_reference(&(noc->option), oc->option,
1182 MDL);
49f61135 1183 }
4d079f0e
SR
1184 save_option(&dhcp_universe, options, noc);
1185 option_cache_dereference(&noc, MDL);
1186
1187 if ((zeroed_ciaddr == ISC_TRUE) && (gip.len != 0))
1188 addr_type = "relay link select";
1189 else
1190 addr_type = "selected";
1191 }
1192
1193 find_subnet(&subnet, sip, MDL);
1194
1195 if (subnet == NULL) {
1196 log_info("%s: unknown subnet for %s address %s",
1197 msgbuf, addr_type, piaddr(sip));
a07d99bb 1198 option_state_dereference(&options, MDL);
4d079f0e 1199 return;
e77892f5
TL
1200 }
1201
e89a5afe
TL
1202 /* We don't respond to DHCPINFORM packets if we're not authoritative.
1203 It would be nice if a per-host value could override this, but
1204 there's overhead involved in checking this, so let's see how people
1205 react first. */
a07d99bb 1206 if (!subnet->group->authoritative) {
20916cae 1207 static int eso = 0;
a07d99bb 1208 log_info("%s: not authoritative for subnet %s",
e89a5afe 1209 msgbuf, piaddr (subnet -> net));
20916cae 1210 if (!eso) {
a07d99bb 1211 log_info("If this DHCP server is authoritative for%s",
20916cae 1212 " that subnet,");
a07d99bb 1213 log_info("please write an `authoritative;' directi%s",
20916cae 1214 "ve either in the");
a07d99bb 1215 log_info("subnet declaration or in some scope that%s",
98311e4b 1216 " encloses the");
a07d99bb 1217 log_info("subnet declaration - for example, write %s",
20916cae 1218 "it at the top");
a07d99bb 1219 log_info("of the dhcpd.conf file.");
20916cae
TL
1220 }
1221 if (eso++ == 100)
1222 eso = 0;
a07d99bb
TM
1223 subnet_dereference(&subnet, MDL);
1224 option_state_dereference(&options, MDL);
e89a5afe
TL
1225 return;
1226 }
4d079f0e 1227
a07d99bb
TM
1228 memset(&outgoing, 0, sizeof outgoing);
1229 memset(&raw, 0, sizeof raw);
e77892f5
TL
1230 outgoing.raw = &raw;
1231
a1308b64
DH
1232 maybe_return_agent_options(packet, options);
1233
e77892f5 1234 /* Execute statements in scope starting with the subnet scope. */
a07d99bb
TM
1235 execute_statements_in_scope(NULL, packet, NULL, NULL,
1236 packet->options, options,
1237 &global_scope, subnet->group,
1238 NULL, NULL);
4d079f0e 1239
e77892f5 1240 /* Execute statements in the class scopes. */
a07d99bb 1241 for (i = packet->class_count; i > 0; i--) {
a7341359
SR
1242 execute_statements_in_scope(NULL, packet, NULL, NULL,
1243 packet->options, options,
1244 &global_scope,
1245 packet->classes[i - 1]->group,
a07d99bb 1246 subnet->group,
a7341359 1247 NULL);
e77892f5
TL
1248 }
1249
4d079f0e
SR
1250 /*
1251 * Process host declarations during DHCPINFORM,
1252 * Try to find a matching host declaration by cli ID or HW addr.
1253 *
1254 * Look through the host decls for one that matches the
1255 * client identifer or the hardware address. The preference
1256 * order is:
1257 * client id with matching ip address
1258 * hardware address with matching ip address
1259 * client id without a ip fixed address
1260 * hardware address without a fixed ip address
1261 * If found, set host to use its option definitions.
1262 */
1263 oc = lookup_option(&dhcp_universe, packet->options,
1264 DHO_DHCP_CLIENT_IDENTIFIER);
1265 memset(&d1, 0, sizeof(d1));
1266 if (oc &&
1267 evaluate_option_cache(&d1, packet, NULL, NULL,
1268 packet->options, NULL,
1269 &global_scope, oc, MDL)) {
1270 find_hosts_by_uid(&hp, d1.data, d1.len, MDL);
1271 data_string_forget(&d1, MDL);
1272
1273#if defined (DEBUG_INFORM_HOST)
1274 if (hp)
1275 log_debug ("dhcpinform: found host by ID "
1276 "-- checking fixed-address match");
1277#endif
1278 /* check if we have one with fixed-address
1279 * matching the client ip first */
1280 for (h = hp; !h_m_client_ip && h; h = h->n_ipaddr) {
1281 if (!h->fixed_addr)
1282 continue;
1283
1284 memset(&fixed_addr, 0, sizeof(fixed_addr));
1285 if (!evaluate_option_cache (&fixed_addr, NULL,
1286 NULL, NULL, NULL, NULL,
1287 &global_scope,
1288 h->fixed_addr, MDL))
1289 continue;
1290
1291#if defined (DEBUG_INFORM_HOST)
1292 h_w_fixed_addr++;
1293#endif
1294 for (i = 0;
1295 (i + cip.len) <= fixed_addr.len;
1296 i += cip.len) {
1297 if (memcmp(fixed_addr.data + i,
1298 cip.iabuf, cip.len) == 0) {
1299#if defined (DEBUG_INFORM_HOST)
1300 log_debug ("dhcpinform: found "
1301 "host with matching "
1302 "fixed-address by ID");
1303#endif
1304 host_reference(&host, h, MDL);
1305 h_m_client_ip = 1;
1306 break;
1307 }
1308 }
1309 data_string_forget(&fixed_addr, MDL);
1310 }
1311
1312 /* fallback to a host without fixed-address */
1313 for (h = hp; !host && h; h = h->n_ipaddr) {
1314 if (h->fixed_addr)
1315 continue;
1316
1317#if defined (DEBUG_INFORM_HOST)
1318 log_debug ("dhcpinform: found host "
1319 "without fixed-address by ID");
1320#endif
1321 host_reference(&host, h, MDL);
1322 break;
1323 }
1324 if (hp)
1325 host_dereference (&hp, MDL);
1326 }
1327 if (!host || !h_m_client_ip) {
1328 find_hosts_by_haddr(&hp, packet->raw->htype,
1329 packet->raw->chaddr,
1330 packet->raw->hlen, MDL);
1331
1332#if defined (DEBUG_INFORM_HOST)
1333 if (hp)
1334 log_debug ("dhcpinform: found host by HW "
1335 "-- checking fixed-address match");
1336#endif
1337
1338 /* check if we have one with fixed-address
1339 * matching the client ip first */
1340 for (h = hp; !h_m_client_ip && h; h = h->n_ipaddr) {
1341 if (!h->fixed_addr)
1342 continue;
1343
1344 memset (&fixed_addr, 0, sizeof(fixed_addr));
1345 if (!evaluate_option_cache (&fixed_addr, NULL,
1346 NULL, NULL, NULL, NULL,
1347 &global_scope,
1348 h->fixed_addr, MDL))
1349 continue;
1350
1351#if defined (DEBUG_INFORM_HOST)
1352 h_w_fixed_addr++;
1353#endif
1354 for (i = 0;
1355 (i + cip.len) <= fixed_addr.len;
1356 i += cip.len) {
1357 if (memcmp(fixed_addr.data + i,
1358 cip.iabuf, cip.len) == 0) {
1359#if defined (DEBUG_INFORM_HOST)
1360 log_debug ("dhcpinform: found "
1361 "host with matching "
1362 "fixed-address by HW");
1363#endif
1364 /*
1365 * Hmm.. we've found one
1366 * without IP by ID and now
1367 * (better) one with IP by HW.
1368 */
1369 if(host)
1370 host_dereference(&host, MDL);
1371 host_reference(&host, h, MDL);
1372 h_m_client_ip = 1;
1373 break;
1374 }
1375 }
1376 data_string_forget(&fixed_addr, MDL);
1377 }
1378 /* fallback to a host without fixed-address */
1379 for (h = hp; !host && h; h = h->n_ipaddr) {
1380 if (h->fixed_addr)
1381 continue;
1382
1383#if defined (DEBUG_INFORM_HOST)
1384 log_debug ("dhcpinform: found host without "
1385 "fixed-address by HW");
1386#endif
1387 host_reference (&host, h, MDL);
1388 break;
1389 }
1390
1391 if (hp)
1392 host_dereference (&hp, MDL);
1393 }
1394
1395#if defined (DEBUG_INFORM_HOST)
1396 /* Hmm..: what when there is a host with a fixed-address,
1397 * that matches by hw or id, but the fixed-addresses
1398 * didn't match client ip?
1399 */
1400 if (h_w_fixed_addr && !h_m_client_ip) {
1401 log_info ("dhcpinform: matching host with "
1402 "fixed-address different than "
1403 "client IP detected?!");
1404 }
1405#endif
1406
1407 /* If we have a host_decl structure, run the options
1408 * associated with its group. Whether the host decl
1409 * struct is old or not. */
1410 if (host) {
1411#if defined (DEBUG_INFORM_HOST)
1412 log_info ("dhcpinform: applying host (group) options");
1413#endif
1414 execute_statements_in_scope(NULL, packet, NULL, NULL,
1415 packet->options, options,
1416 &global_scope, host->group,
dd9738aa 1417 subnet->group,
4d079f0e
SR
1418 NULL);
1419 host_dereference (&host, MDL);
1420 }
1421
1422 /* CC: end of host entry processing.... */
1423
e77892f5 1424 /* Figure out the filename. */
cdc336ab 1425 memset (&d1, 0, sizeof d1);
e77892f5 1426 oc = lookup_option (&server_universe, options, SV_FILENAME);
ca1c700e
TL
1427 if (oc &&
1428 evaluate_option_cache (&d1, packet, (struct lease *)0,
9e383163 1429 (struct client_state *)0,
ca1c700e 1430 packet -> options, (struct option_state *)0,
12c9957e 1431 &global_scope, oc, MDL)) {
e77892f5 1432 i = d1.len;
66be0ad1
SR
1433 if (i >= sizeof(raw.file)) {
1434 log_info("file name longer than packet field "
228e4447 1435 "truncated - field: %lu name: %d %.*s",
4176a700
MA
1436 (unsigned long)sizeof(raw.file), i,
1437 (int)i, d1.data);
66be0ad1
SR
1438 i = sizeof(raw.file);
1439 } else
1440 raw.file[i] = 0;
e77892f5 1441 memcpy (raw.file, d1.data, i);
4bd8800e 1442 data_string_forget (&d1, MDL);
e77892f5
TL
1443 }
1444
1445 /* Choose a server name as above. */
10553ccb 1446 oc = lookup_option (&server_universe, options, SV_SERVER_NAME);
ca1c700e 1447 if (oc &&
9e383163
TL
1448 evaluate_option_cache (&d1, packet, (struct lease *)0,
1449 (struct client_state *)0,
ca1c700e 1450 packet -> options, (struct option_state *)0,
12c9957e 1451 &global_scope, oc, MDL)) {
e77892f5 1452 i = d1.len;
66be0ad1
SR
1453 if (i >= sizeof(raw.sname)) {
1454 log_info("server name longer than packet field "
228e4447 1455 "truncated - field: %lu name: %d %.*s",
4176a700
MA
1456 (unsigned long)sizeof(raw.sname), i,
1457 (int)i, d1.data);
66be0ad1
SR
1458 i = sizeof(raw.sname);
1459 } else
1460 raw.sname[i] = 0;
e77892f5 1461 memcpy (raw.sname, d1.data, i);
4bd8800e 1462 data_string_forget (&d1, MDL);
e77892f5
TL
1463 }
1464
1465 /* Set a flag if this client is a lame Microsoft client that NUL
1466 terminates string options and expects us to do likewise. */
1467 nulltp = 0;
1468 if ((oc = lookup_option (&dhcp_universe, packet -> options,
1469 DHO_HOST_NAME))) {
88cd8aca
DH
1470 if (!oc->expression)
1471 nulltp = oc->flags & OPTION_HAD_NULLS;
e77892f5
TL
1472 }
1473
1474 /* Put in DHCP-specific options. */
1475 i = DHO_DHCP_MESSAGE_TYPE;
1476 oc = (struct option_cache *)0;
4bd8800e 1477 if (option_cache_allocate (&oc, MDL)) {
d758ad8c
TL
1478 if (make_const_data (&oc -> expression,
1479 &dhcpack, 1, 0, 0, MDL)) {
f7fdb216
DH
1480 option_code_hash_lookup(&oc->option,
1481 dhcp_universe.code_hash,
1482 &i, 0, MDL);
e77892f5
TL
1483 save_option (&dhcp_universe, options, oc);
1484 }
4bd8800e 1485 option_cache_dereference (&oc, MDL);
e77892f5
TL
1486 }
1487
f8380d3f 1488 get_server_source_address(&from, options, options, packet);
e77892f5
TL
1489
1490 /* Use the subnet mask from the subnet declaration if no other
1491 mask has been provided. */
1492 i = DHO_SUBNET_MASK;
10553ccb 1493 if (subnet && !lookup_option (&dhcp_universe, options, i)) {
cdc336ab 1494 oc = (struct option_cache *)0;
4bd8800e 1495 if (option_cache_allocate (&oc, MDL)) {
e77892f5
TL
1496 if (make_const_data (&oc -> expression,
1497 subnet -> netmask.iabuf,
d758ad8c
TL
1498 subnet -> netmask.len,
1499 0, 0, MDL)) {
f7fdb216
DH
1500 option_code_hash_lookup(&oc->option,
1501 dhcp_universe.code_hash,
1502 &i, 0, MDL);
e77892f5
TL
1503 save_option (&dhcp_universe, options, oc);
1504 }
4bd8800e 1505 option_cache_dereference (&oc, MDL);
e77892f5
TL
1506 }
1507 }
1508
10553ccb
TL
1509 /* If a site option space has been specified, use that for
1510 site option codes. */
1511 i = SV_SITE_OPTION_SPACE;
0af446bc 1512 if ((oc = lookup_option (&server_universe, options, i)) &&
ca1c700e 1513 evaluate_option_cache (&d1, packet, (struct lease *)0,
9e383163 1514 (struct client_state *)0,
12c9957e
TL
1515 packet -> options, options,
1516 &global_scope, oc, MDL)) {
20916cae 1517 struct universe *u = (struct universe *)0;
dd9237c3 1518
20916cae 1519 if (!universe_hash_lookup (&u, universe_hash,
165bce70
TL
1520 (const char *)d1.data, d1.len,
1521 MDL)) {
10553ccb 1522 log_error ("unknown option space %s.", d1.data);
4bd8800e 1523 option_state_dereference (&options, MDL);
20916cae
TL
1524 if (subnet)
1525 subnet_dereference (&subnet, MDL);
10553ccb
TL
1526 return;
1527 }
1528
1529 options -> site_universe = u -> index;
2c9bf1f4 1530 options->site_code_min = find_min_site_code(u);
4bd8800e 1531 data_string_forget (&d1, MDL);
10553ccb
TL
1532 } else {
1533 options -> site_universe = dhcp_universe.index;
1534 options -> site_code_min = 0; /* Trust me, it works. */
1535 }
1536
cdc336ab 1537 memset (&prl, 0, sizeof prl);
431693d1
TL
1538
1539 /* Use the parameter list from the scope if there is one. */
1540 oc = lookup_option (&dhcp_universe, options,
e77892f5
TL
1541 DHO_DHCP_PARAMETER_REQUEST_LIST);
1542
431693d1
TL
1543 /* Otherwise, if the client has provided a list of options
1544 that it wishes returned, use it to prioritize. Otherwise,
1545 prioritize based on the default priority list. */
1546
cdc336ab 1547 if (!oc)
431693d1 1548 oc = lookup_option (&dhcp_universe, packet -> options,
cdc336ab
TL
1549 DHO_DHCP_PARAMETER_REQUEST_LIST);
1550
1551 if (oc)
ca1c700e 1552 evaluate_option_cache (&prl, packet, (struct lease *)0,
9e383163 1553 (struct client_state *)0,
12c9957e
TL
1554 packet -> options, options,
1555 &global_scope, oc, MDL);
e77892f5
TL
1556
1557#ifdef DEBUG_PACKET
1558 dump_packet (packet);
1559 dump_raw ((unsigned char *)packet -> raw, packet -> packet_length);
1560#endif
1561
1562 log_info ("%s", msgbuf);
1563
10553ccb 1564 /* Figure out the address of the boot file server. */
10553ccb
TL
1565 if ((oc =
1566 lookup_option (&server_universe, options, SV_NEXT_SERVER))) {
ca1c700e 1567 if (evaluate_option_cache (&d1, packet, (struct lease *)0,
9e383163 1568 (struct client_state *)0,
12c9957e
TL
1569 packet -> options, options,
1570 &global_scope, oc, MDL)) {
10553ccb
TL
1571 /* If there was more than one answer,
1572 take the first. */
1573 if (d1.len >= 4 && d1.data)
1574 memcpy (&raw.siaddr, d1.data, 4);
4bd8800e 1575 data_string_forget (&d1, MDL);
10553ccb
TL
1576 }
1577 }
1578
1e05d095
SR
1579 /*
1580 * Remove any time options, per section 3.4 RFC 2131
1581 */
1582 delete_option(&dhcp_universe, options, DHO_DHCP_LEASE_TIME);
1583 delete_option(&dhcp_universe, options, DHO_DHCP_RENEWAL_TIME);
1584 delete_option(&dhcp_universe, options, DHO_DHCP_REBINDING_TIME);
1585
e77892f5
TL
1586 /* Set up the option buffer... */
1587 outgoing.packet_length =
da38df14 1588 cons_options (packet, outgoing.raw, (struct lease *)0,
9e383163 1589 (struct client_state *)0,
12c9957e
TL
1590 0, packet -> options, options, &global_scope,
1591 0, nulltp, 0,
9030b313
TL
1592 prl.len ? &prl : (struct data_string *)0,
1593 (char *)0);
4bd8800e
TL
1594 option_state_dereference (&options, MDL);
1595 data_string_forget (&prl, MDL);
e77892f5
TL
1596
1597 /* Make sure that the packet is at least as big as a BOOTP packet. */
1598 if (outgoing.packet_length < BOOTP_MIN_LEN)
1599 outgoing.packet_length = BOOTP_MIN_LEN;
1600
e77892f5 1601 raw.giaddr = packet -> raw -> giaddr;
cdc336ab 1602 raw.ciaddr = packet -> raw -> ciaddr;
e77892f5
TL
1603 memcpy (raw.chaddr, packet -> raw -> chaddr, sizeof raw.chaddr);
1604 raw.hlen = packet -> raw -> hlen;
1605 raw.htype = packet -> raw -> htype;
1606
1607 raw.xid = packet -> raw -> xid;
1608 raw.secs = packet -> raw -> secs;
1609 raw.flags = packet -> raw -> flags;
1610 raw.hops = packet -> raw -> hops;
1611 raw.op = BOOTREPLY;
1612
e77892f5
TL
1613#ifdef DEBUG_PACKET
1614 dump_packet (&outgoing);
1615 dump_raw ((unsigned char *)&raw, outgoing.packet_length);
1616#endif
1617
785c1a51
FD
1618#if defined(DHCPv6) && defined(DHCP4o6)
1619 if (dhcpv4_over_dhcpv6 && (packet->dhcp4o6_response != NULL)) {
1620 /* Report what we're sending. */
1621 snprintf(msgbuf, sizeof msgbuf,
1622 "DHCP4o6 DHCPACK to %s (%s) via", piaddr(cip),
1623 (packet->raw->htype && packet->raw->hlen) ?
1624 print_hw_addr(packet->raw->htype, packet->raw->hlen,
1625 packet->raw->chaddr) :
1626 "<no client hardware address>");
1627 log_info("%s %s", msgbuf, piaddr(packet->client_addr));
1628
1629 /* fill dhcp4o6_response */
1630 packet->dhcp4o6_response->len = outgoing.packet_length;
1631 packet->dhcp4o6_response->buffer = NULL;
1632 if (!buffer_allocate(&packet->dhcp4o6_response->buffer,
1633 outgoing.packet_length, MDL)) {
1634 log_fatal("No memory to store DHCP4o6 reply.");
1635 }
1636 packet->dhcp4o6_response->data =
1637 packet->dhcp4o6_response->buffer->data;
1638 memcpy(packet->dhcp4o6_response->buffer->data,
1639 outgoing.raw, outgoing.packet_length);
1640
1641 /* done */
1642 if (subnet)
1643 subnet_dereference (&subnet, MDL);
1644 return;
1645 }
1646#endif
1647
e77892f5
TL
1648 /* Set up the common stuff... */
1649 to.sin_family = AF_INET;
1650#ifdef HAVE_SA_LEN
1651 to.sin_len = sizeof to;
1652#endif
1653 memset (to.sin_zero, 0, sizeof to.sin_zero);
1654
3496e9bc 1655 /* RFC2131 states the server SHOULD unicast to ciaddr.
88cd8aca 1656 * There are two wrinkles - relays, and when ciaddr is zero.
87a08ccc
DH
1657 * There's actually no mention of relays at all in rfc2131 in
1658 * regard to DHCPINFORM, except to say we might get packets from
1659 * clients via them. Note: relays unicast to clients to the
1660 * "yiaddr" address, which servers are forbidden to set when
1661 * answering an inform.
88cd8aca 1662 *
87a08ccc
DH
1663 * The solution: If ciaddr is zero, and giaddr is set, go via the
1664 * relay with the broadcast flag set to help the relay (with no
1665 * yiaddr and very likely no chaddr, it will have no idea where to
1666 * send the packet).
88cd8aca 1667 *
87a08ccc
DH
1668 * If the ciaddr is zero and giaddr is not set, go via the source
1669 * IP address (but you are permitted to barf on their shoes).
88cd8aca 1670 *
87a08ccc 1671 * If ciaddr is not zero, send the packet there always.
88cd8aca 1672 */
87a08ccc 1673 if (!raw.ciaddr.s_addr && gip.len) {
88cd8aca
DH
1674 memcpy(&to.sin_addr, gip.iabuf, 4);
1675 to.sin_port = local_port;
87a08ccc 1676 raw.flags |= htons(BOOTP_BROADCAST);
88cd8aca 1677 } else {
87a08ccc 1678 gip.len = 0;
88cd8aca
DH
1679 memcpy(&to.sin_addr, cip.iabuf, 4);
1680 to.sin_port = remote_port;
1681 }
1682
1683 /* Report what we're sending. */
1684 snprintf(msgbuf, sizeof msgbuf, "DHCPACK to %s (%s) via", piaddr(cip),
1685 (packet->raw->htype && packet->raw->hlen) ?
1686 print_hw_addr(packet->raw->htype, packet->raw->hlen,
1687 packet->raw->chaddr) :
1688 "<no client hardware address>");
1689 log_info("%s %s", msgbuf, gip.len ? piaddr(gip) :
1690 packet->interface->name);
e77892f5
TL
1691
1692 errno = 0;
dd9237c3
TM
1693 interface = (fallback_interface ? fallback_interface
1694 : packet -> interface);
1695 result = send_packet(interface, &outgoing, &raw,
1696 outgoing.packet_length, from, &to, NULL);
1697 if (result < 0) {
1698 log_error ("%s:%d: Failed to send %d byte long packet over %s "
1699 "interface.", MDL, outgoing.packet_length,
1700 interface->name);
1701 }
1702
1703
20916cae
TL
1704 if (subnet)
1705 subnet_dereference (&subnet, MDL);
b88e8e15
TL
1706}
1707
e046c826
TM
1708/*!
1709 * \brief Constructs and sends a DHCP Nak
1710 *
1711 * In order to populate options such as dhcp-server-id and
1712 * dhcp-client-identifier, the function creates a temporary option cache
1713 * and evaluates options based on the packet's shared-network or the
1714 * network_group in its absence, as well as the packet->clasess (if any).
1715 *
1716 * \param packet inbound packet received from the client
1717 * \param cip address requested by the client
1718 * \param network_group optional scope for use in setting up options
1719 */
1720void nak_lease (packet, cip, network_group)
ed8bcd8f 1721 struct packet *packet;
a8b53b42 1722 struct iaddr *cip;
e046c826 1723 struct group *network_group; /* scope to use for options */
ed8bcd8f
TL
1724{
1725 struct sockaddr_in to;
4fbcd991 1726 struct in_addr from;
ed8bcd8f
TL
1727 int result;
1728 struct dhcp_packet raw;
1729 unsigned char nak = DHCPNAK;
1730 struct packet outgoing;
20916cae 1731 unsigned i;
951323fe 1732 struct option_state *options = (struct option_state *)0;
5d25508c 1733 struct option_cache *oc = (struct option_cache *)0;
e046c826 1734 struct option_state *eval_options = NULL;
ed8bcd8f 1735
4bd8800e 1736 option_state_allocate (&options, MDL);
ed8bcd8f
TL
1737 memset (&outgoing, 0, sizeof outgoing);
1738 memset (&raw, 0, sizeof raw);
1739 outgoing.raw = &raw;
1740
1741 /* Set DHCP_MESSAGE_TYPE to DHCPNAK */
4bd8800e 1742 if (!option_cache_allocate (&oc, MDL)) {
8ae2d595 1743 log_error ("No memory for DHCPNAK message type.");
4bd8800e 1744 option_state_dereference (&options, MDL);
5d25508c
TL
1745 return;
1746 }
d758ad8c
TL
1747 if (!make_const_data (&oc -> expression, &nak, sizeof nak,
1748 0, 0, MDL)) {
8ae2d595 1749 log_error ("No memory for expr_const expression.");
4bd8800e
TL
1750 option_cache_dereference (&oc, MDL);
1751 option_state_dereference (&options, MDL);
5d25508c
TL
1752 return;
1753 }
f7fdb216
DH
1754 i = DHO_DHCP_MESSAGE_TYPE;
1755 option_code_hash_lookup(&oc->option, dhcp_universe.code_hash,
1756 &i, 0, MDL);
951323fe 1757 save_option (&dhcp_universe, options, oc);
4bd8800e 1758 option_cache_dereference (&oc, MDL);
5d25508c 1759
b88e8e15 1760 /* Set DHCP_MESSAGE to whatever the message is */
4bd8800e 1761 if (!option_cache_allocate (&oc, MDL)) {
8ae2d595 1762 log_error ("No memory for DHCPNAK message type.");
4bd8800e 1763 option_state_dereference (&options, MDL);
5d25508c
TL
1764 return;
1765 }
1766 if (!make_const_data (&oc -> expression,
c5b0f529 1767 (unsigned char *)dhcp_message,
d758ad8c 1768 strlen (dhcp_message), 1, 0, MDL)) {
8ae2d595 1769 log_error ("No memory for expr_const expression.");
4bd8800e
TL
1770 option_cache_dereference (&oc, MDL);
1771 option_state_dereference (&options, MDL);
5d25508c
TL
1772 return;
1773 }
f7fdb216
DH
1774 i = DHO_DHCP_MESSAGE;
1775 option_code_hash_lookup(&oc->option, dhcp_universe.code_hash,
1776 &i, 0, MDL);
951323fe 1777 save_option (&dhcp_universe, options, oc);
4bd8800e 1778 option_cache_dereference (&oc, MDL);
d56788df 1779
e046c826
TM
1780 /* Setup the options at the global and subnet scopes. These
1781 * may be used to locate sever id option if enabled as well
1782 * for echo-client-id further on. (This allocates eval_options). */
1783 eval_network_statements(&eval_options, packet, network_group);
1784
f8380d3f 1785#if defined(SERVER_ID_FOR_NAK)
e046c826
TM
1786 /* Pass in the evaluated options so they can be searched for
1787 * server-id, otherwise source address comes from the interface
1788 * address. */
1789 get_server_source_address(&from, eval_options, options, packet);
f8380d3f 1790#else
e046c826 1791 /* Get server source address from the interface address */
f8380d3f 1792 get_server_source_address(&from, NULL, options, packet);
d56788df
SR
1793#endif /* if defined(SERVER_ID_FOR_NAK) */
1794
98311e4b 1795 /* If there were agent options in the incoming packet, return
02428754
DH
1796 * them. We do not check giaddr to detect the presence of a
1797 * relay, as this excludes "l2" relay agents which have no
1798 * giaddr to set.
1799 */
1800 if (packet->options->universe_count > agent_universe.index &&
1801 packet->options->universes [agent_universe.index]) {
98311e4b
DH
1802 option_chain_head_reference
1803 ((struct option_chain_head **)
1804 &(options -> universes [agent_universe.index]),
1805 (struct option_chain_head *)
1806 packet -> options -> universes [agent_universe.index],
1807 MDL);
1808 }
1809
e046c826
TM
1810 /* echo-client-id can specified at the class level so add class-scoped
1811 * options into eval_options. */
1812 for (i = packet->class_count; i > 0; i--) {
1813 execute_statements_in_scope(NULL, packet, NULL, NULL,
1814 packet->options, eval_options,
1815 &global_scope,
1816 packet->classes[i - 1]->group,
1817 NULL, NULL);
1818 }
1819
1820 /* Echo client id if we received and it's enabled */
1821 echo_client_id(packet, NULL, eval_options, options);
1822 option_state_dereference (&eval_options, MDL);
1823
b88e8e15 1824 /* Do not use the client's requested parameter list. */
951323fe 1825 delete_option (&dhcp_universe, packet -> options,
5d25508c 1826 DHO_DHCP_PARAMETER_REQUEST_LIST);
b88e8e15 1827
ed8bcd8f 1828 /* Set up the option buffer... */
a4cb16ca 1829 outgoing.packet_length =
da38df14 1830 cons_options (packet, outgoing.raw, (struct lease *)0,
9e383163 1831 (struct client_state *)0,
12c9957e 1832 0, packet -> options, options, &global_scope,
9030b313 1833 0, 0, 0, (struct data_string *)0, (char *)0);
4bd8800e 1834 option_state_dereference (&options, MDL);
ed8bcd8f 1835
b88e8e15 1836/* memset (&raw.ciaddr, 0, sizeof raw.ciaddr);*/
ed8bcd8f 1837 raw.giaddr = packet -> raw -> giaddr;
b88e8e15
TL
1838 memcpy (raw.chaddr, packet -> raw -> chaddr, sizeof raw.chaddr);
1839 raw.hlen = packet -> raw -> hlen;
1840 raw.htype = packet -> raw -> htype;
ed8bcd8f
TL
1841
1842 raw.xid = packet -> raw -> xid;
1843 raw.secs = packet -> raw -> secs;
b88e8e15 1844 raw.flags = packet -> raw -> flags | htons (BOOTP_BROADCAST);
ed8bcd8f
TL
1845 raw.hops = packet -> raw -> hops;
1846 raw.op = BOOTREPLY;
1847
785c1a51
FD
1848 /* Make sure that the packet is at least as big as a BOOTP packet. */
1849 if (outgoing.packet_length < BOOTP_MIN_LEN)
1850 outgoing.packet_length = BOOTP_MIN_LEN;
1851
7a049f2c 1852 /* Report what we're sending... */
785c1a51
FD
1853#if defined(DHCPv6) && defined(DHCP4o6)
1854 if (dhcpv4_over_dhcpv6 && (packet->dhcp4o6_response != NULL)) {
1855 log_info ("DHCP4o6 DHCPNAK on %s to %s via %s",
1856 piaddr (*cip),
1857 print_hw_addr (packet -> raw -> htype,
1858 packet -> raw -> hlen,
1859 packet -> raw -> chaddr),
1860 piaddr(packet->client_addr));
1861 } else
1862#endif
8ae2d595 1863 log_info ("DHCPNAK on %s to %s via %s",
7a049f2c
TL
1864 piaddr (*cip),
1865 print_hw_addr (packet -> raw -> htype,
1866 packet -> raw -> hlen,
a69f4fd3
TL
1867 packet -> raw -> chaddr),
1868 packet -> raw -> giaddr.s_addr
1869 ? inet_ntoa (packet -> raw -> giaddr)
1870 : packet -> interface -> name);
1871
7a049f2c
TL
1872#ifdef DEBUG_PACKET
1873 dump_packet (packet);
1874 dump_raw ((unsigned char *)packet -> raw, packet -> packet_length);
1875 dump_packet (&outgoing);
1876 dump_raw ((unsigned char *)&raw, outgoing.packet_length);
1877#endif
1878
785c1a51
FD
1879#if defined(DHCPv6) && defined(DHCP4o6)
1880 if (dhcpv4_over_dhcpv6 && (packet->dhcp4o6_response != NULL)) {
1881 /* fill dhcp4o6_response */
1882 packet->dhcp4o6_response->len = outgoing.packet_length;
1883 packet->dhcp4o6_response->buffer = NULL;
1884 if (!buffer_allocate(&packet->dhcp4o6_response->buffer,
1885 outgoing.packet_length, MDL)) {
1886 log_fatal("No memory to store DHCP4o6 reply.");
1887 }
1888 packet->dhcp4o6_response->data =
1889 packet->dhcp4o6_response->buffer->data;
1890 memcpy(packet->dhcp4o6_response->buffer->data,
1891 outgoing.raw, outgoing.packet_length);
1892 return;
1893 }
1894#endif
1895
7a049f2c
TL
1896 /* Set up the common stuff... */
1897 to.sin_family = AF_INET;
1898#ifdef HAVE_SA_LEN
1899 to.sin_len = sizeof to;
1900#endif
1901 memset (to.sin_zero, 0, sizeof to.sin_zero);
1902
b88e8e15
TL
1903 /* If this was gatewayed, send it back to the gateway.
1904 Otherwise, broadcast it on the local network. */
1905 if (raw.giaddr.s_addr) {
ed8bcd8f 1906 to.sin_addr = raw.giaddr;
bfe2d221 1907 if (raw.giaddr.s_addr != htonl (INADDR_LOOPBACK))
1b871100
TL
1908 to.sin_port = local_port;
1909 else
1910 to.sin_port = remote_port; /* for testing. */
7a049f2c 1911
027f46cb 1912 if (fallback_interface) {
3c941d42
DH
1913 result = send_packet(fallback_interface, packet, &raw,
1914 outgoing.packet_length, from, &to,
1915 NULL);
dd9237c3
TM
1916 if (result < 0) {
1917 log_error ("%s:%d: Failed to send %d byte long "
1918 "packet over %s interface.", MDL,
1919 outgoing.packet_length,
1920 fallback_interface->name);
1921 }
1922
027f46cb
TL
1923 return;
1924 }
b88e8e15 1925 } else {
71df44f5 1926 to.sin_addr = limited_broadcast;
44b2e3ad 1927 to.sin_port = remote_port;
b88e8e15 1928 }
ed8bcd8f 1929
ed8bcd8f 1930 errno = 0;
3c941d42
DH
1931 result = send_packet(packet->interface, packet, &raw,
1932 outgoing.packet_length, from, &to, NULL);
dd9237c3
TM
1933 if (result < 0) {
1934 log_error ("%s:%d: Failed to send %d byte long packet over %s "
1935 "interface.", MDL, outgoing.packet_length,
1936 packet->interface->name);
1937 }
1938
ed8bcd8f
TL
1939}
1940
e046c826
TM
1941/*!
1942 * \brief Adds a dhcp-client-id option to a set of options
1943 * Given a set of input options, it searches for echo-client-id. If it is
1944 * defined and enabled, the given packet is searched for dhcp-client-id. If
1945 * the option is found it is replicated into the given set of output options.
1946 * This allows us to provide compliance with RFC 6842. It is called when we ack
1947 * or nak a lease. In the latter case we may or may not have created the
1948 * requisite scope to lookup echo-client-id.
1949 *
1950 * Note the flag packet.sv_echo_client_id is set to reflect the configuration
1951 * option. This bypases inaccessiblity of server_universe in cons_options()
1952 * which must amend the PRL (when not empty) if echoing is enabled.
1953 *
1954 * \param packet inbound packet received from the client
1955 * \param lease lease associated with this client (if one)
1956 * \param in_options options in which to search for echo-client-id
1957 * \param out_options options to which to save the client-id
1958 */
1959void echo_client_id(packet, lease, in_options, out_options)
1960 struct packet *packet;
1961 struct lease *lease;
1962 struct option_state *in_options;
1963 struct option_state *out_options;
1964{
1965 struct option_cache *oc;
1966 int ignorep;
1967
1968 /* Check if echo-client-id is enabled */
1969 oc = lookup_option(&server_universe, in_options, SV_ECHO_CLIENT_ID);
1970 if (oc && evaluate_boolean_option_cache(&ignorep, packet, lease,
1971 NULL, packet->options,
1972 in_options,
1973 (lease ? &lease->scope : NULL),
1974 oc, MDL)) {
1975 struct data_string client_id;
1976 unsigned int opcode = DHO_DHCP_CLIENT_IDENTIFIER;
1977
1978 /* Save knowledge that echo is enabled to the packet */
1979 packet->sv_echo_client_id = ISC_TRUE;
1980
1981 /* Now see if inbound packet contains client-id */
1982 oc = lookup_option(&dhcp_universe, packet->options, opcode);
1983 memset(&client_id, 0, sizeof client_id);
1984 if (oc && evaluate_option_cache(&client_id,
1985 packet, NULL, NULL,
1986 packet->options, NULL,
1987 (lease ? &lease->scope : NULL),
1988 oc, MDL)) {
1989 /* Packet contained client-id, add it to out_options. */
1990 oc = NULL;
1991 if (option_cache_allocate(&oc, MDL)) {
1992 if (make_const_data(&oc->expression,
1993 client_id.data,
1994 client_id.len,
1995 1, 0, MDL)) {
1996 option_code_hash_lookup(&oc->option,
1997 dhcp_universe.
1998 code_hash,
1999 &opcode,
2000 0, MDL);
2001 save_option(&dhcp_universe,
2002 out_options, oc);
2003 }
2004 option_cache_dereference(&oc, MDL);
2005 }
2006 }
2007 }
2008}
2009
250f7134
SR
2010void check_pool_threshold (packet, lease, state)
2011 struct packet *packet;
2012 struct lease *lease;
2013 struct lease_state *state;
2014
2015{
2016
2017 struct pool *pool = lease->pool;
2018 int used, count, high_threshold, poolhigh = 0, poollow = 0;
2019 char *shared_name = "no name";
2020
2021 if (pool == NULL)
2022 return;
2023
2024 /* get a pointer to the name if we have one */
2025 if ((pool->shared_network != NULL) &&
2026 (pool->shared_network->name != NULL)) {
2027 shared_name = pool->shared_network->name;
2028 }
2029
2030 count = pool->lease_count;
2031 used = count - (pool->free_leases + pool->backup_leases);
2032
2033 /* The logged flag indicates if we have already crossed the high
2034 * threshold and emitted a log message. If it is set we check to
2035 * see if we have re-crossed the low threshold and need to reset
2036 * things. When we cross the high threshold we determine what
2037 * the low threshold is and save it into the low_threshold value.
2038 * When we cross that threshold we reset the logged flag and
2039 * the low_threshold to 0 which allows the high threshold message
2040 * to be emitted once again.
2041 * if we haven't recrossed the boundry we don't need to do anything.
2042 */
2043 if (pool->logged !=0) {
2044 if (used <= pool->low_threshold) {
2045 pool->low_threshold = 0;
2046 pool->logged = 0;
2047 log_error("Pool threshold reset - shared subnet: %s; "
2048 "address: %s; low threshold %d/%d.",
2049 shared_name, piaddr(lease->ip_addr),
2050 used, count);
2051 }
2052 return;
2053 }
2054
2055 /* find the high threshold */
2056 if (get_option_int(&poolhigh, &server_universe, packet, lease, NULL,
2057 packet->options, state->options, state->options,
2058 &lease->scope, SV_LOG_THRESHOLD_HIGH, MDL) == 0) {
2059 /* no threshold bail out */
2060 return;
2061 }
2062
2063 /* We do have a threshold for this pool, see if its valid */
2064 if ((poolhigh <= 0) || (poolhigh > 100)) {
2065 /* not valid */
2066 return;
2067 }
2068
2069 /* we have a valid value, have we exceeded it */
2070 high_threshold = FIND_PERCENT(count, poolhigh);
2071 if (used < high_threshold) {
2072 /* nope, no more to do */
2073 return;
2074 }
2075
2076 /* we've exceeded it, output a message */
2077 log_error("Pool threshold exceeded - shared subnet: %s; "
2078 "address: %s; high threshold %d%% %d/%d.",
2079 shared_name, piaddr(lease->ip_addr),
2080 poolhigh, used, count);
2081
2082 /* handle the low threshold now, if we don't
2083 * have a valid one we default to 0. */
2084 if ((get_option_int(&poollow, &server_universe, packet, lease, NULL,
2085 packet->options, state->options, state->options,
2086 &lease->scope, SV_LOG_THRESHOLD_LOW, MDL) == 0) ||
2087 (poollow > 100)) {
2088 poollow = 0;
2089 }
2090
2091 /*
2092 * If the low theshold is higher than the high threshold we continue to log
2093 * If it isn't then we set the flag saying we already logged and determine
2094 * what the reset threshold is.
2095 */
2096 if (poollow < poolhigh) {
2097 pool->logged = 1;
2098 pool->low_threshold = FIND_PERCENT(count, poollow);
2099 }
2100}
2101
c75473d8 2102void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
ed8bcd8f
TL
2103 struct packet *packet;
2104 struct lease *lease;
a7822eac 2105 unsigned int offer;
ed8bcd8f 2106 TIME when;
c4924529 2107 char *msg;
5bc2e1f2 2108 int ms_nulltp;
c75473d8 2109 struct host_decl *hp;
ed8bcd8f 2110{
20916cae 2111 struct lease *lt;
9cc3ad7f 2112 struct lease_state *state;
cb8176c4 2113 struct lease *next;
98311e4b 2114 struct host_decl *host = (struct host_decl *)0;
ed8bcd8f 2115 TIME lease_time;
4ecd2958 2116 TIME offered_lease_time;
b1dd98c9 2117 struct data_string d1;
eeea1395
TL
2118 TIME min_lease_time;
2119 TIME max_lease_time;
2120 TIME default_lease_time;
5d25508c 2121 struct option_cache *oc;
20916cae 2122 isc_result_t result;
98311e4b 2123 TIME ping_timeout;
6d103865
SK
2124 TIME lease_cltt;
2125 struct in_addr from;
b1d3778c
DH
2126 TIME remaining_time;
2127 struct iaddr cip;
785c1a51 2128#if defined(DELAYED_ACK) && !defined(DHCP4o6)
8cd88e20
SR
2129 /* By default we don't do the enqueue */
2130 isc_boolean_t enqueue = ISC_FALSE;
929a2364
TM
2131#endif
2132 int use_old_lease = 0;
ed8bcd8f 2133
b1b7b521 2134 unsigned i, j;
28868515 2135 int s1;
19654922 2136 int ignorep;
be62cf06 2137 struct timeval tv;
b88e8e15 2138
9cc3ad7f 2139 /* If we're already acking this lease, don't do it again. */
c4924529 2140 if (lease -> state)
9cc3ad7f 2141 return;
9cc3ad7f 2142
6d103865
SK
2143 /* Save original cltt for comparison later. */
2144 lease_cltt = lease->cltt;
2145
98311e4b 2146 /* If the lease carries a host record, remember it. */
c75473d8
DH
2147 if (hp)
2148 host_reference (&host, hp, MDL);
2149 else if (lease -> host)
98311e4b
DH
2150 host_reference (&host, lease -> host, MDL);
2151
a52d8045 2152 /* Allocate a lease state structure... */
4bd8800e 2153 state = new_lease_state (MDL);
a52d8045 2154 if (!state)
8ae2d595 2155 log_fatal ("unable to allocate lease state!");
cdc336ab 2156 state -> got_requested_address = packet -> got_requested_address;
20916cae
TL
2157 shared_network_reference (&state -> shared_network,
2158 packet -> interface -> shared_network, MDL);
cdc336ab
TL
2159
2160 /* See if we got a server identifier option. */
2161 if (lookup_option (&dhcp_universe,
2162 packet -> options, DHO_DHCP_SERVER_IDENTIFIER))
2163 state -> got_server_identifier = 1;
a52d8045 2164
a1308b64 2165 maybe_return_agent_options(packet, state->options);
b1dd98c9 2166
d9eefc5d
TL
2167 /* If we are offering a lease that is still currently valid, preserve
2168 the events. We need to do this because if the client does not
2169 REQUEST our offer, it will expire in 2 minutes, overriding the
2170 expire time in the currently in force lease. We want the expire
2171 events to be executed at that point. */
a7341359 2172 if (lease->ends <= cur_time && offer != DHCPOFFER) {
d9eefc5d
TL
2173 /* Get rid of any old expiry or release statements - by
2174 executing the statements below, we will be inserting new
2175 ones if there are any to insert. */
a7341359
SR
2176 if (lease->on_star.on_expiry)
2177 executable_statement_dereference
2178 (&lease->on_star.on_expiry, MDL);
2179 if (lease->on_star.on_commit)
2180 executable_statement_dereference
2181 (&lease->on_star.on_commit, MDL);
2182 if (lease->on_star.on_release)
2183 executable_statement_dereference
2184 (&lease->on_star.on_release, MDL);
d9eefc5d 2185 }
ed2529e5 2186
10553ccb 2187 /* Execute statements in scope starting with the subnet scope. */
a7341359
SR
2188 execute_statements_in_scope (NULL, packet, lease,
2189 NULL, packet->options,
2190 state->options, &lease->scope,
2191 lease->subnet->group, NULL, NULL);
b1dd98c9 2192
10553ccb 2193 /* If the lease is from a pool, run the pool scope. */
a7341359
SR
2194 if (lease->pool)
2195 (execute_statements_in_scope(NULL, packet, lease, NULL,
2196 packet->options, state->options,
2197 &lease->scope, lease->pool->group,
2198 lease->pool->
2199 shared_network->group,
2200 NULL));
10553ccb
TL
2201
2202 /* Execute statements from class scopes. */
fa661adb 2203 for (i = packet -> class_count; i > 0; i--) {
a7341359
SR
2204 execute_statements_in_scope(NULL, packet, lease, NULL,
2205 packet->options, state->options,
2206 &lease->scope,
2207 packet->classes[i - 1]->group,
2208 (lease->pool ? lease->pool->group
2209 : lease->subnet->group),
2210 NULL);
b1dd98c9
TL
2211 }
2212
e8e6a30f
TL
2213 /* See if the client is only supposed to have one lease at a time,
2214 and if so, find its other leases and release them. We can only
2215 do this on DHCPREQUEST. It's a little weird to do this before
2216 looking at permissions, because the client might not actually
2217 _get_ a lease after we've done the permission check, but the
2218 assumption for this option is that the client has exactly one
2219 network interface, and will only ever remember one lease. So
2220 if it sends a DHCPREQUEST, and doesn't get the lease, it's already
2221 forgotten about its old lease, so we can too. */
3db5bf9c 2222 if (packet -> packet_type == DHCPREQUEST &&
e8e6a30f
TL
2223 (oc = lookup_option (&server_universe, state -> options,
2224 SV_ONE_LEASE_PER_CLIENT)) &&
19654922 2225 evaluate_boolean_option_cache (&ignorep,
9e383163
TL
2226 packet, lease,
2227 (struct client_state *)0,
2228 packet -> options,
12c9957e
TL
2229 state -> options, &lease -> scope,
2230 oc, MDL)) {
d758ad8c
TL
2231 struct lease *seek;
2232 if (lease -> uid_len) {
2233 do {
2234 seek = (struct lease *)0;
2235 find_lease_by_uid (&seek, lease -> uid,
2236 lease -> uid_len, MDL);
2237 if (!seek)
2238 break;
2239 if (seek == lease && !seek -> n_uid) {
2240 lease_dereference (&seek, MDL);
2241 break;
2242 }
2243 next = (struct lease *)0;
2244
2245 /* Don't release expired leases, and don't
2246 release the lease we're going to assign. */
2247 next = (struct lease *)0;
2248 while (seek) {
2249 if (seek -> n_uid)
2250 lease_reference (&next, seek -> n_uid, MDL);
2251 if (seek != lease &&
2252 seek -> binding_state != FTS_RELEASED &&
2253 seek -> binding_state != FTS_EXPIRED &&
2254 seek -> binding_state != FTS_RESET &&
2255 seek -> binding_state != FTS_FREE &&
2256 seek -> binding_state != FTS_BACKUP)
2257 break;
2258 lease_dereference (&seek, MDL);
2259 if (next) {
2260 lease_reference (&seek, next, MDL);
2261 lease_dereference (&next, MDL);
2262 }
2263 }
2264 if (next)
2265 lease_dereference (&next, MDL);
2266 if (seek) {
2267 release_lease (seek, packet);
2268 lease_dereference (&seek, MDL);
2269 } else
2270 break;
2271 } while (1);
2272 }
2273 if (!lease -> uid_len ||
98311e4b
DH
2274 (host &&
2275 !host -> client_identifier.len &&
d758ad8c
TL
2276 (oc = lookup_option (&server_universe, state -> options,
2277 SV_DUPLICATES)) &&
2278 !evaluate_boolean_option_cache (&ignorep, packet, lease,
2279 (struct client_state *)0,
2280 packet -> options,
2281 state -> options,
2282 &lease -> scope,
2283 oc, MDL))) {
2284 do {
2285 seek = (struct lease *)0;
2286 find_lease_by_hw_addr
2287 (&seek, lease -> hardware_addr.hbuf,
2288 lease -> hardware_addr.hlen, MDL);
2289 if (!seek)
2290 break;
2291 if (seek == lease && !seek -> n_hw) {
2292 lease_dereference (&seek, MDL);
2293 break;
2294 }
2295 next = (struct lease *)0;
2296 while (seek) {
2297 if (seek -> n_hw)
2298 lease_reference (&next, seek -> n_hw, MDL);
2299 if (seek != lease &&
2300 seek -> binding_state != FTS_RELEASED &&
2301 seek -> binding_state != FTS_EXPIRED &&
2302 seek -> binding_state != FTS_RESET &&
2303 seek -> binding_state != FTS_FREE &&
2304 seek -> binding_state != FTS_BACKUP)
2305 break;
2306 lease_dereference (&seek, MDL);
2307 if (next) {
2308 lease_reference (&seek, next, MDL);
2309 lease_dereference (&next, MDL);
2310 }
2311 }
2312 if (next)
2313 lease_dereference (&next, MDL);
2314 if (seek) {
2315 release_lease (seek, packet);
2316 lease_dereference (&seek, MDL);
2317 } else
2318 break;
2319 } while (1);
2320 }
e8e6a30f
TL
2321 }
2322
2323
b1dd98c9
TL
2324 /* Make sure this packet satisfies the configured minimum
2325 number of seconds. */
d73e855d 2326 memset (&d1, 0, sizeof d1);
2540af04 2327 if (offer == DHCPOFFER &&
951323fe 2328 (oc = lookup_option (&server_universe, state -> options,
5d25508c 2329 SV_MIN_SECS))) {
ca1c700e 2330 if (evaluate_option_cache (&d1, packet, lease,
9e383163 2331 (struct client_state *)0,
ca1c700e 2332 packet -> options, state -> options,
12c9957e 2333 &lease -> scope, oc, MDL)) {
6c608437
TL
2334 if (d1.len &&
2335 ntohs (packet -> raw -> secs) < d1.data [0]) {
00638355
DH
2336 log_info("%s: configured min-secs value (%d) "
2337 "is greater than secs field (%d). "
2338 "message dropped.", msg, d1.data[0],
2339 ntohs(packet->raw->secs));
4bd8800e
TL
2340 data_string_forget (&d1, MDL);
2341 free_lease_state (state, MDL);
98311e4b
DH
2342 if (host)
2343 host_dereference (&host, MDL);
5d25508c
TL
2344 return;
2345 }
4bd8800e 2346 data_string_forget (&d1, MDL);
5d25508c
TL
2347 }
2348 }
2349
98311e4b
DH
2350 /* Try to find a matching host declaration for this lease.
2351 */
2352 if (!host) {
007e3ee4
TL
2353 struct host_decl *hp = (struct host_decl *)0;
2354 struct host_decl *h;
5d25508c
TL
2355
2356 /* Try to find a host_decl that matches the client
2357 identifier or hardware address on the packet, and
2358 has no fixed IP address. If there is one, hang
2359 it off the lease so that its option definitions
2360 can be used. */
951323fe 2361 oc = lookup_option (&dhcp_universe, packet -> options,
5d25508c
TL
2362 DHO_DHCP_CLIENT_IDENTIFIER);
2363 if (oc &&
ca1c700e 2364 evaluate_option_cache (&d1, packet, lease,
9e383163 2365 (struct client_state *)0,
ca1c700e 2366 packet -> options, state -> options,
12c9957e 2367 &lease -> scope, oc, MDL)) {
20916cae 2368 find_hosts_by_uid (&hp, d1.data, d1.len, MDL);
4bd8800e 2369 data_string_forget (&d1, MDL);
98311e4b
DH
2370 for (h = hp; h; h = h -> n_ipaddr) {
2371 if (!h -> fixed_addr)
2372 break;
2373 }
2374 if (h)
2375 host_reference (&host, h, MDL);
95f5d38c
DH
2376 if (hp != NULL)
2377 host_dereference(&hp, MDL);
007e3ee4 2378 }
98311e4b 2379 if (!host) {
007e3ee4
TL
2380 find_hosts_by_haddr (&hp,
2381 packet -> raw -> htype,
2382 packet -> raw -> chaddr,
2383 packet -> raw -> hlen,
2384 MDL);
20916cae
TL
2385 for (h = hp; h; h = h -> n_ipaddr) {
2386 if (!h -> fixed_addr)
5d25508c
TL
2387 break;
2388 }
20916cae 2389 if (h)
98311e4b 2390 host_reference (&host, h, MDL);
95f5d38c
DH
2391 if (hp != NULL)
2392 host_dereference(&hp, MDL);
007e3ee4 2393 }
bd0b98c1 2394 if (!host) {
a7341359
SR
2395 find_hosts_by_option(&hp, packet,
2396 packet->options, MDL);
bd0b98c1
SR
2397 for (h = hp; h; h = h -> n_ipaddr) {
2398 if (!h -> fixed_addr)
2399 break;
2400 }
2401 if (h)
2402 host_reference (&host, h, MDL);
2403 if (hp != NULL)
2404 host_dereference(&hp, MDL);
2405 }
b1dd98c9
TL
2406 }
2407
98311e4b 2408 /* If we have a host_decl structure, run the options associated
a55ccdd0 2409 with its group. Whether the host decl struct is old or not. */
98311e4b 2410 if (host)
a7341359
SR
2411 execute_statements_in_scope (NULL, packet, lease, NULL,
2412 packet->options, state->options,
2413 &lease->scope, host->group,
2414 (lease->pool
2415 ? lease->pool->group
2416 : lease->subnet->group),
2417 NULL);
98311e4b 2418
ddb4c2ac
TL
2419 /* Drop the request if it's not allowed for this client. By
2420 default, unknown clients are allowed. */
98311e4b 2421 if (!host &&
951323fe 2422 (oc = lookup_option (&server_universe, state -> options,
ddb4c2ac 2423 SV_BOOT_UNKNOWN_CLIENTS)) &&
19654922 2424 !evaluate_boolean_option_cache (&ignorep,
9e383163
TL
2425 packet, lease,
2426 (struct client_state *)0,
2427 packet -> options,
12c9957e
TL
2428 state -> options,
2429 &lease -> scope, oc, MDL)) {
19654922
TL
2430 if (!ignorep)
2431 log_info ("%s: unknown client", msg);
4bd8800e 2432 free_lease_state (state, MDL);
98311e4b
DH
2433 if (host)
2434 host_dereference (&host, MDL);
ddb4c2ac 2435 return;
b1dd98c9
TL
2436 }
2437
2438 /* Drop the request if it's not allowed for this client. */
2439 if (!offer &&
951323fe 2440 (oc = lookup_option (&server_universe, state -> options,
ddb4c2ac 2441 SV_ALLOW_BOOTP)) &&
19654922 2442 !evaluate_boolean_option_cache (&ignorep,
9e383163
TL
2443 packet, lease,
2444 (struct client_state *)0,
2445 packet -> options,
12c9957e
TL
2446 state -> options,
2447 &lease -> scope, oc, MDL)) {
19654922
TL
2448 if (!ignorep)
2449 log_info ("%s: bootp disallowed", msg);
4bd8800e 2450 free_lease_state (state, MDL);
98311e4b
DH
2451 if (host)
2452 host_dereference (&host, MDL);
ddb4c2ac 2453 return;
b1dd98c9
TL
2454 }
2455
5d25508c 2456 /* Drop the request if booting is specifically denied. */
951323fe
TL
2457 oc = lookup_option (&server_universe, state -> options,
2458 SV_ALLOW_BOOTING);
5d25508c 2459 if (oc &&
19654922 2460 !evaluate_boolean_option_cache (&ignorep,
9e383163
TL
2461 packet, lease,
2462 (struct client_state *)0,
2463 packet -> options,
12c9957e
TL
2464 state -> options,
2465 &lease -> scope, oc, MDL)) {
19654922 2466 if (!ignorep)
8ae2d595 2467 log_info ("%s: booting disallowed", msg);
4bd8800e 2468 free_lease_state (state, MDL);
98311e4b
DH
2469 if (host)
2470 host_dereference (&host, MDL);
19654922 2471 return;
b1dd98c9
TL
2472 }
2473
c4924529 2474 /* If we are configured to do per-class billing, do it. */
3acf1dca 2475 if (have_billing_classes && !(lease -> flags & STATIC_LEASE)) {
c4924529
TL
2476 /* See if the lease is currently being billed to a
2477 class, and if so, whether or not it can continue to
2478 be billed to that class. */
2479 if (lease -> billing_class) {
2480 for (i = 0; i < packet -> class_count; i++)
2481 if (packet -> classes [i] ==
2482 lease -> billing_class)
2483 break;
f3a44c10 2484 if (i == packet -> class_count) {
6a39bcf0 2485 unbill_class(lease);
f3a44c10
TM
2486 /* Active lease billing change negates reuse */
2487 if (lease->binding_state == FTS_ACTIVE) {
2488 lease->cannot_reuse = 1;
2489 }
2490 }
c4924529 2491 }
65cf86d7 2492
c4924529
TL
2493 /* If we don't have an active billing, see if we need
2494 one, and if we do, try to do so. */
65cf86d7 2495 if (lease->billing_class == NULL) {
6980ae03 2496 char *cname = "";
65cf86d7 2497 int bill = 0;
6980ae03 2498
65cf86d7 2499 for (i = 0; i < packet->class_count; i++) {
6980ae03
SR
2500 struct class *billclass, *subclass;
2501
2502 billclass = packet->classes[i];
2503 if (billclass->lease_limit) {
65cf86d7 2504 bill++;
6980ae03 2505 if (bill_class(lease, billclass))
c4924529 2506 break;
6980ae03
SR
2507
2508 subclass = billclass->superclass;
2509 if (subclass == NULL)
2510 cname = subclass->name;
2511 else
2512 cname = billclass->name;
c4924529
TL
2513 }
2514 }
65cf86d7
EH
2515 if (bill != 0 && i == packet->class_count) {
2516 log_info("%s: no available billing: lease "
2517 "limit reached in all matching "
6980ae03 2518 "classes (last: '%s')", msg, cname);
65cf86d7
EH
2519 free_lease_state(state, MDL);
2520 if (host)
2521 host_dereference(&host, MDL);
2522 return;
2523 }
1b2ab55f 2524
6980ae03
SR
2525 /*
2526 * If this is an offer, undo the billing. We go
1b2ab55f
DH
2527 * through all the steps above to bill a class so
2528 * we can hit the 'no available billing' mark and
2529 * abort without offering. But it just doesn't make
2530 * sense to permanently bill a class for a non-active
2531 * lease. This means on REQUEST, we will bill this
2532 * lease again (if there is a REQUEST).
2533 */
2534 if (offer == DHCPOFFER &&
2535 lease->billing_class != NULL &&
c36d062e 2536 lease->binding_state != FTS_ACTIVE)
6a39bcf0 2537 unbill_class(lease);
f3a44c10
TM
2538
2539 /* Lease billing change negates reuse */
2540 if (lease->billing_class != NULL) {
2541 lease->cannot_reuse = 1;
2542 }
c4924529
TL
2543 }
2544 }
2545
b1dd98c9 2546 /* Figure out the filename. */
951323fe 2547 oc = lookup_option (&server_universe, state -> options, SV_FILENAME);
5d25508c 2548 if (oc)
ca1c700e 2549 evaluate_option_cache (&state -> filename, packet, lease,
9e383163 2550 (struct client_state *)0,
ca1c700e 2551 packet -> options, state -> options,
12c9957e 2552 &lease -> scope, oc, MDL);
ed8bcd8f 2553
7a049f2c 2554 /* Choose a server name as above. */
951323fe
TL
2555 oc = lookup_option (&server_universe, state -> options,
2556 SV_SERVER_NAME);
5d25508c 2557 if (oc)
ca1c700e 2558 evaluate_option_cache (&state -> server_name, packet, lease,
9e383163 2559 (struct client_state *)0,
ca1c700e 2560 packet -> options, state -> options,
12c9957e 2561 &lease -> scope, oc, MDL);
7a049f2c 2562
97ca1699
TL
2563 /* At this point, we have a lease that we can offer the client.
2564 Now we construct a lease structure that contains what we want,
2565 and call supersede_lease to do the right thing with it. */
20916cae
TL
2566 lt = (struct lease *)0;
2567 result = lease_allocate (&lt, MDL);
2568 if (result != ISC_R_SUCCESS) {
2569 log_info ("%s: can't allocate temporary lease structure: %s",
2570 msg, isc_result_totext (result));
2571 free_lease_state (state, MDL);
98311e4b
DH
2572 if (host)
2573 host_dereference (&host, MDL);
20916cae
TL
2574 return;
2575 }
2576
97ca1699
TL
2577 /* Use the ip address of the lease that we finally found in
2578 the database. */
20916cae 2579 lt -> ip_addr = lease -> ip_addr;
97ca1699
TL
2580
2581 /* Start now. */
20916cae 2582 lt -> starts = cur_time;
97ca1699 2583
7a049f2c
TL
2584 /* Figure out how long a lease to assign. If this is a
2585 dynamic BOOTP lease, its duration must be infinite. */
2586 if (offer) {
a55ccdd0
DH
2587 lt->flags &= ~BOOTP_LEASE;
2588
eeea1395 2589 default_lease_time = DEFAULT_DEFAULT_LEASE_TIME;
951323fe 2590 if ((oc = lookup_option (&server_universe, state -> options,
eeea1395 2591 SV_DEFAULT_LEASE_TIME))) {
ca1c700e 2592 if (evaluate_option_cache (&d1, packet, lease,
9e383163 2593 (struct client_state *)0,
da38df14 2594 packet -> options,
12c9957e
TL
2595 state -> options,
2596 &lease -> scope, oc, MDL)) {
eeea1395
TL
2597 if (d1.len == sizeof (u_int32_t))
2598 default_lease_time =
2599 getULong (d1.data);
4bd8800e 2600 data_string_forget (&d1, MDL);
eeea1395
TL
2601 }
2602 }
2603
951323fe 2604 if ((oc = lookup_option (&dhcp_universe, packet -> options,
1ffcdd2a 2605 DHO_DHCP_LEASE_TIME)))
ca1c700e 2606 s1 = evaluate_option_cache (&d1, packet, lease,
9e383163 2607 (struct client_state *)0,
da38df14 2608 packet -> options,
12c9957e
TL
2609 state -> options,
2610 &lease -> scope, oc, MDL);
1ffcdd2a
TL
2611 else
2612 s1 = 0;
98311e4b 2613
a55ccdd0
DH
2614 if (s1 && (d1.len == 4)) {
2615 u_int32_t ones = 0xffffffff;
2616
2617 /* One potential use of reserved leases is to allow
2618 * clients to signal reservation of their lease. They
2619 * can kinda sorta do this, if you squint hard enough,
2620 * by supplying an 'infinite' requested-lease-time
2621 * option. This is generally bad practice...you want
2622 * clients to return to the server on at least some
2623 * period (days, months, years) to get up-to-date
2624 * config state. So;
2625 *
2626 * 1) A client requests 0xffffffff lease-time.
2627 * 2) The server reserves the lease, and assigns a
2628 * <= max_lease_time lease-time to the client, which
2629 * we presume is much smaller than 0xffffffff.
2630 * 3) The client ultimately fails to renew its lease
2631 * (all clients go offline at some point).
2632 * 4) The server retains the reservation, although
2633 * the lease expires and passes through those states
2634 * as normal, it's placed in the 'reserved' queue,
2635 * and is under no circumstances allocated to any
2636 * clients.
2637 *
2638 * Whether the client knows its reserving its lease or
2639 * not, this can be a handy tool for a sysadmin.
2640 */
2641 if ((memcmp(d1.data, &ones, 4) == 0) &&
2642 (oc = lookup_option(&server_universe,
2643 state->options,
2644 SV_RESERVE_INFINITE)) &&
2645 evaluate_boolean_option_cache(&ignorep, packet,
2646 lease, NULL, packet->options,
2647 state->options, &lease->scope,
2648 oc, MDL)) {
2649 lt->flags |= RESERVED_LEASE;
2650 if (!ignorep)
2651 log_info("Infinite-leasetime "
2652 "reservation made on %s.",
2653 piaddr(lt->ip_addr));
2654 }
2655
5d25508c 2656 lease_time = getULong (d1.data);
a55ccdd0 2657 } else
eeea1395 2658 lease_time = default_lease_time;
a55ccdd0
DH
2659
2660 if (s1)
2661 data_string_forget(&d1, MDL);
98311e4b 2662
daa1b24f
TL
2663 /* See if there's a maximum lease time. */
2664 max_lease_time = DEFAULT_MAX_LEASE_TIME;
2665 if ((oc = lookup_option (&server_universe, state -> options,
2666 SV_MAX_LEASE_TIME))) {
ca1c700e 2667 if (evaluate_option_cache (&d1, packet, lease,
9e383163 2668 (struct client_state *)0,
daa1b24f 2669 packet -> options,
12c9957e
TL
2670 state -> options,
2671 &lease -> scope, oc, MDL)) {
daa1b24f
TL
2672 if (d1.len == sizeof (u_int32_t))
2673 max_lease_time =
2674 getULong (d1.data);
4bd8800e 2675 data_string_forget (&d1, MDL);
daa1b24f
TL
2676 }
2677 }
2678
10553ccb 2679 /* Enforce the maximum lease length. */
daa1b24f
TL
2680 if (lease_time < 0 /* XXX */
2681 || lease_time > max_lease_time)
10553ccb
TL
2682 lease_time = max_lease_time;
2683
eeea1395 2684 min_lease_time = DEFAULT_MIN_LEASE_TIME;
00855426
TL
2685 if (min_lease_time > max_lease_time)
2686 min_lease_time = max_lease_time;
2687
951323fe 2688 if ((oc = lookup_option (&server_universe, state -> options,
5d25508c 2689 SV_MIN_LEASE_TIME))) {
ca1c700e 2690 if (evaluate_option_cache (&d1, packet, lease,
9e383163 2691 (struct client_state *)0,
da38df14 2692 packet -> options,
12c9957e
TL
2693 state -> options,
2694 &lease -> scope, oc, MDL)) {
5d25508c 2695 if (d1.len == sizeof (u_int32_t))
eeea1395 2696 min_lease_time = getULong (d1.data);
4bd8800e 2697 data_string_forget (&d1, MDL);
5d25508c 2698 }
421563ea
TL
2699 }
2700
b22de500
DH
2701 /* CC: If there are less than
2702 adaptive-lease-time-threshold % free leases,
2703 hand out only short term leases */
2704
2705 memset(&d1, 0, sizeof(d1));
2706 if (lease->pool &&
2707 (oc = lookup_option(&server_universe, state->options,
2708 SV_ADAPTIVE_LEASE_TIME_THRESHOLD)) &&
2709 evaluate_option_cache(&d1, packet, lease, NULL,
2710 packet->options, state->options,
2711 &lease->scope, oc, MDL)) {
2712 if (d1.len == 1 && d1.data[0] > 0 &&
2713 d1.data[0] < 100) {
2714 TIME adaptive_time;
2715 int poolfilled, total, count;
2716
2717 if (min_lease_time)
2718 adaptive_time = min_lease_time;
2719 else
2720 adaptive_time = DEFAULT_MIN_LEASE_TIME;
2721
2722 /* Allow the client to keep its lease. */
2723 if (lease->ends - cur_time > adaptive_time)
2724 adaptive_time = lease->ends - cur_time;
2725
2726 count = lease->pool->lease_count;
2727 total = count - (lease->pool->free_leases +
2728 lease->pool->backup_leases);
2729
2730 poolfilled = (total > (INT_MAX / 100)) ?
2731 total / (count / 100) :
2732 (total * 100) / count;
2733
2734 log_debug("Adap-lease: Total: %d, Free: %d, "
2735 "Ends: %d, Adaptive: %d, Fill: %d, "
2736 "Threshold: %d",
2737 lease->pool->lease_count,
2738 lease->pool->free_leases,
2739 (int)(lease->ends - cur_time),
2740 (int)adaptive_time, poolfilled,
2741 d1.data[0]);
2742
2743 if (poolfilled >= d1.data[0] &&
2744 lease_time > adaptive_time) {
2745 log_info("Pool over threshold, time "
2746 "for %s reduced from %d to "
2747 "%d.", piaddr(lease->ip_addr),
2748 (int)lease_time,
2749 (int)adaptive_time);
2750
2751 lease_time = adaptive_time;
2752 }
2753 }
2754 data_string_forget(&d1, MDL);
2755 }
2756
250f7134
SR
2757
2758 /*
2759 * If this is an ack check to see if we have used enough of
2760 * the pool to want to log a message
2761 */
2762 if (offer == DHCPACK)
2763 check_pool_threshold(packet, lease, state);
2764
b1d3778c
DH
2765 /* a client requests an address which is not yet active*/
2766 if (lease->pool && lease->pool->valid_from &&
2767 cur_time < lease->pool->valid_from) {
2768 /* NAK leases before pool activation date */
2769 cip.len = 4;
2770 memcpy (cip.iabuf, &lt->ip_addr.iabuf, 4);
e046c826 2771 nak_lease(packet, &cip, lease->subnet->group);
b1d3778c
DH
2772 free_lease_state (state, MDL);
2773 lease_dereference (&lt, MDL);
2774 if (host)
2775 host_dereference (&host, MDL);
2776 return;
2777
2778 }
2779
2780 /* CC:
2781 a) NAK current lease if past the expiration date
2782 b) extend lease only up to the expiration date, but not
2783 below min-lease-time
2784 Setting min-lease-time is essential for this to work!
250f7134 2785 The value of min-lease-time determines the length
b1d3778c
DH
2786 of the transition window:
2787 A client renewing a second before the deadline will
2788 get a min-lease-time lease. Since the current ip might not
2789 be routable after the deadline, the client will
2790 be offline until it DISCOVERS again. Otherwise it will
2791 receive a NAK at T/2.
2792 A min-lease-time of 6 seconds effectively switches over
2793 all clients in this pool very quickly.
2794 */
2795
2796 if (lease->pool && lease->pool->valid_until) {
2797 if (cur_time >= lease->pool->valid_until) {
2798 /* NAK leases after pool expiration date */
2799 cip.len = 4;
2800 memcpy (cip.iabuf, &lt->ip_addr.iabuf, 4);
e046c826 2801 nak_lease(packet, &cip, lease->subnet->group);
b1d3778c
DH
2802 free_lease_state (state, MDL);
2803 lease_dereference (&lt, MDL);
2804 if (host)
2805 host_dereference (&host, MDL);
2806 return;
2807 }
2808 remaining_time = lease->pool->valid_until - cur_time;
2809 if (lease_time > remaining_time)
2810 lease_time = remaining_time;
2811 }
2812
eeea1395
TL
2813 if (lease_time < min_lease_time) {
2814 if (min_lease_time)
2815 lease_time = min_lease_time;
2816 else
2817 lease_time = default_lease_time;
2818 }
b1dd98c9 2819
b1d3778c 2820
2cbc0e48
TL
2821#if defined (FAILOVER_PROTOCOL)
2822 /* Okay, we know the lease duration. Now check the
2823 failover state, if any. */
20916cae 2824 if (lease -> pool && lease -> pool -> failover_peer) {
88cd8aca 2825 TIME new_lease_time = lease_time;
2cbc0e48
TL
2826 dhcp_failover_state_t *peer =
2827 lease -> pool -> failover_peer;
2828
88cd8aca
DH
2829 /* Copy previous lease failover ack-state. */
2830 lt->tsfp = lease->tsfp;
2831 lt->atsfp = lease->atsfp;
2832
6d103865 2833 /* cltt set below */
88cd8aca
DH
2834
2835 /* Lease times less than MCLT are not a concern. */
2836 if (lease_time > peer->mclt) {
2837 /* Each server can only offer a lease time
2838 * that is either equal to MCLT (at least),
2839 * or up to TSFP+MCLT. Only if the desired
2840 * lease time falls within TSFP+MCLT, can
2841 * the server allow it.
2842 */
2843 if (lt->tsfp <= cur_time)
2844 new_lease_time = peer->mclt;
2845 else if ((cur_time + lease_time) >
2846 (lt->tsfp + peer->mclt))
2847 new_lease_time = (lt->tsfp - cur_time)
2848 + peer->mclt;
2cbc0e48 2849 }
5b01171a 2850
88cd8aca 2851 /* Update potential expiry. Allow for the desired
98bd7ca0 2852 * lease time plus one half the actual (whether
88cd8aca
DH
2853 * modified downward or not) lease time, which is
2854 * actually an estimate of when the client will
2855 * renew. This way, the client will be able to get
2856 * the desired lease time upon renewal.
2857 */
2858 if (offer == DHCPACK) {
2859 lt->tstp = cur_time + lease_time +
2860 (new_lease_time / 2);
2861
2862 /* If we reduced the potential expiry time,
2863 * make sure we don't offer an old-expiry-time
2864 * lease for this lease before the change is
2865 * ack'd.
2866 */
2867 if (lt->tstp < lt->tsfp)
2868 lt->tsfp = lt->tstp;
2869 } else
2870 lt->tstp = lease->tstp;
2871
2872 /* Use failover-modified lease time. */
2873 lease_time = new_lease_time;
2cbc0e48
TL
2874 }
2875#endif /* FAILOVER_PROTOCOL */
2876
00855426
TL
2877 /* If the lease duration causes the time value to wrap,
2878 use the maximum expiry time. */
2879 if (cur_time + lease_time < cur_time)
5b01171a 2880 state -> offered_expiry = MAX_TIME - 1;
00855426
TL
2881 else
2882 state -> offered_expiry = cur_time + lease_time;
7a049f2c 2883 if (when)
20916cae 2884 lt -> ends = when;
7a049f2c 2885 else
20916cae 2886 lt -> ends = state -> offered_expiry;
d758ad8c
TL
2887
2888 /* Don't make lease active until we actually get a
2889 DHCPREQUEST. */
2890 if (offer == DHCPACK)
2891 lt -> next_binding_state = FTS_ACTIVE;
2892 else
2893 lt -> next_binding_state = lease -> binding_state;
7a049f2c 2894 } else {
a55ccdd0
DH
2895 lt->flags |= BOOTP_LEASE;
2896
b1dd98c9
TL
2897 lease_time = MAX_TIME - cur_time;
2898
951323fe 2899 if ((oc = lookup_option (&server_universe, state -> options,
5d25508c 2900 SV_BOOTP_LEASE_LENGTH))) {
ca1c700e 2901 if (evaluate_option_cache (&d1, packet, lease,
9e383163 2902 (struct client_state *)0,
ca1c700e
TL
2903 packet -> options,
2904 state -> options,
12c9957e 2905 &lease -> scope, oc, MDL)) {
5d25508c
TL
2906 if (d1.len == sizeof (u_int32_t))
2907 lease_time = getULong (d1.data);
4bd8800e 2908 data_string_forget (&d1, MDL);
5d25508c 2909 }
b1dd98c9
TL
2910 }
2911
951323fe 2912 if ((oc = lookup_option (&server_universe, state -> options,
5d25508c 2913 SV_BOOTP_LEASE_CUTOFF))) {
ca1c700e 2914 if (evaluate_option_cache (&d1, packet, lease,
9e383163 2915 (struct client_state *)0,
da38df14 2916 packet -> options,
ca1c700e 2917 state -> options,
12c9957e 2918 &lease -> scope, oc, MDL)) {
5d25508c
TL
2919 if (d1.len == sizeof (u_int32_t))
2920 lease_time = (getULong (d1.data) -
2921 cur_time);
4bd8800e 2922 data_string_forget (&d1, MDL);
5d25508c 2923 }
b1dd98c9
TL
2924 }
2925
20916cae 2926 lt -> ends = state -> offered_expiry = cur_time + lease_time;
98311e4b 2927 lt -> next_binding_state = FTS_ACTIVE;
7a049f2c 2928 }
97ca1699 2929
6d103865
SK
2930 /* Update Client Last Transaction Time. */
2931 lt->cltt = cur_time;
97ca1699 2932
38ee81bd
SR
2933 /* See if we want to record the uid for this client */
2934 oc = lookup_option(&server_universe, state->options,
2935 SV_IGNORE_CLIENT_UIDS);
2936 if ((oc == NULL) ||
2937 !evaluate_boolean_option_cache(&ignorep, packet, lease, NULL,
2938 packet->options, state->options,
2939 &lease->scope, oc, MDL)) {
2940
2941 /* Record the uid, if given... */
2942 oc = lookup_option (&dhcp_universe, packet -> options,
2943 DHO_DHCP_CLIENT_IDENTIFIER);
2944 if (oc &&
2945 evaluate_option_cache(&d1, packet, lease, NULL,
2946 packet->options, state->options,
2947 &lease->scope, oc, MDL)) {
2948 if (d1.len <= sizeof(lt->uid_buf)) {
2949 memcpy(lt->uid_buf, d1.data, d1.len);
2950 lt->uid = lt->uid_buf;
2951 lt->uid_max = sizeof(lt->uid_buf);
2952 lt->uid_len = d1.len;
2953 } else {
2954 unsigned char *tuid;
2955 lt->uid_max = d1.len;
2956 lt->uid_len = d1.len;
2957 tuid = (unsigned char *)dmalloc(lt->uid_max,
2958 MDL);
2959 /* XXX inelegant */
2960 if (!tuid)
2961 log_fatal ("no memory for large uid.");
2962 memcpy(tuid, d1.data, lt->uid_len);
2963 lt->uid = tuid;
2964 }
2965 data_string_forget (&d1, MDL);
11b37280 2966 }
97ca1699
TL
2967 }
2968
98311e4b
DH
2969 if (host) {
2970 host_reference (&lt -> host, host, MDL);
2971 host_dereference (&host, MDL);
2972 }
20916cae
TL
2973 if (lease -> subnet)
2974 subnet_reference (&lt -> subnet, lease -> subnet, MDL);
2975 if (lease -> billing_class)
2976 class_reference (&lt -> billing_class,
2977 lease -> billing_class, MDL);
97ca1699 2978
9e0e9ed8
TL
2979 /* Set a flag if this client is a broken client that NUL
2980 terminates string options and expects us to do likewise. */
5bc2e1f2
TL
2981 if (ms_nulltp)
2982 lease -> flags |= MS_NULL_TERMINATION;
2983 else
8c8e27c5 2984 lease -> flags &= ~MS_NULL_TERMINATION;
9e0e9ed8 2985
12c9957e 2986 /* Save any bindings. */
6ceb9118
TL
2987 if (lease -> scope) {
2988 binding_scope_reference (&lt -> scope, lease -> scope, MDL);
2989 binding_scope_dereference (&lease -> scope, MDL);
2990 }
bfe2d221
TL
2991 if (lease -> agent_options)
2992 option_chain_head_reference (&lt -> agent_options,
2993 lease -> agent_options, MDL);
12c9957e 2994
656b1ece
TM
2995 /* Save the vendor-class-identifier for DHCPLEASEQUERY. */
2996 oc = lookup_option(&dhcp_universe, packet->options,
2997 DHO_VENDOR_CLASS_IDENTIFIER);
2998 if (oc != NULL &&
2999 evaluate_option_cache(&d1, packet, NULL, NULL, packet->options,
f3a44c10 3000 NULL, &lt->scope, oc, MDL)) {
656b1ece 3001 if (d1.len != 0) {
f3a44c10 3002 bind_ds_value(&lt->scope, "vendor-class-identifier",
656b1ece
TM
3003 &d1);
3004 }
3005
3006 data_string_forget(&d1, MDL);
3007 }
3008
9aa3f3a5
DH
3009 /* If we got relay agent information options from the packet, then
3010 * cache them for renewal in case the relay agent can't supply them
3011 * when the client unicasts. The options may be from an addressed
3012 * "l3" relay, or from an unaddressed "l2" relay which does not set
3013 * giaddr.
02428754 3014 */
9aa3f3a5 3015 if (!packet->agent_options_stashed &&
8bd96ccb 3016 (packet->options != NULL) &&
9aa3f3a5
DH
3017 packet->options->universe_count > agent_universe.index &&
3018 packet->options->universes[agent_universe.index] != NULL) {
9e383163
TL
3019 oc = lookup_option (&server_universe, state -> options,
3020 SV_STASH_AGENT_OPTIONS);
3021 if (!oc ||
3022 evaluate_boolean_option_cache (&ignorep, packet, lease,
3023 (struct client_state *)0,
3024 packet -> options,
3025 state -> options,
3026 &lease -> scope, oc, MDL)) {
de528760
TL
3027 if (lt -> agent_options)
3028 option_chain_head_dereference (&lt -> agent_options, MDL);
bfe2d221 3029 option_chain_head_reference
9e383163 3030 (&lt -> agent_options,
bfe2d221 3031 (struct option_chain_head *)
9e383163
TL
3032 packet -> options -> universes [agent_universe.index],
3033 MDL);
3034 }
3035 }
3036
d73e855d
TL
3037 /* Replace the old lease hostname with the new one, if it's changed. */
3038 oc = lookup_option (&dhcp_universe, packet -> options, DHO_HOST_NAME);
3039 if (oc)
3040 s1 = evaluate_option_cache (&d1, packet, (struct lease *)0,
9e383163 3041 (struct client_state *)0,
d73e855d
TL
3042 packet -> options,
3043 (struct option_state *)0,
3044 &global_scope, oc, MDL);
98311e4b
DH
3045 else
3046 s1 = 0;
3047
d73e855d
TL
3048 if (oc && s1 &&
3049 lease -> client_hostname &&
3050 strlen (lease -> client_hostname) == d1.len &&
3051 !memcmp (lease -> client_hostname, d1.data, d1.len)) {
3052 /* Hasn't changed. */
3053 data_string_forget (&d1, MDL);
3054 lt -> client_hostname = lease -> client_hostname;
3055 lease -> client_hostname = (char *)0;
3056 } else if (oc && s1) {
3057 lt -> client_hostname = dmalloc (d1.len + 1, MDL);
3058 if (!lt -> client_hostname)
3059 log_error ("no memory for client hostname.");
3060 else {
3061 memcpy (lt -> client_hostname, d1.data, d1.len);
3062 lt -> client_hostname [d1.len] = 0;
3063 }
3064 data_string_forget (&d1, MDL);
3065 }
3066
b992d7e2
DN
3067 /* Record the hardware address, if given... */
3068 lt -> hardware_addr.hlen = packet -> raw -> hlen + 1;
3069 lt -> hardware_addr.hbuf [0] = packet -> raw -> htype;
3070 memcpy (&lt -> hardware_addr.hbuf [1], packet -> raw -> chaddr,
3071 sizeof packet -> raw -> chaddr);
3072
606f2720
TM
3073 /*
3074 * If client has requested the lease become infinite, then it
3075 * doens't qualify for reuse even if it's younger than the
3076 * dhcp-cache-threshold.
3077 */
3078 if ((lt->flags & RESERVED_LEASE) && !(lease->flags & RESERVED_LEASE)) {
3079 log_debug ("Cannot reuse: lease is changing to RESERVED");
3080 lease->cannot_reuse = 1;
3081 }
3082
3083 lt->flags |= lease->flags & ~PERSISTENT_FLAGS;
c6708cba 3084
39ae5027
TL
3085 /* If there are statements to execute when the lease is
3086 committed, execute them. */
a7341359
SR
3087 if (lease->on_star.on_commit && (!offer || offer == DHCPACK)) {
3088 execute_statements (NULL, packet, lt, NULL, packet->options,
3089 state->options, &lt->scope,
3090 lease->on_star.on_commit, NULL);
3091 if (lease->on_star.on_commit)
3092 executable_statement_dereference
3093 (&lease->on_star.on_commit, MDL);
39ae5027
TL
3094 }
3095
b992d7e2
DN
3096#ifdef NSUPDATE
3097 /* Perform DDNS updates, if configured to. */
3098 if ((!offer || offer == DHCPACK) &&
bf9d9d27
TL
3099 (!(oc = lookup_option (&server_universe, state -> options,
3100 SV_DDNS_UPDATES)) ||
3101 evaluate_boolean_option_cache (&ignorep, packet, lt,
3102 (struct client_state *)0,
3103 packet -> options,
3104 state -> options,
3105 &lt -> scope, oc, MDL))) {
98bd7ca0 3106 ddns_updates(packet, lt, lease, NULL, NULL, state->options);
b992d7e2
DN
3107 }
3108#endif /* NSUPDATE */
3109
7a049f2c 3110 /* Don't call supersede_lease on a mocked-up lease. */
ec8d21a7
TL
3111 if (lease -> flags & STATIC_LEASE) {
3112 /* Copy the hardware address into the static lease
3113 structure. */
2cbc0e48
TL
3114 lease -> hardware_addr.hlen = packet -> raw -> hlen + 1;
3115 lease -> hardware_addr.hbuf [0] = packet -> raw -> htype;
3116 memcpy (&lease -> hardware_addr.hbuf [1],
3117 packet -> raw -> chaddr,
3c893bb6 3118 sizeof packet -> raw -> chaddr); /* XXX */
ec8d21a7 3119 } else {
929a2364 3120 int commit = (!offer || (offer == DHCPACK));
929a2364 3121
f3a44c10
TM
3122 /* If dhcp-cache-threshold is enabled, see if "lease" can
3123 * be reused. */
3124 use_old_lease = reuse_lease(packet, lt, lease, state, offer);
3125 if (use_old_lease == 1) {
3126 commit = 0;
929a2364
TM
3127 }
3128
785c1a51 3129#if !defined(DELAYED_ACK) || defined(DHCP4o6)
6368a1bd 3130 /* Install the new information on 'lt' onto the lease at
fbcee149
DH
3131 * 'lease'. If this is a DHCPOFFER, it is a 'soft' promise,
3132 * if it is a DHCPACK, it is a 'hard' binding, so it needs
3133 * to be recorded and propogated immediately. If the update
3134 * fails, don't ACK it (or BOOTREPLY) either; we may give
3135 * the same lease to another client later, and that would be
3136 * a conflict.
3137 */
8cd88e20
SR
3138 if ((use_old_lease == 0) &&
3139 !supersede_lease(lease, lt, commit,
491bf4a2 3140 offer == DHCPACK, offer == DHCPACK, 0)) {
785c1a51 3141#else /* defined(DELAYED_ACK) && !defined(DHCP4o6) */
929a2364
TM
3142 /*
3143 * If there already isn't a need for a lease commit, and we
3144 * can just answer right away, set a flag to indicate this.
3145 */
8cd88e20 3146 if (commit)
929a2364 3147 enqueue = ISC_TRUE;
929a2364 3148
fbcee149 3149 /* Install the new information on 'lt' onto the lease at
f8380d3f 3150 * 'lease'. We will not 'commit' this information to disk
fbcee149
DH
3151 * yet (fsync()), we will 'propogate' the information if
3152 * this is BOOTP or a DHCPACK, but we will not 'pimmediate'ly
3153 * transmit failover binding updates (this is delayed until
3154 * after the fsync()). If the update fails, don't ACK it (or
3155 * BOOTREPLY either); we may give the same lease out to a
3156 * different client, and that would be a conflict.
3157 */
8cd88e20
SR
3158 if ((use_old_lease == 0) &&
3159 !supersede_lease(lease, lt, 0,
491bf4a2 3160 !offer || offer == DHCPACK, 0, 0)) {
fbcee149 3161#endif
8ae2d595 3162 log_info ("%s: database update failed", msg);
4bd8800e 3163 free_lease_state (state, MDL);
20916cae 3164 lease_dereference (&lt, MDL);
7a049f2c 3165 return;
c4924529 3166 }
ec8d21a7 3167 }
20916cae 3168 lease_dereference (&lt, MDL);
97ca1699 3169
11b37280 3170 /* Remember the interface on which the packet arrived. */
9cc3ad7f 3171 state -> ip = packet -> interface;
685963dc 3172
11b37280 3173 /* Remember the giaddr, xid, secs, flags and hops. */
9cc3ad7f 3174 state -> giaddr = packet -> raw -> giaddr;
44b2e3ad 3175 state -> ciaddr = packet -> raw -> ciaddr;
9cc3ad7f
TL
3176 state -> xid = packet -> raw -> xid;
3177 state -> secs = packet -> raw -> secs;
3178 state -> bootp_flags = packet -> raw -> flags;
3179 state -> hops = packet -> raw -> hops;
3180 state -> offer = offer;
685963dc 3181
6dadd610
TL
3182 /* If we're always supposed to broadcast to this client, set
3183 the broadcast bit in the bootp flags field. */
e3b5f7f8
TL
3184 if ((oc = lookup_option (&server_universe, state -> options,
3185 SV_ALWAYS_BROADCAST)) &&
19654922 3186 evaluate_boolean_option_cache (&ignorep, packet, lease,
9e383163 3187 (struct client_state *)0,
ca1c700e 3188 packet -> options, state -> options,
12c9957e 3189 &lease -> scope, oc, MDL))
6dadd610
TL
3190 state -> bootp_flags |= htons (BOOTP_BROADCAST);
3191
3c893bb6
TL
3192 /* Get the Maximum Message Size option from the packet, if one
3193 was sent. */
951323fe 3194 oc = lookup_option (&dhcp_universe, packet -> options,
5d25508c
TL
3195 DHO_DHCP_MAX_MESSAGE_SIZE);
3196 if (oc &&
ca1c700e 3197 evaluate_option_cache (&d1, packet, lease,
9e383163 3198 (struct client_state *)0,
12c9957e
TL
3199 packet -> options, state -> options,
3200 &lease -> scope, oc, MDL)) {
5d25508c
TL
3201 if (d1.len == sizeof (u_int16_t))
3202 state -> max_message_size = getUShort (d1.data);
4bd8800e 3203 data_string_forget (&d1, MDL);
c76aff91
TL
3204 } else {
3205 oc = lookup_option (&dhcp_universe, state -> options,
3206 DHO_DHCP_MAX_MESSAGE_SIZE);
3207 if (oc &&
3208 evaluate_option_cache (&d1, packet, lease,
9e383163 3209 (struct client_state *)0,
c76aff91
TL
3210 packet -> options, state -> options,
3211 &lease -> scope, oc, MDL)) {
3212 if (d1.len == sizeof (u_int16_t))
3213 state -> max_message_size =
3214 getUShort (d1.data);
3215 data_string_forget (&d1, MDL);
3216 }
3c893bb6
TL
3217 }
3218
98311e4b
DH
3219 /* Get the Subnet Selection option from the packet, if one
3220 was sent. */
3221 if ((oc = lookup_option (&dhcp_universe, packet -> options,
3222 DHO_SUBNET_SELECTION))) {
3223
3224 /* Make a copy of the data. */
3225 struct option_cache *noc = (struct option_cache *)0;
3226 if (option_cache_allocate (&noc, MDL)) {
3227 if (oc -> data.len)
3228 data_string_copy (&noc -> data,
3229 &oc -> data, MDL);
3230 if (oc -> expression)
3231 expression_reference (&noc -> expression,
3232 oc -> expression, MDL);
3233 if (oc -> option)
66c8f734
DH
3234 option_reference(&(noc->option), oc->option,
3235 MDL);
98311e4b 3236
d56788df
SR
3237 save_option (&dhcp_universe, state -> options, noc);
3238 option_cache_dereference (&noc, MDL);
3239 }
98311e4b
DH
3240 }
3241
7a049f2c 3242 /* Now, if appropriate, put in DHCP-specific options that
65cf86d7 3243 override those. */
9cc3ad7f 3244 if (state -> offer) {
11b37280 3245 i = DHO_DHCP_MESSAGE_TYPE;
5d25508c 3246 oc = (struct option_cache *)0;
4bd8800e 3247 if (option_cache_allocate (&oc, MDL)) {
5d25508c 3248 if (make_const_data (&oc -> expression,
d758ad8c 3249 &state -> offer, 1, 0, 0, MDL)) {
f7fdb216
DH
3250 option_code_hash_lookup(&oc->option,
3251 dhcp_universe.code_hash,
3252 &i, 0, MDL);
951323fe
TL
3253 save_option (&dhcp_universe,
3254 state -> options, oc);
5d25508c 3255 }
4bd8800e 3256 option_cache_dereference (&oc, MDL);
5d25508c 3257 }
6d103865 3258
f8380d3f
SR
3259 get_server_source_address(&from, state->options,
3260 state->options, packet);
6d103865
SK
3261 memcpy(state->from.iabuf, &from, sizeof(from));
3262 state->from.len = sizeof(from);
7a049f2c 3263
b1dd98c9
TL
3264 offered_lease_time =
3265 state -> offered_expiry - cur_time;
b88e8e15 3266
dcc557db 3267 putULong(state->expiry, (u_int32_t)offered_lease_time);
11b37280 3268 i = DHO_DHCP_LEASE_TIME;
5d25508c 3269 oc = (struct option_cache *)0;
4bd8800e 3270 if (option_cache_allocate (&oc, MDL)) {
dcc557db
DH
3271 if (make_const_data(&oc->expression, state->expiry,
3272 4, 0, 0, MDL)) {
f7fdb216
DH
3273 option_code_hash_lookup(&oc->option,
3274 dhcp_universe.code_hash,
3275 &i, 0, MDL);
951323fe
TL
3276 save_option (&dhcp_universe,
3277 state -> options, oc);
5d25508c 3278 }
4bd8800e 3279 option_cache_dereference (&oc, MDL);
5d25508c 3280 }
7a049f2c 3281
5a671e87
DH
3282 /*
3283 * Validate any configured renew or rebinding times against
3284 * the determined lease time. Do rebinding first so that
3285 * the renew time can be validated against the rebind time.
3286 */
3287 if ((oc = lookup_option(&dhcp_universe, state->options,
3288 DHO_DHCP_REBINDING_TIME)) != NULL &&
3289 evaluate_option_cache(&d1, packet, lease, NULL,
3290 packet->options, state->options,
3291 &lease->scope, oc, MDL)) {
3292 TIME rebind_time = getULong(d1.data);
3293
3294 /* Drop the configured (invalid) rebinding time. */
3295 if (rebind_time >= offered_lease_time)
3296 delete_option(&dhcp_universe, state->options,
3297 DHO_DHCP_REBINDING_TIME);
3298 else /* XXX: variable is reused. */
3299 offered_lease_time = rebind_time;
3300
3301 data_string_forget(&d1, MDL);
5d25508c 3302 }
4ecd2958 3303
5a671e87
DH
3304 if ((oc = lookup_option(&dhcp_universe, state->options,
3305 DHO_DHCP_RENEWAL_TIME)) != NULL &&
3306 evaluate_option_cache(&d1, packet, lease, NULL,
3307 packet->options, state->options,
3308 &lease->scope, oc, MDL)) {
3309 if (getULong(d1.data) >= offered_lease_time)
3310 delete_option(&dhcp_universe, state->options,
3311 DHO_DHCP_RENEWAL_TIME);
3312
3313 data_string_forget(&d1, MDL);
5d25508c 3314 }
10553ccb 3315 } else {
6d103865 3316 /* XXXSK: should we use get_server_source_address() here? */
98bd7ca0
DH
3317 if (state -> ip -> address_count) {
3318 state -> from.len =
3319 sizeof state -> ip -> addresses [0];
3320 memcpy (state -> from.iabuf,
3321 &state -> ip -> addresses [0],
3322 state -> from.len);
3323 }
10553ccb
TL
3324 }
3325
3326 /* Figure out the address of the boot file server. */
98311e4b 3327 memset (&state -> siaddr, 0, sizeof state -> siaddr);
10553ccb
TL
3328 if ((oc =
3329 lookup_option (&server_universe,
3330 state -> options, SV_NEXT_SERVER))) {
ca1c700e 3331 if (evaluate_option_cache (&d1, packet, lease,
9e383163 3332 (struct client_state *)0,
ca1c700e 3333 packet -> options, state -> options,
12c9957e 3334 &lease -> scope, oc, MDL)) {
10553ccb
TL
3335 /* If there was more than one answer,
3336 take the first. */
3337 if (d1.len >= 4 && d1.data)
46904800 3338 memcpy (&state -> siaddr, d1.data, 4);
4bd8800e 3339 data_string_forget (&d1, MDL);
10553ccb 3340 }
7a049f2c 3341 }
685963dc 3342
4ecd2958
TL
3343 /* Use the subnet mask from the subnet declaration if no other
3344 mask has been provided. */
11b37280 3345 i = DHO_SUBNET_MASK;
951323fe 3346 if (!lookup_option (&dhcp_universe, state -> options, i)) {
4d0aaa17 3347 oc = (struct option_cache *)0;
4bd8800e 3348 if (option_cache_allocate (&oc, MDL)) {
5d25508c
TL
3349 if (make_const_data (&oc -> expression,
3350 lease -> subnet -> netmask.iabuf,
3351 lease -> subnet -> netmask.len,
d758ad8c 3352 0, 0, MDL)) {
f7fdb216
DH
3353 option_code_hash_lookup(&oc->option,
3354 dhcp_universe.code_hash,
3355 &i, 0, MDL);
951323fe
TL
3356 save_option (&dhcp_universe,
3357 state -> options, oc);
5d25508c 3358 }
4bd8800e 3359 option_cache_dereference (&oc, MDL);
5d25508c 3360 }
b1dd98c9
TL
3361 }
3362
0a7e1a8a 3363 /* Use the name of the host declaration if there is one
b1dd98c9
TL
3364 and no hostname has otherwise been provided, and if the
3365 use-host-decl-name flag is set. */
0a7e1a8a 3366 use_host_decl_name(packet, lease, state->options);
b1dd98c9 3367
e046c826
TM
3368 /* Send client_id back if we received it and echo-client-id is on. */
3369 echo_client_id(packet, lease, state->options, state->options);
3370
b1dd98c9
TL
3371 /* If we don't have a hostname yet, and we've been asked to do
3372 a reverse lookup to find the hostname, do it. */
524705e5 3373 i = DHO_HOST_NAME;
5d25508c 3374 j = SV_GET_LEASE_HOSTNAMES;
524705e5
DH
3375 if (!lookup_option(&dhcp_universe, state->options, i) &&
3376 evaluate_boolean_option_cache
3377 (&ignorep, packet, lease, NULL,
3378 packet->options, state->options, &lease->scope,
3379 lookup_option (&server_universe, state->options, j), MDL)) {
5d25508c
TL
3380 struct in_addr ia;
3381 struct hostent *h;
3382
3383 memcpy (&ia, lease -> ip_addr.iabuf, 4);
3384
3385 h = gethostbyaddr ((char *)&ia, sizeof ia, AF_INET);
3386 if (!h)
8ae2d595 3387 log_error ("No hostname for %s", inet_ntoa (ia));
5d25508c
TL
3388 else {
3389 oc = (struct option_cache *)0;
4bd8800e 3390 if (option_cache_allocate (&oc, MDL)) {
5d25508c 3391 if (make_const_data (&oc -> expression,
c5b0f529
TL
3392 ((unsigned char *)
3393 h -> h_name),
5d25508c 3394 strlen (h -> h_name) + 1,
d758ad8c 3395 1, 1, MDL)) {
f7fdb216
DH
3396 option_code_hash_lookup(&oc->option,
3397 dhcp_universe.code_hash,
3398 &i, 0, MDL);
951323fe
TL
3399 save_option (&dhcp_universe,
3400 state -> options, oc);
5d25508c 3401 }
4bd8800e 3402 option_cache_dereference (&oc, MDL);
b1dd98c9
TL
3403 }
3404 }
4ecd2958
TL
3405 }
3406
421563ea
TL
3407 /* If so directed, use the leased IP address as the router address.
3408 This supposedly makes Win95 machines ARP for all IP addresses,
3409 so if the local router does proxy arp, you win. */
b1dd98c9 3410
5d25508c 3411 if (evaluate_boolean_option_cache
9e383163
TL
3412 (&ignorep, packet, lease, (struct client_state *)0,
3413 packet -> options, state -> options, &lease -> scope,
951323fe 3414 lookup_option (&server_universe, state -> options,
12c9957e 3415 SV_USE_LEASE_ADDR_FOR_DEFAULT_ROUTE), MDL)) {
5d25508c 3416 i = DHO_ROUTERS;
951323fe 3417 oc = lookup_option (&dhcp_universe, state -> options, i);
027f46cb
TL
3418 if (!oc) {
3419 oc = (struct option_cache *)0;
4bd8800e 3420 if (option_cache_allocate (&oc, MDL)) {
027f46cb
TL
3421 if (make_const_data (&oc -> expression,
3422 lease -> ip_addr.iabuf,
3423 lease -> ip_addr.len,
d758ad8c 3424 0, 0, MDL)) {
f7fdb216
DH
3425 option_code_hash_lookup(&oc->option,
3426 dhcp_universe.code_hash,
3427 &i, 0, MDL);
951323fe
TL
3428 save_option (&dhcp_universe,
3429 state -> options, oc);
027f46cb 3430 }
ba450294 3431 option_cache_dereference (&oc, MDL);
5d25508c 3432 }
b1dd98c9 3433 }
421563ea
TL
3434 }
3435
10553ccb
TL
3436 /* If a site option space has been specified, use that for
3437 site option codes. */
3438 i = SV_SITE_OPTION_SPACE;
0af446bc 3439 if ((oc = lookup_option (&server_universe, state -> options, i)) &&
ca1c700e 3440 evaluate_option_cache (&d1, packet, lease,
9e383163 3441 (struct client_state *)0,
12c9957e
TL
3442 packet -> options, state -> options,
3443 &lease -> scope, oc, MDL)) {
20916cae
TL
3444 struct universe *u = (struct universe *)0;
3445
3446 if (!universe_hash_lookup (&u, universe_hash,
165bce70
TL
3447 (const char *)d1.data, d1.len,
3448 MDL)) {
10553ccb
TL
3449 log_error ("unknown option space %s.", d1.data);
3450 return;
3451 }
3452
3453 state -> options -> site_universe = u -> index;
2c9bf1f4 3454 state->options->site_code_min = find_min_site_code(u);
4bd8800e 3455 data_string_forget (&d1, MDL);
10553ccb
TL
3456 } else {
3457 state -> options -> site_code_min = 0;
3458 state -> options -> site_universe = dhcp_universe.index;
3459 }
3460
eddb16f4 3461 /* If the client has provided a list of options that it wishes
431693d1
TL
3462 returned, use it to prioritize. If there's a parameter
3463 request list in scope, use that in preference. Otherwise
3464 use the default priority list. */
eddb16f4 3465
431693d1 3466 oc = lookup_option (&dhcp_universe, state -> options,
eddb16f4
TL
3467 DHO_DHCP_PARAMETER_REQUEST_LIST);
3468
cdc336ab 3469 if (!oc)
431693d1 3470 oc = lookup_option (&dhcp_universe, packet -> options,
cdc336ab 3471 DHO_DHCP_PARAMETER_REQUEST_LIST);
eddb16f4
TL
3472 if (oc)
3473 evaluate_option_cache (&state -> parameter_request_list,
9e383163 3474 packet, lease, (struct client_state *)0,
ca1c700e 3475 packet -> options, state -> options,
12c9957e 3476 &lease -> scope, oc, MDL);
eddb16f4 3477
11b37280
TL
3478#ifdef DEBUG_PACKET
3479 dump_packet (packet);
3480 dump_raw ((unsigned char *)packet -> raw, packet -> packet_length);
3481#endif
3482
9cc3ad7f 3483 lease -> state = state;
4b7df707 3484
8ae2d595 3485 log_info ("%s", msg);
c4924529 3486
ca1c700e 3487 /* Hang the packet off the lease state. */
4bd8800e 3488 packet_reference (&lease -> state -> packet, packet, MDL);
ca1c700e 3489
4b7df707
TL
3490 /* If this is a DHCPOFFER, ping the lease address before actually
3491 sending the offer. */
027f46cb 3492 if (offer == DHCPOFFER && !(lease -> flags & STATIC_LEASE) &&
a5252220
TM
3493 (((cur_time - lease_cltt) > 60) ||
3494 (lease->binding_state == FTS_ABANDONED)) &&
174f5ef5
TL
3495 (!(oc = lookup_option (&server_universe, state -> options,
3496 SV_PING_CHECKS)) ||
3497 evaluate_boolean_option_cache (&ignorep, packet, lease,
3498 (struct client_state *)0,
3499 packet -> options,
3500 state -> options,
3501 &lease -> scope, oc, MDL))) {
4b7df707 3502 icmp_echorequest (&lease -> ip_addr);
98311e4b 3503
a55ccdd0 3504 /* Determine whether to use configured or default ping timeout.
98311e4b
DH
3505 */
3506 if ((oc = lookup_option (&server_universe, state -> options,
3507 SV_PING_TIMEOUT)) &&
3508 evaluate_option_cache (&d1, packet, lease, NULL,
3509 packet -> options,
3510 state -> options,
3511 &lease -> scope, oc, MDL)) {
3512 if (d1.len == sizeof (u_int32_t))
3513 ping_timeout = getULong (d1.data);
3514 else
3515 ping_timeout = DEFAULT_PING_TIMEOUT;
3516
3517 data_string_forget (&d1, MDL);
3518 } else
3519 ping_timeout = DEFAULT_PING_TIMEOUT;
3520
3521#ifdef DEBUG
3522 log_debug ("Ping timeout: %ld", (long)ping_timeout);
3523#endif
3524
5d082abd
TM
3525 /*
3526 * Set a timeout for 'ping-timeout' seconds from NOW, including
3527 * current microseconds. As ping-timeout defaults to 1, the
3528 * exclusion of current microseconds causes a value somewhere
3529 * /between/ zero and one.
3530 */
3531 tv.tv_sec = cur_tv.tv_sec + ping_timeout;
3532 tv.tv_usec = cur_tv.tv_usec;
be62cf06 3533 add_timeout (&tv, lease_ping_timeout, lease,
20916cae
TL
3534 (tvref_t)lease_reference,
3535 (tvunref_t)lease_dereference);
4b7df707
TL
3536 ++outstanding_pings;
3537 } else {
6368a1bd 3538 lease->cltt = cur_time;
785c1a51 3539#if defined(DELAYED_ACK) && !defined(DHCP4o6)
929a2364 3540 if (enqueue)
6368a1bd
DH
3541 delayed_ack_enqueue(lease);
3542 else
fbcee149 3543#endif
6368a1bd
DH
3544 dhcp_reply(lease);
3545 }
3546}
3547
e422b8c7
TM
3548#if defined(DELAYED_ACK)
3549
0585235c
SR
3550/*
3551 * CC: queue single ACK:
3552 * - write the lease (but do not fsync it yet)
3553 * - add to double linked list
3554 * - commit if more than xx ACKs pending
3555 * - if necessary set the max timer and bump the next timer
3556 * but only up to the max timer value.
6368a1bd
DH
3557 */
3558
e422b8c7 3559static void
6368a1bd
DH
3560delayed_ack_enqueue(struct lease *lease)
3561{
3562 struct leasequeue *q;
f8cbf390 3563
6368a1bd
DH
3564 if (!write_lease(lease))
3565 return;
3566 if (free_ackqueue) {
3567 q = free_ackqueue;
3568 free_ackqueue = q->next;
3569 } else {
3570 q = ((struct leasequeue *)
3571 dmalloc(sizeof(struct leasequeue), MDL));
3572 if (!q)
3573 log_fatal("delayed_ack_enqueue: no memory!");
4b7df707 3574 }
6368a1bd
DH
3575 memset(q, 0, sizeof *q);
3576 /* prepend to ackqueue*/
087b8f18 3577 lease_reference(&q->lease, lease, MDL);
6368a1bd
DH
3578 q->next = ackqueue_head;
3579 ackqueue_head = q;
3580 if (!ackqueue_tail)
3581 ackqueue_tail = q;
3582 else
3583 q->next->prev = q;
3584
3585 outstanding_acks++;
0585235c 3586 if (outstanding_acks > max_outstanding_acks) {
e422b8c7
TM
3587 /* Cancel any pending timeout and call handler directly */
3588 cancel_timeout(delayed_acks_timer, NULL);
3589 delayed_acks_timer(NULL);
0585235c
SR
3590 } else {
3591 struct timeval next_fsync;
3592
3593 if (max_fsync.tv_sec == 0 && max_fsync.tv_usec == 0) {
3594 /* set the maximum time we'll wait */
3595 max_fsync.tv_sec = cur_tv.tv_sec + max_ack_delay_secs;
3596 max_fsync.tv_usec = cur_tv.tv_usec +
3597 max_ack_delay_usecs;
f8cbf390 3598
0585235c
SR
3599 if (max_fsync.tv_usec >= 1000000) {
3600 max_fsync.tv_sec++;
3601 max_fsync.tv_usec -= 1000000;
3602 }
3603 }
3604
3605 /* Set the timeout */
3606 next_fsync.tv_sec = cur_tv.tv_sec;
3607 next_fsync.tv_usec = cur_tv.tv_usec + min_ack_delay_usecs;
f8cbf390
DH
3608 if (next_fsync.tv_usec >= 1000000) {
3609 next_fsync.tv_sec++;
3610 next_fsync.tv_usec -= 1000000;
3611 }
0585235c
SR
3612 /* but not more than the max */
3613 if ((next_fsync.tv_sec > max_fsync.tv_sec) ||
3614 ((next_fsync.tv_sec == max_fsync.tv_sec) &&
3615 (next_fsync.tv_usec > max_fsync.tv_usec))) {
3616 next_fsync.tv_sec = max_fsync.tv_sec;
3617 next_fsync.tv_usec = max_fsync.tv_usec;
3618 }
f8cbf390 3619
e422b8c7 3620 add_timeout(&next_fsync, delayed_acks_timer, NULL,
6368a1bd
DH
3621 (tvref_t) NULL, (tvunref_t) NULL);
3622 }
11b37280
TL
3623}
3624
e422b8c7
TM
3625/* Processes any delayed acks:
3626 * Commits the leases and then for each delayed ack:
3627 * - Update the failover peer if we're in failover
3628 * - Send the REPLY to the client
3629 */
f8cbf390 3630static void
e422b8c7 3631delayed_acks_timer(void *foo)
f8cbf390 3632{
e422b8c7
TM
3633 struct leasequeue *ack, *p;
3634
3635 /* Reset max fsync */
3636 memset(&max_fsync, 0, sizeof(max_fsync));
f8cbf390 3637
e422b8c7
TM
3638 if (!outstanding_acks) {
3639 /* Nothing to do, so punt, shouldn't happen? */
3640 return;
f8cbf390 3641 }
6368a1bd 3642
e422b8c7
TM
3643 /* Commit the leases first */
3644 commit_leases();
3645
3646 /* Now process the delayed ACKs
3647 - update failover peer
3648 - send out the ACK packets
3649 - move the queue slots to the free list
3650 */
3651
6368a1bd
DH
3652 /* process from bottom to retain packet order */
3653 for (ack = ackqueue_tail ; ack ; ack = p) {
3654 p = ack->prev;
087b8f18 3655
e422b8c7
TM
3656#if defined(FAILOVER_PROTOCOL)
3657 /* If we're in failover we need to send any deferred
3658 * bind updates as well as the replies */
3659 if (ack->lease->pool) {
3660 dhcp_failover_state_t *fpeer;
3661
3662 fpeer = ack->lease->pool->failover_peer;
3663 if (fpeer && fpeer->link_to_peer) {
3664 dhcp_failover_send_updates(fpeer);
3665 }
3666 }
3667#endif
3668
087b8f18
DH
3669 /* dhcp_reply() requires that the reply state still be valid */
3670 if (ack->lease->state == NULL)
3671 log_error("delayed ack for %s has gone stale",
3672 piaddr(ack->lease->ip_addr));
e422b8c7 3673 else {
087b8f18 3674 dhcp_reply(ack->lease);
e422b8c7 3675 }
087b8f18
DH
3676
3677 lease_dereference(&ack->lease, MDL);
6368a1bd
DH
3678 ack->next = free_ackqueue;
3679 free_ackqueue = ack;
3680 }
e422b8c7 3681
6368a1bd
DH
3682 ackqueue_head = NULL;
3683 ackqueue_tail = NULL;
3684 outstanding_acks = 0;
3685}
3686
3687#if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
3688void
3689relinquish_ackqueue(void)
3690{
3691 struct leasequeue *q, *n;
3692
95fd7038 3693 for (q = ackqueue_head ; q ; q = n) {
6368a1bd
DH
3694 n = q->next;
3695 dfree(q, MDL);
3696 }
3697 for (q = free_ackqueue ; q ; q = n) {
3698 n = q->next;
3699 dfree(q, MDL);
3700 }
3701}
3702#endif
3703
e422b8c7
TM
3704#endif /* defined(DELAYED_ACK) */
3705
11b37280
TL
3706void dhcp_reply (lease)
3707 struct lease *lease;
3708{
3709 int bufs = 0;
b1b7b521 3710 unsigned packet_length;
11b37280
TL
3711 struct dhcp_packet raw;
3712 struct sockaddr_in to;
3713 struct in_addr from;
3714 struct hardware hto;
3715 int result;
9cc3ad7f 3716 struct lease_state *state = lease -> state;
bca94423 3717 int nulltp, bootpp, unicastp = 1;
b1dd98c9 3718 struct data_string d1;
98311e4b 3719 const char *s;
9cc3ad7f
TL
3720
3721 if (!state)
8ae2d595 3722 log_fatal ("dhcp_reply was supplied lease with no state!");
11b37280 3723
9cc3ad7f 3724 /* Compose a response for the client... */
11b37280 3725 memset (&raw, 0, sizeof raw);
5d25508c 3726 memset (&d1, 0, sizeof d1);
11b37280
TL
3727
3728 /* Copy in the filename if given; otherwise, flag the filename
3729 buffer as available for options. */
b1dd98c9
TL
3730 if (state -> filename.len && state -> filename.data) {
3731 memcpy (raw.file,
3732 state -> filename.data,
3733 state -> filename.len > sizeof raw.file
3734 ? sizeof raw.file : state -> filename.len);
3735 if (sizeof raw.file > state -> filename.len)
3736 memset (&raw.file [state -> filename.len], 0,
3737 (sizeof raw.file) - state -> filename.len);
66be0ad1
SR
3738 else
3739 log_info("file name longer than packet field "
228e4447
MA
3740 "truncated - field: %lu name: %d %.*s",
3741 (unsigned long)sizeof(raw.file),
4176a700 3742 state->filename.len, (int)state->filename.len,
228e4447 3743 state->filename.data);
b1dd98c9 3744 } else
11b37280
TL
3745 bufs |= 1;
3746
3747 /* Copy in the server name if given; otherwise, flag the
3748 server_name buffer as available for options. */
b1dd98c9
TL
3749 if (state -> server_name.len && state -> server_name.data) {
3750 memcpy (raw.sname,
3751 state -> server_name.data,
3752 state -> server_name.len > sizeof raw.sname
3753 ? sizeof raw.sname : state -> server_name.len);
3754 if (sizeof raw.sname > state -> server_name.len)
3755 memset (&raw.sname [state -> server_name.len], 0,
3756 (sizeof raw.sname) - state -> server_name.len);
66be0ad1
SR
3757 else
3758 log_info("server name longer than packet field "
228e4447
MA
3759 "truncated - field: %lu name: %d %.*s",
3760 (unsigned long)sizeof(raw.sname),
3761 state->server_name.len,
4176a700 3762 (int)state->server_name.len,
66be0ad1 3763 state->server_name.data);
b1dd98c9 3764 } else
11b37280
TL
3765 bufs |= 2; /* XXX */
3766
2cbc0e48
TL
3767 memcpy (raw.chaddr,
3768 &lease -> hardware_addr.hbuf [1], sizeof raw.chaddr);
3769 raw.hlen = lease -> hardware_addr.hlen - 1;
3770 raw.htype = lease -> hardware_addr.hbuf [0];
11b37280 3771
c34fcd38
TL
3772 /* See if this is a Microsoft client that NUL-terminates its
3773 strings and expects us to do likewise... */
11b37280 3774 if (lease -> flags & MS_NULL_TERMINATION)
a52d8045 3775 nulltp = 1;
c34fcd38 3776 else
a52d8045
TL
3777 nulltp = 0;
3778
3779 /* See if this is a bootp client... */
3780 if (state -> offer)
3781 bootpp = 0;
3782 else
3783 bootpp = 1;
3784
3785 /* Insert such options as will fit into the buffer. */
ca1c700e 3786 packet_length = cons_options (state -> packet, &raw, lease,
9e383163 3787 (struct client_state *)0,
3c893bb6 3788 state -> max_message_size,
ca1c700e 3789 state -> packet -> options,
12c9957e 3790 state -> options, &global_scope,
eddb16f4 3791 bufs, nulltp, bootpp,
9030b313
TL
3792 &state -> parameter_request_list,
3793 (char *)0);
11b37280 3794
9cc3ad7f 3795 memcpy (&raw.ciaddr, &state -> ciaddr, sizeof raw.ciaddr);
685963dc 3796 memcpy (&raw.yiaddr, lease -> ip_addr.iabuf, 4);
10553ccb 3797 raw.siaddr = state -> siaddr;
9cc3ad7f 3798 raw.giaddr = state -> giaddr;
685963dc 3799
9cc3ad7f
TL
3800 raw.xid = state -> xid;
3801 raw.secs = state -> secs;
3802 raw.flags = state -> bootp_flags;
3803 raw.hops = state -> hops;
685963dc
TL
3804 raw.op = BOOTREPLY;
3805
98311e4b
DH
3806 if (lease -> client_hostname) {
3807 if ((strlen (lease -> client_hostname) <= 64) &&
28868515 3808 db_printable((unsigned char *)lease->client_hostname))
98311e4b
DH
3809 s = lease -> client_hostname;
3810 else
3811 s = "Hostname Unsuitable for Printing";
3812 } else
d9eefc5d
TL
3813 s = (char *)0;
3814
785c1a51
FD
3815 /* Make sure outgoing packets are at least as big
3816 as a BOOTP packet. */
3817 if (packet_length < BOOTP_MIN_LEN)
3818 packet_length = BOOTP_MIN_LEN;
3819
3820#if defined(DHCPv6) && defined(DHCP4o6)
3821 if (dhcpv4_over_dhcpv6 && (state->packet->dhcp4o6_response != NULL)) {
3822 /* Say what we're doing... */
3823 log_info ("DHCP4o6 %s on %s to %s %s%s%svia %s",
3824 (state -> offer
3825 ? (state -> offer == DHCPACK
3826 ? "DHCPACK" : "DHCPOFFER")
3827 : "BOOTREPLY"),
3828 piaddr (lease -> ip_addr),
3829 (lease -> hardware_addr.hlen
3830 ? print_hw_addr (lease -> hardware_addr.hbuf [0],
3831 lease -> hardware_addr.hlen - 1,
3832 &lease -> hardware_addr.hbuf [1])
3833 : print_hex_1(lease->uid_len, lease->uid, 60)),
3834 s ? "(" : "", s ? s : "", s ? ") " : "",
3835 piaddr(state->packet->client_addr));
3836
3837 /* fill dhcp4o6_response */
3838 state->packet->dhcp4o6_response->len = packet_length;
3839 state->packet->dhcp4o6_response->buffer = NULL;
3840 if (!buffer_allocate(&state->packet->dhcp4o6_response->buffer,
3841 packet_length, MDL)) {
3842 log_fatal("No memory to store DHCP4o6 reply.");
3843 }
3844 state->packet->dhcp4o6_response->data =
3845 state->packet->dhcp4o6_response->buffer->data;
3846 memcpy(state->packet->dhcp4o6_response->buffer->data,
3847 &raw, packet_length);
3848
3849 /* done */
3850 free_lease_state (state, MDL);
3851 lease -> state = (struct lease_state *)0;
3852
3853 return;
3854 }
3855#endif
3856
7a049f2c 3857 /* Say what we're doing... */
d9eefc5d 3858 log_info ("%s on %s to %s %s%s%svia %s",
86bbcc1c
TL
3859 (state -> offer
3860 ? (state -> offer == DHCPACK ? "DHCPACK" : "DHCPOFFER")
3861 : "BOOTREPLY"),
3862 piaddr (lease -> ip_addr),
2cbc0e48
TL
3863 (lease -> hardware_addr.hlen
3864 ? print_hw_addr (lease -> hardware_addr.hbuf [0],
3865 lease -> hardware_addr.hlen - 1,
3866 &lease -> hardware_addr.hbuf [1])
6d103865 3867 : print_hex_1(lease->uid_len, lease->uid, 60)),
fdd46b53
TL
3868 s ? "(" : "", s ? s : "", s ? ") " : "",
3869 (state -> giaddr.s_addr
3870 ? inet_ntoa (state -> giaddr)
3871 : state -> ip -> name));
7a049f2c 3872
785c1a51
FD
3873#ifdef DEBUG_PACKET
3874 dump_raw ((unsigned char *)&raw, packet_length);
3875#endif
3876
7a049f2c 3877 /* Set up the hardware address... */
11b37280 3878 hto.hlen = lease -> hardware_addr.hlen;
2cbc0e48 3879 memcpy (hto.hbuf, lease -> hardware_addr.hbuf, hto.hlen);
7a049f2c
TL
3880
3881 to.sin_family = AF_INET;
3882#ifdef HAVE_SA_LEN
3883 to.sin_len = sizeof to;
3884#endif
3885 memset (to.sin_zero, 0, sizeof to.sin_zero);
3886
ed8bcd8f 3887 /* If this was gatewayed, send it back to the gateway... */
b88e8e15 3888 if (raw.giaddr.s_addr) {
ed8bcd8f 3889 to.sin_addr = raw.giaddr;
bfe2d221 3890 if (raw.giaddr.s_addr != htonl (INADDR_LOOPBACK))
1b871100
TL
3891 to.sin_port = local_port;
3892 else
3893 to.sin_port = remote_port; /* For debugging. */
8ec97099 3894
027f46cb 3895 if (fallback_interface) {
dd9237c3
TM
3896 result = send_packet(fallback_interface, NULL, &raw,
3897 packet_length, raw.siaddr, &to,
3898 NULL);
3899 if (result < 0) {
3900 log_error ("%s:%d: Failed to send %d byte long "
3901 "packet over %s interface.", MDL,
3902 packet_length,
3903 fallback_interface->name);
3904 }
3905
9cc3ad7f 3906
4bd8800e 3907 free_lease_state (state, MDL);
027f46cb
TL
3908 lease -> state = (struct lease_state *)0;
3909 return;
3910 }
b88e8e15 3911
566ecd40 3912 /* If the client is RENEWING, unicast to the client using the
cdc336ab
TL
3913 regular IP stack. Some clients, particularly those that
3914 follow RFC1541, are buggy, and send both ciaddr and server
3915 identifier. We deal with this situation by assuming that
3916 if we got both dhcp-server-identifier and ciaddr, and
3917 giaddr was not set, then the client is on the local
3918 network, and we can therefore unicast or broadcast to it
3919 successfully. A client in REQUESTING state on another
3920 network that's making this mistake will have set giaddr,
3921 and will therefore get a relayed response from the above
3922 code. */
3923 } else if (raw.ciaddr.s_addr &&
0af446bc
TL
3924 !((state -> got_server_identifier ||
3925 (raw.flags & htons (BOOTP_BROADCAST))) &&
3926 /* XXX This won't work if giaddr isn't zero, but it is: */
cdc336ab
TL
3927 (state -> shared_network ==
3928 lease -> subnet -> shared_network)) &&
3929 state -> offer == DHCPACK) {
531fa185 3930 to.sin_addr = raw.ciaddr;
566ecd40 3931 to.sin_port = remote_port;
b88e8e15 3932
027f46cb 3933 if (fallback_interface) {
dd9237c3
TM
3934 result = send_packet(fallback_interface, NULL, &raw,
3935 packet_length, raw.siaddr, &to,
3936 NULL);
3937 if (result < 0) {
3938 log_error("%s:%d: Failed to send %d byte long"
3939 " packet over %s interface.", MDL,
3940 packet_length,
3941 fallback_interface->name);
3942 }
3943
4bd8800e 3944 free_lease_state (state, MDL);
027f46cb
TL
3945 lease -> state = (struct lease_state *)0;
3946 return;
3947 }
e2cb6d53 3948
566ecd40
TL
3949 /* If it comes from a client that already knows its address
3950 and is not requesting a broadcast response, and we can
3951 unicast to a client without using the ARP protocol, sent it
3952 directly to that client. */
3953 } else if (!(raw.flags & htons (BOOTP_BROADCAST)) &&
531fa185
TL
3954 can_unicast_without_arp (state -> ip)) {
3955 to.sin_addr = raw.yiaddr;
566ecd40
TL
3956 to.sin_port = remote_port;
3957
ed8bcd8f 3958 /* Otherwise, broadcast it on the local network. */
b88e8e15 3959 } else {
71df44f5 3960 to.sin_addr = limited_broadcast;
566ecd40 3961 to.sin_port = remote_port;
bca94423
TL
3962 if (!(lease -> flags & UNICAST_BROADCAST_HACK))
3963 unicastp = 0;
b88e8e15 3964 }
ed8bcd8f 3965
5d25508c 3966 memcpy (&from, state -> from.iabuf, sizeof from);
fde927d2 3967
dd9237c3
TM
3968 result = send_packet(state->ip, NULL, &raw, packet_length,
3969 from, &to, unicastp ? &hto : NULL);
3970 if (result < 0) {
3971 log_error ("%s:%d: Failed to send %d byte long "
3972 "packet over %s interface.", MDL,
3973 packet_length, state->ip->name);
3974 }
3975
9cc3ad7f 3976
10553ccb
TL
3977 /* Free all of the entries in the option_state structure
3978 now that we're done with them. */
3979
4bd8800e 3980 free_lease_state (state, MDL);
9cc3ad7f 3981 lease -> state = (struct lease_state *)0;
d7837182 3982}
ed8bcd8f 3983
20916cae
TL
3984int find_lease (struct lease **lp,
3985 struct packet *packet, struct shared_network *share, int *ours,
88cd8aca 3986 int *peer_has_leases, struct lease *ip_lease_in,
9e383163 3987 const char *file, int line)
ed8bcd8f 3988{
20916cae
TL
3989 struct lease *uid_lease = (struct lease *)0;
3990 struct lease *ip_lease = (struct lease *)0;
3991 struct lease *hw_lease = (struct lease *)0;
7a049f2c 3992 struct lease *lease = (struct lease *)0;
ed8bcd8f 3993 struct iaddr cip;
20916cae
TL
3994 struct host_decl *hp = (struct host_decl *)0;
3995 struct host_decl *host = (struct host_decl *)0;
3996 struct lease *fixed_lease = (struct lease *)0;
4f767627 3997 struct lease *next = (struct lease *)0;
5d25508c
TL
3998 struct option_cache *oc;
3999 struct data_string d1;
4000 int have_client_identifier = 0;
4001 struct data_string client_identifier;
4d0aaa17 4002 struct hardware h;
ed8bcd8f 4003
66cebfcb 4004#if defined(FAILOVER_PROTOCOL)
88cd8aca
DH
4005 /* Quick check to see if the peer has leases. */
4006 if (peer_has_leases) {
4007 struct pool *pool;
4008
4009 for (pool = share->pools ; pool ; pool = pool->next) {
4010 dhcp_failover_state_t *peer = pool->failover_peer;
4011
4012 if (peer &&
4013 ((peer->i_am == primary && pool->backup_leases) ||
4014 (peer->i_am == secondary && pool->free_leases))) {
4015 *peer_has_leases = 1;
4016 break;
4017 }
4018 }
4019 }
66cebfcb 4020#endif /* FAILOVER_PROTOCOL */
88cd8aca 4021
9e383163 4022 if (packet -> raw -> ciaddr.s_addr) {
74f45f96
TL
4023 cip.len = 4;
4024 memcpy (cip.iabuf, &packet -> raw -> ciaddr, 4);
9e383163
TL
4025 } else {
4026 /* Look up the requested address. */
4027 oc = lookup_option (&dhcp_universe, packet -> options,
4028 DHO_DHCP_REQUESTED_ADDRESS);
4029 memset (&d1, 0, sizeof d1);
4030 if (oc &&
4031 evaluate_option_cache (&d1, packet, (struct lease *)0,
4032 (struct client_state *)0,
4033 packet -> options,
4034 (struct option_state *)0,
4035 &global_scope, oc, MDL)) {
4036 packet -> got_requested_address = 1;
4037 cip.len = 4;
4038 memcpy (cip.iabuf, d1.data, cip.len);
4039 data_string_forget (&d1, MDL);
4040 } else
4041 cip.len = 0;
4042 }
74f45f96 4043
7a049f2c
TL
4044 /* Try to find a host or lease that's been assigned to the
4045 specified unique client identifier. */
951323fe 4046 oc = lookup_option (&dhcp_universe, packet -> options,
5d25508c
TL
4047 DHO_DHCP_CLIENT_IDENTIFIER);
4048 memset (&client_identifier, 0, sizeof client_identifier);
4049 if (oc &&
4050 evaluate_option_cache (&client_identifier,
ca1c700e 4051 packet, (struct lease *)0,
9e383163 4052 (struct client_state *)0,
ca1c700e 4053 packet -> options, (struct option_state *)0,
12c9957e 4054 &global_scope, oc, MDL)) {
5d25508c
TL
4055 /* Remember this for later. */
4056 have_client_identifier = 1;
4057
7a049f2c
TL
4058 /* First, try to find a fixed host entry for the specified
4059 client identifier... */
20916cae
TL
4060 if (find_hosts_by_uid (&hp, client_identifier.data,
4061 client_identifier.len, MDL)) {
f63b4929
TL
4062 /* Remember if we know of this client. */
4063 packet -> known = 1;
20916cae
TL
4064 mockup_lease (&fixed_lease, packet, share, hp);
4065 }
5d25508c 4066
5d25508c 4067#if defined (DEBUG_FIND_LEASE)
74f45f96 4068 if (fixed_lease) {
8ae2d595 4069 log_info ("Found host for client identifier: %s.",
5d25508c 4070 piaddr (fixed_lease -> ip_addr));
74f45f96 4071 }
5d25508c 4072#endif
7f65aa81
TL
4073 if (hp) {
4074 if (!fixed_lease) /* Save the host if we found one. */
4075 host_reference (&host, hp, MDL);
20916cae 4076 host_dereference (&hp, MDL);
7f65aa81 4077 }
5d25508c 4078
20916cae
TL
4079 find_lease_by_uid (&uid_lease, client_identifier.data,
4080 client_identifier.len, MDL);
7a049f2c
TL
4081 }
4082
4083 /* If we didn't find a fixed lease using the uid, try doing
4084 it with the hardware address... */
5d25508c 4085 if (!fixed_lease && !host) {
20916cae
TL
4086 if (find_hosts_by_haddr (&hp, packet -> raw -> htype,
4087 packet -> raw -> chaddr,
4088 packet -> raw -> hlen, MDL)) {
f63b4929
TL
4089 /* Remember if we know of this client. */
4090 packet -> known = 1;
20916cae
TL
4091 if (host)
4092 host_dereference (&host, MDL);
4093 host_reference (&host, hp, MDL);
4094 host_dereference (&hp, MDL);
4095 mockup_lease (&fixed_lease, packet, share, host);
5d25508c
TL
4096#if defined (DEBUG_FIND_LEASE)
4097 if (fixed_lease) {
74f45f96 4098 log_info ("Found host for link address: %s.",
5d25508c
TL
4099 piaddr (fixed_lease -> ip_addr));
4100 }
4101#endif
7a049f2c
TL
4102 }
4103 }
ed8bcd8f 4104
bd0b98c1
SR
4105 /* Finally, if we haven't found anything yet try again with the
4106 * host-identifier option ... */
4107 if (!fixed_lease && !host) {
4108 if (find_hosts_by_option(&hp, packet,
4109 packet->options, MDL) == 1) {
4110 packet->known = 1;
4111 if (host)
4112 host_dereference(&host, MDL);
4113 host_reference(&host, hp, MDL);
4114 host_dereference(&hp, MDL);
4115 mockup_lease (&fixed_lease, packet, share, host);
4116#if defined (DEBUG_FIND_LEASE)
4117 if (fixed_lease) {
4118 log_info ("Found host via host-identifier");
4119 }
4120#endif
4121 }
4122 }
4123
74f45f96
TL
4124 /* If fixed_lease is present but does not match the requested
4125 IP address, and this is a DHCPREQUEST, then we can't return
4126 any other lease, so we might as well return now. */
4127 if (packet -> packet_type == DHCPREQUEST && fixed_lease &&
4128 (fixed_lease -> ip_addr.len != cip.len ||
4129 memcmp (fixed_lease -> ip_addr.iabuf,
4130 cip.iabuf, cip.len))) {
4131 if (ours)
4132 *ours = 1;
4133 strcpy (dhcp_message, "requested address is incorrect");
4134#if defined (DEBUG_FIND_LEASE)
4135 log_info ("Client's fixed-address %s doesn't match %s%s",
4136 piaddr (fixed_lease -> ip_addr), "request ",
4137 print_dotted_quads (cip.len, cip.iabuf));
4138#endif
4139 goto out;
4140 }
4141
fdfebedf
DH
4142 /*
4143 * If we found leases matching the client identifier, loop through
d5b6835f
DH
4144 * the n_uid pointer looking for one that's actually valid. We
4145 * can't do this until we get here because we depend on
4146 * packet -> known, which may be set by either the uid host
4147 * lookup or the haddr host lookup.
4148 *
4149 * Note that the n_uid lease chain is sorted in order of
4150 * preference, so the first one is the best one.
4151 */
20916cae 4152 while (uid_lease) {
74f45f96
TL
4153#if defined (DEBUG_FIND_LEASE)
4154 log_info ("trying next lease matching client id: %s",
4155 piaddr (uid_lease -> ip_addr));
4156#endif
d758ad8c
TL
4157
4158#if defined (FAILOVER_PROTOCOL)
fdfebedf
DH
4159 /*
4160 * When we lookup a lease by uid, we know the client identifier
4161 * matches the lease's record. If it is active, or was last
4162 * active with the same client, we can trivially extend it.
4163 * If is not or was not active, we can allocate it to this
4164 * client if it matches the usual free/backup criteria (which
4165 * is contained in lease_mine_to_reallocate()).
4166 */
4167 if (uid_lease->binding_state != FTS_ACTIVE &&
4168 uid_lease->rewind_binding_state != FTS_ACTIVE &&
4169 !lease_mine_to_reallocate(uid_lease)) {
d758ad8c 4170#if defined (DEBUG_FIND_LEASE)
fdfebedf
DH
4171 log_info("not active or not mine to allocate: %s",
4172 piaddr(uid_lease->ip_addr));
d758ad8c
TL
4173#endif
4174 goto n_uid;
4175 }
4176#endif
4177
74f45f96
TL
4178 if (uid_lease -> subnet -> shared_network != share) {
4179#if defined (DEBUG_FIND_LEASE)
4180 log_info ("wrong network segment: %s",
4181 piaddr (uid_lease -> ip_addr));
4182#endif
d758ad8c 4183 goto n_uid;
74f45f96 4184 }
d758ad8c 4185
74f45f96 4186 if ((uid_lease -> pool -> prohibit_list &&
951323fe 4187 permitted (packet, uid_lease -> pool -> prohibit_list)) ||
74f45f96
TL
4188 (uid_lease -> pool -> permit_list &&
4189 !permitted (packet, uid_lease -> pool -> permit_list))) {
4190#if defined (DEBUG_FIND_LEASE)
4191 log_info ("not permitted: %s",
4192 piaddr (uid_lease -> ip_addr));
4193#endif
d758ad8c 4194 n_uid:
bfe2d221
TL
4195 if (uid_lease -> n_uid)
4196 lease_reference (&next,
4197 uid_lease -> n_uid, MDL);
74f45f96 4198 if (!packet -> raw -> ciaddr.s_addr)
43f23dcc 4199 release_lease (uid_lease, packet);
20916cae 4200 lease_dereference (&uid_lease, MDL);
bfe2d221
TL
4201 if (next) {
4202 lease_reference (&uid_lease, next, MDL);
4203 lease_dereference (&next, MDL);
4204 }
74f45f96
TL
4205 continue;
4206 }
4207 break;
4208 }
4209#if defined (DEBUG_FIND_LEASE)
4210 if (uid_lease)
4211 log_info ("Found lease for client id: %s.",
4212 piaddr (uid_lease -> ip_addr));
4213#endif
4214
4215 /* Find a lease whose hardware address matches, whose client
d5b6835f
DH
4216 * identifier matches (or equally doesn't have one), that's
4217 * permitted, and that's on the correct subnet.
4218 *
4219 * Note that the n_hw chain is sorted in order of preference, so
4220 * the first one found is the best one.
4221 */
4d0aaa17
TL
4222 h.hlen = packet -> raw -> hlen + 1;
4223 h.hbuf [0] = packet -> raw -> htype;
4224 memcpy (&h.hbuf [1], packet -> raw -> chaddr, packet -> raw -> hlen);
20916cae
TL
4225 find_lease_by_hw_addr (&hw_lease, h.hbuf, h.hlen, MDL);
4226 while (hw_lease) {
74f45f96
TL
4227#if defined (DEBUG_FIND_LEASE)
4228 log_info ("trying next lease matching hw addr: %s",
4229 piaddr (hw_lease -> ip_addr));
4230#endif
d758ad8c 4231#if defined (FAILOVER_PROTOCOL)
fdfebedf
DH
4232 /*
4233 * When we lookup a lease by chaddr, we know the MAC address
4234 * matches the lease record (we will check if the lease has a
4235 * client-id the client does not next). If the lease is
4236 * currently active or was last active with this client, we can
4237 * trivially extend it. Otherwise, there are a set of rules
4238 * that govern if we can reallocate this lease to any client
4239 * ("lease_mine_to_reallocate()") including this one.
4240 */
4241 if (hw_lease->binding_state != FTS_ACTIVE &&
4242 hw_lease->rewind_binding_state != FTS_ACTIVE &&
4243 !lease_mine_to_reallocate(hw_lease)) {
d758ad8c 4244#if defined (DEBUG_FIND_LEASE)
fdfebedf
DH
4245 log_info("not active or not mine to allocate: %s",
4246 piaddr(hw_lease->ip_addr));
d758ad8c
TL
4247#endif
4248 goto n_hw;
4249 }
4250#endif
4251
fdfebedf
DH
4252 /*
4253 * This conditional skips "potentially active" leases (leases
4254 * we think are expired may be extended by the peer, etc) that
4255 * may be assigned to a differently /client-identified/ client
4256 * with the same MAC address.
4257 */
d758ad8c
TL
4258 if (hw_lease -> binding_state != FTS_FREE &&
4259 hw_lease -> binding_state != FTS_BACKUP &&
74f45f96
TL
4260 hw_lease -> uid &&
4261 (!have_client_identifier ||
4262 hw_lease -> uid_len != client_identifier.len ||
4263 memcmp (hw_lease -> uid, client_identifier.data,
4264 hw_lease -> uid_len))) {
4265#if defined (DEBUG_FIND_LEASE)
4266 log_info ("wrong client identifier: %s",
4267 piaddr (hw_lease -> ip_addr));
4268#endif
d758ad8c 4269 goto n_hw;
74f45f96
TL
4270 }
4271 if (hw_lease -> subnet -> shared_network != share) {
4272#if defined (DEBUG_FIND_LEASE)
4273 log_info ("wrong network segment: %s",
4274 piaddr (hw_lease -> ip_addr));
4275#endif
d758ad8c 4276 goto n_hw;
355bf452 4277 }
74f45f96
TL
4278 if ((hw_lease -> pool -> prohibit_list &&
4279 permitted (packet, hw_lease -> pool -> prohibit_list)) ||
4280 (hw_lease -> pool -> permit_list &&
4281 !permitted (packet, hw_lease -> pool -> permit_list))) {
4282#if defined (DEBUG_FIND_LEASE)
4283 log_info ("not permitted: %s",
4284 piaddr (hw_lease -> ip_addr));
4285#endif
74f45f96 4286 if (!packet -> raw -> ciaddr.s_addr)
43f23dcc 4287 release_lease (hw_lease, packet);
d758ad8c
TL
4288 n_hw:
4289 if (hw_lease -> n_hw)
4290 lease_reference (&next, hw_lease -> n_hw, MDL);
20916cae 4291 lease_dereference (&hw_lease, MDL);
bfe2d221
TL
4292 if (next) {
4293 lease_reference (&hw_lease, next, MDL);
4294 lease_dereference (&next, MDL);
4295 }
74f45f96
TL
4296 continue;
4297 }
4298 break;
355bf452 4299 }
5d25508c
TL
4300#if defined (DEBUG_FIND_LEASE)
4301 if (hw_lease)
8ae2d595 4302 log_info ("Found lease for hardware address: %s.",
5d25508c
TL
4303 piaddr (hw_lease -> ip_addr));
4304#endif
ed8bcd8f
TL
4305
4306 /* Try to find a lease that's been allocated to the client's
4307 IP address. */
9e383163
TL
4308 if (ip_lease_in)
4309 lease_reference (&ip_lease, ip_lease_in, MDL);
4310 else if (cip.len)
20916cae 4311 find_lease_by_ip_addr (&ip_lease, cip, MDL);
5d25508c
TL
4312
4313#if defined (DEBUG_FIND_LEASE)
4314 if (ip_lease)
8ae2d595 4315 log_info ("Found lease for requested address: %s.",
5d25508c
TL
4316 piaddr (ip_lease -> ip_addr));
4317#endif
ed8bcd8f 4318
fa97acc1
TL
4319 /* If ip_lease is valid at this point, set ours to one, so that
4320 even if we choose a different lease, we know that the address
4321 the client was requesting was ours, and thus we can NAK it. */
be6b4b2a 4322 if (ip_lease && ours)
fa97acc1
TL
4323 *ours = 1;
4324
4fbcd991 4325 /* If the requested IP address isn't on the network the packet
c54885bd
TL
4326 came from, don't use it. Allow abandoned leases to be matched
4327 here - if the client is requesting it, there's a decent chance
4328 that it's because the lease database got trashed and a client
4329 that thought it had this lease answered an ARP or PING, causing the
4330 lease to be abandoned. If so, this request probably came from
4331 that client. */
027f46cb 4332 if (ip_lease && (ip_lease -> subnet -> shared_network != share)) {
74f45f96
TL
4333 if (ours)
4334 *ours = 1;
4335#if defined (DEBUG_FIND_LEASE)
8ae2d595 4336 log_info ("...but it was on the wrong shared network.");
74f45f96
TL
4337#endif
4338 strcpy (dhcp_message, "requested address on bad subnet");
20916cae 4339 lease_dereference (&ip_lease, MDL);
5d25508c 4340 }
4fbcd991 4341
fdfebedf
DH
4342 /*
4343 * If the requested address is in use (or potentially in use) by
4344 * a different client, it can't be granted.
4345 *
4346 * This first conditional only detects if the lease is currently
4347 * identified to a different client (client-id and/or chaddr
4348 * mismatch). In this case we may not want to give the client the
4349 * lease, if doing so may potentially be an addressing conflict.
4350 */
f8cd781e 4351 if (ip_lease &&
bb0b00a5
TL
4352 (ip_lease -> uid ?
4353 (!have_client_identifier ||
4354 ip_lease -> uid_len != client_identifier.len ||
4355 memcmp (ip_lease -> uid, client_identifier.data,
4356 ip_lease -> uid_len)) :
d642c2a6
TL
4357 (ip_lease -> hardware_addr.hbuf [0] != packet -> raw -> htype ||
4358 ip_lease -> hardware_addr.hlen != packet -> raw -> hlen + 1 ||
4359 memcmp (&ip_lease -> hardware_addr.hbuf [1],
4360 packet -> raw -> chaddr,
4361 (unsigned)(ip_lease -> hardware_addr.hlen - 1))))) {
fdfebedf
DH
4362 /*
4363 * A lease is unavailable for allocation to a new client if
4364 * it is not in the FREE or BACKUP state. There may be
4365 * leases that are in the expired state with a rewinding
4366 * state that is free or backup, but these will be processed
4367 * into the free or backup states by expiration processes, so
4368 * checking for them here is superfluous.
4369 */
d758ad8c
TL
4370 if (ip_lease -> binding_state != FTS_FREE &&
4371 ip_lease -> binding_state != FTS_BACKUP) {
5d25508c 4372#if defined (DEBUG_FIND_LEASE)
8ae2d595 4373 log_info ("rejecting lease for requested address.");
5d25508c 4374#endif
dbc855c9
TL
4375 /* If we're rejecting it because the peer has
4376 it, don't set "ours", because we shouldn't NAK. */
4377 if (ours && ip_lease -> binding_state != FTS_ACTIVE)
4378 *ours = 0;
007e3ee4 4379 lease_dereference (&ip_lease, MDL);
88cd8aca 4380 }
5d25508c
TL
4381 }
4382
fdfebedf
DH
4383 /*
4384 * If we got an ip_lease and a uid_lease or hw_lease, and ip_lease
4385 * is/was not active, and is not ours to reallocate, forget about it.
4386 */
d758ad8c 4387 if (ip_lease && (uid_lease || hw_lease) &&
fdfebedf
DH
4388 ip_lease->binding_state != FTS_ACTIVE &&
4389 ip_lease->rewind_binding_state != FTS_ACTIVE &&
66cebfcb 4390#if defined(FAILOVER_PROTOCOL)
fdfebedf 4391 !lease_mine_to_reallocate(ip_lease) &&
66cebfcb 4392#endif
fdfebedf 4393 packet->packet_type == DHCPDISCOVER) {
d758ad8c 4394#if defined (DEBUG_FIND_LEASE)
fdfebedf 4395 log_info("ip lease not active or not ours to offer.");
d758ad8c 4396#endif
fdfebedf 4397 lease_dereference(&ip_lease, MDL);
d758ad8c
TL
4398 }
4399
5d25508c
TL
4400 /* If for some reason the client has more than one lease
4401 on the subnet that matches its uid, pick the one that
4402 it asked for and (if we can) free the other. */
a55ccdd0
DH
4403 if (ip_lease && ip_lease->binding_state == FTS_ACTIVE &&
4404 ip_lease->uid && ip_lease != uid_lease) {
74f45f96 4405 if (have_client_identifier &&
5d25508c
TL
4406 (ip_lease -> uid_len == client_identifier.len) &&
4407 !memcmp (client_identifier.data,
599c23c1 4408 ip_lease -> uid, ip_lease -> uid_len)) {
eeea1395 4409 if (uid_lease) {
a55ccdd0 4410 if (uid_lease->binding_state == FTS_ACTIVE) {
74f45f96 4411 log_error ("client %s has duplicate%s on %s",
74f45f96
TL
4412 (print_hw_addr
4413 (packet -> raw -> htype,
4414 packet -> raw -> hlen,
4415 packet -> raw -> chaddr)),
12c9957e
TL
4416 " leases",
4417 (ip_lease -> subnet ->
4418 shared_network -> name));
48984237 4419
eeea1395
TL
4420 /* If the client is REQUESTing the lease,
4421 it shouldn't still be using the old
4422 one, so we can free it for allocation. */
4423 if (uid_lease &&
a55ccdd0 4424 uid_lease->binding_state == FTS_ACTIVE &&
eeea1395
TL
4425 !packet -> raw -> ciaddr.s_addr &&
4426 (share ==
a1e9fabd
TL
4427 uid_lease -> subnet -> shared_network) &&
4428 packet -> packet_type == DHCPREQUEST)
88cd8aca 4429 release_lease (uid_lease, packet);
eeea1395 4430 }
20916cae
TL
4431 lease_dereference (&uid_lease, MDL);
4432 lease_reference (&uid_lease, ip_lease, MDL);
eeea1395 4433 }
599c23c1 4434 }
f8cd781e 4435
74f45f96
TL
4436 /* If we get to here and fixed_lease is not null, that means
4437 that there are both a dynamic lease and a fixed-address
4438 declaration for the same IP address. */
4439 if (packet -> packet_type == DHCPREQUEST && fixed_lease) {
20916cae 4440 lease_dereference (&fixed_lease, MDL);
74f45f96 4441 db_conflict:
c5b0f529
TL
4442 log_error ("Dynamic and static leases present for %s.",
4443 piaddr (cip));
4444 log_error ("Remove host declaration %s or remove %s",
4445 (fixed_lease && fixed_lease -> host
4446 ? (fixed_lease -> host -> name
4447 ? fixed_lease -> host -> name
4448 : piaddr (cip))
4449 : piaddr (cip)),
4450 piaddr (cip));
4451 log_error ("from the dynamic address pool for %s",
4452 ip_lease -> subnet -> shared_network -> name
4453 );
74f45f96 4454 if (fixed_lease)
20916cae 4455 lease_dereference (&ip_lease, MDL);
74f45f96
TL
4456 strcpy (dhcp_message,
4457 "database conflict - call for help!");
4458 }
9e383163
TL
4459
4460 if (ip_lease && ip_lease != uid_lease) {
4461#if defined (DEBUG_FIND_LEASE)
4462 log_info ("requested address not available.");
4463#endif
4464 lease_dereference (&ip_lease, MDL);
4465 }
5d25508c 4466 }
f8cd781e 4467
74f45f96
TL
4468 /* If we get to here with both fixed_lease and ip_lease not
4469 null, then we have a configuration file bug. */
4470 if (packet -> packet_type == DHCPREQUEST && fixed_lease && ip_lease)
4471 goto db_conflict;
4472
74f45f96 4473 /* Toss extra pointers to the same lease... */
20916cae 4474 if (hw_lease && hw_lease == uid_lease) {
5d25508c 4475#if defined (DEBUG_FIND_LEASE)
8ae2d595 4476 log_info ("hardware lease and uid lease are identical.");
5d25508c 4477#endif
20916cae 4478 lease_dereference (&hw_lease, MDL);
5d25508c 4479 }
20916cae
TL
4480 if (ip_lease && ip_lease == hw_lease) {
4481 lease_dereference (&hw_lease, MDL);
74f45f96
TL
4482#if defined (DEBUG_FIND_LEASE)
4483 log_info ("hardware lease and ip lease are identical.");
4484#endif
4485 }
20916cae
TL
4486 if (ip_lease && ip_lease == uid_lease) {
4487 lease_dereference (&uid_lease, MDL);
5d25508c 4488#if defined (DEBUG_FIND_LEASE)
8ae2d595 4489 log_info ("uid lease and ip lease are identical.");
5d25508c
TL
4490#endif
4491 }
ed8bcd8f 4492
007e3ee4
TL
4493 /* Make sure the client is permitted to use the requested lease. */
4494 if (ip_lease &&
4495 ((ip_lease -> pool -> prohibit_list &&
4496 permitted (packet, ip_lease -> pool -> prohibit_list)) ||
4497 (ip_lease -> pool -> permit_list &&
4498 !permitted (packet, ip_lease -> pool -> permit_list)))) {
88cd8aca
DH
4499 if (!packet->raw->ciaddr.s_addr &&
4500 (ip_lease->binding_state == FTS_ACTIVE))
007e3ee4 4501 release_lease (ip_lease, packet);
88cd8aca 4502
007e3ee4
TL
4503 lease_dereference (&ip_lease, MDL);
4504 }
4505
4506 if (uid_lease &&
4507 ((uid_lease -> pool -> prohibit_list &&
4508 permitted (packet, uid_lease -> pool -> prohibit_list)) ||
4509 (uid_lease -> pool -> permit_list &&
4510 !permitted (packet, uid_lease -> pool -> permit_list)))) {
4511 if (!packet -> raw -> ciaddr.s_addr)
4512 release_lease (uid_lease, packet);
4513 lease_dereference (&uid_lease, MDL);
4514 }
4515
4516 if (hw_lease &&
4517 ((hw_lease -> pool -> prohibit_list &&
4518 permitted (packet, hw_lease -> pool -> prohibit_list)) ||
4519 (hw_lease -> pool -> permit_list &&
4520 !permitted (packet, hw_lease -> pool -> permit_list)))) {
4521 if (!packet -> raw -> ciaddr.s_addr)
4522 release_lease (hw_lease, packet);
4523 lease_dereference (&hw_lease, MDL);
4524 }
4525
b88e8e15
TL
4526 /* If we've already eliminated the lease, it wasn't there to
4527 begin with. If we have come up with a matching lease,
4528 set the message to bad network in case we have to throw it out. */
74f45f96 4529 if (!ip_lease) {
b88e8e15 4530 strcpy (dhcp_message, "requested address not available");
b88e8e15
TL
4531 }
4532
74f45f96
TL
4533 /* If this is a DHCPREQUEST, make sure the lease we're going to return
4534 matches the requested IP address. If it doesn't, don't return a
4535 lease at all. */
4536 if (packet -> packet_type == DHCPREQUEST &&
4537 !ip_lease && !fixed_lease) {
5d25508c 4538#if defined (DEBUG_FIND_LEASE)
74f45f96 4539 log_info ("no applicable lease found for DHCPREQUEST.");
5d25508c 4540#endif
74f45f96 4541 goto out;
ed8bcd8f
TL
4542 }
4543
7a049f2c 4544 /* At this point, if fixed_lease is nonzero, we can assign it to
ed8bcd8f 4545 this client. */
4fbcd991 4546 if (fixed_lease) {
20916cae
TL
4547 lease_reference (&lease, fixed_lease, MDL);
4548 lease_dereference (&fixed_lease, MDL);
5d25508c 4549#if defined (DEBUG_FIND_LEASE)
8ae2d595 4550 log_info ("choosing fixed address.");
5d25508c 4551#endif
4fbcd991 4552 }
7a049f2c
TL
4553
4554 /* If we got a lease that matched the ip address and don't have
4555 a better offer, use that; otherwise, release it. */
4556 if (ip_lease) {
4557 if (lease) {
74f45f96 4558 if (!packet -> raw -> ciaddr.s_addr)
43f23dcc 4559 release_lease (ip_lease, packet);
5d25508c 4560#if defined (DEBUG_FIND_LEASE)
8ae2d595 4561 log_info ("not choosing requested address (!).");
5d25508c 4562#endif
7a049f2c 4563 } else {
5d25508c 4564#if defined (DEBUG_FIND_LEASE)
8ae2d595 4565 log_info ("choosing lease on requested address.");
5d25508c 4566#endif
20916cae
TL
4567 lease_reference (&lease, ip_lease, MDL);
4568 if (lease -> host)
4569 host_dereference (&lease -> host, MDL);
7a049f2c 4570 }
20916cae 4571 lease_dereference (&ip_lease, MDL);
7a049f2c 4572 }
ed8bcd8f
TL
4573
4574 /* If we got a lease that matched the client identifier, we may want
4575 to use it, but if we already have a lease we like, we must free
4576 the lease that matched the client identifier. */
4577 if (uid_lease) {
4578 if (lease) {
88cd8aca
DH
4579 log_error("uid lease %s for client %s is duplicate "
4580 "on %s",
4581 piaddr(uid_lease->ip_addr),
4582 print_hw_addr(packet->raw->htype,
4583 packet->raw->hlen,
4584 packet->raw->chaddr),
4585 uid_lease->subnet->shared_network->name);
4586
a1e9fabd 4587 if (!packet -> raw -> ciaddr.s_addr &&
d758ad8c 4588 packet -> packet_type == DHCPREQUEST &&
a55ccdd0 4589 uid_lease -> binding_state == FTS_ACTIVE)
88cd8aca 4590 release_lease(uid_lease, packet);
5d25508c 4591#if defined (DEBUG_FIND_LEASE)
8ae2d595 4592 log_info ("not choosing uid lease.");
5d25508c 4593#endif
7a049f2c 4594 } else {
20916cae
TL
4595 lease_reference (&lease, uid_lease, MDL);
4596 if (lease -> host)
4597 host_dereference (&lease -> host, MDL);
5d25508c 4598#if defined (DEBUG_FIND_LEASE)
8ae2d595 4599 log_info ("choosing uid lease.");
5d25508c 4600#endif
7a049f2c 4601 }
20916cae 4602 lease_dereference (&uid_lease, MDL);
ed8bcd8f
TL
4603 }
4604
4605 /* The lease that matched the hardware address is treated likewise. */
4606 if (hw_lease) {
4607 if (lease) {
5d25508c 4608#if defined (DEBUG_FIND_LEASE)
8ae2d595 4609 log_info ("not choosing hardware lease.");
5d25508c 4610#endif
7a049f2c 4611 } else {
7f65aa81
TL
4612 /* We're a little lax here - if the client didn't
4613 send a client identifier and it's a bootp client,
4614 but the lease has a client identifier, we still
4615 let the client have a lease. */
4616 if (!hw_lease -> uid_len ||
4617 (have_client_identifier
4618 ? (hw_lease -> uid_len ==
4619 client_identifier.len &&
4620 !memcmp (hw_lease -> uid,
4621 client_identifier.data,
4622 client_identifier.len))
4623 : packet -> packet_type == 0)) {
4624 lease_reference (&lease, hw_lease, MDL);
4625 if (lease -> host)
4626 host_dereference (&lease -> host, MDL);
5d25508c 4627#if defined (DEBUG_FIND_LEASE)
7f65aa81 4628 log_info ("choosing hardware lease.");
5d25508c 4629#endif
7f65aa81
TL
4630 } else {
4631#if defined (DEBUG_FIND_LEASE)
4632 log_info ("not choosing hardware lease: %s.",
4633 "uid mismatch");
4634#endif
4635 }
7a049f2c 4636 }
20916cae 4637 lease_dereference (&hw_lease, MDL);
7a049f2c
TL
4638 }
4639
ea75d544
DH
4640 /*
4641 * If we found a host_decl but no matching address, try to
4642 * find a host_decl that has no address, and if there is one,
4643 * hang it off the lease so that we can use the supplied
4644 * options.
4645 */
4646 if (lease && host && !lease->host) {
4647 struct host_decl *p = NULL;
4648 struct host_decl *n = NULL;
4649
4650 host_reference(&p, host, MDL);
4651 while (p != NULL) {
4652 if (!p->fixed_addr) {
4653 /*
4654 * If the lease is currently active, then it
4655 * must be allocated to the present client.
4656 * We store a reference to the host record on
4657 * the lease to save a lookup later (in
4658 * ack_lease()). We mustn't refer to the host
4659 * record on non-active leases because the
4660 * client may be denied later.
4661 *
4662 * XXX: Not having this reference (such as in
4663 * DHCPDISCOVER/INIT) means ack_lease will have
4664 * to perform this lookup a second time. This
4665 * hopefully isn't a problem as DHCPREQUEST is
4666 * more common than DHCPDISCOVER.
4667 */
4668 if (lease->binding_state == FTS_ACTIVE)
4669 host_reference(&lease->host, p, MDL);
4670
4671 host_dereference(&p, MDL);
7a049f2c
TL
4672 break;
4673 }
ea75d544
DH
4674 if (p->n_ipaddr != NULL)
4675 host_reference(&n, p->n_ipaddr, MDL);
4676 host_dereference(&p, MDL);
4677 if (n != NULL) {
4678 host_reference(&p, n, MDL);
4679 host_dereference(&n, MDL);
225fed91 4680 }
7a049f2c 4681 }
ed8bcd8f
TL
4682 }
4683
027f46cb
TL
4684 /* If we find an abandoned lease, but it's the one the client
4685 requested, we assume that previous bugginess on the part
4686 of the client, or a server database loss, caused the lease to
4687 be abandoned, so we reclaim it and let the client have it. */
007e3ee4
TL
4688 if (lease &&
4689 (lease -> binding_state == FTS_ABANDONED) &&
4690 lease == ip_lease &&
027f46cb 4691 packet -> packet_type == DHCPREQUEST) {
8ae2d595 4692 log_error ("Reclaiming REQUESTed abandoned IP address %s.",
c54885bd 4693 piaddr (lease -> ip_addr));
007e3ee4 4694 } else if (lease && (lease -> binding_state == FTS_ABANDONED)) {
027f46cb
TL
4695 /* Otherwise, if it's not the one the client requested, we do not
4696 return it - instead, we claim it's ours, causing a DHCPNAK to be
4697 sent if this lookup is for a DHCPREQUEST, and force the client
4698 to go back through the allocation process. */
4699 if (ours)
4700 *ours = 1;
20916cae 4701 lease_dereference (&lease, MDL);
c54885bd
TL
4702 }
4703
74f45f96
TL
4704 out:
4705 if (have_client_identifier)
4bd8800e 4706 data_string_forget (&client_identifier, MDL);
74f45f96 4707
20916cae
TL
4708 if (fixed_lease)
4709 lease_dereference (&fixed_lease, MDL);
4710 if (hw_lease)
4711 lease_dereference (&hw_lease, MDL);
4712 if (uid_lease)
4713 lease_dereference (&uid_lease, MDL);
4714 if (ip_lease)
4715 lease_dereference (&ip_lease, MDL);
4716 if (host)
4717 host_dereference (&host, MDL);
4718
4719 if (lease) {
74f45f96 4720#if defined (DEBUG_FIND_LEASE)
74f45f96
TL
4721 log_info ("Returning lease: %s.",
4722 piaddr (lease -> ip_addr));
74f45f96 4723#endif
20916cae
TL
4724 lease_reference (lp, lease, file, line);
4725 lease_dereference (&lease, MDL);
4726 return 1;
4727 }
4728#if defined (DEBUG_FIND_LEASE)
4729 log_info ("Not returning a lease.");
4730#endif
4731 return 0;
ed8bcd8f 4732}
7a049f2c
TL
4733
4734/* Search the provided host_decl structure list for an address that's on
4735 the specified shared network. If one is found, mock up and return a
4736 lease structure for it; otherwise return the null pointer. */
4737
20916cae
TL
4738int mockup_lease (struct lease **lp, struct packet *packet,
4739 struct shared_network *share, struct host_decl *hp)
7a049f2c 4740{
20916cae 4741 struct lease *lease = (struct lease *)0;
79f3c35c 4742 struct host_decl *rhp = (struct host_decl *)0;
7a049f2c 4743
98311e4b 4744 if (lease_allocate (&lease, MDL) != ISC_R_SUCCESS)
20916cae 4745 return 0;
98311e4b
DH
4746 if (host_reference (&rhp, hp, MDL) != ISC_R_SUCCESS) {
4747 lease_dereference (&lease, MDL);
79f3c35c 4748 return 0;
98311e4b 4749 }
20916cae 4750 if (!find_host_for_network (&lease -> subnet,
79f3c35c 4751 &rhp, &lease -> ip_addr, share)) {
20916cae 4752 lease_dereference (&lease, MDL);
98311e4b 4753 host_dereference (&rhp, MDL);
20916cae
TL
4754 return 0;
4755 }
79f3c35c
TL
4756 host_reference (&lease -> host, rhp, MDL);
4757 if (rhp -> client_identifier.len > sizeof lease -> uid_buf)
4758 lease -> uid = dmalloc (rhp -> client_identifier.len, MDL);
fb6297b1 4759 else
20916cae
TL
4760 lease -> uid = lease -> uid_buf;
4761 if (!lease -> uid) {
4762 lease_dereference (&lease, MDL);
79f3c35c 4763 host_dereference (&rhp, MDL);
20916cae
TL
4764 return 0;
4765 }
79f3c35c
TL
4766 memcpy (lease -> uid, rhp -> client_identifier.data,
4767 rhp -> client_identifier.len);
4768 lease -> uid_len = rhp -> client_identifier.len;
4769 lease -> hardware_addr = rhp -> interface;
6d103865 4770 lease -> starts = lease -> cltt = lease -> ends = MIN_TIME;
20916cae 4771 lease -> flags = STATIC_LEASE;
007e3ee4 4772 lease -> binding_state = FTS_FREE;
98311e4b 4773
20916cae 4774 lease_reference (lp, lease, MDL);
98311e4b 4775
20916cae 4776 lease_dereference (&lease, MDL);
79f3c35c 4777 host_dereference (&rhp, MDL);
20916cae 4778 return 1;
7a049f2c 4779}
f63b4929
TL
4780
4781/* Look through all the pools in a list starting with the specified pool
4782 for a free lease. We try to find a virgin lease if we can. If we
4783 don't find a virgin lease, we try to find a non-virgin lease that's
4784 free. If we can't find one of those, we try to reclaim an abandoned
4785 lease. If all of these possibilities fail to pan out, we don't return
4786 a lease at all. */
4787
20916cae 4788int allocate_lease (struct lease **lp, struct packet *packet,
65cf86d7 4789 struct pool *pool, int *peer_has_leases)
f63b4929 4790{
3933e2aa
SR
4791 struct lease *lease = NULL;
4792 struct lease *candl = NULL;
f63b4929 4793
98311e4b
DH
4794 for (; pool ; pool = pool -> next) {
4795 if ((pool -> prohibit_list &&
4796 permitted (packet, pool -> prohibit_list)) ||
4797 (pool -> permit_list &&
4798 !permitted (packet, pool -> permit_list)))
4799 continue;
f63b4929 4800
2cbc0e48 4801#if defined (FAILOVER_PROTOCOL)
98311e4b
DH
4802 /* Peer_has_leases just says that we found at least one
4803 free lease. If no free lease is returned, the caller
4804 can deduce that this means the peer is hogging all the
4805 free leases, so we can print a better error message. */
4806 /* XXX Do we need code here to ignore PEER_IS_OWNER and
4807 * XXX just check tstp if we're in, e.g., PARTNER_DOWN?
4808 * XXX Where do we deal with CONFLICT_DETECTED, et al? */
4809 /* XXX This should be handled by the lease binding "state
4810 * XXX machine" - that is, when we get here, if a lease
4811 * XXX could be allocated, it will have the correct
4812 * XXX binding state so that the following code will
4813 * XXX result in its being allocated. */
4814 /* Skip to the most expired lease in the pool that is not
4815 * owned by a failover peer. */
8fbb55ff 4816 if (pool->failover_peer != NULL) {
5cc6f201 4817 struct lease *peerl = NULL;
8fbb55ff 4818 if (pool->failover_peer->i_am == primary) {
3933e2aa 4819 candl = LEASE_GET_FIRST(pool->free);
8fbb55ff
DH
4820
4821 /*
4822 * In normal operation, we never want to touch
4823 * the peer's leases. In partner-down
4824 * operation, we need to be able to pick up
4825 * the peer's leases after STOS+MCLT.
4826 */
3933e2aa
SR
4827 peerl = LEASE_GET_FIRST(pool->backup);
4828 if (peerl != NULL) {
8fbb55ff 4829 if (((candl == NULL) ||
3933e2aa
SR
4830 (candl->ends > peerl->ends)) &&
4831 lease_mine_to_reallocate(peerl)) {
4832 candl = peerl;
8fbb55ff
DH
4833 } else {
4834 *peer_has_leases = 1;
4835 }
4836 }
98311e4b 4837 } else {
3933e2aa 4838 candl = LEASE_GET_FIRST(pool->backup);
8fbb55ff 4839
3933e2aa
SR
4840 peerl = LEASE_GET_FIRST(pool->free);
4841 if (peerl != NULL) {
8fbb55ff 4842 if (((candl == NULL) ||
3933e2aa
SR
4843 (candl->ends > peerl->ends)) &&
4844 lease_mine_to_reallocate(peerl)) {
4845 candl = peerl;
8fbb55ff
DH
4846 } else {
4847 *peer_has_leases = 1;
4848 }
4849 }
98311e4b 4850 }
8fbb55ff 4851
fdfebedf 4852 /* Try abandoned leases as a last resort. */
3933e2aa
SR
4853 peerl = LEASE_GET_FIRST(pool->abandoned);
4854 if ((candl == NULL) && (peerl != NULL) &&
4855 lease_mine_to_reallocate(peerl))
4856 candl = peerl;
98311e4b
DH
4857 } else
4858#endif
4859 {
3933e2aa
SR
4860 if (LEASE_NOT_EMPTY(pool->free))
4861 candl = LEASE_GET_FIRST(pool->free);
98311e4b 4862 else
3933e2aa 4863 candl = LEASE_GET_FIRST(pool->abandoned);
007e3ee4 4864 }
98311e4b 4865
8fbb55ff
DH
4866 /*
4867 * XXX: This may not match with documented expectation.
4868 * It's expected that when we OFFER a lease, we set its
4869 * ends time forward 2 minutes so that it gets sorted to
4870 * the end of its free list (avoiding a similar allocation
4871 * to another client). It is not expected that we issue a
4872 * "no free leases" error when the last lease has been
4873 * offered, but it's not exactly broken either.
4874 */
a5252220
TM
4875 if (!candl ||
4876 (candl->binding_state != FTS_ABANDONED &&
4877 (candl->ends > cur_time))) {
98311e4b 4878 continue;
a5252220 4879 }
98311e4b
DH
4880
4881 if (!lease) {
4882 lease = candl;
4883 continue;
f63b4929 4884 }
98311e4b 4885
fdfebedf
DH
4886 /*
4887 * There are tiers of lease state preference, listed here in
4888 * reverse order (least to most preferential):
4889 *
4890 * ABANDONED
4891 * FREE/BACKUP
4892 *
4893 * If the selected lease and candidate are both of the same
4894 * state, select the oldest (longest ago) expiration time
4895 * between the two. If the candidate lease is of a higher
4896 * preferred grade over the selected lease, use it.
4897 */
98311e4b
DH
4898 if ((lease -> binding_state == FTS_ABANDONED) &&
4899 ((candl -> binding_state != FTS_ABANDONED) ||
4900 (candl -> ends < lease -> ends))) {
4901 lease = candl;
4902 continue;
4903 } else if (candl -> binding_state == FTS_ABANDONED)
4904 continue;
4905
4906 if ((lease -> uid_len || lease -> hardware_addr.hlen) &&
4907 ((!candl -> uid_len && !candl -> hardware_addr.hlen) ||
4908 (candl -> ends < lease -> ends))) {
4909 lease = candl;
4910 continue;
4911 } else if (candl -> uid_len || candl -> hardware_addr.hlen)
4912 continue;
4913
4914 if (candl -> ends < lease -> ends)
4915 lease = candl;
f63b4929
TL
4916 }
4917
ea75d544
DH
4918 if (lease != NULL) {
4919 if (lease->binding_state == FTS_ABANDONED)
4920 log_error("Reclaiming abandoned lease %s.",
4921 piaddr(lease->ip_addr));
4922
4923 /*
4924 * XXX: For reliability, we go ahead and remove the host
4925 * record and try to move on. For correctness, if there
4926 * are any other stale host vectors, we want to find them.
4927 */
4928 if (lease->host != NULL) {
4929 log_debug("soft impossible condition (%s:%d): stale "
4930 "host \"%s\" found on lease %s", MDL,
4931 lease->host->name,
4932 piaddr(lease->ip_addr));
4933 host_dereference(&lease->host, MDL);
4934 }
f63b4929 4935
98311e4b
DH
4936 lease_reference (lp, lease, MDL);
4937 return 1;
f63b4929
TL
4938 }
4939
98311e4b 4940 return 0;
f63b4929
TL
4941}
4942
4943/* Determine whether or not a permit exists on a particular permit list
4944 that matches the specified packet, returning nonzero if so, zero if
4945 not. */
4946
4947int permitted (packet, permit_list)
4948 struct packet *packet;
4949 struct permit *permit_list;
4950{
4951 struct permit *p;
4952 int i;
4953
4954 for (p = permit_list; p; p = p -> next) {
4955 switch (p -> type) {
4956 case permit_unknown_clients:
4957 if (!packet -> known)
4958 return 1;
4959 break;
4960
4961 case permit_known_clients:
4962 if (packet -> known)
4963 return 1;
4964 break;
4965
4966 case permit_authenticated_clients:
4967 if (packet -> authenticated)
4968 return 1;
4969 break;
4970
4971 case permit_unauthenticated_clients:
4972 if (!packet -> authenticated)
4973 return 1;
4974 break;
4975
4976 case permit_all_clients:
4977 return 1;
4978
4979 case permit_dynamic_bootp_clients:
4980 if (!packet -> options_valid ||
4981 !packet -> packet_type)
4982 return 1;
4983 break;
4984
4985 case permit_class:
00855426 4986 for (i = 0; i < packet -> class_count; i++) {
f63b4929
TL
4987 if (p -> class == packet -> classes [i])
4988 return 1;
00855426
TL
4989 if (packet -> classes [i] &&
4990 packet -> classes [i] -> superclass &&
4991 (packet -> classes [i] -> superclass ==
4992 p -> class))
4993 return 1;
4994 }
f63b4929 4995 break;
b1d3778c
DH
4996
4997 case permit_after:
4998 if (cur_time > p->after)
4999 return 1;
5000 break;
f63b4929
TL
5001 }
5002 }
5003 return 0;
5004}
5005
785c1a51
FD
5006#if defined(DHCPv6) && defined(DHCP4o6)
5007static int locate_network6 (packet)
5008 struct packet *packet;
5009{
5010 const struct packet *chk_packet;
5011 const struct in6_addr *link_addr, *first_link_addr;
5012 struct iaddr ia;
5013 struct data_string data;
5014 struct subnet *subnet = NULL;
5015 struct option_cache *oc;
5016
5017 /* from locate_network() */
5018
5019 /* See if there's a Relay Agent Link Selection Option, or a
5020 * Subnet Selection Option. The Link-Select and Subnet-Select
5021 * are formatted and used precisely the same, but we must prefer
5022 * the link-select over the subnet-select.
5023 * BTW in DHCPv4 over DHCPv6 no cross version relay was specified
5024 * so it is unlikely to see a link-select.
5025 */
5026 if ((oc = lookup_option(&agent_universe, packet->options,
5027 RAI_LINK_SELECT)) == NULL)
5028 oc = lookup_option(&dhcp_universe, packet->options,
5029 DHO_SUBNET_SELECTION);
5030
5031 /* If there's an option indicating link connection or subnet
5032 * selection, and it's valid, use it to figure out the subnet.
5033 * If it's not valid, fail.
5034 */
5035 if (oc) {
5036 memset(&data, 0, sizeof data);
5037 if (!evaluate_option_cache(&data, packet, NULL, NULL,
5038 packet->options, NULL,
5039 &global_scope, oc, MDL)) {
5040 return (0);
5041 }
5042 if (data.len == 0) {
5043 return (0);
5044 }
5045 if (data.len != 4) {
5046 data_string_forget(&data, MDL);
5047 return (0);
5048 }
5049 ia.len = 4;
5050 memcpy(ia.iabuf, data.data, 4);
5051 data_string_forget(&data, MDL);
5052
5053 if (find_subnet(&subnet, ia, MDL)) {
5054 shared_network_reference(&packet->shared_network,
5055 subnet->shared_network, MDL);
5056 subnet_dereference(&subnet, MDL);
5057 return (1);
5058 }
5059 return (0);
5060 }
5061
5062 /* See if there is a giaddr (still unlikely), if there is one
5063 * use it to figure out the subnet. If it's not valid, fail.
5064 */
5065 if (packet->raw->giaddr.s_addr) {
5066 ia.len = 4;
5067 memcpy(ia.iabuf, &packet->raw->giaddr, 4);
5068
5069 if (find_subnet(&subnet, ia, MDL)) {
5070 shared_network_reference(&packet->shared_network,
5071 subnet->shared_network, MDL);
5072 subnet_dereference(&subnet, MDL);
5073 return (1);
5074 }
5075 return (0);
5076 }
5077
5078 /* from shared_network_from_packet6() */
5079
5080 /* First, find the link address where the packet from the client
5081 * first appeared (if this packet was relayed).
5082 */
5083 first_link_addr = NULL;
5084 chk_packet = packet->dhcpv6_container_packet;
5085 while (chk_packet != NULL) {
5086 link_addr = &chk_packet->dhcpv6_link_address;
5087 if (!IN6_IS_ADDR_UNSPECIFIED(link_addr) &&
5088 !IN6_IS_ADDR_LINKLOCAL(link_addr)) {
5089 first_link_addr = link_addr;
5090 break;
5091 }
5092 chk_packet = chk_packet->dhcpv6_container_packet;
5093 }
5094
5095 /* If there is a relayed link address, find the subnet associated
5096 * with that, and use that to get the appropriate shared_network.
5097 */
5098 if (first_link_addr != NULL) {
5099 ia.len = sizeof(*first_link_addr);
5100 memcpy(ia.iabuf, first_link_addr, sizeof(*first_link_addr));
5101 if (find_subnet (&subnet, ia, MDL)) {
5102 shared_network_reference(&packet->shared_network,
5103 subnet->shared_network, MDL);
5104 subnet_dereference(&subnet, MDL);
5105 return (1);
5106 }
5107 return (0);
5108 }
5109
5110 /* If there is no link address, we will use the interface
5111 * that this packet came in on to pick the shared_network.
5112 */
5113 if (packet->interface != NULL) {
5114 if (packet->interface->shared_network == NULL)
5115 return (0);
5116 shared_network_reference(&packet->shared_network,
5117 packet->interface->shared_network,
5118 MDL);
5119 return (1);
5120 }
5121
5122 /* We shouldn't be able to get here but if there is no link
5123 * address and no interface we don't know where to get the
5124 * shared_network from, log an error and return an error.
5125 */
5126 log_error("No interface and no link address "
5127 "can't determine DHCP4o6 shared network");
5128 return (0);
5129}
5130#endif
5131
e2c5cba2
TL
5132int locate_network (packet)
5133 struct packet *packet;
5134{
5135 struct iaddr ia;
1a634d56 5136 struct data_string data;
20916cae 5137 struct subnet *subnet = (struct subnet *)0;
1a634d56 5138 struct option_cache *oc;
e2c5cba2 5139
785c1a51
FD
5140#if defined(DHCPv6) && defined(DHCP4o6)
5141 if (dhcpv4_over_dhcpv6 && (packet->dhcp4o6_response != NULL)) {
5142 return (locate_network6 (packet));
5143 }
5144#endif
5145
334bf491
DH
5146 /* See if there's a Relay Agent Link Selection Option, or a
5147 * Subnet Selection Option. The Link-Select and Subnet-Select
5148 * are formatted and used precisely the same, but we must prefer
5149 * the link-select over the subnet-select.
5150 */
5151 if ((oc = lookup_option(&agent_universe, packet->options,
5152 RAI_LINK_SELECT)) == NULL)
5153 oc = lookup_option(&dhcp_universe, packet->options,
5154 DHO_SUBNET_SELECTION);
1a634d56
TL
5155
5156 /* If there's no SSO and no giaddr, then use the shared_network
5157 from the interface, if there is one. If not, fail. */
5158 if (!oc && !packet -> raw -> giaddr.s_addr) {
20916cae
TL
5159 if (packet -> interface -> shared_network) {
5160 shared_network_reference
5161 (&packet -> shared_network,
5162 packet -> interface -> shared_network, MDL);
1a634d56 5163 return 1;
20916cae 5164 }
1a634d56
TL
5165 return 0;
5166 }
5167
334bf491
DH
5168 /* If there's an option indicating link connection, and it's valid,
5169 * use it to figure out the subnet. If it's not valid, fail.
5170 */
1a634d56
TL
5171 if (oc) {
5172 memset (&data, 0, sizeof data);
5173 if (!evaluate_option_cache (&data, packet, (struct lease *)0,
9e383163 5174 (struct client_state *)0,
1a634d56
TL
5175 packet -> options,
5176 (struct option_state *)0,
5177 &global_scope, oc, MDL)) {
1a634d56
TL
5178 return 0;
5179 }
785c1a51
FD
5180 if (data.len == 0) {
5181 return 0;
5182 }
1a634d56 5183 if (data.len != 4) {
785c1a51 5184 data_string_forget (&data, MDL);
1a634d56
TL
5185 return 0;
5186 }
5187 ia.len = 4;
5188 memcpy (ia.iabuf, data.data, 4);
5189 data_string_forget (&data, MDL);
e2c5cba2 5190 } else {
1a634d56
TL
5191 ia.len = 4;
5192 memcpy (ia.iabuf, &packet -> raw -> giaddr, 4);
e2c5cba2 5193 }
1a634d56
TL
5194
5195 /* If we know the subnet on which the IP address lives, use it. */
20916cae
TL
5196 if (find_subnet (&subnet, ia, MDL)) {
5197 shared_network_reference (&packet -> shared_network,
5198 subnet -> shared_network, MDL);
5199 subnet_dereference (&subnet, MDL);
e2c5cba2 5200 return 1;
1a634d56
TL
5201 }
5202
5203 /* Otherwise, fail. */
e2c5cba2
TL
5204 return 0;
5205}
6d103865
SK
5206
5207/*
5208 * Try to figure out the source address to send packets from.
5209 *
f8380d3f
SR
5210 * from is the address structure we use to return any address
5211 * we find.
5212 *
5213 * options is the option cache to search. This may include
5214 * options from the incoming packet and configuration information.
6d103865 5215 *
f8380d3f 5216 * out_options is the outgoing option cache. This cache
e046c826 5217 * may be the same as options. If out_options isn't NULL
f8380d3f 5218 * we may save the server address option into it. We do so
e046c826 5219 * if out_options is different than options or if the option
f8380d3f
SR
5220 * wasn't in options and we needed to find the address elsewhere.
5221 *
5222 * packet is the state structure for the incoming packet
5223 *
5224 * When finding the address we first check to see if it is
5225 * in the options list. If it isn't we use the first address
5226 * from the interface.
5227 *
5228 * While this is slightly more complicated than I'd like it allows
5229 * us to use the same code in several different places. ack,
5230 * inform and lease query use it to find the address and fill
5231 * in the options if we get the address from the interface.
5232 * nack uses it to find the address and copy it to the outgoing
5233 * cache. dhcprequest uses it to find the address for comparison
5234 * and doesn't need to add it to an outgoing list.
6d103865 5235 */
f8380d3f 5236
6d103865
SK
5237void
5238get_server_source_address(struct in_addr *from,
5239 struct option_state *options,
f8380d3f 5240 struct option_state *out_options,
6d103865 5241 struct packet *packet) {
e889ded1 5242 unsigned option_num;
f8380d3f 5243 struct option_cache *oc = NULL;
e889ded1 5244 struct data_string d;
f8380d3f
SR
5245 struct in_addr *a = NULL;
5246 isc_boolean_t found = ISC_FALSE;
5247 int allocate = 0;
e889ded1
DH
5248
5249 memset(&d, 0, sizeof(d));
f8380d3f 5250 memset(from, 0, sizeof(*from));
6d103865
SK
5251
5252 option_num = DHO_DHCP_SERVER_IDENTIFIER;
5253 oc = lookup_option(&dhcp_universe, options, option_num);
1b601efa
TM
5254 if (oc != NULL) {
5255 if (evaluate_option_cache(&d, packet, NULL, NULL,
5256 packet->options, options,
5257 &global_scope, oc, MDL)) {
5258 if (d.len == sizeof(*from)) {
f8380d3f 5259 found = ISC_TRUE;
1b601efa 5260 memcpy(from, d.data, sizeof(*from));
f8380d3f
SR
5261
5262 /*
5263 * Arrange to save a copy of the data
5264 * to the outgoing list.
5265 */
5266 if ((out_options != NULL) &&
5267 (options != out_options)) {
5268 a = from;
5269 allocate = 1;
5270 }
1b601efa 5271 }
6d103865 5272 data_string_forget(&d, MDL);
6d103865 5273 }
1b601efa 5274 oc = NULL;
6d103865
SK
5275 }
5276
f8380d3f
SR
5277 if ((found == ISC_FALSE) &&
5278 (packet->interface->address_count > 0)) {
5279 *from = packet->interface->addresses[0];
5280
5281 if (out_options != NULL) {
98bd7ca0 5282 a = &packet->interface->addresses[0];
6d103865 5283 }
6d103865 5284 }
f8380d3f
SR
5285
5286 if ((a != NULL) &&
5287 (option_cache_allocate(&oc, MDL))) {
5288 if (make_const_data(&oc->expression,
5289 (unsigned char *)a, sizeof(*a),
5290 0, allocate, MDL)) {
5291 option_code_hash_lookup(&oc->option,
5292 dhcp_universe.code_hash,
5293 &option_num, 0, MDL);
5294 save_option(&dhcp_universe, out_options, oc);
5295 }
5296 option_cache_dereference(&oc, MDL);
5297 }
5298
5299 return;
5300}
5301
e046c826
TM
5302/*!
5303 * \brief Builds option set from statements at the global and network scope
f8380d3f 5304 *
e046c826
TM
5305 * Set up an option state list based on the global and network scopes.
5306 * These are primarily used by NAK logic to locate dhcp-server-id and
5307 * echo-client-id.
5308 *
5309 * We don't go through all possible options - in particualr we skip the hosts
5310 * and we don't include the lease to avoid making changes to it. This means
5311 * that using these, we won't get the correct server id if the admin puts them
5312 * on hosts or builds the server id with information from the lease.
5313 *
5314 * As this is a fallback function (used to handle NAKs or sort out server id
5315 * mismatch in failover) and requires configuration by the admin, it should be
5316 * okay.
5317 *
5318 * \param network_options option_state to which options will be added. If it
5319 * refers to NULL, it will be allocated. Caller is responsible to delete it.
5320 * \param packet inbound packet
5321 * \param network_group scope group to use if packet->shared_network is null.
f8380d3f 5322 */
f8380d3f 5323void
e046c826
TM
5324eval_network_statements(struct option_state **network_options,
5325 struct packet *packet,
5326 struct group *network_group) {
f8380d3f 5327
e046c826
TM
5328 if (*network_options == NULL) {
5329 option_state_allocate (network_options, MDL);
5330 }
f8380d3f 5331
e046c826
TM
5332 /* Use the packet's shared_network if it has one. If not use
5333 * network_group and if it is null then use global scope. */
f8380d3f 5334 if (packet->shared_network != NULL) {
f8380d3f
SR
5335 /*
5336 * If we have a subnet and group start with that else start
5337 * with the shared network group. The first will recurse and
5338 * include the second.
5339 */
5340 if ((packet->shared_network->subnets != NULL) &&
5341 (packet->shared_network->subnets->group != NULL)) {
5342 execute_statements_in_scope(NULL, packet, NULL, NULL,
e046c826 5343 packet->options, *network_options,
f8380d3f
SR
5344 &global_scope,
5345 packet->shared_network->subnets->group,
a7341359 5346 NULL, NULL);
f8380d3f
SR
5347 } else {
5348 execute_statements_in_scope(NULL, packet, NULL, NULL,
e046c826 5349 packet->options, *network_options,
f8380d3f
SR
5350 &global_scope,
5351 packet->shared_network->group,
a7341359 5352 NULL, NULL);
f8380d3f
SR
5353 }
5354
5355 /* do the pool if there is one */
5356 if (packet->shared_network->pools != NULL) {
5357 execute_statements_in_scope(NULL, packet, NULL, NULL,
e046c826 5358 packet->options, *network_options,
f8380d3f
SR
5359 &global_scope,
5360 packet->shared_network->pools->group,
a7341359
SR
5361 packet->shared_network->group,
5362 NULL);
f8380d3f 5363 }
e046c826
TM
5364 } else if (network_group != NULL) {
5365 execute_statements_in_scope(NULL, packet, NULL, NULL,
5366 packet->options, *network_options,
5367 &global_scope, network_group,
5368 NULL, NULL);
5369 } else {
5370 execute_statements_in_scope(NULL, packet, NULL, NULL,
5371 packet->options, *network_options,
5372 &global_scope, root_group,
5373 NULL, NULL);
5374 }
6d103865
SK
5375}
5376
2c9bf1f4
DH
5377/*
5378 * Look for the lowest numbered site code number and
5379 * apply a log warning if it is less than 224. Do not
5380 * permit site codes less than 128 (old code never did).
5381 *
5382 * Note that we could search option codes 224 down to 128
5383 * on the hash table, but the table is (probably) smaller
5384 * than that if it was declared as a standalone table with
5385 * defaults. So we traverse the option code hash.
5386 */
5387static int
5388find_min_site_code(struct universe *u)
5389{
5390 if (u->site_code_min)
5391 return u->site_code_min;
5392
5393 /*
5394 * Note that site_code_min has to be global as we can't pass an
5395 * argument through hash_foreach(). The value 224 is taken from
5396 * RFC 3942.
5397 */
5398 site_code_min = 224;
5399 option_code_hash_foreach(u->code_hash, lowest_site_code);
5400
5401 if (site_code_min < 224) {
5402 log_error("WARNING: site-local option codes less than 224 have "
5403 "been deprecated by RFC3942. You have options "
5404 "listed in site local space %s that number as low as "
5405 "%d. Please investigate if these should be declared "
5406 "as regular options rather than site-local options, "
5407 "or migrated up past 224.",
5408 u->name, site_code_min);
5409 }
5410
5411 /*
5412 * don't even bother logging, this is just silly, and never worked
5413 * on any old version of software.
5414 */
5415 if (site_code_min < 128)
5416 site_code_min = 128;
5417
5418 /*
5419 * Cache the determined minimum site code on the universe structure.
5420 * Note that due to the < 128 check above, a value of zero is
5421 * impossible.
5422 */
5423 u->site_code_min = site_code_min;
5424
5425 return site_code_min;
5426}
5427
5428static isc_result_t
5429lowest_site_code(const void *key, unsigned len, void *object)
5430{
5431 struct option *option = object;
5432
5433 if (option->code < site_code_min)
5434 site_code_min = option->code;
5435
5436 return ISC_R_SUCCESS;
5437}
5438
a1308b64
DH
5439static void
5440maybe_return_agent_options(struct packet *packet, struct option_state *options)
5441{
5442 /* If there were agent options in the incoming packet, return
5443 * them. Do not return the agent options if they were stashed
5444 * on the lease. We do not check giaddr to detect the presence of
5445 * a relay, as this excludes "l2" relay agents which have no giaddr
5446 * to set.
5447 *
5448 * XXX: If the user configures options for the relay agent information
5449 * (state->options->universes[agent_universe.index] is not NULL),
5450 * we're still required to duplicate other values provided by the
5451 * relay agent. So we need to merge the old values not configured
5452 * by the user into the new state, not just give up.
5453 */
5454 if (!packet->agent_options_stashed &&
8bd96ccb 5455 (packet->options != NULL) &&
a1308b64
DH
5456 packet->options->universe_count > agent_universe.index &&
5457 packet->options->universes[agent_universe.index] != NULL &&
5458 (options->universe_count <= agent_universe.index ||
5459 options->universes[agent_universe.index] == NULL)) {
5460 option_chain_head_reference
5461 ((struct option_chain_head **)
5462 &(options->universes[agent_universe.index]),
5463 (struct option_chain_head *)
5464 packet->options->universes[agent_universe.index], MDL);
5465
5466 if (options->universe_count <= agent_universe.index)
5467 options->universe_count = agent_universe.index + 1;
5468 }
5469}
0a7e1a8a
TM
5470
5471/*!
5472 * \brief Adds hostname option when use-host-decl-names is enabled.
5473 *
5474 * Constructs a hostname option from the name of the host declaration if
5475 * there is one and no hostname has otherwise been provided and the
5476 * use-host-decl-names flag is set, then adds the new option to the given
5477 * option_state. This funciton is used for both bootp and dhcp.
5478 *
5479 * \param packet inbound packet received from the client
5480 * \param lease lease associated with the client
5481 * \param options option state to search and update
5482 */
5483void use_host_decl_name(struct packet* packet,
5484 struct lease *lease,
5485 struct option_state *options) {
5486 unsigned int ocode = SV_USE_HOST_DECL_NAMES;
5487 if ((lease->host && lease->host->name) &&
5488 !lookup_option(&dhcp_universe, options, DHO_HOST_NAME) &&
5489 (evaluate_boolean_option_cache(NULL, packet, lease, NULL,
5490 packet->options, options,
5491 &lease->scope,
5492 lookup_option(&server_universe,
5493 options, ocode),
5494 MDL))) {
5495 struct option_cache *oc = NULL;
5496 if (option_cache_allocate (&oc, MDL)) {
5497 if (make_const_data(&oc -> expression,
5498 ((unsigned char*)lease->host->name),
5499 strlen(lease->host->name),
5500 1, 0, MDL)) {
5501 ocode = DHO_HOST_NAME;
5502 option_code_hash_lookup(&oc->option,
5503 dhcp_universe.code_hash,
5504 &ocode, 0, MDL);
5505 save_option(&dhcp_universe, options, oc);
5506 }
5507 option_cache_dereference(&oc, MDL);
5508 }
5509 }
5510}
f3a44c10
TM
5511
5512/*!
5513 * \brief Checks and preps for lease resuse based on dhcp-cache-threshold
5514 *
5515 * If dhcp-cache-threshold is enabled (i.e. greater than zero), this function
5516 * determines if the current lease is young enough to be reused. If the lease
5517 * can be resused the function returns 1, O if not. This function is called
5518 * by ack_lease when responding to both DISCOVERs and REQUESTS.
5519 *
5520 * The current lease can be reused only if all of the following are true:
5521 * a. dhcp-cache-threshold is > 0
5522 * b. The current lease is active
5523 * c. The lease "age" is less than that allowed by the threshold
5524 * d. DNS updates are not being performed on the new lease.
5525 * e. Lease has not been otherwise disqualified for reuse (Ex: billing class
5526 * changed)
5527 *
5528 * Clients may renew leases using full DORA cycles or just RAs. This means
5529 * that reusability must be checked when acking both DISCOVERs and REQUESTs.
5530 * When a lease cannot be reused, ack_lease() calls supersede_lease() which
5531 * updates the lease start time (among other things). If this occurs on the
5532 * DISCOVER, then the lease will virtually always be seen as young enough to
5533 * reuse on the ensuing REQUEST and the lease updates will not get committed
5534 * to the lease file. The lease.cannot_reuse flag is used to handle this
5535 * this situation.
5536 *
5537 * \param packet inbound packet received from the client
5538 * \param new_lease candidate new lease to associate with the client
5539 * \param lease current lease associated with the client
5540 * \param options option state to search and update
5541 */
5542int
5543reuse_lease (struct packet* packet,
5544 struct lease* new_lease,
5545 struct lease* lease,
5546 struct lease_state *state,
5547 int offer) {
5548 int reusable = 0;
5549
5550 /* To even consider reuse all of the following must be true:
5551 * 1 - reuse hasn't already disqualified
5552 * 2 - current lease is active
5553 * 3 - DNS info hasn't changed */
5554 if ((lease->cannot_reuse == 0) &&
5555 (lease->binding_state == FTS_ACTIVE) &&
5556 (new_lease->ddns_cb == NULL)) {
5557 int thresh = DEFAULT_CACHE_THRESHOLD;
5558 struct option_cache* oc = NULL;
5559 struct data_string d1;
5560
5561 /* Look up threshold value */
5562 memset(&d1, 0, sizeof(struct data_string));
5563 if ((oc = lookup_option(&server_universe, state->options,
5564 SV_CACHE_THRESHOLD)) &&
5565 (evaluate_option_cache(&d1, packet, new_lease, NULL,
5566 packet->options, state->options,
5567 &new_lease->scope, oc, MDL))) {
5568 if (d1.len == 1 && (d1.data[0] < 100))
5569 thresh = d1.data[0];
5570
5571 data_string_forget(&d1, MDL);
5572 }
5573
5574 /* If threshold is enabled, check lease age */
5575 if (thresh > 0) {
5576 int limit = 0;
5577 int lease_length = 0;
5578 long lease_age = 0;
5579
5580 /* Calculate limit in seconds */
5581 lease_length = lease->ends - lease->starts;
5582 if (lease_length <= (INT_MAX / thresh))
5583 limit = lease_length * thresh / 100;
5584 else
5585 limit = lease_length / 100 * thresh;
5586
5587 /* Note new_lease->starts is really just cur_time */
5588 lease_age = new_lease->starts - lease->starts;
5589
5590 /* Is the lease is young enough to reuse? */
5591 if (lease_age <= limit) {
5592 /* Restore expiry to its original value */
5593 state->offered_expiry = lease->ends;
5594
5595 /* Restore bindings. This fixes 37368. */
5596 if (new_lease->scope != NULL) {
5597 if (lease->scope != NULL) {
5598 binding_scope_dereference(
5599 &lease->scope,
5600 MDL);
5601 }
5602
5603 binding_scope_reference(&lease->scope,
5604 new_lease->scope, MDL);
5605 }
5606
5607 /* We're cleared to reuse it */
59990751
TM
5608 log_debug("reuse_lease: lease age %ld (secs)"
5609 " under %d%% threshold, reply with "
20931f53
TM
5610 "unaltered, existing lease for %s",
5611 lease_age, thresh, piaddr(lease->ip_addr));
59990751 5612
f3a44c10
TM
5613 reusable = 1;
5614 }
5615 }
5616 }
5617
5618 /* If we can't reuse it and this is an offer disqualify reuse for
5619 * ensuing REQUEST, otherwise clear the flag. */
5620 lease->cannot_reuse = (!reusable && offer == DHCPOFFER);
5621 return (reusable);
5622}