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