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