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