3 DHCP Protocol engine. */
6 * Copyright (c) 2004-2017 by Internet Systems Consortium, Inc. ("ISC")
7 * Copyright (c) 1995-2003 by Internet Software Consortium
9 * This Source Code Form is subject to the terms of the Mozilla Public
10 * License, v. 2.0. If a copy of the MPL was not distributed with this
11 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
13 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 * Internet Systems Consortium, Inc.
23 * Redwood City, CA 94063
25 * https://www.isc.org/
34 static void maybe_return_agent_options(struct packet
*packet
,
35 struct option_state
*options
);
36 static int reuse_lease (struct packet
* packet
, struct lease
* new_lease
,
37 struct lease
* lease
, struct lease_state
*state
,
39 #if defined(DHCPv6) && defined(DHCP4o6)
40 static int locate_network6(struct packet
*packet
);
43 int outstanding_pings
;
45 #if defined(DELAYED_ACK)
46 static void delayed_ack_enqueue(struct lease
*);
47 static void delayed_acks_timer(void *);
50 struct leasequeue
*ackqueue_head
, *ackqueue_tail
;
51 static struct leasequeue
*free_ackqueue
;
52 static struct timeval max_fsync
;
55 int max_outstanding_acks
= DEFAULT_DELAYED_ACK
;
56 int max_ack_delay_secs
= DEFAULT_ACK_DELAY_SECS
;
57 int max_ack_delay_usecs
= DEFAULT_ACK_DELAY_USECS
;
58 int min_ack_delay_usecs
= DEFAULT_MIN_ACK_DELAY_USECS
;
61 static char dhcp_message
[256];
62 static int site_code_min
;
64 static int find_min_site_code(struct universe
*);
65 static isc_result_t
lowest_site_code(const void *, unsigned, void *);
67 static const char *dhcp_type_names
[] = {
78 "DHCPLEASEUNASSIGNED",
82 const int dhcp_type_name_max
= ((sizeof dhcp_type_names
) / sizeof (char *));
85 # define send_packet trace_packet_send
88 static TIME
leaseTimeCheck(TIME calculated
, TIME alternate
);
91 dhcp (struct packet
*packet
) {
93 struct option_cache
*oc
;
94 struct lease
*lease
= NULL
;
96 struct data_string data
;
98 if (!locate_network(packet
) &&
99 packet
->packet_type
!= DHCPREQUEST
&&
100 packet
->packet_type
!= DHCPINFORM
&&
101 packet
->packet_type
!= DHCPLEASEQUERY
) {
104 errmsg
= "unknown network segment";
107 if (packet
->packet_type
> 0 &&
108 packet
->packet_type
<= dhcp_type_name_max
) {
109 s
= dhcp_type_names
[packet
->packet_type
- 1];
111 /* %Audit% Cannot exceed 28 bytes. %2004.06.17,Safe% */
112 sprintf(typebuf
, "type %d", packet
->packet_type
);
116 #if defined(DHCPv6) && defined(DHCP4o6)
117 if (dhcpv4_over_dhcpv6
&& (packet
->dhcp4o6_response
!= NULL
)) {
118 log_info("DHCP4o6 %s from %s via %s: %s", s
,
120 ? print_hw_addr(packet
->raw
->htype
,
123 : "<no identifier>"),
124 piaddr(packet
->client_addr
),
130 log_info("%s from %s via %s: %s", s
,
132 ? print_hw_addr(packet
->raw
->htype
,
135 : "<no identifier>"),
136 packet
->raw
->giaddr
.s_addr
137 ? inet_ntoa(packet
->raw
->giaddr
)
138 : packet
->interface
->name
, errmsg
);
142 /* There is a problem with the relay agent information option,
143 * which is that in order for a normal relay agent to append
144 * this option, the relay agent has to have been involved in
145 * getting the packet from the client to the server. Note
146 * that this is the software entity known as the relay agent,
147 * _not_ the hardware entity known as a router in which the
148 * relay agent may be running, so the fact that a router has
149 * forwarded a packet does not mean that the relay agent in
150 * the router was involved.
152 * So when the client broadcasts (DHCPDISCOVER, or giaddr is set),
153 * we can be sure that there are either agent options in the
154 * packet, or there aren't supposed to be. When the giaddr is not
155 * set, it's still possible that the client is on a directly
156 * attached subnet, and agent options are being appended by an l2
157 * device that has no address, and so sets no giaddr.
159 * But in either case it's possible that the packets we receive
160 * from the client in RENEW state may not include the agent options,
161 * so if they are not in the packet we must "pretend" the last values
162 * we observed were provided.
164 if (packet
->packet_type
== DHCPREQUEST
&&
165 packet
->raw
->ciaddr
.s_addr
&& !packet
->raw
->giaddr
.s_addr
&&
166 (packet
->options
->universe_count
<= agent_universe
.index
||
167 packet
->options
->universes
[agent_universe
.index
] == NULL
))
171 cip
.len
= sizeof packet
-> raw
-> ciaddr
;
172 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
,
173 sizeof packet
-> raw
-> ciaddr
);
174 if (!find_lease_by_ip_addr (&lease
, cip
, MDL
))
177 /* If there are no agent options on the lease, it's not
179 if (!lease
-> agent_options
)
182 /* The client should not be unicasting a renewal if its lease
183 has expired, so make it go through the process of getting
184 its agent options legally. */
185 if (lease
-> ends
< cur_time
)
188 if (lease
-> uid_len
) {
189 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
190 DHO_DHCP_CLIENT_IDENTIFIER
);
194 memset (&data
, 0, sizeof data
);
195 if (!evaluate_option_cache (&data
,
196 packet
, (struct lease
*)0,
197 (struct client_state
*)0,
199 (struct option_state
*)0,
200 &global_scope
, oc
, MDL
))
202 if (lease
-> uid_len
!= data
.len
||
203 memcmp (lease
-> uid
, data
.data
, data
.len
)) {
204 data_string_forget (&data
, MDL
);
207 data_string_forget (&data
, MDL
);
209 if ((lease
-> hardware_addr
.hbuf
[0] !=
210 packet
-> raw
-> htype
) ||
211 (lease
-> hardware_addr
.hlen
- 1 !=
212 packet
-> raw
-> hlen
) ||
213 memcmp (&lease
-> hardware_addr
.hbuf
[1],
214 packet
-> raw
-> chaddr
,
215 packet
-> raw
-> hlen
))
218 /* Okay, so we found a lease that matches the client. */
219 option_chain_head_reference ((struct option_chain_head
**)
220 &(packet
-> options
-> universes
221 [agent_universe
.index
]),
222 lease
-> agent_options
, MDL
);
224 if (packet
->options
->universe_count
<= agent_universe
.index
)
225 packet
->options
->universe_count
=
226 agent_universe
.index
+ 1;
228 packet
->agent_options_stashed
= ISC_TRUE
;
232 /* If a client null terminates options it sends, it probably
233 * expects the server to reciprocate.
235 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
237 if (!oc
-> expression
)
238 ms_nulltp
= oc
->flags
& OPTION_HAD_NULLS
;
241 /* Classify the client. */
242 classify_client (packet
);
244 switch (packet
-> packet_type
) {
246 dhcpdiscover (packet
, ms_nulltp
);
250 dhcprequest (packet
, ms_nulltp
, lease
);
254 dhcprelease (packet
, ms_nulltp
);
258 dhcpdecline (packet
, ms_nulltp
);
262 dhcpinform (packet
, ms_nulltp
);
266 dhcpleasequery(packet
, ms_nulltp
);
272 case DHCPLEASEUNASSIGNED
:
273 case DHCPLEASEUNKNOWN
:
274 case DHCPLEASEACTIVE
:
278 errmsg
= "unknown packet type";
283 lease_dereference (&lease
, MDL
);
286 void dhcpdiscover (packet
, ms_nulltp
)
287 struct packet
*packet
;
290 struct lease
*lease
= (struct lease
*)0;
291 char msgbuf
[1024]; /* XXX */
294 int peer_has_leases
= 0;
295 #if defined (FAILOVER_PROTOCOL)
296 dhcp_failover_state_t
*peer
;
299 find_lease (&lease
, packet
, packet
-> shared_network
,
300 0, &peer_has_leases
, (struct lease
*)0, MDL
);
302 if (lease
&& lease
-> client_hostname
) {
303 if ((strlen (lease
-> client_hostname
) <= 64) &&
304 db_printable((unsigned char *)lease
->client_hostname
))
305 s
= lease
-> client_hostname
;
307 s
= "Hostname Unsuitable for Printing";
311 /* %Audit% This is log output. %2004.06.17,Safe%
312 * If we truncate we hope the user can get a hint from the log.
314 #if defined(DHCPv6) && defined(DHCP4o6)
315 if (dhcpv4_over_dhcpv6
&& (packet
->dhcp4o6_response
!= NULL
)) {
316 snprintf (msgbuf
, sizeof msgbuf
,
317 "DHCP4o6 DHCPDISCOVER from %s %s%s%svia %s",
318 (packet
-> raw
-> htype
319 ? print_hw_addr (packet
-> raw
-> htype
,
320 packet
-> raw
-> hlen
,
321 packet
-> raw
-> chaddr
)
323 ? print_hex_1(lease
->uid_len
, lease
->uid
, 60)
324 : "<no identifier>")),
325 s
? "(" : "", s
? s
: "", s
? ") " : "",
326 piaddr(packet
->client_addr
));
329 snprintf (msgbuf
, sizeof msgbuf
, "DHCPDISCOVER from %s %s%s%svia %s",
330 (packet
-> raw
-> htype
331 ? print_hw_addr (packet
-> raw
-> htype
,
332 packet
-> raw
-> hlen
,
333 packet
-> raw
-> chaddr
)
335 ? print_hex_1(lease
->uid_len
, lease
->uid
, 60)
336 : "<no identifier>")),
337 s
? "(" : "", s
? s
: "", s
? ") " : "",
338 packet
-> raw
-> giaddr
.s_addr
339 ? inet_ntoa (packet
-> raw
-> giaddr
)
340 : packet
-> interface
-> name
);
342 /* Sourceless packets don't make sense here. */
343 if (!packet
-> shared_network
) {
344 #if defined(DHCPv6) && defined(DHCP4o6)
345 if (dhcpv4_over_dhcpv6
&& (packet
->dhcp4o6_response
!= NULL
)) {
346 log_info ("DHCP4o6 packet from unknown subnet: %s",
347 piaddr(packet
->client_addr
));
350 log_info ("Packet from unknown subnet: %s",
351 inet_ntoa (packet
-> raw
-> giaddr
));
355 #if defined (FAILOVER_PROTOCOL)
356 if (lease
&& lease
-> pool
&& lease
-> pool
-> failover_peer
) {
357 peer
= lease
-> pool
-> failover_peer
;
360 * If the lease is ours to (re)allocate, then allocate it.
362 * If the lease is active, it belongs to the client. This
363 * is the right lease, if we are to offer one. We decide
364 * whether or not to offer later on.
366 * If the lease was last active, and we've reached this
367 * point, then it was last active with the same client. We
368 * can safely re-activate the lease with this client.
370 if (lease
->binding_state
== FTS_ACTIVE
||
371 lease
->rewind_binding_state
== FTS_ACTIVE
||
372 lease_mine_to_reallocate(lease
)) {
373 ; /* This space intentionally left blank. */
375 /* Otherwise, we can't let the client have this lease. */
377 #if defined (DEBUG_FIND_LEASE)
378 log_debug ("discarding %s - %s",
379 piaddr (lease
-> ip_addr
),
380 binding_state_print (lease
-> binding_state
));
382 lease_dereference (&lease
, MDL
);
387 /* If we didn't find a lease, try to allocate one... */
389 if (!allocate_lease (&lease
, packet
,
390 packet
-> shared_network
-> pools
,
393 log_error ("%s: peer holds all free leases",
396 log_error ("%s: network %s: no free leases",
398 packet
-> shared_network
-> name
);
403 #if defined (FAILOVER_PROTOCOL)
404 if (lease
&& lease
-> pool
&& lease
-> pool
-> failover_peer
) {
405 peer
= lease
-> pool
-> failover_peer
;
406 if (peer
-> service_state
== not_responding
||
407 peer
-> service_state
== service_startup
) {
408 log_info ("%s: not responding%s",
409 msgbuf
, peer
-> nrr
);
413 peer
= (dhcp_failover_state_t
*)0;
415 /* Do load balancing if configured. */
416 if (peer
&& (peer
-> service_state
== cooperating
) &&
417 !load_balance_mine (packet
, peer
)) {
418 if (peer_has_leases
) {
419 log_debug ("%s: load balance to peer %s",
420 msgbuf
, peer
-> name
);
423 log_debug ("%s: cancel load balance to peer %s - %s",
424 msgbuf
, peer
-> name
, "no free leases");
429 /* If it's an expired lease, get rid of any bindings. */
430 if (lease
-> ends
< cur_time
&& lease
-> scope
)
431 binding_scope_dereference (&lease
-> scope
, MDL
);
433 /* Set the lease to really expire in 2 minutes, unless it has
434 not yet expired, in which case leave its expiry time alone. */
435 when
= cur_time
+ 120;
436 if (when
< lease
-> ends
)
437 when
= lease
-> ends
;
439 ack_lease (packet
, lease
, DHCPOFFER
, when
, msgbuf
, ms_nulltp
,
440 (struct host_decl
*)0);
443 lease_dereference (&lease
, MDL
);
446 void dhcprequest (packet
, ms_nulltp
, ip_lease
)
447 struct packet
*packet
;
449 struct lease
*ip_lease
;
454 struct subnet
*subnet
;
456 struct option_cache
*oc
;
457 struct data_string data
;
458 char msgbuf
[1024]; /* XXX */
461 #if defined (FAILOVER_PROTOCOL)
462 dhcp_failover_state_t
*peer
;
464 int have_requested_addr
= 0;
466 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
467 DHO_DHCP_REQUESTED_ADDRESS
);
468 memset (&data
, 0, sizeof data
);
470 evaluate_option_cache (&data
, packet
, (struct lease
*)0,
471 (struct client_state
*)0,
472 packet
-> options
, (struct option_state
*)0,
473 &global_scope
, oc
, MDL
)) {
475 memcpy (cip
.iabuf
, data
.data
, 4);
476 data_string_forget (&data
, MDL
);
477 have_requested_addr
= 1;
479 oc
= (struct option_cache
*)0;
481 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
.s_addr
, 4);
484 /* Find the lease that matches the address requested by the
487 subnet
= (struct subnet
*)0;
488 lease
= (struct lease
*)0;
489 if (find_subnet (&subnet
, cip
, MDL
))
490 find_lease (&lease
, packet
,
491 subnet
-> shared_network
, &ours
, 0, ip_lease
, MDL
);
493 if (lease
&& lease
-> client_hostname
) {
494 if ((strlen (lease
-> client_hostname
) <= 64) &&
495 db_printable((unsigned char *)lease
->client_hostname
))
496 s
= lease
-> client_hostname
;
498 s
= "Hostname Unsuitable for Printing";
502 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
503 DHO_DHCP_SERVER_IDENTIFIER
);
504 memset (&data
, 0, sizeof data
);
506 evaluate_option_cache (&data
, packet
, (struct lease
*)0,
507 (struct client_state
*)0,
508 packet
-> options
, (struct option_state
*)0,
509 &global_scope
, oc
, MDL
)) {
511 memcpy (sip
.iabuf
, data
.data
, 4);
512 data_string_forget (&data
, MDL
);
513 /* piaddr() should not return more than a 15 byte string.
516 sprintf (smbuf
, " (%s)", piaddr (sip
));
522 /* %Audit% This is log output. %2004.06.17,Safe%
523 * If we truncate we hope the user can get a hint from the log.
525 #if defined(DHCPv6) && defined(DHCP4o6)
526 if (dhcpv4_over_dhcpv6
&& (packet
->dhcp4o6_response
!= NULL
)) {
527 snprintf (msgbuf
, sizeof msgbuf
,
528 "DHCP4o6 DHCPREQUEST for %s%s from %s %s%s%svia %s",
530 (packet
-> raw
-> htype
531 ? print_hw_addr (packet
-> raw
-> htype
,
532 packet
-> raw
-> hlen
,
533 packet
-> raw
-> chaddr
)
535 ? print_hex_1(lease
->uid_len
, lease
->uid
, 60)
536 : "<no identifier>")),
537 s
? "(" : "", s
? s
: "", s
? ") " : "",
538 piaddr(packet
->client_addr
));
541 snprintf (msgbuf
, sizeof msgbuf
,
542 "DHCPREQUEST for %s%s from %s %s%s%svia %s",
544 (packet
-> raw
-> htype
545 ? print_hw_addr (packet
-> raw
-> htype
,
546 packet
-> raw
-> hlen
,
547 packet
-> raw
-> chaddr
)
549 ? print_hex_1(lease
->uid_len
, lease
->uid
, 60)
550 : "<no identifier>")),
551 s
? "(" : "", s
? s
: "", s
? ") " : "",
552 packet
-> raw
-> giaddr
.s_addr
553 ? inet_ntoa (packet
-> raw
-> giaddr
)
554 : packet
-> interface
-> name
);
556 #if defined (FAILOVER_PROTOCOL)
557 if (lease
&& lease
-> pool
&& lease
-> pool
-> failover_peer
) {
558 peer
= lease
-> pool
-> failover_peer
;
559 if (peer
-> service_state
== not_responding
||
560 peer
-> service_state
== service_startup
) {
561 log_info ("%s: not responding%s",
562 msgbuf
, peer
-> nrr
);
566 /* "load balance to peer" - is not done at all for request.
568 * If it's RENEWING, we are the only server to hear it, so
569 * we have to serve it. If it's REBINDING, it's out of
570 * communication with the other server, so there's no point
571 * in waiting to serve it. However, if the lease we're
572 * offering is not a free lease, then we may be the only
573 * server that can offer it, so we can't load balance if
574 * the lease isn't in the free or backup state. If it is
575 * in the free or backup state, then that state is what
576 * mandates one server or the other should perform the
577 * allocation, not the LBA...we know the peer cannot
578 * allocate a request for an address in our free state.
580 * So our only compass is lease_mine_to_reallocate(). This
581 * effects both load balancing, and a sanity-check that we
582 * are not going to try to allocate a lease that isn't ours.
584 if ((lease
-> binding_state
== FTS_FREE
||
585 lease
-> binding_state
== FTS_BACKUP
) &&
586 !lease_mine_to_reallocate (lease
)) {
587 log_debug ("%s: lease owned by peer", msgbuf
);
592 * If the lease is in a transitional state, we can't
593 * renew it unless we can rewind it to a non-transitional
594 * state (active, free, or backup). lease_mine_to_reallocate()
595 * checks for free/backup, so we only need to check for active.
597 if ((lease
->binding_state
== FTS_RELEASED
||
598 lease
->binding_state
== FTS_EXPIRED
) &&
599 lease
->rewind_binding_state
!= FTS_ACTIVE
&&
600 !lease_mine_to_reallocate(lease
)) {
601 log_debug("%s: lease in transition state %s", msgbuf
,
602 (lease
->binding_state
== FTS_RELEASED
)
603 ? "released" : "expired");
607 /* It's actually very unlikely that we'll ever get here,
608 but if we do, tell the client to stop using the lease,
609 because the administrator reset it. */
610 if (lease
-> binding_state
== FTS_RESET
&&
611 !lease_mine_to_reallocate (lease
)) {
612 log_debug ("%s: lease reset by administrator", msgbuf
);
613 nak_lease (packet
, &cip
, lease
->subnet
->group
);
617 /* If server-id-check is enabled, verify that the client's
618 * server source address (sip from incoming packet) is ours.
619 * To avoid problems with confused clients we do some sanity
620 * checks to verify sip's length and that it isn't all zeros.
621 * We then get the server id we would likely use for this
622 * packet and compare them. If they don't match it we assume
623 * we didn't send the offer and so we don't process the
625 if ((server_id_check
== 1) && (sip
.len
== 4) &&
626 (memcmp(sip
.iabuf
, "\0\0\0\0", sip
.len
) != 0)) {
628 struct option_state
*eval_options
= NULL
;
630 eval_network_statements(&eval_options
, packet
, NULL
);
631 get_server_source_address(&from
, eval_options
,
633 option_state_dereference (&eval_options
, MDL
);
634 if (memcmp(sip
.iabuf
, &from
, sip
.len
) != 0) {
635 log_debug("%s: not our server id", msgbuf
);
640 /* At this point it's possible that we will get a broadcast
641 DHCPREQUEST for a lease that we didn't offer, because
642 both we and the peer are in a position to offer it.
643 In that case, we probably shouldn't answer. In order
644 to not answer, we would have to compare the server
645 identifier sent by the client with the list of possible
646 server identifiers we can send, and if the client's
647 identifier isn't on the list, drop the DHCPREQUEST.
648 We aren't currently doing that for two reasons - first,
649 it's not clear that all clients do the right thing
650 with respect to sending the client identifier, which
651 could mean that we might simply not respond to a client
652 that is depending on us to respond. Secondly, we allow
653 the user to specify the server identifier to send, and
654 we don't enforce that the server identifier should be
655 one of our IP addresses. This is probably not a big
656 deal, but it's theoretically an issue.
658 The reason we care about this is that if both servers
659 send a DHCPACK to the DHCPREQUEST, they are then going
660 to send dueling BNDUPD messages, which could cause
661 trouble. I think it causes no harm, but it seems
664 peer
= (dhcp_failover_state_t
*)0;
667 /* If a client on a given network REQUESTs a lease on an
668 address on a different network, NAK it. If the Requested
669 Address option was used, the protocol says that it must
670 have been broadcast, so we can trust the source network
673 If ciaddr was specified and Requested Address was not, then
674 we really only know for sure what network a packet came from
675 if it came through a BOOTP gateway - if it came through an
676 IP router, we'll just have to assume that it's cool.
678 If we don't think we know where the packet came from, it
679 came through a gateway from an unknown network, so it's not
680 from a RENEWING client. If we recognize the network it
681 *thinks* it's on, we can NAK it even though we don't
682 recognize the network it's *actually* on; otherwise we just
685 We don't currently try to take advantage of access to the
686 raw packet, because it's not available on all platforms.
687 So a packet that was unicast to us through a router from a
688 RENEWING client is going to look exactly like a packet that
689 was broadcast to us from an INIT-REBOOT client.
691 Since we can't tell the difference between these two kinds
692 of packets, if the packet appears to have come in off the
693 local wire, we have to treat it as if it's a RENEWING
694 client. This means that we can't NAK a RENEWING client on
695 the local wire that has a bogus address. The good news is
696 that we won't ACK it either, so it should revert to INIT
697 state and send us a DHCPDISCOVER, which we *can* work with.
699 Because we can't detect that a RENEWING client is on the
700 wrong wire, it's going to sit there trying to renew until
701 it gets to the REBIND state, when we *can* NAK it because
702 the packet will get to us through a BOOTP gateway. We
703 shouldn't actually see DHCPREQUEST packets from RENEWING
704 clients on the wrong wire anyway, since their idea of their
705 local router will be wrong. In any case, the protocol
706 doesn't really allow us to NAK a DHCPREQUEST from a
707 RENEWING client, so we can punt on this issue. */
709 if (!packet
-> shared_network
||
710 (packet
-> raw
-> ciaddr
.s_addr
&&
711 packet
-> raw
-> giaddr
.s_addr
) ||
712 (have_requested_addr
&& !packet
-> raw
-> ciaddr
.s_addr
)) {
714 /* If we don't know where it came from but we do know
715 where it claims to have come from, it didn't come
717 if (!packet
-> shared_network
) {
718 if (subnet
&& subnet
-> group
-> authoritative
) {
719 log_info ("%s: wrong network.", msgbuf
);
720 nak_lease (packet
, &cip
, NULL
);
723 /* Otherwise, ignore it. */
724 log_info ("%s: ignored (%s).", msgbuf
,
726 ? "not authoritative" : "unknown subnet"));
730 /* If we do know where it came from and it asked for an
731 address that is not on that shared network, nak it. */
733 subnet_dereference (&subnet
, MDL
);
734 if (!find_grouped_subnet (&subnet
, packet
-> shared_network
,
736 if (packet
-> shared_network
-> group
-> authoritative
)
738 log_info ("%s: wrong network.", msgbuf
);
739 nak_lease (packet
, &cip
, NULL
);
742 log_info ("%s: ignored (not authoritative).", msgbuf
);
747 /* If the address the client asked for is ours, but it wasn't
748 available for the client, NAK it. */
749 if (!lease
&& ours
) {
750 log_info ("%s: lease %s unavailable.", msgbuf
, piaddr (cip
));
751 nak_lease (packet
, &cip
, (subnet
? subnet
->group
: NULL
));
755 /* Otherwise, send the lease to the client if we found one. */
757 ack_lease (packet
, lease
, DHCPACK
, 0, msgbuf
, ms_nulltp
,
758 (struct host_decl
*)0);
760 log_info ("%s: unknown lease %s.", msgbuf
, piaddr (cip
));
764 subnet_dereference (&subnet
, MDL
);
766 lease_dereference (&lease
, MDL
);
770 void dhcprelease (packet
, ms_nulltp
)
771 struct packet
*packet
;
774 struct lease
*lease
= (struct lease
*)0, *next
= (struct lease
*)0;
776 struct option_cache
*oc
;
777 struct data_string data
;
779 char msgbuf
[1024], cstr
[16]; /* XXX */
782 /* DHCPRELEASE must not specify address in requested-address
783 option, but old protocol specs weren't explicit about this,
785 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
786 DHO_DHCP_REQUESTED_ADDRESS
))) {
787 log_info ("DHCPRELEASE from %s specified requested-address.",
788 print_hw_addr (packet
-> raw
-> htype
,
789 packet
-> raw
-> hlen
,
790 packet
-> raw
-> chaddr
));
793 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
794 DHO_DHCP_CLIENT_IDENTIFIER
);
795 memset (&data
, 0, sizeof data
);
797 evaluate_option_cache (&data
, packet
, (struct lease
*)0,
798 (struct client_state
*)0,
799 packet
-> options
, (struct option_state
*)0,
800 &global_scope
, oc
, MDL
)) {
801 find_lease_by_uid (&lease
, data
.data
, data
.len
, MDL
);
802 data_string_forget (&data
, MDL
);
804 /* See if we can find a lease that matches the IP address
805 the client is claiming. */
808 lease_reference (&next
, lease
-> n_uid
, MDL
);
809 if (!memcmp (&packet
-> raw
-> ciaddr
,
810 lease
-> ip_addr
.iabuf
, 4)) {
813 lease_dereference (&lease
, MDL
);
815 lease_reference (&lease
, next
, MDL
);
816 lease_dereference (&next
, MDL
);
820 lease_dereference (&next
, MDL
);
823 /* The client is supposed to pass a valid client-identifier,
824 but the spec on this has changed historically, so try the
825 IP address in ciaddr if the client-identifier fails. */
828 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
, 4);
829 find_lease_by_ip_addr (&lease
, cip
, MDL
);
833 /* If the hardware address doesn't match, don't do the release. */
835 (lease
-> hardware_addr
.hlen
!= packet
-> raw
-> hlen
+ 1 ||
836 lease
-> hardware_addr
.hbuf
[0] != packet
-> raw
-> htype
||
837 memcmp (&lease
-> hardware_addr
.hbuf
[1],
838 packet
-> raw
-> chaddr
, packet
-> raw
-> hlen
)))
839 lease_dereference (&lease
, MDL
);
841 if (lease
&& lease
-> client_hostname
) {
842 if ((strlen (lease
-> client_hostname
) <= 64) &&
843 db_printable((unsigned char *)lease
->client_hostname
))
844 s
= lease
-> client_hostname
;
846 s
= "Hostname Unsuitable for Printing";
850 /* %Audit% Cannot exceed 16 bytes. %2004.06.17,Safe%
851 * We copy this out to stack because we actually want to log two
852 * inet_ntoa()'s in this message.
854 strncpy(cstr
, inet_ntoa (packet
-> raw
-> ciaddr
), 15);
857 /* %Audit% This is log output. %2004.06.17,Safe%
858 * If we truncate we hope the user can get a hint from the log.
860 #if defined(DHCPv6) && defined(DHCP4o6)
861 if (dhcpv4_over_dhcpv6
&& (packet
->dhcp4o6_response
!= NULL
)) {
862 snprintf (msgbuf
, sizeof msgbuf
,
863 "DHCP4o6 DHCPRELEASE of %s from %s %s%s%svia "
866 (packet
-> raw
-> htype
867 ? print_hw_addr (packet
-> raw
-> htype
,
868 packet
-> raw
-> hlen
,
869 packet
-> raw
-> chaddr
)
871 ? print_hex_1(lease
->uid_len
, lease
->uid
, 60)
872 : "<no identifier>")),
873 s
? "(" : "", s
? s
: "", s
? ") " : "",
874 piaddr(packet
->client_addr
),
875 lease
? "" : "not ");
878 snprintf (msgbuf
, sizeof msgbuf
,
879 "DHCPRELEASE of %s from %s %s%s%svia %s (%sfound)",
881 (packet
-> raw
-> htype
882 ? print_hw_addr (packet
-> raw
-> htype
,
883 packet
-> raw
-> hlen
,
884 packet
-> raw
-> chaddr
)
886 ? print_hex_1(lease
->uid_len
, lease
->uid
, 60)
887 : "<no identifier>")),
888 s
? "(" : "", s
? s
: "", s
? ") " : "",
889 packet
-> raw
-> giaddr
.s_addr
890 ? inet_ntoa (packet
-> raw
-> giaddr
)
891 : packet
-> interface
-> name
,
892 lease
? "" : "not ");
894 #if defined (FAILOVER_PROTOCOL)
895 if (lease
&& lease
-> pool
&& lease
-> pool
-> failover_peer
) {
896 dhcp_failover_state_t
*peer
= lease
-> pool
-> failover_peer
;
897 if (peer
-> service_state
== not_responding
||
898 peer
-> service_state
== service_startup
) {
899 log_info ("%s: ignored%s",
900 peer
-> name
, peer
-> nrr
);
904 /* DHCPRELEASE messages are unicast, so if the client
905 sent the DHCPRELEASE to us, it's not going to send it
906 to the peer. Not sure why this would happen, and
907 if it does happen I think we still have to change the
908 lease state, so that's what we're doing.
909 XXX See what it says in the draft about this. */
913 /* If we found a lease, release it. */
914 if (lease
&& lease
-> ends
> cur_time
) {
915 release_lease (lease
, packet
);
917 log_info ("%s", msgbuf
);
918 #if defined(FAILOVER_PROTOCOL)
922 lease_dereference (&lease
, MDL
);
925 void dhcpdecline (packet
, ms_nulltp
)
926 struct packet
*packet
;
929 struct lease
*lease
= (struct lease
*)0;
930 struct option_state
*options
= (struct option_state
*)0;
935 char msgbuf
[1024]; /* XXX */
937 struct option_cache
*oc
;
938 struct data_string data
;
940 /* DHCPDECLINE must specify address. */
941 if (!(oc
= lookup_option (&dhcp_universe
, packet
-> options
,
942 DHO_DHCP_REQUESTED_ADDRESS
)))
944 memset (&data
, 0, sizeof data
);
945 if (!evaluate_option_cache (&data
, packet
, (struct lease
*)0,
946 (struct client_state
*)0,
948 (struct option_state
*)0,
949 &global_scope
, oc
, MDL
))
953 memcpy (cip
.iabuf
, data
.data
, 4);
954 data_string_forget (&data
, MDL
);
955 find_lease_by_ip_addr (&lease
, cip
, MDL
);
957 if (lease
&& lease
-> client_hostname
) {
958 if ((strlen (lease
-> client_hostname
) <= 64) &&
959 db_printable((unsigned char *)lease
->client_hostname
))
960 s
= lease
-> client_hostname
;
962 s
= "Hostname Unsuitable for Printing";
966 /* %Audit% This is log output. %2004.06.17,Safe%
967 * If we truncate we hope the user can get a hint from the log.
969 #if defined(DHCPv6) && defined(DHCP4o6)
970 if (dhcpv4_over_dhcpv6
&& (packet
->dhcp4o6_response
!= NULL
)) {
971 snprintf (msgbuf
, sizeof msgbuf
,
972 "DHCP4o6 DHCPDECLINE of %s from %s %s%s%svia %s",
974 (packet
-> raw
-> htype
975 ? print_hw_addr (packet
-> raw
-> htype
,
976 packet
-> raw
-> hlen
,
977 packet
-> raw
-> chaddr
)
979 ? print_hex_1(lease
->uid_len
, lease
->uid
, 60)
980 : "<no identifier>")),
981 s
? "(" : "", s
? s
: "", s
? ") " : "",
982 piaddr(packet
->client_addr
));
985 snprintf (msgbuf
, sizeof msgbuf
,
986 "DHCPDECLINE of %s from %s %s%s%svia %s",
988 (packet
-> raw
-> htype
989 ? print_hw_addr (packet
-> raw
-> htype
,
990 packet
-> raw
-> hlen
,
991 packet
-> raw
-> chaddr
)
993 ? print_hex_1(lease
->uid_len
, lease
->uid
, 60)
994 : "<no identifier>")),
995 s
? "(" : "", s
? s
: "", s
? ") " : "",
996 packet
-> raw
-> giaddr
.s_addr
997 ? inet_ntoa (packet
-> raw
-> giaddr
)
998 : packet
-> interface
-> name
);
1000 option_state_allocate (&options
, MDL
);
1002 /* Execute statements in scope starting with the subnet scope. */
1004 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
1005 packet
->options
, options
,
1007 lease
->subnet
->group
,
1010 /* Execute statements in the class scopes. */
1011 for (i
= packet
-> class_count
; i
> 0; i
--) {
1012 execute_statements_in_scope
1013 (NULL
, packet
, NULL
, NULL
, packet
->options
, options
,
1014 &global_scope
, packet
->classes
[i
- 1]->group
,
1015 lease
? lease
->subnet
->group
: NULL
, NULL
);
1018 /* Drop the request if dhcpdeclines are being ignored. */
1019 oc
= lookup_option (&server_universe
, options
, SV_DECLINES
);
1021 evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
1022 (struct client_state
*)0,
1023 packet
-> options
, options
,
1024 &lease
-> scope
, oc
, MDL
)) {
1025 /* If we found a lease, mark it as unusable and complain. */
1027 #if defined (FAILOVER_PROTOCOL)
1028 if (lease
-> pool
&& lease
-> pool
-> failover_peer
) {
1029 dhcp_failover_state_t
*peer
=
1030 lease
-> pool
-> failover_peer
;
1031 if (peer
-> service_state
== not_responding
||
1032 peer
-> service_state
== service_startup
) {
1034 log_info ("%s: ignored%s",
1035 peer
-> name
, peer
-> nrr
);
1039 /* DHCPDECLINE messages are broadcast, so we can safely
1040 ignore the DHCPDECLINE if the peer has the lease.
1041 XXX Of course, at this point that information has been
1046 abandon_lease (lease
, "declined.");
1047 status
= "abandoned";
1049 status
= "not found";
1055 log_info ("%s: %s", msgbuf
, status
);
1057 #if defined(FAILOVER_PROTOCOL)
1061 option_state_dereference (&options
, MDL
);
1063 lease_dereference (&lease
, MDL
);
1066 void dhcpinform (packet
, ms_nulltp
)
1067 struct packet
*packet
;
1070 char msgbuf
[1024], *addr_type
;
1071 struct data_string d1
, prl
, fixed_addr
;
1072 struct option_cache
*oc
;
1073 struct option_state
*options
= NULL
;
1074 struct dhcp_packet raw
;
1075 struct packet outgoing
;
1076 unsigned char dhcpack
= DHCPACK
;
1077 struct subnet
*subnet
= NULL
;
1078 struct iaddr cip
, gip
, sip
;
1081 struct sockaddr_in to
;
1082 struct in_addr from
;
1083 isc_boolean_t zeroed_ciaddr
;
1084 struct interface_info
*interface
;
1085 int result
, h_m_client_ip
= 0;
1086 struct host_decl
*host
= NULL
, *hp
= NULL
, *h
;
1087 #if defined (DEBUG_INFORM_HOST)
1088 int h_w_fixed_addr
= 0;
1091 /* The client should set ciaddr to its IP address, but apparently
1092 it's common for clients not to do this, so we'll use their IP
1093 source address if they didn't set ciaddr. */
1094 if (!packet
->raw
->ciaddr
.s_addr
) {
1095 zeroed_ciaddr
= ISC_TRUE
;
1096 /* With DHCPv4-over-DHCPv6 it can be an IPv6 address
1097 so we check its length. */
1098 if (packet
->client_addr
.len
== 4) {
1100 memcpy(cip
.iabuf
, &packet
->client_addr
.iabuf
, 4);
1101 addr_type
= "source";
1104 memset(cip
.iabuf
, 0, 4);
1108 zeroed_ciaddr
= ISC_FALSE
;
1110 memcpy(cip
.iabuf
, &packet
->raw
->ciaddr
, 4);
1111 addr_type
= "client";
1114 memcpy(sip
.iabuf
, cip
.iabuf
, 4);
1116 if (packet
->raw
->giaddr
.s_addr
) {
1118 memcpy(gip
.iabuf
, &packet
->raw
->giaddr
, 4);
1119 if (zeroed_ciaddr
== ISC_TRUE
) {
1120 addr_type
= "relay";
1121 memcpy(sip
.iabuf
, gip
.iabuf
, 4);
1126 /* %Audit% This is log output. %2004.06.17,Safe%
1127 * If we truncate we hope the user can get a hint from the log.
1129 #if defined(DHCPv6) && defined(DHCP4o6)
1130 if (dhcpv4_over_dhcpv6
&& (packet
->dhcp4o6_response
!= NULL
)) {
1131 snprintf(msgbuf
, sizeof(msgbuf
),
1132 "DHCP4o6 DHCPINFORM from %s via %s",
1134 piaddr(packet
->client_addr
));
1137 snprintf(msgbuf
, sizeof(msgbuf
), "DHCPINFORM from %s via %s",
1139 packet
->raw
->giaddr
.s_addr
?
1140 inet_ntoa(packet
->raw
->giaddr
) :
1141 packet
->interface
->name
);
1143 /* If the IP source address is zero, don't respond. */
1144 if (!memcmp(cip
.iabuf
, "\0\0\0", 4)) {
1145 log_info("%s: ignored (null source address).", msgbuf
);
1149 /* Find the subnet that the client is on.
1150 * CC: Do the link selection / subnet selection
1153 option_state_allocate(&options
, MDL
);
1155 if ((oc
= lookup_option(&agent_universe
, packet
->options
,
1156 RAI_LINK_SELECT
)) == NULL
)
1157 oc
= lookup_option(&dhcp_universe
, packet
->options
,
1158 DHO_SUBNET_SELECTION
);
1160 memset(&d1
, 0, sizeof d1
);
1161 if (oc
&& evaluate_option_cache(&d1
, packet
, NULL
, NULL
,
1162 packet
->options
, NULL
,
1163 &global_scope
, oc
, MDL
)) {
1164 struct option_cache
*noc
= NULL
;
1167 log_info("%s: ignored (invalid subnet selection option).", msgbuf
);
1168 option_state_dereference(&options
, MDL
);
1172 memcpy(sip
.iabuf
, d1
.data
, 4);
1173 data_string_forget(&d1
, MDL
);
1175 /* Make a copy of the data. */
1176 if (option_cache_allocate(&noc
, MDL
)) {
1178 data_string_copy(&noc
->data
, &oc
->data
, MDL
);
1180 expression_reference(&noc
->expression
,
1181 oc
->expression
, MDL
);
1183 option_reference(&(noc
->option
), oc
->option
,
1186 save_option(&dhcp_universe
, options
, noc
);
1187 option_cache_dereference(&noc
, MDL
);
1189 if ((zeroed_ciaddr
== ISC_TRUE
) && (gip
.len
!= 0))
1190 addr_type
= "relay link select";
1192 addr_type
= "selected";
1195 find_subnet(&subnet
, sip
, MDL
);
1197 if (subnet
== NULL
) {
1198 log_info("%s: unknown subnet for %s address %s",
1199 msgbuf
, addr_type
, piaddr(sip
));
1200 option_state_dereference(&options
, MDL
);
1204 /* We don't respond to DHCPINFORM packets if we're not authoritative.
1205 It would be nice if a per-host value could override this, but
1206 there's overhead involved in checking this, so let's see how people
1208 if (!subnet
->group
->authoritative
) {
1210 log_info("%s: not authoritative for subnet %s",
1211 msgbuf
, piaddr (subnet
-> net
));
1213 log_info("If this DHCP server is authoritative for%s",
1215 log_info("please write an `authoritative;' directi%s",
1216 "ve either in the");
1217 log_info("subnet declaration or in some scope that%s",
1219 log_info("subnet declaration - for example, write %s",
1221 log_info("of the dhcpd.conf file.");
1225 subnet_dereference(&subnet
, MDL
);
1226 option_state_dereference(&options
, MDL
);
1230 memset(&outgoing
, 0, sizeof outgoing
);
1231 memset(&raw
, 0, sizeof raw
);
1232 outgoing
.raw
= &raw
;
1234 maybe_return_agent_options(packet
, options
);
1236 /* Execute statements network statements starting at the subnet level */
1237 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
1238 packet
->options
, options
,
1239 &global_scope
, subnet
->group
,
1242 /* If we have ciaddr, find its lease so we can find its pool. */
1243 if (zeroed_ciaddr
== ISC_FALSE
) {
1244 struct lease
* cip_lease
= NULL
;
1246 find_lease_by_ip_addr (&cip_lease
, cip
, MDL
);
1248 /* Overlay with pool options if ciaddr mapped to a lease. */
1250 if (cip_lease
->pool
&& cip_lease
->pool
->group
) {
1251 execute_statements_in_scope(
1252 NULL
, packet
, NULL
, NULL
,
1253 packet
->options
, options
,
1255 cip_lease
->pool
->group
,
1256 cip_lease
->pool
->shared_network
->group
,
1260 lease_dereference (&cip_lease
, MDL
);
1264 /* Execute statements in the class scopes. */
1265 for (i
= packet
->class_count
; i
> 0; i
--) {
1266 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
1267 packet
->options
, options
,
1269 packet
->classes
[i
- 1]->group
,
1275 * Process host declarations during DHCPINFORM,
1276 * Try to find a matching host declaration by cli ID or HW addr.
1278 * Look through the host decls for one that matches the
1279 * client identifer or the hardware address. The preference
1281 * client id with matching ip address
1282 * hardware address with matching ip address
1283 * client id without a ip fixed address
1284 * hardware address without a fixed ip address
1285 * If found, set host to use its option definitions.
1287 oc
= lookup_option(&dhcp_universe
, packet
->options
,
1288 DHO_DHCP_CLIENT_IDENTIFIER
);
1289 memset(&d1
, 0, sizeof(d1
));
1291 evaluate_option_cache(&d1
, packet
, NULL
, NULL
,
1292 packet
->options
, NULL
,
1293 &global_scope
, oc
, MDL
)) {
1294 find_hosts_by_uid(&hp
, d1
.data
, d1
.len
, MDL
);
1295 data_string_forget(&d1
, MDL
);
1297 #if defined (DEBUG_INFORM_HOST)
1299 log_debug ("dhcpinform: found host by ID "
1300 "-- checking fixed-address match");
1302 /* check if we have one with fixed-address
1303 * matching the client ip first */
1304 for (h
= hp
; !h_m_client_ip
&& h
; h
= h
->n_ipaddr
) {
1308 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
1309 if (!evaluate_option_cache (&fixed_addr
, NULL
,
1310 NULL
, NULL
, NULL
, NULL
,
1312 h
->fixed_addr
, MDL
))
1315 #if defined (DEBUG_INFORM_HOST)
1319 (i
+ cip
.len
) <= fixed_addr
.len
;
1321 if (memcmp(fixed_addr
.data
+ i
,
1322 cip
.iabuf
, cip
.len
) == 0) {
1323 #if defined (DEBUG_INFORM_HOST)
1324 log_debug ("dhcpinform: found "
1325 "host with matching "
1326 "fixed-address by ID");
1328 host_reference(&host
, h
, MDL
);
1333 data_string_forget(&fixed_addr
, MDL
);
1336 /* fallback to a host without fixed-address */
1337 for (h
= hp
; !host
&& h
; h
= h
->n_ipaddr
) {
1341 #if defined (DEBUG_INFORM_HOST)
1342 log_debug ("dhcpinform: found host "
1343 "without fixed-address by ID");
1345 host_reference(&host
, h
, MDL
);
1349 host_dereference (&hp
, MDL
);
1351 if (!host
|| !h_m_client_ip
) {
1352 find_hosts_by_haddr(&hp
, packet
->raw
->htype
,
1353 packet
->raw
->chaddr
,
1354 packet
->raw
->hlen
, MDL
);
1356 #if defined (DEBUG_INFORM_HOST)
1358 log_debug ("dhcpinform: found host by HW "
1359 "-- checking fixed-address match");
1362 /* check if we have one with fixed-address
1363 * matching the client ip first */
1364 for (h
= hp
; !h_m_client_ip
&& h
; h
= h
->n_ipaddr
) {
1368 memset (&fixed_addr
, 0, sizeof(fixed_addr
));
1369 if (!evaluate_option_cache (&fixed_addr
, NULL
,
1370 NULL
, NULL
, NULL
, NULL
,
1372 h
->fixed_addr
, MDL
))
1375 #if defined (DEBUG_INFORM_HOST)
1379 (i
+ cip
.len
) <= fixed_addr
.len
;
1381 if (memcmp(fixed_addr
.data
+ i
,
1382 cip
.iabuf
, cip
.len
) == 0) {
1383 #if defined (DEBUG_INFORM_HOST)
1384 log_debug ("dhcpinform: found "
1385 "host with matching "
1386 "fixed-address by HW");
1389 * Hmm.. we've found one
1390 * without IP by ID and now
1391 * (better) one with IP by HW.
1394 host_dereference(&host
, MDL
);
1395 host_reference(&host
, h
, MDL
);
1400 data_string_forget(&fixed_addr
, MDL
);
1402 /* fallback to a host without fixed-address */
1403 for (h
= hp
; !host
&& h
; h
= h
->n_ipaddr
) {
1407 #if defined (DEBUG_INFORM_HOST)
1408 log_debug ("dhcpinform: found host without "
1409 "fixed-address by HW");
1411 host_reference (&host
, h
, MDL
);
1416 host_dereference (&hp
, MDL
);
1419 #if defined (DEBUG_INFORM_HOST)
1420 /* Hmm..: what when there is a host with a fixed-address,
1421 * that matches by hw or id, but the fixed-addresses
1422 * didn't match client ip?
1424 if (h_w_fixed_addr
&& !h_m_client_ip
) {
1425 log_info ("dhcpinform: matching host with "
1426 "fixed-address different than "
1427 "client IP detected?!");
1431 /* If we have a host_decl structure, run the options
1432 * associated with its group. Whether the host decl
1433 * struct is old or not. */
1435 #if defined (DEBUG_INFORM_HOST)
1436 log_info ("dhcpinform: applying host (group) options");
1438 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
1439 packet
->options
, options
,
1440 &global_scope
, host
->group
,
1443 host_dereference (&host
, MDL
);
1446 /* CC: end of host entry processing.... */
1448 /* Figure out the filename. */
1449 memset (&d1
, 0, sizeof d1
);
1450 oc
= lookup_option (&server_universe
, options
, SV_FILENAME
);
1452 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1453 (struct client_state
*)0,
1454 packet
-> options
, (struct option_state
*)0,
1455 &global_scope
, oc
, MDL
)) {
1457 if (i
>= sizeof(raw
.file
)) {
1458 log_info("file name longer than packet field "
1459 "truncated - field: %lu name: %d %.*s",
1460 (unsigned long)sizeof(raw
.file
), i
,
1462 i
= sizeof(raw
.file
);
1465 memcpy (raw
.file
, d1
.data
, i
);
1466 data_string_forget (&d1
, MDL
);
1469 /* Choose a server name as above. */
1470 oc
= lookup_option (&server_universe
, options
, SV_SERVER_NAME
);
1472 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1473 (struct client_state
*)0,
1474 packet
-> options
, (struct option_state
*)0,
1475 &global_scope
, oc
, MDL
)) {
1477 if (i
>= sizeof(raw
.sname
)) {
1478 log_info("server name longer than packet field "
1479 "truncated - field: %lu name: %d %.*s",
1480 (unsigned long)sizeof(raw
.sname
), i
,
1482 i
= sizeof(raw
.sname
);
1485 memcpy (raw
.sname
, d1
.data
, i
);
1486 data_string_forget (&d1
, MDL
);
1489 /* Set a flag if this client is a lame Microsoft client that NUL
1490 terminates string options and expects us to do likewise. */
1492 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
1494 if (!oc
->expression
)
1495 nulltp
= oc
->flags
& OPTION_HAD_NULLS
;
1498 /* Put in DHCP-specific options. */
1499 i
= DHO_DHCP_MESSAGE_TYPE
;
1500 oc
= (struct option_cache
*)0;
1501 if (option_cache_allocate (&oc
, MDL
)) {
1502 if (make_const_data (&oc
-> expression
,
1503 &dhcpack
, 1, 0, 0, MDL
)) {
1504 option_code_hash_lookup(&oc
->option
,
1505 dhcp_universe
.code_hash
,
1507 save_option (&dhcp_universe
, options
, oc
);
1509 option_cache_dereference (&oc
, MDL
);
1512 get_server_source_address(&from
, options
, options
, packet
);
1514 /* Use the subnet mask from the subnet declaration if no other
1515 mask has been provided. */
1516 i
= DHO_SUBNET_MASK
;
1517 if (subnet
&& !lookup_option (&dhcp_universe
, options
, i
)) {
1518 oc
= (struct option_cache
*)0;
1519 if (option_cache_allocate (&oc
, MDL
)) {
1520 if (make_const_data (&oc
-> expression
,
1521 subnet
-> netmask
.iabuf
,
1522 subnet
-> netmask
.len
,
1524 option_code_hash_lookup(&oc
->option
,
1525 dhcp_universe
.code_hash
,
1527 save_option (&dhcp_universe
, options
, oc
);
1529 option_cache_dereference (&oc
, MDL
);
1533 /* If a site option space has been specified, use that for
1534 site option codes. */
1535 i
= SV_SITE_OPTION_SPACE
;
1536 if ((oc
= lookup_option (&server_universe
, options
, i
)) &&
1537 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1538 (struct client_state
*)0,
1539 packet
-> options
, options
,
1540 &global_scope
, oc
, MDL
)) {
1541 struct universe
*u
= (struct universe
*)0;
1543 if (!universe_hash_lookup (&u
, universe_hash
,
1544 (const char *)d1
.data
, d1
.len
,
1546 log_error ("unknown option space %s.", d1
.data
);
1547 option_state_dereference (&options
, MDL
);
1549 subnet_dereference (&subnet
, MDL
);
1553 options
-> site_universe
= u
-> index
;
1554 options
->site_code_min
= find_min_site_code(u
);
1555 data_string_forget (&d1
, MDL
);
1557 options
-> site_universe
= dhcp_universe
.index
;
1558 options
-> site_code_min
= 0; /* Trust me, it works. */
1561 memset (&prl
, 0, sizeof prl
);
1563 /* Use the parameter list from the scope if there is one. */
1564 oc
= lookup_option (&dhcp_universe
, options
,
1565 DHO_DHCP_PARAMETER_REQUEST_LIST
);
1567 /* Otherwise, if the client has provided a list of options
1568 that it wishes returned, use it to prioritize. Otherwise,
1569 prioritize based on the default priority list. */
1572 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
1573 DHO_DHCP_PARAMETER_REQUEST_LIST
);
1576 evaluate_option_cache (&prl
, packet
, (struct lease
*)0,
1577 (struct client_state
*)0,
1578 packet
-> options
, options
,
1579 &global_scope
, oc
, MDL
);
1582 dump_packet (packet
);
1583 dump_raw ((unsigned char *)packet
-> raw
, packet
-> packet_length
);
1586 log_info ("%s", msgbuf
);
1588 /* Figure out the address of the boot file server. */
1590 lookup_option (&server_universe
, options
, SV_NEXT_SERVER
))) {
1591 if (evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1592 (struct client_state
*)0,
1593 packet
-> options
, options
,
1594 &global_scope
, oc
, MDL
)) {
1595 /* If there was more than one answer,
1597 if (d1
.len
>= 4 && d1
.data
)
1598 memcpy (&raw
.siaddr
, d1
.data
, 4);
1599 data_string_forget (&d1
, MDL
);
1604 * Remove any time options, per section 3.4 RFC 2131
1606 delete_option(&dhcp_universe
, options
, DHO_DHCP_LEASE_TIME
);
1607 delete_option(&dhcp_universe
, options
, DHO_DHCP_RENEWAL_TIME
);
1608 delete_option(&dhcp_universe
, options
, DHO_DHCP_REBINDING_TIME
);
1610 /* Set up the option buffer... */
1611 outgoing
.packet_length
=
1612 cons_options (packet
, outgoing
.raw
, (struct lease
*)0,
1613 (struct client_state
*)0,
1614 0, packet
-> options
, options
, &global_scope
,
1616 prl
.len
? &prl
: (struct data_string
*)0,
1618 option_state_dereference (&options
, MDL
);
1619 data_string_forget (&prl
, MDL
);
1621 /* Make sure that the packet is at least as big as a BOOTP packet. */
1622 if (outgoing
.packet_length
< BOOTP_MIN_LEN
)
1623 outgoing
.packet_length
= BOOTP_MIN_LEN
;
1625 raw
.giaddr
= packet
-> raw
-> giaddr
;
1626 raw
.ciaddr
= packet
-> raw
-> ciaddr
;
1627 memcpy (raw
.chaddr
, packet
-> raw
-> chaddr
, sizeof raw
.chaddr
);
1628 raw
.hlen
= packet
-> raw
-> hlen
;
1629 raw
.htype
= packet
-> raw
-> htype
;
1631 raw
.xid
= packet
-> raw
-> xid
;
1632 raw
.secs
= packet
-> raw
-> secs
;
1633 raw
.flags
= packet
-> raw
-> flags
;
1634 raw
.hops
= packet
-> raw
-> hops
;
1638 dump_packet (&outgoing
);
1639 dump_raw ((unsigned char *)&raw
, outgoing
.packet_length
);
1642 #if defined(DHCPv6) && defined(DHCP4o6)
1643 if (dhcpv4_over_dhcpv6
&& (packet
->dhcp4o6_response
!= NULL
)) {
1644 /* Report what we're sending. */
1645 snprintf(msgbuf
, sizeof msgbuf
,
1646 "DHCP4o6 DHCPACK to %s (%s) via", piaddr(cip
),
1647 (packet
->raw
->htype
&& packet
->raw
->hlen
) ?
1648 print_hw_addr(packet
->raw
->htype
, packet
->raw
->hlen
,
1649 packet
->raw
->chaddr
) :
1650 "<no client hardware address>");
1651 log_info("%s %s", msgbuf
, piaddr(packet
->client_addr
));
1653 /* fill dhcp4o6_response */
1654 packet
->dhcp4o6_response
->len
= outgoing
.packet_length
;
1655 packet
->dhcp4o6_response
->buffer
= NULL
;
1656 if (!buffer_allocate(&packet
->dhcp4o6_response
->buffer
,
1657 outgoing
.packet_length
, MDL
)) {
1658 log_fatal("No memory to store DHCP4o6 reply.");
1660 packet
->dhcp4o6_response
->data
=
1661 packet
->dhcp4o6_response
->buffer
->data
;
1662 memcpy(packet
->dhcp4o6_response
->buffer
->data
,
1663 outgoing
.raw
, outgoing
.packet_length
);
1667 subnet_dereference (&subnet
, MDL
);
1672 /* Set up the common stuff... */
1673 to
.sin_family
= AF_INET
;
1675 to
.sin_len
= sizeof to
;
1677 memset (to
.sin_zero
, 0, sizeof to
.sin_zero
);
1679 /* RFC2131 states the server SHOULD unicast to ciaddr.
1680 * There are two wrinkles - relays, and when ciaddr is zero.
1681 * There's actually no mention of relays at all in rfc2131 in
1682 * regard to DHCPINFORM, except to say we might get packets from
1683 * clients via them. Note: relays unicast to clients to the
1684 * "yiaddr" address, which servers are forbidden to set when
1685 * answering an inform.
1687 * The solution: If ciaddr is zero, and giaddr is set, go via the
1688 * relay with the broadcast flag set to help the relay (with no
1689 * yiaddr and very likely no chaddr, it will have no idea where to
1692 * If the ciaddr is zero and giaddr is not set, go via the source
1693 * IP address (but you are permitted to barf on their shoes).
1695 * If ciaddr is not zero, send the packet there always.
1697 if (!raw
.ciaddr
.s_addr
&& gip
.len
) {
1698 memcpy(&to
.sin_addr
, gip
.iabuf
, 4);
1699 to
.sin_port
= local_port
;
1700 raw
.flags
|= htons(BOOTP_BROADCAST
);
1703 memcpy(&to
.sin_addr
, cip
.iabuf
, 4);
1704 to
.sin_port
= remote_port
;
1707 /* Report what we're sending. */
1708 snprintf(msgbuf
, sizeof msgbuf
, "DHCPACK to %s (%s) via", piaddr(cip
),
1709 (packet
->raw
->htype
&& packet
->raw
->hlen
) ?
1710 print_hw_addr(packet
->raw
->htype
, packet
->raw
->hlen
,
1711 packet
->raw
->chaddr
) :
1712 "<no client hardware address>");
1713 log_info("%s %s", msgbuf
, gip
.len
? piaddr(gip
) :
1714 packet
->interface
->name
);
1717 interface
= (fallback_interface
? fallback_interface
1718 : packet
-> interface
);
1719 result
= send_packet(interface
, &outgoing
, &raw
,
1720 outgoing
.packet_length
, from
, &to
, NULL
);
1722 log_error ("%s:%d: Failed to send %d byte long packet over %s "
1723 "interface.", MDL
, outgoing
.packet_length
,
1729 subnet_dereference (&subnet
, MDL
);
1733 * \brief Constructs and sends a DHCP Nak
1735 * In order to populate options such as dhcp-server-id and
1736 * dhcp-client-identifier, the function creates a temporary option cache
1737 * and evaluates options based on the packet's shared-network or the
1738 * network_group in its absence, as well as the packet->clasess (if any).
1740 * \param packet inbound packet received from the client
1741 * \param cip address requested by the client
1742 * \param network_group optional scope for use in setting up options
1744 void nak_lease (packet
, cip
, network_group
)
1745 struct packet
*packet
;
1747 struct group
*network_group
; /* scope to use for options */
1749 struct sockaddr_in to
;
1750 struct in_addr from
;
1752 struct dhcp_packet raw
;
1753 unsigned char nak
= DHCPNAK
;
1754 struct packet outgoing
;
1756 struct option_state
*options
= (struct option_state
*)0;
1757 struct option_cache
*oc
= (struct option_cache
*)0;
1758 struct option_state
*eval_options
= NULL
;
1760 option_state_allocate (&options
, MDL
);
1761 memset (&outgoing
, 0, sizeof outgoing
);
1762 memset (&raw
, 0, sizeof raw
);
1763 outgoing
.raw
= &raw
;
1765 /* Set DHCP_MESSAGE_TYPE to DHCPNAK */
1766 if (!option_cache_allocate (&oc
, MDL
)) {
1767 log_error ("No memory for DHCPNAK message type.");
1768 option_state_dereference (&options
, MDL
);
1771 if (!make_const_data (&oc
-> expression
, &nak
, sizeof nak
,
1773 log_error ("No memory for expr_const expression.");
1774 option_cache_dereference (&oc
, MDL
);
1775 option_state_dereference (&options
, MDL
);
1778 i
= DHO_DHCP_MESSAGE_TYPE
;
1779 option_code_hash_lookup(&oc
->option
, dhcp_universe
.code_hash
,
1781 save_option (&dhcp_universe
, options
, oc
);
1782 option_cache_dereference (&oc
, MDL
);
1784 /* Set DHCP_MESSAGE to whatever the message is */
1785 if (!option_cache_allocate (&oc
, MDL
)) {
1786 log_error ("No memory for DHCPNAK message type.");
1787 option_state_dereference (&options
, MDL
);
1790 if (!make_const_data (&oc
-> expression
,
1791 (unsigned char *)dhcp_message
,
1792 strlen (dhcp_message
), 1, 0, MDL
)) {
1793 log_error ("No memory for expr_const expression.");
1794 option_cache_dereference (&oc
, MDL
);
1795 option_state_dereference (&options
, MDL
);
1798 i
= DHO_DHCP_MESSAGE
;
1799 option_code_hash_lookup(&oc
->option
, dhcp_universe
.code_hash
,
1801 save_option (&dhcp_universe
, options
, oc
);
1802 option_cache_dereference (&oc
, MDL
);
1804 /* Setup the options at the global and subnet scopes. These
1805 * may be used to locate sever id option if enabled as well
1806 * for echo-client-id further on. (This allocates eval_options). */
1807 eval_network_statements(&eval_options
, packet
, network_group
);
1809 #if defined(SERVER_ID_FOR_NAK)
1810 /* Pass in the evaluated options so they can be searched for
1811 * server-id, otherwise source address comes from the interface
1813 get_server_source_address(&from
, eval_options
, options
, packet
);
1815 /* Get server source address from the interface address */
1816 get_server_source_address(&from
, NULL
, options
, packet
);
1817 #endif /* if defined(SERVER_ID_FOR_NAK) */
1819 /* If there were agent options in the incoming packet, return
1820 * them. We do not check giaddr to detect the presence of a
1821 * relay, as this excludes "l2" relay agents which have no
1824 if (packet
->options
->universe_count
> agent_universe
.index
&&
1825 packet
->options
->universes
[agent_universe
.index
]) {
1826 option_chain_head_reference
1827 ((struct option_chain_head
**)
1828 &(options
-> universes
[agent_universe
.index
]),
1829 (struct option_chain_head
*)
1830 packet
-> options
-> universes
[agent_universe
.index
],
1834 /* echo-client-id can specified at the class level so add class-scoped
1835 * options into eval_options. */
1836 for (i
= packet
->class_count
; i
> 0; i
--) {
1837 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
1838 packet
->options
, eval_options
,
1840 packet
->classes
[i
- 1]->group
,
1844 /* Echo client id if we received and it's enabled */
1845 echo_client_id(packet
, NULL
, eval_options
, options
);
1846 option_state_dereference (&eval_options
, MDL
);
1848 /* Do not use the client's requested parameter list. */
1849 delete_option (&dhcp_universe
, packet
-> options
,
1850 DHO_DHCP_PARAMETER_REQUEST_LIST
);
1852 /* Set up the option buffer... */
1853 outgoing
.packet_length
=
1854 cons_options (packet
, outgoing
.raw
, (struct lease
*)0,
1855 (struct client_state
*)0,
1856 0, packet
-> options
, options
, &global_scope
,
1857 0, 0, 0, (struct data_string
*)0, (char *)0);
1858 option_state_dereference (&options
, MDL
);
1860 /* memset (&raw.ciaddr, 0, sizeof raw.ciaddr);*/
1861 raw
.giaddr
= packet
-> raw
-> giaddr
;
1862 memcpy (raw
.chaddr
, packet
-> raw
-> chaddr
, sizeof raw
.chaddr
);
1863 raw
.hlen
= packet
-> raw
-> hlen
;
1864 raw
.htype
= packet
-> raw
-> htype
;
1866 raw
.xid
= packet
-> raw
-> xid
;
1867 raw
.secs
= packet
-> raw
-> secs
;
1868 raw
.flags
= packet
-> raw
-> flags
| htons (BOOTP_BROADCAST
);
1869 raw
.hops
= packet
-> raw
-> hops
;
1872 /* Make sure that the packet is at least as big as a BOOTP packet. */
1873 if (outgoing
.packet_length
< BOOTP_MIN_LEN
)
1874 outgoing
.packet_length
= BOOTP_MIN_LEN
;
1876 /* Report what we're sending... */
1877 #if defined(DHCPv6) && defined(DHCP4o6)
1878 if (dhcpv4_over_dhcpv6
&& (packet
->dhcp4o6_response
!= NULL
)) {
1879 log_info ("DHCP4o6 DHCPNAK on %s to %s via %s",
1881 print_hw_addr (packet
-> raw
-> htype
,
1882 packet
-> raw
-> hlen
,
1883 packet
-> raw
-> chaddr
),
1884 piaddr(packet
->client_addr
));
1887 log_info ("DHCPNAK on %s to %s via %s",
1889 print_hw_addr (packet
-> raw
-> htype
,
1890 packet
-> raw
-> hlen
,
1891 packet
-> raw
-> chaddr
),
1892 packet
-> raw
-> giaddr
.s_addr
1893 ? inet_ntoa (packet
-> raw
-> giaddr
)
1894 : packet
-> interface
-> name
);
1897 dump_packet (packet
);
1898 dump_raw ((unsigned char *)packet
-> raw
, packet
-> packet_length
);
1899 dump_packet (&outgoing
);
1900 dump_raw ((unsigned char *)&raw
, outgoing
.packet_length
);
1903 #if defined(DHCPv6) && defined(DHCP4o6)
1904 if (dhcpv4_over_dhcpv6
&& (packet
->dhcp4o6_response
!= NULL
)) {
1905 /* fill dhcp4o6_response */
1906 packet
->dhcp4o6_response
->len
= outgoing
.packet_length
;
1907 packet
->dhcp4o6_response
->buffer
= NULL
;
1908 if (!buffer_allocate(&packet
->dhcp4o6_response
->buffer
,
1909 outgoing
.packet_length
, MDL
)) {
1910 log_fatal("No memory to store DHCP4o6 reply.");
1912 packet
->dhcp4o6_response
->data
=
1913 packet
->dhcp4o6_response
->buffer
->data
;
1914 memcpy(packet
->dhcp4o6_response
->buffer
->data
,
1915 outgoing
.raw
, outgoing
.packet_length
);
1920 /* Set up the common stuff... */
1921 to
.sin_family
= AF_INET
;
1923 to
.sin_len
= sizeof to
;
1925 memset (to
.sin_zero
, 0, sizeof to
.sin_zero
);
1927 /* If this was gatewayed, send it back to the gateway.
1928 Otherwise, broadcast it on the local network. */
1929 if (raw
.giaddr
.s_addr
) {
1930 to
.sin_addr
= raw
.giaddr
;
1931 if (raw
.giaddr
.s_addr
!= htonl (INADDR_LOOPBACK
))
1932 to
.sin_port
= local_port
;
1934 to
.sin_port
= remote_port
; /* for testing. */
1936 if (fallback_interface
) {
1937 result
= send_packet(fallback_interface
, packet
, &raw
,
1938 outgoing
.packet_length
, from
, &to
,
1941 log_error ("%s:%d: Failed to send %d byte long "
1942 "packet over %s interface.", MDL
,
1943 outgoing
.packet_length
,
1944 fallback_interface
->name
);
1950 to
.sin_addr
= limited_broadcast
;
1951 to
.sin_port
= remote_port
;
1955 result
= send_packet(packet
->interface
, packet
, &raw
,
1956 outgoing
.packet_length
, from
, &to
, NULL
);
1958 log_error ("%s:%d: Failed to send %d byte long packet over %s "
1959 "interface.", MDL
, outgoing
.packet_length
,
1960 packet
->interface
->name
);
1966 * \brief Adds a dhcp-client-id option to a set of options
1967 * Given a set of input options, it searches for echo-client-id. If it is
1968 * defined and enabled, the given packet is searched for dhcp-client-id. If
1969 * the option is found it is replicated into the given set of output options.
1970 * This allows us to provide compliance with RFC 6842. It is called when we ack
1971 * or nak a lease. In the latter case we may or may not have created the
1972 * requisite scope to lookup echo-client-id.
1974 * Note the flag packet.sv_echo_client_id is set to reflect the configuration
1975 * option. This bypases inaccessiblity of server_universe in cons_options()
1976 * which must amend the PRL (when not empty) if echoing is enabled.
1978 * \param packet inbound packet received from the client
1979 * \param lease lease associated with this client (if one)
1980 * \param in_options options in which to search for echo-client-id
1981 * \param out_options options to which to save the client-id
1983 void echo_client_id(packet
, lease
, in_options
, out_options
)
1984 struct packet
*packet
;
1985 struct lease
*lease
;
1986 struct option_state
*in_options
;
1987 struct option_state
*out_options
;
1989 struct option_cache
*oc
;
1992 /* Check if echo-client-id is enabled */
1993 oc
= lookup_option(&server_universe
, in_options
, SV_ECHO_CLIENT_ID
);
1994 if (oc
&& evaluate_boolean_option_cache(&ignorep
, packet
, lease
,
1995 NULL
, packet
->options
,
1997 (lease
? &lease
->scope
: NULL
),
1999 struct data_string client_id
;
2000 unsigned int opcode
= DHO_DHCP_CLIENT_IDENTIFIER
;
2002 /* Save knowledge that echo is enabled to the packet */
2003 packet
->sv_echo_client_id
= ISC_TRUE
;
2005 /* Now see if inbound packet contains client-id */
2006 oc
= lookup_option(&dhcp_universe
, packet
->options
, opcode
);
2007 memset(&client_id
, 0, sizeof client_id
);
2008 if (oc
&& evaluate_option_cache(&client_id
,
2010 packet
->options
, NULL
,
2011 (lease
? &lease
->scope
: NULL
),
2013 /* Packet contained client-id, add it to out_options. */
2015 if (option_cache_allocate(&oc
, MDL
)) {
2016 if (make_const_data(&oc
->expression
,
2020 option_code_hash_lookup(&oc
->option
,
2025 save_option(&dhcp_universe
,
2028 option_cache_dereference(&oc
, MDL
);
2034 void check_pool_threshold (packet
, lease
, state
)
2035 struct packet
*packet
;
2036 struct lease
*lease
;
2037 struct lease_state
*state
;
2041 struct pool
*pool
= lease
->pool
;
2042 int used
, count
, high_threshold
, poolhigh
= 0, poollow
= 0;
2043 char *shared_name
= "no name";
2048 /* get a pointer to the name if we have one */
2049 if ((pool
->shared_network
!= NULL
) &&
2050 (pool
->shared_network
->name
!= NULL
)) {
2051 shared_name
= pool
->shared_network
->name
;
2054 count
= pool
->lease_count
;
2055 used
= count
- (pool
->free_leases
+ pool
->backup_leases
);
2057 /* The logged flag indicates if we have already crossed the high
2058 * threshold and emitted a log message. If it is set we check to
2059 * see if we have re-crossed the low threshold and need to reset
2060 * things. When we cross the high threshold we determine what
2061 * the low threshold is and save it into the low_threshold value.
2062 * When we cross that threshold we reset the logged flag and
2063 * the low_threshold to 0 which allows the high threshold message
2064 * to be emitted once again.
2065 * if we haven't recrossed the boundry we don't need to do anything.
2067 if (pool
->logged
!=0) {
2068 if (used
<= pool
->low_threshold
) {
2069 pool
->low_threshold
= 0;
2071 log_error("Pool threshold reset - shared subnet: %s; "
2072 "address: %s; low threshold %d/%d.",
2073 shared_name
, piaddr(lease
->ip_addr
),
2079 /* find the high threshold */
2080 if (get_option_int(&poolhigh
, &server_universe
, packet
, lease
, NULL
,
2081 packet
->options
, state
->options
, state
->options
,
2082 &lease
->scope
, SV_LOG_THRESHOLD_HIGH
, MDL
) == 0) {
2083 /* no threshold bail out */
2087 /* We do have a threshold for this pool, see if its valid */
2088 if ((poolhigh
<= 0) || (poolhigh
> 100)) {
2093 /* we have a valid value, have we exceeded it */
2094 high_threshold
= FIND_PERCENT(count
, poolhigh
);
2095 if (used
< high_threshold
) {
2096 /* nope, no more to do */
2100 /* we've exceeded it, output a message */
2101 log_error("Pool threshold exceeded - shared subnet: %s; "
2102 "address: %s; high threshold %d%% %d/%d.",
2103 shared_name
, piaddr(lease
->ip_addr
),
2104 poolhigh
, used
, count
);
2106 /* handle the low threshold now, if we don't
2107 * have a valid one we default to 0. */
2108 if ((get_option_int(&poollow
, &server_universe
, packet
, lease
, NULL
,
2109 packet
->options
, state
->options
, state
->options
,
2110 &lease
->scope
, SV_LOG_THRESHOLD_LOW
, MDL
) == 0) ||
2116 * If the low theshold is higher than the high threshold we continue to log
2117 * If it isn't then we set the flag saying we already logged and determine
2118 * what the reset threshold is.
2120 if (poollow
< poolhigh
) {
2122 pool
->low_threshold
= FIND_PERCENT(count
, poollow
);
2126 void ack_lease (packet
, lease
, offer
, when
, msg
, ms_nulltp
, hp
)
2127 struct packet
*packet
;
2128 struct lease
*lease
;
2133 struct host_decl
*hp
;
2136 struct lease_state
*state
;
2138 struct host_decl
*host
= (struct host_decl
*)0;
2140 TIME offered_lease_time
;
2141 struct data_string d1
;
2142 TIME min_lease_time
;
2143 TIME max_lease_time
;
2144 TIME default_lease_time
;
2145 struct option_cache
*oc
;
2146 isc_result_t result
;
2149 struct in_addr from
;
2150 TIME remaining_time
;
2152 #if defined(DELAYED_ACK) && !defined(DHCP4o6)
2153 /* By default we don't do the enqueue */
2154 isc_boolean_t enqueue
= ISC_FALSE
;
2156 int use_old_lease
= 0;
2163 /* If we're already acking this lease, don't do it again. */
2167 /* Save original cltt for comparison later. */
2168 lease_cltt
= lease
->cltt
;
2170 /* If the lease carries a host record, remember it. */
2172 host_reference (&host
, hp
, MDL
);
2173 else if (lease
-> host
)
2174 host_reference (&host
, lease
-> host
, MDL
);
2176 /* Allocate a lease state structure... */
2177 state
= new_lease_state (MDL
);
2179 log_fatal ("unable to allocate lease state!");
2180 state
-> got_requested_address
= packet
-> got_requested_address
;
2181 shared_network_reference (&state
-> shared_network
,
2182 packet
-> interface
-> shared_network
, MDL
);
2184 /* See if we got a server identifier option. */
2185 if (lookup_option (&dhcp_universe
,
2186 packet
-> options
, DHO_DHCP_SERVER_IDENTIFIER
))
2187 state
-> got_server_identifier
= 1;
2189 maybe_return_agent_options(packet
, state
->options
);
2191 /* If we are offering a lease that is still currently valid, preserve
2192 the events. We need to do this because if the client does not
2193 REQUEST our offer, it will expire in 2 minutes, overriding the
2194 expire time in the currently in force lease. We want the expire
2195 events to be executed at that point. */
2196 if (lease
->ends
<= cur_time
&& offer
!= DHCPOFFER
) {
2197 /* Get rid of any old expiry or release statements - by
2198 executing the statements below, we will be inserting new
2199 ones if there are any to insert. */
2200 if (lease
->on_star
.on_expiry
)
2201 executable_statement_dereference
2202 (&lease
->on_star
.on_expiry
, MDL
);
2203 if (lease
->on_star
.on_commit
)
2204 executable_statement_dereference
2205 (&lease
->on_star
.on_commit
, MDL
);
2206 if (lease
->on_star
.on_release
)
2207 executable_statement_dereference
2208 (&lease
->on_star
.on_release
, MDL
);
2211 /* Execute statements in scope starting with the subnet scope. */
2212 execute_statements_in_scope (NULL
, packet
, lease
,
2213 NULL
, packet
->options
,
2214 state
->options
, &lease
->scope
,
2215 lease
->subnet
->group
, NULL
, NULL
);
2217 /* If the lease is from a pool, run the pool scope. */
2219 (execute_statements_in_scope(NULL
, packet
, lease
, NULL
,
2220 packet
->options
, state
->options
,
2221 &lease
->scope
, lease
->pool
->group
,
2223 shared_network
->group
,
2226 /* Execute statements from class scopes. */
2227 for (i
= packet
-> class_count
; i
> 0; i
--) {
2228 execute_statements_in_scope(NULL
, packet
, lease
, NULL
,
2229 packet
->options
, state
->options
,
2231 packet
->classes
[i
- 1]->group
,
2232 (lease
->pool
? lease
->pool
->group
2233 : lease
->subnet
->group
),
2237 /* See if the client is only supposed to have one lease at a time,
2238 and if so, find its other leases and release them. We can only
2239 do this on DHCPREQUEST. It's a little weird to do this before
2240 looking at permissions, because the client might not actually
2241 _get_ a lease after we've done the permission check, but the
2242 assumption for this option is that the client has exactly one
2243 network interface, and will only ever remember one lease. So
2244 if it sends a DHCPREQUEST, and doesn't get the lease, it's already
2245 forgotten about its old lease, so we can too. */
2246 if (packet
-> packet_type
== DHCPREQUEST
&&
2247 (oc
= lookup_option (&server_universe
, state
-> options
,
2248 SV_ONE_LEASE_PER_CLIENT
)) &&
2249 evaluate_boolean_option_cache (&ignorep
,
2251 (struct client_state
*)0,
2253 state
-> options
, &lease
-> scope
,
2256 if (lease
-> uid_len
) {
2258 seek
= (struct lease
*)0;
2259 find_lease_by_uid (&seek
, lease
-> uid
,
2260 lease
-> uid_len
, MDL
);
2263 if (seek
== lease
&& !seek
-> n_uid
) {
2264 lease_dereference (&seek
, MDL
);
2267 next
= (struct lease
*)0;
2269 /* Don't release expired leases, and don't
2270 release the lease we're going to assign. */
2271 next
= (struct lease
*)0;
2274 lease_reference (&next
, seek
-> n_uid
, MDL
);
2275 if (seek
!= lease
&&
2276 seek
-> binding_state
!= FTS_RELEASED
&&
2277 seek
-> binding_state
!= FTS_EXPIRED
&&
2278 seek
-> binding_state
!= FTS_RESET
&&
2279 seek
-> binding_state
!= FTS_FREE
&&
2280 seek
-> binding_state
!= FTS_BACKUP
)
2282 lease_dereference (&seek
, MDL
);
2284 lease_reference (&seek
, next
, MDL
);
2285 lease_dereference (&next
, MDL
);
2289 lease_dereference (&next
, MDL
);
2291 release_lease (seek
, packet
);
2292 lease_dereference (&seek
, MDL
);
2297 if (!lease
-> uid_len
||
2299 !host
-> client_identifier
.len
&&
2300 (oc
= lookup_option (&server_universe
, state
-> options
,
2302 !evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
2303 (struct client_state
*)0,
2309 seek
= (struct lease
*)0;
2310 find_lease_by_hw_addr
2311 (&seek
, lease
-> hardware_addr
.hbuf
,
2312 lease
-> hardware_addr
.hlen
, MDL
);
2315 if (seek
== lease
&& !seek
-> n_hw
) {
2316 lease_dereference (&seek
, MDL
);
2319 next
= (struct lease
*)0;
2322 lease_reference (&next
, seek
-> n_hw
, MDL
);
2323 if (seek
!= lease
&&
2324 seek
-> binding_state
!= FTS_RELEASED
&&
2325 seek
-> binding_state
!= FTS_EXPIRED
&&
2326 seek
-> binding_state
!= FTS_RESET
&&
2327 seek
-> binding_state
!= FTS_FREE
&&
2328 seek
-> binding_state
!= FTS_BACKUP
)
2330 lease_dereference (&seek
, MDL
);
2332 lease_reference (&seek
, next
, MDL
);
2333 lease_dereference (&next
, MDL
);
2337 lease_dereference (&next
, MDL
);
2339 release_lease (seek
, packet
);
2340 lease_dereference (&seek
, MDL
);
2348 /* Make sure this packet satisfies the configured minimum
2349 number of seconds. */
2350 memset (&d1
, 0, sizeof d1
);
2351 if (offer
== DHCPOFFER
&&
2352 (oc
= lookup_option (&server_universe
, state
-> options
,
2354 if (evaluate_option_cache (&d1
, packet
, lease
,
2355 (struct client_state
*)0,
2356 packet
-> options
, state
-> options
,
2357 &lease
-> scope
, oc
, MDL
)) {
2359 ntohs (packet
-> raw
-> secs
) < d1
.data
[0]) {
2360 log_info("%s: configured min-secs value (%d) "
2361 "is greater than secs field (%d). "
2362 "message dropped.", msg
, d1
.data
[0],
2363 ntohs(packet
->raw
->secs
));
2364 data_string_forget (&d1
, MDL
);
2365 free_lease_state (state
, MDL
);
2367 host_dereference (&host
, MDL
);
2370 data_string_forget (&d1
, MDL
);
2374 /* Try to find a matching host declaration for this lease.
2377 struct host_decl
*hp
= (struct host_decl
*)0;
2378 struct host_decl
*h
;
2380 /* Try to find a host_decl that matches the client
2381 identifier or hardware address on the packet, and
2382 has no fixed IP address. If there is one, hang
2383 it off the lease so that its option definitions
2385 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
2386 DHO_DHCP_CLIENT_IDENTIFIER
);
2388 evaluate_option_cache (&d1
, packet
, lease
,
2389 (struct client_state
*)0,
2390 packet
-> options
, state
-> options
,
2391 &lease
-> scope
, oc
, MDL
)) {
2392 find_hosts_by_uid (&hp
, d1
.data
, d1
.len
, MDL
);
2393 data_string_forget (&d1
, MDL
);
2394 for (h
= hp
; h
; h
= h
-> n_ipaddr
) {
2395 if (!h
-> fixed_addr
)
2399 host_reference (&host
, h
, MDL
);
2401 host_dereference(&hp
, MDL
);
2404 find_hosts_by_haddr (&hp
,
2405 packet
-> raw
-> htype
,
2406 packet
-> raw
-> chaddr
,
2407 packet
-> raw
-> hlen
,
2409 for (h
= hp
; h
; h
= h
-> n_ipaddr
) {
2410 if (!h
-> fixed_addr
)
2414 host_reference (&host
, h
, MDL
);
2416 host_dereference(&hp
, MDL
);
2419 find_hosts_by_option(&hp
, packet
,
2420 packet
->options
, MDL
);
2421 for (h
= hp
; h
; h
= h
-> n_ipaddr
) {
2422 if (!h
-> fixed_addr
)
2426 host_reference (&host
, h
, MDL
);
2428 host_dereference(&hp
, MDL
);
2432 /* If we have a host_decl structure, run the options associated
2433 with its group. Whether the host decl struct is old or not. */
2435 execute_statements_in_scope (NULL
, packet
, lease
, NULL
,
2436 packet
->options
, state
->options
,
2437 &lease
->scope
, host
->group
,
2439 ? lease
->pool
->group
2440 : lease
->subnet
->group
),
2443 /* Drop the request if it's not allowed for this client. By
2444 default, unknown clients are allowed. */
2446 (oc
= lookup_option (&server_universe
, state
-> options
,
2447 SV_BOOT_UNKNOWN_CLIENTS
)) &&
2448 !evaluate_boolean_option_cache (&ignorep
,
2450 (struct client_state
*)0,
2453 &lease
-> scope
, oc
, MDL
)) {
2455 log_info ("%s: unknown client", msg
);
2456 free_lease_state (state
, MDL
);
2458 host_dereference (&host
, MDL
);
2462 /* Drop the request if it's not allowed for this client. */
2464 (oc
= lookup_option (&server_universe
, state
-> options
,
2466 !evaluate_boolean_option_cache (&ignorep
,
2468 (struct client_state
*)0,
2471 &lease
-> scope
, oc
, MDL
)) {
2473 log_info ("%s: bootp disallowed", msg
);
2474 free_lease_state (state
, MDL
);
2476 host_dereference (&host
, MDL
);
2480 /* Drop the request if booting is specifically denied. */
2481 oc
= lookup_option (&server_universe
, state
-> options
,
2484 !evaluate_boolean_option_cache (&ignorep
,
2486 (struct client_state
*)0,
2489 &lease
-> scope
, oc
, MDL
)) {
2491 log_info ("%s: booting disallowed", msg
);
2492 free_lease_state (state
, MDL
);
2494 host_dereference (&host
, MDL
);
2498 /* If we are configured to do per-class billing, do it. */
2499 if (have_billing_classes
&& !(lease
-> flags
& STATIC_LEASE
)) {
2500 /* See if the lease is currently being billed to a
2501 class, and if so, whether or not it can continue to
2502 be billed to that class. */
2503 if (lease
-> billing_class
) {
2504 for (i
= 0; i
< packet
-> class_count
; i
++)
2505 if (packet
-> classes
[i
] ==
2506 lease
-> billing_class
)
2508 if (i
== packet
-> class_count
) {
2509 unbill_class(lease
);
2510 /* Active lease billing change negates reuse */
2511 if (lease
->binding_state
== FTS_ACTIVE
) {
2512 lease
->cannot_reuse
= 1;
2517 /* If we don't have an active billing, see if we need
2518 one, and if we do, try to do so. */
2519 if (lease
->billing_class
== NULL
) {
2523 for (i
= 0; i
< packet
->class_count
; i
++) {
2524 struct class *billclass
, *subclass
;
2526 billclass
= packet
->classes
[i
];
2527 if (billclass
->lease_limit
) {
2529 if (bill_class(lease
, billclass
))
2532 subclass
= billclass
->superclass
;
2533 if (subclass
== NULL
)
2534 cname
= subclass
->name
;
2536 cname
= billclass
->name
;
2539 if (bill
!= 0 && i
== packet
->class_count
) {
2540 log_info("%s: no available billing: lease "
2541 "limit reached in all matching "
2542 "classes (last: '%s')", msg
, cname
);
2543 free_lease_state(state
, MDL
);
2545 host_dereference(&host
, MDL
);
2550 * If this is an offer, undo the billing. We go
2551 * through all the steps above to bill a class so
2552 * we can hit the 'no available billing' mark and
2553 * abort without offering. But it just doesn't make
2554 * sense to permanently bill a class for a non-active
2555 * lease. This means on REQUEST, we will bill this
2556 * lease again (if there is a REQUEST).
2558 if (offer
== DHCPOFFER
&&
2559 lease
->billing_class
!= NULL
&&
2560 lease
->binding_state
!= FTS_ACTIVE
)
2561 unbill_class(lease
);
2563 /* Lease billing change negates reuse */
2564 if (lease
->billing_class
!= NULL
) {
2565 lease
->cannot_reuse
= 1;
2570 /* Figure out the filename. */
2571 oc
= lookup_option (&server_universe
, state
-> options
, SV_FILENAME
);
2573 evaluate_option_cache (&state
-> filename
, packet
, lease
,
2574 (struct client_state
*)0,
2575 packet
-> options
, state
-> options
,
2576 &lease
-> scope
, oc
, MDL
);
2578 /* Choose a server name as above. */
2579 oc
= lookup_option (&server_universe
, state
-> options
,
2582 evaluate_option_cache (&state
-> server_name
, packet
, lease
,
2583 (struct client_state
*)0,
2584 packet
-> options
, state
-> options
,
2585 &lease
-> scope
, oc
, MDL
);
2587 /* At this point, we have a lease that we can offer the client.
2588 Now we construct a lease structure that contains what we want,
2589 and call supersede_lease to do the right thing with it. */
2590 lt
= (struct lease
*)0;
2591 result
= lease_allocate (<
, MDL
);
2592 if (result
!= ISC_R_SUCCESS
) {
2593 log_info ("%s: can't allocate temporary lease structure: %s",
2594 msg
, isc_result_totext (result
));
2595 free_lease_state (state
, MDL
);
2597 host_dereference (&host
, MDL
);
2601 /* Use the ip address of the lease that we finally found in
2603 lt
-> ip_addr
= lease
-> ip_addr
;
2606 lt
-> starts
= cur_time
;
2608 /* Figure out how long a lease to assign. If this is a
2609 dynamic BOOTP lease, its duration must be infinite. */
2611 lt
->flags
&= ~BOOTP_LEASE
;
2613 default_lease_time
= DEFAULT_DEFAULT_LEASE_TIME
;
2614 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2615 SV_DEFAULT_LEASE_TIME
))) {
2616 if (evaluate_option_cache (&d1
, packet
, lease
,
2617 (struct client_state
*)0,
2620 &lease
-> scope
, oc
, MDL
)) {
2621 if (d1
.len
== sizeof (u_int32_t
))
2622 default_lease_time
=
2624 data_string_forget (&d1
, MDL
);
2628 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
2629 DHO_DHCP_LEASE_TIME
)))
2630 s1
= evaluate_option_cache (&d1
, packet
, lease
,
2631 (struct client_state
*)0,
2634 &lease
-> scope
, oc
, MDL
);
2638 if (s1
&& (d1
.len
== 4)) {
2639 u_int32_t ones
= 0xffffffff;
2641 /* One potential use of reserved leases is to allow
2642 * clients to signal reservation of their lease. They
2643 * can kinda sorta do this, if you squint hard enough,
2644 * by supplying an 'infinite' requested-lease-time
2645 * option. This is generally bad practice...you want
2646 * clients to return to the server on at least some
2647 * period (days, months, years) to get up-to-date
2650 * 1) A client requests 0xffffffff lease-time.
2651 * 2) The server reserves the lease, and assigns a
2652 * <= max_lease_time lease-time to the client, which
2653 * we presume is much smaller than 0xffffffff.
2654 * 3) The client ultimately fails to renew its lease
2655 * (all clients go offline at some point).
2656 * 4) The server retains the reservation, although
2657 * the lease expires and passes through those states
2658 * as normal, it's placed in the 'reserved' queue,
2659 * and is under no circumstances allocated to any
2662 * Whether the client knows its reserving its lease or
2663 * not, this can be a handy tool for a sysadmin.
2665 if ((memcmp(d1
.data
, &ones
, 4) == 0) &&
2666 (oc
= lookup_option(&server_universe
,
2668 SV_RESERVE_INFINITE
)) &&
2669 evaluate_boolean_option_cache(&ignorep
, packet
,
2670 lease
, NULL
, packet
->options
,
2671 state
->options
, &lease
->scope
,
2673 lt
->flags
|= RESERVED_LEASE
;
2675 log_info("Infinite-leasetime "
2676 "reservation made on %s.",
2677 piaddr(lt
->ip_addr
));
2680 lease_time
= getULong (d1
.data
);
2682 lease_time
= default_lease_time
;
2685 data_string_forget(&d1
, MDL
);
2687 /* See if there's a maximum lease time. */
2688 max_lease_time
= DEFAULT_MAX_LEASE_TIME
;
2689 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2690 SV_MAX_LEASE_TIME
))) {
2691 if (evaluate_option_cache (&d1
, packet
, lease
,
2692 (struct client_state
*)0,
2695 &lease
-> scope
, oc
, MDL
)) {
2696 if (d1
.len
== sizeof (u_int32_t
))
2699 data_string_forget (&d1
, MDL
);
2703 /* Enforce the maximum lease length. */
2704 if (lease_time
< 0 /* XXX */
2705 || lease_time
> max_lease_time
)
2706 lease_time
= max_lease_time
;
2708 min_lease_time
= DEFAULT_MIN_LEASE_TIME
;
2709 if (min_lease_time
> max_lease_time
)
2710 min_lease_time
= max_lease_time
;
2712 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2713 SV_MIN_LEASE_TIME
))) {
2714 if (evaluate_option_cache (&d1
, packet
, lease
,
2715 (struct client_state
*)0,
2718 &lease
-> scope
, oc
, MDL
)) {
2719 if (d1
.len
== sizeof (u_int32_t
))
2720 min_lease_time
= getULong (d1
.data
);
2721 data_string_forget (&d1
, MDL
);
2725 /* CC: If there are less than
2726 adaptive-lease-time-threshold % free leases,
2727 hand out only short term leases */
2729 memset(&d1
, 0, sizeof(d1
));
2731 (oc
= lookup_option(&server_universe
, state
->options
,
2732 SV_ADAPTIVE_LEASE_TIME_THRESHOLD
)) &&
2733 evaluate_option_cache(&d1
, packet
, lease
, NULL
,
2734 packet
->options
, state
->options
,
2735 &lease
->scope
, oc
, MDL
)) {
2736 if (d1
.len
== 1 && d1
.data
[0] > 0 &&
2739 int poolfilled
, total
, count
;
2742 adaptive_time
= min_lease_time
;
2744 adaptive_time
= DEFAULT_MIN_LEASE_TIME
;
2746 /* Allow the client to keep its lease. */
2747 if (lease
->ends
- cur_time
> adaptive_time
)
2748 adaptive_time
= lease
->ends
- cur_time
;
2750 count
= lease
->pool
->lease_count
;
2751 total
= count
- (lease
->pool
->free_leases
+
2752 lease
->pool
->backup_leases
);
2754 poolfilled
= (total
> (INT_MAX
/ 100)) ?
2755 total
/ (count
/ 100) :
2756 (total
* 100) / count
;
2758 log_debug("Adap-lease: Total: %d, Free: %d, "
2759 "Ends: %d, Adaptive: %d, Fill: %d, "
2761 lease
->pool
->lease_count
,
2762 lease
->pool
->free_leases
,
2763 (int)(lease
->ends
- cur_time
),
2764 (int)adaptive_time
, poolfilled
,
2767 if (poolfilled
>= d1
.data
[0] &&
2768 lease_time
> adaptive_time
) {
2769 log_info("Pool over threshold, time "
2770 "for %s reduced from %d to "
2771 "%d.", piaddr(lease
->ip_addr
),
2773 (int)adaptive_time
);
2775 lease_time
= adaptive_time
;
2778 data_string_forget(&d1
, MDL
);
2783 * If this is an ack check to see if we have used enough of
2784 * the pool to want to log a message
2786 if (offer
== DHCPACK
)
2787 check_pool_threshold(packet
, lease
, state
);
2789 /* a client requests an address which is not yet active*/
2790 if (lease
->pool
&& lease
->pool
->valid_from
&&
2791 cur_time
< lease
->pool
->valid_from
) {
2792 /* NAK leases before pool activation date */
2794 memcpy (cip
.iabuf
, <
->ip_addr
.iabuf
, 4);
2795 nak_lease(packet
, &cip
, lease
->subnet
->group
);
2796 free_lease_state (state
, MDL
);
2797 lease_dereference (<
, MDL
);
2799 host_dereference (&host
, MDL
);
2805 a) NAK current lease if past the expiration date
2806 b) extend lease only up to the expiration date, but not
2807 below min-lease-time
2808 Setting min-lease-time is essential for this to work!
2809 The value of min-lease-time determines the length
2810 of the transition window:
2811 A client renewing a second before the deadline will
2812 get a min-lease-time lease. Since the current ip might not
2813 be routable after the deadline, the client will
2814 be offline until it DISCOVERS again. Otherwise it will
2815 receive a NAK at T/2.
2816 A min-lease-time of 6 seconds effectively switches over
2817 all clients in this pool very quickly.
2820 if (lease
->pool
&& lease
->pool
->valid_until
) {
2821 if (cur_time
>= lease
->pool
->valid_until
) {
2822 /* NAK leases after pool expiration date */
2824 memcpy (cip
.iabuf
, <
->ip_addr
.iabuf
, 4);
2825 nak_lease(packet
, &cip
, lease
->subnet
->group
);
2826 free_lease_state (state
, MDL
);
2827 lease_dereference (<
, MDL
);
2829 host_dereference (&host
, MDL
);
2832 remaining_time
= lease
->pool
->valid_until
- cur_time
;
2833 if (lease_time
> remaining_time
)
2834 lease_time
= remaining_time
;
2837 if (lease_time
< min_lease_time
) {
2839 lease_time
= min_lease_time
;
2841 lease_time
= default_lease_time
;
2845 #if defined (FAILOVER_PROTOCOL)
2846 /* Okay, we know the lease duration. Now check the
2847 failover state, if any. */
2848 if (lease
-> pool
&& lease
-> pool
-> failover_peer
) {
2849 TIME new_lease_time
= lease_time
;
2850 dhcp_failover_state_t
*peer
=
2851 lease
-> pool
-> failover_peer
;
2853 /* Copy previous lease failover ack-state. */
2854 lt
->tsfp
= lease
->tsfp
;
2855 lt
->atsfp
= lease
->atsfp
;
2857 /* cltt set below */
2859 /* Lease times less than MCLT are not a concern. */
2860 if (lease_time
> peer
->mclt
) {
2861 /* Each server can only offer a lease time
2862 * that is either equal to MCLT (at least),
2863 * or up to TSFP+MCLT. Only if the desired
2864 * lease time falls within TSFP+MCLT, can
2865 * the server allow it.
2867 if (lt
->tsfp
<= cur_time
)
2868 new_lease_time
= peer
->mclt
;
2869 else if ((cur_time
+ lease_time
) >
2870 (lt
->tsfp
+ peer
->mclt
))
2871 new_lease_time
= (lt
->tsfp
- cur_time
)
2875 /* Update potential expiry. Allow for the desired
2876 * lease time plus one half the actual (whether
2877 * modified downward or not) lease time, which is
2878 * actually an estimate of when the client will
2879 * renew. This way, the client will be able to get
2880 * the desired lease time upon renewal.
2882 if (offer
== DHCPACK
) {
2883 if (lease_time
== INFINITE_TIME
) {
2884 lt
->tstp
= MAX_TIME
;
2888 (cur_time
+ lease_time
2889 + (new_lease_time
/ 2)),
2893 /* If we reduced the potential expiry time,
2894 * make sure we don't offer an old-expiry-time
2895 * lease for this lease before the change is
2898 if (lt
->tstp
< lt
->tsfp
)
2899 lt
->tsfp
= lt
->tstp
;
2901 lt
->tstp
= lease
->tstp
;
2903 /* Use failover-modified lease time. */
2904 lease_time
= new_lease_time
;
2906 #endif /* FAILOVER_PROTOCOL */
2908 if (lease_time
== INFINITE_TIME
) {
2909 state
->offered_expiry
= MAX_TIME
;
2911 /* If the lease duration causes the time value to wrap,
2912 use the maximum expiry time. */
2913 state
->offered_expiry
2914 = leaseTimeCheck(cur_time
+ lease_time
,
2921 lt
-> ends
= state
-> offered_expiry
;
2923 /* Don't make lease active until we actually get a
2925 if (offer
== DHCPACK
)
2926 lt
-> next_binding_state
= FTS_ACTIVE
;
2928 lt
-> next_binding_state
= lease
-> binding_state
;
2930 lt
->flags
|= BOOTP_LEASE
;
2932 lease_time
= MAX_TIME
- cur_time
;
2934 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2935 SV_BOOTP_LEASE_LENGTH
))) {
2936 if (evaluate_option_cache (&d1
, packet
, lease
,
2937 (struct client_state
*)0,
2940 &lease
-> scope
, oc
, MDL
)) {
2941 if (d1
.len
== sizeof (u_int32_t
))
2942 lease_time
= getULong (d1
.data
);
2943 data_string_forget (&d1
, MDL
);
2947 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2948 SV_BOOTP_LEASE_CUTOFF
))) {
2949 if (evaluate_option_cache (&d1
, packet
, lease
,
2950 (struct client_state
*)0,
2953 &lease
-> scope
, oc
, MDL
)) {
2954 if (d1
.len
== sizeof (u_int32_t
))
2955 lease_time
= (getULong (d1
.data
) -
2957 data_string_forget (&d1
, MDL
);
2961 lt
-> ends
= state
-> offered_expiry
= cur_time
+ lease_time
;
2962 lt
-> next_binding_state
= FTS_ACTIVE
;
2965 /* Update Client Last Transaction Time. */
2966 lt
->cltt
= cur_time
;
2968 /* See if we want to record the uid for this client */
2969 oc
= lookup_option(&server_universe
, state
->options
,
2970 SV_IGNORE_CLIENT_UIDS
);
2972 !evaluate_boolean_option_cache(&ignorep
, packet
, lease
, NULL
,
2973 packet
->options
, state
->options
,
2974 &lease
->scope
, oc
, MDL
)) {
2976 /* Record the uid, if given... */
2977 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
2978 DHO_DHCP_CLIENT_IDENTIFIER
);
2980 evaluate_option_cache(&d1
, packet
, lease
, NULL
,
2981 packet
->options
, state
->options
,
2982 &lease
->scope
, oc
, MDL
)) {
2983 if (d1
.len
<= sizeof(lt
->uid_buf
)) {
2984 memcpy(lt
->uid_buf
, d1
.data
, d1
.len
);
2985 lt
->uid
= lt
->uid_buf
;
2986 lt
->uid_max
= sizeof(lt
->uid_buf
);
2987 lt
->uid_len
= d1
.len
;
2989 unsigned char *tuid
;
2990 lt
->uid_max
= d1
.len
;
2991 lt
->uid_len
= d1
.len
;
2992 tuid
= (unsigned char *)dmalloc(lt
->uid_max
,
2996 log_fatal ("no memory for large uid.");
2997 memcpy(tuid
, d1
.data
, lt
->uid_len
);
3000 data_string_forget (&d1
, MDL
);
3005 host_reference (<
-> host
, host
, MDL
);
3006 host_dereference (&host
, MDL
);
3008 if (lease
-> subnet
)
3009 subnet_reference (<
-> subnet
, lease
-> subnet
, MDL
);
3010 if (lease
-> billing_class
)
3011 class_reference (<
-> billing_class
,
3012 lease
-> billing_class
, MDL
);
3014 /* Set a flag if this client is a broken client that NUL
3015 terminates string options and expects us to do likewise. */
3017 lease
-> flags
|= MS_NULL_TERMINATION
;
3019 lease
-> flags
&= ~MS_NULL_TERMINATION
;
3021 /* Save any bindings. */
3022 if (lease
-> scope
) {
3023 binding_scope_reference (<
-> scope
, lease
-> scope
, MDL
);
3024 binding_scope_dereference (&lease
-> scope
, MDL
);
3026 if (lease
-> agent_options
)
3027 option_chain_head_reference (<
-> agent_options
,
3028 lease
-> agent_options
, MDL
);
3030 /* Save the vendor-class-identifier for DHCPLEASEQUERY. */
3031 oc
= lookup_option(&dhcp_universe
, packet
->options
,
3032 DHO_VENDOR_CLASS_IDENTIFIER
);
3034 evaluate_option_cache(&d1
, packet
, NULL
, NULL
, packet
->options
,
3035 NULL
, <
->scope
, oc
, MDL
)) {
3037 bind_ds_value(<
->scope
, "vendor-class-identifier",
3041 data_string_forget(&d1
, MDL
);
3044 /* If we got relay agent information options from the packet, then
3045 * cache them for renewal in case the relay agent can't supply them
3046 * when the client unicasts. The options may be from an addressed
3047 * "l3" relay, or from an unaddressed "l2" relay which does not set
3050 if (!packet
->agent_options_stashed
&&
3051 (packet
->options
!= NULL
) &&
3052 packet
->options
->universe_count
> agent_universe
.index
&&
3053 packet
->options
->universes
[agent_universe
.index
] != NULL
) {
3054 oc
= lookup_option (&server_universe
, state
-> options
,
3055 SV_STASH_AGENT_OPTIONS
);
3057 evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
3058 (struct client_state
*)0,
3061 &lease
-> scope
, oc
, MDL
)) {
3062 if (lt
-> agent_options
)
3063 option_chain_head_dereference (<
-> agent_options
, MDL
);
3064 option_chain_head_reference
3065 (<
-> agent_options
,
3066 (struct option_chain_head
*)
3067 packet
-> options
-> universes
[agent_universe
.index
],
3072 /* Replace the old lease hostname with the new one, if it's changed. */
3073 oc
= lookup_option (&dhcp_universe
, packet
-> options
, DHO_HOST_NAME
);
3075 s1
= evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
3076 (struct client_state
*)0,
3078 (struct option_state
*)0,
3079 &global_scope
, oc
, MDL
);
3084 lease
-> client_hostname
&&
3085 strlen (lease
-> client_hostname
) == d1
.len
&&
3086 !memcmp (lease
-> client_hostname
, d1
.data
, d1
.len
)) {
3087 /* Hasn't changed. */
3088 data_string_forget (&d1
, MDL
);
3089 lt
-> client_hostname
= lease
-> client_hostname
;
3090 lease
-> client_hostname
= (char *)0;
3091 } else if (oc
&& s1
) {
3092 lt
-> client_hostname
= dmalloc (d1
.len
+ 1, MDL
);
3093 if (!lt
-> client_hostname
)
3094 log_error ("no memory for client hostname.");
3096 memcpy (lt
-> client_hostname
, d1
.data
, d1
.len
);
3097 lt
-> client_hostname
[d1
.len
] = 0;
3099 data_string_forget (&d1
, MDL
);
3100 /* hostname changed, can't reuse lease */
3101 lease
->cannot_reuse
= 1;
3104 /* Record the hardware address, if given... */
3105 lt
-> hardware_addr
.hlen
= packet
-> raw
-> hlen
+ 1;
3106 lt
-> hardware_addr
.hbuf
[0] = packet
-> raw
-> htype
;
3107 memcpy (<
-> hardware_addr
.hbuf
[1], packet
-> raw
-> chaddr
,
3108 sizeof packet
-> raw
-> chaddr
);
3111 * If client has requested the lease become infinite, then it
3112 * doens't qualify for reuse even if it's younger than the
3113 * dhcp-cache-threshold.
3115 if ((lt
->flags
& RESERVED_LEASE
) && !(lease
->flags
& RESERVED_LEASE
)) {
3116 log_debug ("Cannot reuse: lease is changing to RESERVED");
3117 lease
->cannot_reuse
= 1;
3120 lt
->flags
|= lease
->flags
& ~PERSISTENT_FLAGS
;
3122 /* If there are statements to execute when the lease is
3123 committed, execute them. */
3124 if (lease
->on_star
.on_commit
&& (!offer
|| offer
== DHCPACK
)) {
3125 execute_statements (NULL
, packet
, lt
, NULL
, packet
->options
,
3126 state
->options
, <
->scope
,
3127 lease
->on_star
.on_commit
, NULL
);
3128 if (lease
->on_star
.on_commit
)
3129 executable_statement_dereference
3130 (&lease
->on_star
.on_commit
, MDL
);
3134 /* Perform DDNS updates, if configured to. */
3135 if ((!offer
|| offer
== DHCPACK
) &&
3136 (!(oc
= lookup_option (&server_universe
, state
-> options
,
3137 SV_DDNS_UPDATES
)) ||
3138 evaluate_boolean_option_cache (&ignorep
, packet
, lt
,
3139 (struct client_state
*)0,
3142 <
-> scope
, oc
, MDL
))) {
3143 ddns_updates(packet
, lt
, lease
, NULL
, NULL
, state
->options
);
3145 #endif /* NSUPDATE */
3147 /* Don't call supersede_lease on a mocked-up lease. */
3148 if (lease
-> flags
& STATIC_LEASE
) {
3149 /* Copy the hardware address into the static lease
3151 lease
-> hardware_addr
.hlen
= packet
-> raw
-> hlen
+ 1;
3152 lease
-> hardware_addr
.hbuf
[0] = packet
-> raw
-> htype
;
3153 memcpy (&lease
-> hardware_addr
.hbuf
[1],
3154 packet
-> raw
-> chaddr
,
3155 sizeof packet
-> raw
-> chaddr
); /* XXX */
3157 int commit
= (!offer
|| (offer
== DHCPACK
));
3159 /* If dhcp-cache-threshold is enabled, see if "lease" can
3161 use_old_lease
= reuse_lease(packet
, lt
, lease
, state
, offer
);
3162 if (use_old_lease
== 1) {
3166 #if !defined(DELAYED_ACK) || defined(DHCP4o6)
3167 /* Install the new information on 'lt' onto the lease at
3168 * 'lease'. If this is a DHCPOFFER, it is a 'soft' promise,
3169 * if it is a DHCPACK, it is a 'hard' binding, so it needs
3170 * to be recorded and propogated immediately. If the update
3171 * fails, don't ACK it (or BOOTREPLY) either; we may give
3172 * the same lease to another client later, and that would be
3175 if ((use_old_lease
== 0) &&
3176 !supersede_lease(lease
, lt
, commit
,
3177 offer
== DHCPACK
, offer
== DHCPACK
, 0)) {
3178 #else /* defined(DELAYED_ACK) && !defined(DHCP4o6) */
3180 * If there already isn't a need for a lease commit, and we
3181 * can just answer right away, set a flag to indicate this.
3186 /* Install the new information on 'lt' onto the lease at
3187 * 'lease'. We will not 'commit' this information to disk
3188 * yet (fsync()), we will 'propogate' the information if
3189 * this is BOOTP or a DHCPACK, but we will not 'pimmediate'ly
3190 * transmit failover binding updates (this is delayed until
3191 * after the fsync()). If the update fails, don't ACK it (or
3192 * BOOTREPLY either); we may give the same lease out to a
3193 * different client, and that would be a conflict.
3195 if ((use_old_lease
== 0) &&
3196 !supersede_lease(lease
, lt
, 0,
3197 !offer
|| offer
== DHCPACK
, 0, 0)) {
3199 log_info ("%s: database update failed", msg
);
3200 free_lease_state (state
, MDL
);
3201 lease_dereference (<
, MDL
);
3205 lease_dereference (<
, MDL
);
3207 /* Remember the interface on which the packet arrived. */
3208 state
-> ip
= packet
-> interface
;
3210 /* Remember the giaddr, xid, secs, flags and hops. */
3211 state
-> giaddr
= packet
-> raw
-> giaddr
;
3212 state
-> ciaddr
= packet
-> raw
-> ciaddr
;
3213 state
-> xid
= packet
-> raw
-> xid
;
3214 state
-> secs
= packet
-> raw
-> secs
;
3215 state
-> bootp_flags
= packet
-> raw
-> flags
;
3216 state
-> hops
= packet
-> raw
-> hops
;
3217 state
-> offer
= offer
;
3219 /* If we're always supposed to broadcast to this client, set
3220 the broadcast bit in the bootp flags field. */
3221 if ((oc
= lookup_option (&server_universe
, state
-> options
,
3222 SV_ALWAYS_BROADCAST
)) &&
3223 evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
3224 (struct client_state
*)0,
3225 packet
-> options
, state
-> options
,
3226 &lease
-> scope
, oc
, MDL
))
3227 state
-> bootp_flags
|= htons (BOOTP_BROADCAST
);
3229 /* Get the Maximum Message Size option from the packet, if one
3231 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
3232 DHO_DHCP_MAX_MESSAGE_SIZE
);
3234 evaluate_option_cache (&d1
, packet
, lease
,
3235 (struct client_state
*)0,
3236 packet
-> options
, state
-> options
,
3237 &lease
-> scope
, oc
, MDL
)) {
3238 if (d1
.len
== sizeof (u_int16_t
))
3239 state
-> max_message_size
= getUShort (d1
.data
);
3240 data_string_forget (&d1
, MDL
);
3242 oc
= lookup_option (&dhcp_universe
, state
-> options
,
3243 DHO_DHCP_MAX_MESSAGE_SIZE
);
3245 evaluate_option_cache (&d1
, packet
, lease
,
3246 (struct client_state
*)0,
3247 packet
-> options
, state
-> options
,
3248 &lease
-> scope
, oc
, MDL
)) {
3249 if (d1
.len
== sizeof (u_int16_t
))
3250 state
-> max_message_size
=
3251 getUShort (d1
.data
);
3252 data_string_forget (&d1
, MDL
);
3256 /* Get the Subnet Selection option from the packet, if one
3258 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
3259 DHO_SUBNET_SELECTION
))) {
3261 /* Make a copy of the data. */
3262 struct option_cache
*noc
= (struct option_cache
*)0;
3263 if (option_cache_allocate (&noc
, MDL
)) {
3265 data_string_copy (&noc
-> data
,
3267 if (oc
-> expression
)
3268 expression_reference (&noc
-> expression
,
3269 oc
-> expression
, MDL
);
3271 option_reference(&(noc
->option
), oc
->option
,
3274 save_option (&dhcp_universe
, state
-> options
, noc
);
3275 option_cache_dereference (&noc
, MDL
);
3279 /* Now, if appropriate, put in DHCP-specific options that
3281 if (state
-> offer
) {
3282 i
= DHO_DHCP_MESSAGE_TYPE
;
3283 oc
= (struct option_cache
*)0;
3284 if (option_cache_allocate (&oc
, MDL
)) {
3285 if (make_const_data (&oc
-> expression
,
3286 &state
-> offer
, 1, 0, 0, MDL
)) {
3287 option_code_hash_lookup(&oc
->option
,
3288 dhcp_universe
.code_hash
,
3290 save_option (&dhcp_universe
,
3291 state
-> options
, oc
);
3293 option_cache_dereference (&oc
, MDL
);
3296 get_server_source_address(&from
, state
->options
,
3297 state
->options
, packet
);
3298 memcpy(state
->from
.iabuf
, &from
, sizeof(from
));
3299 state
->from
.len
= sizeof(from
);
3301 offered_lease_time
=
3302 state
-> offered_expiry
- cur_time
;
3304 putULong(state
->expiry
, (u_int32_t
)offered_lease_time
);
3305 i
= DHO_DHCP_LEASE_TIME
;
3306 oc
= (struct option_cache
*)0;
3307 if (option_cache_allocate (&oc
, MDL
)) {
3308 if (make_const_data(&oc
->expression
, state
->expiry
,
3310 option_code_hash_lookup(&oc
->option
,
3311 dhcp_universe
.code_hash
,
3313 save_option (&dhcp_universe
,
3314 state
-> options
, oc
);
3316 option_cache_dereference (&oc
, MDL
);
3320 * Validate any configured renew or rebinding times against
3321 * the determined lease time. Do rebinding first so that
3322 * the renew time can be validated against the rebind time.
3324 if ((oc
= lookup_option(&dhcp_universe
, state
->options
,
3325 DHO_DHCP_REBINDING_TIME
)) != NULL
&&
3326 evaluate_option_cache(&d1
, packet
, lease
, NULL
,
3327 packet
->options
, state
->options
,
3328 &lease
->scope
, oc
, MDL
)) {
3329 TIME rebind_time
= getULong(d1
.data
);
3331 /* Drop the configured (invalid) rebinding time. */
3332 if (rebind_time
>= offered_lease_time
)
3333 delete_option(&dhcp_universe
, state
->options
,
3334 DHO_DHCP_REBINDING_TIME
);
3335 else /* XXX: variable is reused. */
3336 offered_lease_time
= rebind_time
;
3338 data_string_forget(&d1
, MDL
);
3341 if ((oc
= lookup_option(&dhcp_universe
, state
->options
,
3342 DHO_DHCP_RENEWAL_TIME
)) != NULL
&&
3343 evaluate_option_cache(&d1
, packet
, lease
, NULL
,
3344 packet
->options
, state
->options
,
3345 &lease
->scope
, oc
, MDL
)) {
3346 if (getULong(d1
.data
) >= offered_lease_time
)
3347 delete_option(&dhcp_universe
, state
->options
,
3348 DHO_DHCP_RENEWAL_TIME
);
3350 data_string_forget(&d1
, MDL
);
3353 /* XXXSK: should we use get_server_source_address() here? */
3354 if (state
-> ip
-> address_count
) {
3356 sizeof state
-> ip
-> addresses
[0];
3357 memcpy (state
-> from
.iabuf
,
3358 &state
-> ip
-> addresses
[0],
3363 /* Figure out the address of the boot file server. */
3364 memset (&state
-> siaddr
, 0, sizeof state
-> siaddr
);
3366 lookup_option (&server_universe
,
3367 state
-> options
, SV_NEXT_SERVER
))) {
3368 if (evaluate_option_cache (&d1
, packet
, lease
,
3369 (struct client_state
*)0,
3370 packet
-> options
, state
-> options
,
3371 &lease
-> scope
, oc
, MDL
)) {
3372 /* If there was more than one answer,
3374 if (d1
.len
>= 4 && d1
.data
)
3375 memcpy (&state
-> siaddr
, d1
.data
, 4);
3376 data_string_forget (&d1
, MDL
);
3380 /* Use the subnet mask from the subnet declaration if no other
3381 mask has been provided. */
3382 i
= DHO_SUBNET_MASK
;
3383 if (!lookup_option (&dhcp_universe
, state
-> options
, i
)) {
3384 oc
= (struct option_cache
*)0;
3385 if (option_cache_allocate (&oc
, MDL
)) {
3386 if (make_const_data (&oc
-> expression
,
3387 lease
-> subnet
-> netmask
.iabuf
,
3388 lease
-> subnet
-> netmask
.len
,
3390 option_code_hash_lookup(&oc
->option
,
3391 dhcp_universe
.code_hash
,
3393 save_option (&dhcp_universe
,
3394 state
-> options
, oc
);
3396 option_cache_dereference (&oc
, MDL
);
3400 /* Use the name of the host declaration if there is one
3401 and no hostname has otherwise been provided, and if the
3402 use-host-decl-name flag is set. */
3403 use_host_decl_name(packet
, lease
, state
->options
);
3405 /* Send client_id back if we received it and echo-client-id is on. */
3406 echo_client_id(packet
, lease
, state
->options
, state
->options
);
3408 /* If we don't have a hostname yet, and we've been asked to do
3409 a reverse lookup to find the hostname, do it. */
3411 j
= SV_GET_LEASE_HOSTNAMES
;
3412 if (!lookup_option(&dhcp_universe
, state
->options
, i
) &&
3413 evaluate_boolean_option_cache
3414 (&ignorep
, packet
, lease
, NULL
,
3415 packet
->options
, state
->options
, &lease
->scope
,
3416 lookup_option (&server_universe
, state
->options
, j
), MDL
)) {
3420 memcpy (&ia
, lease
-> ip_addr
.iabuf
, 4);
3422 h
= gethostbyaddr ((char *)&ia
, sizeof ia
, AF_INET
);
3424 log_error ("No hostname for %s", inet_ntoa (ia
));
3426 oc
= (struct option_cache
*)0;
3427 if (option_cache_allocate (&oc
, MDL
)) {
3428 if (make_const_data (&oc
-> expression
,
3431 strlen (h
-> h_name
) + 1,
3433 option_code_hash_lookup(&oc
->option
,
3434 dhcp_universe
.code_hash
,
3436 save_option (&dhcp_universe
,
3437 state
-> options
, oc
);
3439 option_cache_dereference (&oc
, MDL
);
3444 /* If so directed, use the leased IP address as the router address.
3445 This supposedly makes Win95 machines ARP for all IP addresses,
3446 so if the local router does proxy arp, you win. */
3448 if (evaluate_boolean_option_cache
3449 (&ignorep
, packet
, lease
, (struct client_state
*)0,
3450 packet
-> options
, state
-> options
, &lease
-> scope
,
3451 lookup_option (&server_universe
, state
-> options
,
3452 SV_USE_LEASE_ADDR_FOR_DEFAULT_ROUTE
), MDL
)) {
3454 oc
= lookup_option (&dhcp_universe
, state
-> options
, i
);
3456 oc
= (struct option_cache
*)0;
3457 if (option_cache_allocate (&oc
, MDL
)) {
3458 if (make_const_data (&oc
-> expression
,
3459 lease
-> ip_addr
.iabuf
,
3460 lease
-> ip_addr
.len
,
3462 option_code_hash_lookup(&oc
->option
,
3463 dhcp_universe
.code_hash
,
3465 save_option (&dhcp_universe
,
3466 state
-> options
, oc
);
3468 option_cache_dereference (&oc
, MDL
);
3473 /* If a site option space has been specified, use that for
3474 site option codes. */
3475 i
= SV_SITE_OPTION_SPACE
;
3476 if ((oc
= lookup_option (&server_universe
, state
-> options
, i
)) &&
3477 evaluate_option_cache (&d1
, packet
, lease
,
3478 (struct client_state
*)0,
3479 packet
-> options
, state
-> options
,
3480 &lease
-> scope
, oc
, MDL
)) {
3481 struct universe
*u
= (struct universe
*)0;
3483 if (!universe_hash_lookup (&u
, universe_hash
,
3484 (const char *)d1
.data
, d1
.len
,
3486 log_error ("unknown option space %s.", d1
.data
);
3490 state
-> options
-> site_universe
= u
-> index
;
3491 state
->options
->site_code_min
= find_min_site_code(u
);
3492 data_string_forget (&d1
, MDL
);
3494 state
-> options
-> site_code_min
= 0;
3495 state
-> options
-> site_universe
= dhcp_universe
.index
;
3498 /* If the client has provided a list of options that it wishes
3499 returned, use it to prioritize. If there's a parameter
3500 request list in scope, use that in preference. Otherwise
3501 use the default priority list. */
3503 oc
= lookup_option (&dhcp_universe
, state
-> options
,
3504 DHO_DHCP_PARAMETER_REQUEST_LIST
);
3507 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
3508 DHO_DHCP_PARAMETER_REQUEST_LIST
);
3510 evaluate_option_cache (&state
-> parameter_request_list
,
3511 packet
, lease
, (struct client_state
*)0,
3512 packet
-> options
, state
-> options
,
3513 &lease
-> scope
, oc
, MDL
);
3516 dump_packet (packet
);
3517 dump_raw ((unsigned char *)packet
-> raw
, packet
-> packet_length
);
3520 lease
-> state
= state
;
3522 log_info ("%s", msg
);
3524 /* Hang the packet off the lease state. */
3525 packet_reference (&lease
-> state
-> packet
, packet
, MDL
);
3527 /* If this is a DHCPOFFER, ping the lease address before actually
3528 sending the offer. */
3529 if (offer
== DHCPOFFER
&& !(lease
-> flags
& STATIC_LEASE
) &&
3530 (((cur_time
- lease_cltt
) > 60) ||
3531 (lease
->binding_state
== FTS_ABANDONED
)) &&
3532 (!(oc
= lookup_option (&server_universe
, state
-> options
,
3534 evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
3535 (struct client_state
*)0,
3538 &lease
-> scope
, oc
, MDL
))) {
3539 icmp_echorequest (&lease
-> ip_addr
);
3541 /* Determine whether to use configured or default ping timeout.
3543 if ((oc
= lookup_option (&server_universe
, state
-> options
,
3544 SV_PING_TIMEOUT
)) &&
3545 evaluate_option_cache (&d1
, packet
, lease
, NULL
,
3548 &lease
-> scope
, oc
, MDL
)) {
3549 if (d1
.len
== sizeof (u_int32_t
))
3550 ping_timeout
= getULong (d1
.data
);
3552 ping_timeout
= DEFAULT_PING_TIMEOUT
;
3554 data_string_forget (&d1
, MDL
);
3556 ping_timeout
= DEFAULT_PING_TIMEOUT
;
3559 log_debug ("Ping timeout: %ld", (long)ping_timeout
);
3563 * Set a timeout for 'ping-timeout' seconds from NOW, including
3564 * current microseconds. As ping-timeout defaults to 1, the
3565 * exclusion of current microseconds causes a value somewhere
3566 * /between/ zero and one.
3568 tv
.tv_sec
= cur_tv
.tv_sec
+ ping_timeout
;
3569 tv
.tv_usec
= cur_tv
.tv_usec
;
3570 add_timeout (&tv
, lease_ping_timeout
, lease
,
3571 (tvref_t
)lease_reference
,
3572 (tvunref_t
)lease_dereference
);
3573 ++outstanding_pings
;
3575 lease
->cltt
= cur_time
;
3576 #if defined(DELAYED_ACK) && !defined(DHCP4o6)
3577 if (enqueue
&& max_outstanding_acks
!= 0)
3578 delayed_ack_enqueue(lease
);
3585 #if defined(DELAYED_ACK)
3588 * CC: queue single ACK:
3589 * - write the lease (but do not fsync it yet)
3590 * - add to double linked list
3591 * - commit if more than xx ACKs pending
3592 * - if necessary set the max timer and bump the next timer
3593 * but only up to the max timer value.
3597 delayed_ack_enqueue(struct lease
*lease
)
3599 struct leasequeue
*q
;
3601 if (!write_lease(lease
))
3603 if (free_ackqueue
) {
3605 free_ackqueue
= q
->next
;
3607 q
= ((struct leasequeue
*)
3608 dmalloc(sizeof(struct leasequeue
), MDL
));
3610 log_fatal("delayed_ack_enqueue: no memory!");
3612 memset(q
, 0, sizeof *q
);
3613 /* prepend to ackqueue*/
3614 lease_reference(&q
->lease
, lease
, MDL
);
3615 q
->next
= ackqueue_head
;
3623 if (outstanding_acks
> max_outstanding_acks
) {
3624 /* Cancel any pending timeout and call handler directly */
3625 cancel_timeout(delayed_acks_timer
, NULL
);
3626 delayed_acks_timer(NULL
);
3628 struct timeval next_fsync
;
3630 if (max_fsync
.tv_sec
== 0 && max_fsync
.tv_usec
== 0) {
3631 /* set the maximum time we'll wait */
3632 max_fsync
.tv_sec
= cur_tv
.tv_sec
+ max_ack_delay_secs
;
3633 max_fsync
.tv_usec
= cur_tv
.tv_usec
+
3634 max_ack_delay_usecs
;
3636 if (max_fsync
.tv_usec
>= 1000000) {
3638 max_fsync
.tv_usec
-= 1000000;
3642 /* Set the timeout */
3643 next_fsync
.tv_sec
= cur_tv
.tv_sec
;
3644 next_fsync
.tv_usec
= cur_tv
.tv_usec
+ min_ack_delay_usecs
;
3645 if (next_fsync
.tv_usec
>= 1000000) {
3646 next_fsync
.tv_sec
++;
3647 next_fsync
.tv_usec
-= 1000000;
3649 /* but not more than the max */
3650 if ((next_fsync
.tv_sec
> max_fsync
.tv_sec
) ||
3651 ((next_fsync
.tv_sec
== max_fsync
.tv_sec
) &&
3652 (next_fsync
.tv_usec
> max_fsync
.tv_usec
))) {
3653 next_fsync
.tv_sec
= max_fsync
.tv_sec
;
3654 next_fsync
.tv_usec
= max_fsync
.tv_usec
;
3657 add_timeout(&next_fsync
, delayed_acks_timer
, NULL
,
3658 (tvref_t
) NULL
, (tvunref_t
) NULL
);
3662 /* Processes any delayed acks:
3663 * Commits the leases and then for each delayed ack:
3664 * - Update the failover peer if we're in failover
3665 * - Send the REPLY to the client
3668 delayed_acks_timer(void *foo
)
3670 struct leasequeue
*ack
, *p
;
3672 /* Reset max fsync */
3673 memset(&max_fsync
, 0, sizeof(max_fsync
));
3675 if (!outstanding_acks
) {
3676 /* Nothing to do, so punt, shouldn't happen? */
3680 /* Commit the leases first */
3683 /* Now process the delayed ACKs
3684 - update failover peer
3685 - send out the ACK packets
3686 - move the queue slots to the free list
3689 /* process from bottom to retain packet order */
3690 for (ack
= ackqueue_tail
; ack
; ack
= p
) {
3693 #if defined(FAILOVER_PROTOCOL)
3694 /* If we're in failover we need to send any deferred
3695 * bind updates as well as the replies */
3696 if (ack
->lease
->pool
) {
3697 dhcp_failover_state_t
*fpeer
;
3699 fpeer
= ack
->lease
->pool
->failover_peer
;
3700 if (fpeer
&& fpeer
->link_to_peer
) {
3701 dhcp_failover_send_updates(fpeer
);
3706 /* dhcp_reply() requires that the reply state still be valid */
3707 if (ack
->lease
->state
== NULL
)
3708 log_error("delayed ack for %s has gone stale",
3709 piaddr(ack
->lease
->ip_addr
));
3711 dhcp_reply(ack
->lease
);
3714 lease_dereference(&ack
->lease
, MDL
);
3715 ack
->next
= free_ackqueue
;
3716 free_ackqueue
= ack
;
3719 ackqueue_head
= NULL
;
3720 ackqueue_tail
= NULL
;
3721 outstanding_acks
= 0;
3724 #if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
3726 relinquish_ackqueue(void)
3728 struct leasequeue
*q
, *n
;
3730 for (q
= ackqueue_head
; q
; q
= n
) {
3734 for (q
= free_ackqueue
; q
; q
= n
) {
3741 #endif /* defined(DELAYED_ACK) */
3743 void dhcp_reply (lease
)
3744 struct lease
*lease
;
3747 unsigned packet_length
;
3748 struct dhcp_packet raw
;
3749 struct sockaddr_in to
;
3750 struct in_addr from
;
3751 struct hardware hto
;
3753 struct lease_state
*state
= lease
-> state
;
3754 int nulltp
, bootpp
, unicastp
= 1;
3755 struct data_string d1
;
3759 log_fatal ("dhcp_reply was supplied lease with no state!");
3761 /* Compose a response for the client... */
3762 memset (&raw
, 0, sizeof raw
);
3763 memset (&d1
, 0, sizeof d1
);
3765 /* Copy in the filename if given; otherwise, flag the filename
3766 buffer as available for options. */
3767 if (state
-> filename
.len
&& state
-> filename
.data
) {
3769 state
-> filename
.data
,
3770 state
-> filename
.len
> sizeof raw
.file
3771 ? sizeof raw
.file
: state
-> filename
.len
);
3772 if (sizeof raw
.file
> state
-> filename
.len
)
3773 memset (&raw
.file
[state
-> filename
.len
], 0,
3774 (sizeof raw
.file
) - state
-> filename
.len
);
3776 log_info("file name longer than packet field "
3777 "truncated - field: %lu name: %d %.*s",
3778 (unsigned long)sizeof(raw
.file
),
3779 state
->filename
.len
, (int)state
->filename
.len
,
3780 state
->filename
.data
);
3784 /* Copy in the server name if given; otherwise, flag the
3785 server_name buffer as available for options. */
3786 if (state
-> server_name
.len
&& state
-> server_name
.data
) {
3788 state
-> server_name
.data
,
3789 state
-> server_name
.len
> sizeof raw
.sname
3790 ? sizeof raw
.sname
: state
-> server_name
.len
);
3791 if (sizeof raw
.sname
> state
-> server_name
.len
)
3792 memset (&raw
.sname
[state
-> server_name
.len
], 0,
3793 (sizeof raw
.sname
) - state
-> server_name
.len
);
3795 log_info("server name longer than packet field "
3796 "truncated - field: %lu name: %d %.*s",
3797 (unsigned long)sizeof(raw
.sname
),
3798 state
->server_name
.len
,
3799 (int)state
->server_name
.len
,
3800 state
->server_name
.data
);
3802 bufs
|= 2; /* XXX */
3805 &lease
-> hardware_addr
.hbuf
[1], sizeof raw
.chaddr
);
3806 raw
.hlen
= lease
-> hardware_addr
.hlen
- 1;
3807 raw
.htype
= lease
-> hardware_addr
.hbuf
[0];
3809 /* See if this is a Microsoft client that NUL-terminates its
3810 strings and expects us to do likewise... */
3811 if (lease
-> flags
& MS_NULL_TERMINATION
)
3816 /* See if this is a bootp client... */
3822 /* Insert such options as will fit into the buffer. */
3823 packet_length
= cons_options (state
-> packet
, &raw
, lease
,
3824 (struct client_state
*)0,
3825 state
-> max_message_size
,
3826 state
-> packet
-> options
,
3827 state
-> options
, &global_scope
,
3828 bufs
, nulltp
, bootpp
,
3829 &state
-> parameter_request_list
,
3832 memcpy (&raw
.ciaddr
, &state
-> ciaddr
, sizeof raw
.ciaddr
);
3833 memcpy (&raw
.yiaddr
, lease
-> ip_addr
.iabuf
, 4);
3834 raw
.siaddr
= state
-> siaddr
;
3835 raw
.giaddr
= state
-> giaddr
;
3837 raw
.xid
= state
-> xid
;
3838 raw
.secs
= state
-> secs
;
3839 raw
.flags
= state
-> bootp_flags
;
3840 raw
.hops
= state
-> hops
;
3843 if (lease
-> client_hostname
) {
3844 if ((strlen (lease
-> client_hostname
) <= 64) &&
3845 db_printable((unsigned char *)lease
->client_hostname
))
3846 s
= lease
-> client_hostname
;
3848 s
= "Hostname Unsuitable for Printing";
3852 /* Make sure outgoing packets are at least as big
3853 as a BOOTP packet. */
3854 if (packet_length
< BOOTP_MIN_LEN
)
3855 packet_length
= BOOTP_MIN_LEN
;
3857 #if defined(DHCPv6) && defined(DHCP4o6)
3858 if (dhcpv4_over_dhcpv6
&& (state
->packet
->dhcp4o6_response
!= NULL
)) {
3859 /* Say what we're doing... */
3860 log_info ("DHCP4o6 %s on %s to %s %s%s%svia %s",
3862 ? (state
-> offer
== DHCPACK
3863 ? "DHCPACK" : "DHCPOFFER")
3865 piaddr (lease
-> ip_addr
),
3866 (lease
-> hardware_addr
.hlen
3867 ? print_hw_addr (lease
-> hardware_addr
.hbuf
[0],
3868 lease
-> hardware_addr
.hlen
- 1,
3869 &lease
-> hardware_addr
.hbuf
[1])
3870 : print_hex_1(lease
->uid_len
, lease
->uid
, 60)),
3871 s
? "(" : "", s
? s
: "", s
? ") " : "",
3872 piaddr(state
->packet
->client_addr
));
3874 /* fill dhcp4o6_response */
3875 state
->packet
->dhcp4o6_response
->len
= packet_length
;
3876 state
->packet
->dhcp4o6_response
->buffer
= NULL
;
3877 if (!buffer_allocate(&state
->packet
->dhcp4o6_response
->buffer
,
3878 packet_length
, MDL
)) {
3879 log_fatal("No memory to store DHCP4o6 reply.");
3881 state
->packet
->dhcp4o6_response
->data
=
3882 state
->packet
->dhcp4o6_response
->buffer
->data
;
3883 memcpy(state
->packet
->dhcp4o6_response
->buffer
->data
,
3884 &raw
, packet_length
);
3887 free_lease_state (state
, MDL
);
3888 lease
-> state
= (struct lease_state
*)0;
3894 /* Say what we're doing... */
3895 log_info ("%s on %s to %s %s%s%svia %s",
3897 ? (state
-> offer
== DHCPACK
? "DHCPACK" : "DHCPOFFER")
3899 piaddr (lease
-> ip_addr
),
3900 (lease
-> hardware_addr
.hlen
3901 ? print_hw_addr (lease
-> hardware_addr
.hbuf
[0],
3902 lease
-> hardware_addr
.hlen
- 1,
3903 &lease
-> hardware_addr
.hbuf
[1])
3904 : print_hex_1(lease
->uid_len
, lease
->uid
, 60)),
3905 s
? "(" : "", s
? s
: "", s
? ") " : "",
3906 (state
-> giaddr
.s_addr
3907 ? inet_ntoa (state
-> giaddr
)
3908 : state
-> ip
-> name
));
3911 dump_raw ((unsigned char *)&raw
, packet_length
);
3914 /* Set up the hardware address... */
3915 hto
.hlen
= lease
-> hardware_addr
.hlen
;
3916 memcpy (hto
.hbuf
, lease
-> hardware_addr
.hbuf
, hto
.hlen
);
3918 to
.sin_family
= AF_INET
;
3920 to
.sin_len
= sizeof to
;
3922 memset (to
.sin_zero
, 0, sizeof to
.sin_zero
);
3924 /* If this was gatewayed, send it back to the gateway... */
3925 if (raw
.giaddr
.s_addr
) {
3926 to
.sin_addr
= raw
.giaddr
;
3927 if (raw
.giaddr
.s_addr
!= htonl (INADDR_LOOPBACK
))
3928 to
.sin_port
= local_port
;
3930 to
.sin_port
= remote_port
; /* For debugging. */
3932 if (fallback_interface
) {
3933 result
= send_packet(fallback_interface
, NULL
, &raw
,
3934 packet_length
, raw
.siaddr
, &to
,
3937 log_error ("%s:%d: Failed to send %d byte long "
3938 "packet over %s interface.", MDL
,
3940 fallback_interface
->name
);
3944 free_lease_state (state
, MDL
);
3945 lease
-> state
= (struct lease_state
*)0;
3949 /* If the client is RENEWING, unicast to the client using the
3950 regular IP stack. Some clients, particularly those that
3951 follow RFC1541, are buggy, and send both ciaddr and server
3952 identifier. We deal with this situation by assuming that
3953 if we got both dhcp-server-identifier and ciaddr, and
3954 giaddr was not set, then the client is on the local
3955 network, and we can therefore unicast or broadcast to it
3956 successfully. A client in REQUESTING state on another
3957 network that's making this mistake will have set giaddr,
3958 and will therefore get a relayed response from the above
3960 } else if (raw
.ciaddr
.s_addr
&&
3961 !((state
-> got_server_identifier
||
3962 (raw
.flags
& htons (BOOTP_BROADCAST
))) &&
3963 /* XXX This won't work if giaddr isn't zero, but it is: */
3964 (state
-> shared_network
==
3965 lease
-> subnet
-> shared_network
)) &&
3966 state
-> offer
== DHCPACK
) {
3967 to
.sin_addr
= raw
.ciaddr
;
3968 to
.sin_port
= remote_port
;
3970 if (fallback_interface
) {
3971 result
= send_packet(fallback_interface
, NULL
, &raw
,
3972 packet_length
, raw
.siaddr
, &to
,
3975 log_error("%s:%d: Failed to send %d byte long"
3976 " packet over %s interface.", MDL
,
3978 fallback_interface
->name
);
3981 free_lease_state (state
, MDL
);
3982 lease
-> state
= (struct lease_state
*)0;
3986 /* If it comes from a client that already knows its address
3987 and is not requesting a broadcast response, and we can
3988 unicast to a client without using the ARP protocol, sent it
3989 directly to that client. */
3990 } else if (!(raw
.flags
& htons (BOOTP_BROADCAST
)) &&
3991 can_unicast_without_arp (state
-> ip
)) {
3992 to
.sin_addr
= raw
.yiaddr
;
3993 to
.sin_port
= remote_port
;
3995 /* Otherwise, broadcast it on the local network. */
3997 to
.sin_addr
= limited_broadcast
;
3998 to
.sin_port
= remote_port
;
3999 if (!(lease
-> flags
& UNICAST_BROADCAST_HACK
))
4003 memcpy (&from
, state
-> from
.iabuf
, sizeof from
);
4005 result
= send_packet(state
->ip
, NULL
, &raw
, packet_length
,
4006 from
, &to
, unicastp
? &hto
: NULL
);
4008 log_error ("%s:%d: Failed to send %d byte long "
4009 "packet over %s interface.", MDL
,
4010 packet_length
, state
->ip
->name
);
4014 /* Free all of the entries in the option_state structure
4015 now that we're done with them. */
4017 free_lease_state (state
, MDL
);
4018 lease
-> state
= (struct lease_state
*)0;
4021 int find_lease (struct lease
**lp
,
4022 struct packet
*packet
, struct shared_network
*share
, int *ours
,
4023 int *peer_has_leases
, struct lease
*ip_lease_in
,
4024 const char *file
, int line
)
4026 struct lease
*uid_lease
= (struct lease
*)0;
4027 struct lease
*ip_lease
= (struct lease
*)0;
4028 struct lease
*hw_lease
= (struct lease
*)0;
4029 struct lease
*lease
= (struct lease
*)0;
4031 struct host_decl
*hp
= (struct host_decl
*)0;
4032 struct host_decl
*host
= (struct host_decl
*)0;
4033 struct lease
*fixed_lease
= (struct lease
*)0;
4034 struct lease
*next
= (struct lease
*)0;
4035 struct option_cache
*oc
;
4036 struct data_string d1
;
4037 int have_client_identifier
= 0;
4038 struct data_string client_identifier
;
4041 #if defined(FAILOVER_PROTOCOL)
4042 /* Quick check to see if the peer has leases. */
4043 if (peer_has_leases
) {
4046 for (pool
= share
->pools
; pool
; pool
= pool
->next
) {
4047 dhcp_failover_state_t
*peer
= pool
->failover_peer
;
4050 ((peer
->i_am
== primary
&& pool
->backup_leases
) ||
4051 (peer
->i_am
== secondary
&& pool
->free_leases
))) {
4052 *peer_has_leases
= 1;
4057 #endif /* FAILOVER_PROTOCOL */
4059 if (packet
-> raw
-> ciaddr
.s_addr
) {
4061 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
, 4);
4063 /* Look up the requested address. */
4064 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
4065 DHO_DHCP_REQUESTED_ADDRESS
);
4066 memset (&d1
, 0, sizeof d1
);
4068 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
4069 (struct client_state
*)0,
4071 (struct option_state
*)0,
4072 &global_scope
, oc
, MDL
)) {
4073 packet
-> got_requested_address
= 1;
4075 memcpy (cip
.iabuf
, d1
.data
, cip
.len
);
4076 data_string_forget (&d1
, MDL
);
4081 /* Try to find a host or lease that's been assigned to the
4082 specified unique client identifier. */
4083 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
4084 DHO_DHCP_CLIENT_IDENTIFIER
);
4085 memset (&client_identifier
, 0, sizeof client_identifier
);
4087 evaluate_option_cache (&client_identifier
,
4088 packet
, (struct lease
*)0,
4089 (struct client_state
*)0,
4090 packet
-> options
, (struct option_state
*)0,
4091 &global_scope
, oc
, MDL
)) {
4092 /* Remember this for later. */
4093 have_client_identifier
= 1;
4095 /* First, try to find a fixed host entry for the specified
4096 client identifier... */
4097 if (find_hosts_by_uid (&hp
, client_identifier
.data
,
4098 client_identifier
.len
, MDL
)) {
4099 /* Remember if we know of this client. */
4100 packet
-> known
= 1;
4101 mockup_lease (&fixed_lease
, packet
, share
, hp
);
4104 #if defined (DEBUG_FIND_LEASE)
4106 log_info ("Found host for client identifier: %s.",
4107 piaddr (fixed_lease
-> ip_addr
));
4111 if (!fixed_lease
) /* Save the host if we found one. */
4112 host_reference (&host
, hp
, MDL
);
4113 host_dereference (&hp
, MDL
);
4116 find_lease_by_uid (&uid_lease
, client_identifier
.data
,
4117 client_identifier
.len
, MDL
);
4120 /* If we didn't find a fixed lease using the uid, try doing
4121 it with the hardware address... */
4122 if (!fixed_lease
&& !host
) {
4123 if (find_hosts_by_haddr (&hp
, packet
-> raw
-> htype
,
4124 packet
-> raw
-> chaddr
,
4125 packet
-> raw
-> hlen
, MDL
)) {
4126 /* Remember if we know of this client. */
4127 packet
-> known
= 1;
4129 host_dereference (&host
, MDL
);
4130 host_reference (&host
, hp
, MDL
);
4131 host_dereference (&hp
, MDL
);
4132 mockup_lease (&fixed_lease
, packet
, share
, host
);
4133 #if defined (DEBUG_FIND_LEASE)
4135 log_info ("Found host for link address: %s.",
4136 piaddr (fixed_lease
-> ip_addr
));
4142 /* Finally, if we haven't found anything yet try again with the
4143 * host-identifier option ... */
4144 if (!fixed_lease
&& !host
) {
4145 if (find_hosts_by_option(&hp
, packet
,
4146 packet
->options
, MDL
) == 1) {
4149 host_dereference(&host
, MDL
);
4150 host_reference(&host
, hp
, MDL
);
4151 host_dereference(&hp
, MDL
);
4152 mockup_lease (&fixed_lease
, packet
, share
, host
);
4153 #if defined (DEBUG_FIND_LEASE)
4155 log_info ("Found host via host-identifier");
4161 /* If fixed_lease is present but does not match the requested
4162 IP address, and this is a DHCPREQUEST, then we can't return
4163 any other lease, so we might as well return now. */
4164 if (packet
-> packet_type
== DHCPREQUEST
&& fixed_lease
&&
4165 (fixed_lease
-> ip_addr
.len
!= cip
.len
||
4166 memcmp (fixed_lease
-> ip_addr
.iabuf
,
4167 cip
.iabuf
, cip
.len
))) {
4170 strcpy (dhcp_message
, "requested address is incorrect");
4171 #if defined (DEBUG_FIND_LEASE)
4172 log_info ("Client's fixed-address %s doesn't match %s%s",
4173 piaddr (fixed_lease
-> ip_addr
), "request ",
4174 print_dotted_quads (cip
.len
, cip
.iabuf
));
4180 * If we found leases matching the client identifier, loop through
4181 * the n_uid pointer looking for one that's actually valid. We
4182 * can't do this until we get here because we depend on
4183 * packet -> known, which may be set by either the uid host
4184 * lookup or the haddr host lookup.
4186 * Note that the n_uid lease chain is sorted in order of
4187 * preference, so the first one is the best one.
4190 isc_boolean_t do_release
= !packet
->raw
->ciaddr
.s_addr
;
4191 #if defined (DEBUG_FIND_LEASE)
4192 log_info ("trying next lease matching client id: %s",
4193 piaddr (uid_lease
-> ip_addr
));
4196 #if defined (FAILOVER_PROTOCOL)
4198 * When we lookup a lease by uid, we know the client identifier
4199 * matches the lease's record. If it is active, or was last
4200 * active with the same client, we can trivially extend it.
4201 * If is not or was not active, we can allocate it to this
4202 * client if it matches the usual free/backup criteria (which
4203 * is contained in lease_mine_to_reallocate()).
4205 if (uid_lease
->binding_state
!= FTS_ACTIVE
&&
4206 uid_lease
->rewind_binding_state
!= FTS_ACTIVE
&&
4207 !lease_mine_to_reallocate(uid_lease
)) {
4208 #if defined (DEBUG_FIND_LEASE)
4209 log_info("not active or not mine to allocate: %s",
4210 piaddr(uid_lease
->ip_addr
));
4216 if (uid_lease
-> subnet
-> shared_network
!= share
) {
4217 #if defined (DEBUG_FIND_LEASE)
4218 log_info ("wrong network segment: %s",
4219 piaddr (uid_lease
-> ip_addr
));
4221 /* Allow multiple leases using the same UID
4222 on different subnetworks. */
4223 do_release
= ISC_FALSE
;
4227 if ((uid_lease
-> pool
-> prohibit_list
&&
4228 permitted (packet
, uid_lease
-> pool
-> prohibit_list
)) ||
4229 (uid_lease
-> pool
-> permit_list
&&
4230 !permitted (packet
, uid_lease
-> pool
-> permit_list
))) {
4231 #if defined (DEBUG_FIND_LEASE)
4232 log_info ("not permitted: %s",
4233 piaddr (uid_lease
-> ip_addr
));
4236 if (uid_lease
-> n_uid
)
4237 lease_reference (&next
,
4238 uid_lease
-> n_uid
, MDL
);
4240 release_lease (uid_lease
, packet
);
4241 lease_dereference (&uid_lease
, MDL
);
4243 lease_reference (&uid_lease
, next
, MDL
);
4244 lease_dereference (&next
, MDL
);
4250 #if defined (DEBUG_FIND_LEASE)
4252 log_info ("Found lease for client id: %s.",
4253 piaddr (uid_lease
-> ip_addr
));
4256 /* Find a lease whose hardware address matches, whose client
4257 * identifier matches (or equally doesn't have one), that's
4258 * permitted, and that's on the correct subnet.
4260 * Note that the n_hw chain is sorted in order of preference, so
4261 * the first one found is the best one.
4263 h
.hlen
= packet
-> raw
-> hlen
+ 1;
4264 h
.hbuf
[0] = packet
-> raw
-> htype
;
4265 memcpy (&h
.hbuf
[1], packet
-> raw
-> chaddr
, packet
-> raw
-> hlen
);
4266 find_lease_by_hw_addr (&hw_lease
, h
.hbuf
, h
.hlen
, MDL
);
4268 #if defined (DEBUG_FIND_LEASE)
4269 log_info ("trying next lease matching hw addr: %s",
4270 piaddr (hw_lease
-> ip_addr
));
4272 #if defined (FAILOVER_PROTOCOL)
4274 * When we lookup a lease by chaddr, we know the MAC address
4275 * matches the lease record (we will check if the lease has a
4276 * client-id the client does not next). If the lease is
4277 * currently active or was last active with this client, we can
4278 * trivially extend it. Otherwise, there are a set of rules
4279 * that govern if we can reallocate this lease to any client
4280 * ("lease_mine_to_reallocate()") including this one.
4282 if (hw_lease
->binding_state
!= FTS_ACTIVE
&&
4283 hw_lease
->rewind_binding_state
!= FTS_ACTIVE
&&
4284 !lease_mine_to_reallocate(hw_lease
)) {
4285 #if defined (DEBUG_FIND_LEASE)
4286 log_info("not active or not mine to allocate: %s",
4287 piaddr(hw_lease
->ip_addr
));
4294 * This conditional skips "potentially active" leases (leases
4295 * we think are expired may be extended by the peer, etc) that
4296 * may be assigned to a differently /client-identified/ client
4297 * with the same MAC address.
4299 if (hw_lease
-> binding_state
!= FTS_FREE
&&
4300 hw_lease
-> binding_state
!= FTS_BACKUP
&&
4302 (!have_client_identifier
||
4303 hw_lease
-> uid_len
!= client_identifier
.len
||
4304 memcmp (hw_lease
-> uid
, client_identifier
.data
,
4305 hw_lease
-> uid_len
))) {
4306 #if defined (DEBUG_FIND_LEASE)
4307 log_info ("wrong client identifier: %s",
4308 piaddr (hw_lease
-> ip_addr
));
4312 if (hw_lease
-> subnet
-> shared_network
!= share
) {
4313 #if defined (DEBUG_FIND_LEASE)
4314 log_info ("wrong network segment: %s",
4315 piaddr (hw_lease
-> ip_addr
));
4319 if ((hw_lease
-> pool
-> prohibit_list
&&
4320 permitted (packet
, hw_lease
-> pool
-> prohibit_list
)) ||
4321 (hw_lease
-> pool
-> permit_list
&&
4322 !permitted (packet
, hw_lease
-> pool
-> permit_list
))) {
4323 #if defined (DEBUG_FIND_LEASE)
4324 log_info ("not permitted: %s",
4325 piaddr (hw_lease
-> ip_addr
));
4327 if (!packet
-> raw
-> ciaddr
.s_addr
)
4328 release_lease (hw_lease
, packet
);
4330 if (hw_lease
-> n_hw
)
4331 lease_reference (&next
, hw_lease
-> n_hw
, MDL
);
4332 lease_dereference (&hw_lease
, MDL
);
4334 lease_reference (&hw_lease
, next
, MDL
);
4335 lease_dereference (&next
, MDL
);
4341 #if defined (DEBUG_FIND_LEASE)
4343 log_info ("Found lease for hardware address: %s.",
4344 piaddr (hw_lease
-> ip_addr
));
4347 /* Try to find a lease that's been allocated to the client's
4350 lease_reference (&ip_lease
, ip_lease_in
, MDL
);
4352 find_lease_by_ip_addr (&ip_lease
, cip
, MDL
);
4354 #if defined (DEBUG_FIND_LEASE)
4356 log_info ("Found lease for requested address: %s.",
4357 piaddr (ip_lease
-> ip_addr
));
4360 /* If ip_lease is valid at this point, set ours to one, so that
4361 even if we choose a different lease, we know that the address
4362 the client was requesting was ours, and thus we can NAK it. */
4363 if (ip_lease
&& ours
)
4366 /* If the requested IP address isn't on the network the packet
4367 came from, don't use it. Allow abandoned leases to be matched
4368 here - if the client is requesting it, there's a decent chance
4369 that it's because the lease database got trashed and a client
4370 that thought it had this lease answered an ARP or PING, causing the
4371 lease to be abandoned. If so, this request probably came from
4373 if (ip_lease
&& (ip_lease
-> subnet
-> shared_network
!= share
)) {
4376 #if defined (DEBUG_FIND_LEASE)
4377 log_info ("...but it was on the wrong shared network.");
4379 strcpy (dhcp_message
, "requested address on bad subnet");
4380 lease_dereference (&ip_lease
, MDL
);
4384 * If the requested address is in use (or potentially in use) by
4385 * a different client, it can't be granted.
4387 * This first conditional only detects if the lease is currently
4388 * identified to a different client (client-id and/or chaddr
4389 * mismatch). In this case we may not want to give the client the
4390 * lease, if doing so may potentially be an addressing conflict.
4394 (!have_client_identifier
||
4395 ip_lease
-> uid_len
!= client_identifier
.len
||
4396 memcmp (ip_lease
-> uid
, client_identifier
.data
,
4397 ip_lease
-> uid_len
)) :
4398 (ip_lease
-> hardware_addr
.hbuf
[0] != packet
-> raw
-> htype
||
4399 ip_lease
-> hardware_addr
.hlen
!= packet
-> raw
-> hlen
+ 1 ||
4400 memcmp (&ip_lease
-> hardware_addr
.hbuf
[1],
4401 packet
-> raw
-> chaddr
,
4402 (unsigned)(ip_lease
-> hardware_addr
.hlen
- 1))))) {
4404 * A lease is unavailable for allocation to a new client if
4405 * it is not in the FREE or BACKUP state. There may be
4406 * leases that are in the expired state with a rewinding
4407 * state that is free or backup, but these will be processed
4408 * into the free or backup states by expiration processes, so
4409 * checking for them here is superfluous.
4411 if (ip_lease
-> binding_state
!= FTS_FREE
&&
4412 ip_lease
-> binding_state
!= FTS_BACKUP
) {
4413 #if defined (DEBUG_FIND_LEASE)
4414 log_info ("rejecting lease for requested address.");
4416 /* If we're rejecting it because the peer has
4417 it, don't set "ours", because we shouldn't NAK. */
4418 if (ours
&& ip_lease
-> binding_state
!= FTS_ACTIVE
)
4420 lease_dereference (&ip_lease
, MDL
);
4425 * If we got an ip_lease and a uid_lease or hw_lease, and ip_lease
4426 * is/was not active, and is not ours to reallocate, forget about it.
4428 if (ip_lease
&& (uid_lease
|| hw_lease
) &&
4429 ip_lease
->binding_state
!= FTS_ACTIVE
&&
4430 ip_lease
->rewind_binding_state
!= FTS_ACTIVE
&&
4431 #if defined(FAILOVER_PROTOCOL)
4432 !lease_mine_to_reallocate(ip_lease
) &&
4434 packet
->packet_type
== DHCPDISCOVER
) {
4435 #if defined (DEBUG_FIND_LEASE)
4436 log_info("ip lease not active or not ours to offer.");
4438 lease_dereference(&ip_lease
, MDL
);
4441 /* If for some reason the client has more than one lease
4442 on the subnet that matches its uid, pick the one that
4443 it asked for and (if we can) free the other. */
4444 if (ip_lease
&& ip_lease
->binding_state
== FTS_ACTIVE
&&
4445 ip_lease
->uid
&& ip_lease
!= uid_lease
) {
4446 if (have_client_identifier
&&
4447 (ip_lease
-> uid_len
== client_identifier
.len
) &&
4448 !memcmp (client_identifier
.data
,
4449 ip_lease
-> uid
, ip_lease
-> uid_len
)) {
4451 if (uid_lease
->binding_state
== FTS_ACTIVE
) {
4452 log_error ("client %s has duplicate%s on %s",
4454 (packet
-> raw
-> htype
,
4455 packet
-> raw
-> hlen
,
4456 packet
-> raw
-> chaddr
)),
4458 (ip_lease
-> subnet
->
4459 shared_network
-> name
));
4461 /* If the client is REQUESTing the lease,
4462 it shouldn't still be using the old
4463 one, so we can free it for allocation. */
4465 uid_lease
->binding_state
== FTS_ACTIVE
&&
4466 !packet
-> raw
-> ciaddr
.s_addr
&&
4468 uid_lease
-> subnet
-> shared_network
) &&
4469 packet
-> packet_type
== DHCPREQUEST
)
4470 release_lease (uid_lease
, packet
);
4472 lease_dereference (&uid_lease
, MDL
);
4473 lease_reference (&uid_lease
, ip_lease
, MDL
);
4477 /* If we get to here and fixed_lease is not null, that means
4478 that there are both a dynamic lease and a fixed-address
4479 declaration for the same IP address. */
4480 if (packet
-> packet_type
== DHCPREQUEST
&& fixed_lease
) {
4481 lease_dereference (&fixed_lease
, MDL
);
4483 log_error ("Dynamic and static leases present for %s.",
4485 log_error ("Remove host declaration %s or remove %s",
4486 (fixed_lease
&& fixed_lease
-> host
4487 ? (fixed_lease
-> host
-> name
4488 ? fixed_lease
-> host
-> name
4492 log_error ("from the dynamic address pool for %s",
4493 ip_lease
-> subnet
-> shared_network
-> name
4496 lease_dereference (&ip_lease
, MDL
);
4497 strcpy (dhcp_message
,
4498 "database conflict - call for help!");
4501 if (ip_lease
&& ip_lease
!= uid_lease
) {
4502 #if defined (DEBUG_FIND_LEASE)
4503 log_info ("requested address not available.");
4505 lease_dereference (&ip_lease
, MDL
);
4509 /* If we get to here with both fixed_lease and ip_lease not
4510 null, then we have a configuration file bug. */
4511 if (packet
-> packet_type
== DHCPREQUEST
&& fixed_lease
&& ip_lease
)
4514 /* Toss extra pointers to the same lease... */
4515 if (hw_lease
&& hw_lease
== uid_lease
) {
4516 #if defined (DEBUG_FIND_LEASE)
4517 log_info ("hardware lease and uid lease are identical.");
4519 lease_dereference (&hw_lease
, MDL
);
4521 if (ip_lease
&& ip_lease
== hw_lease
) {
4522 lease_dereference (&hw_lease
, MDL
);
4523 #if defined (DEBUG_FIND_LEASE)
4524 log_info ("hardware lease and ip lease are identical.");
4527 if (ip_lease
&& ip_lease
== uid_lease
) {
4528 lease_dereference (&uid_lease
, MDL
);
4529 #if defined (DEBUG_FIND_LEASE)
4530 log_info ("uid lease and ip lease are identical.");
4534 /* Make sure the client is permitted to use the requested lease. */
4536 ((ip_lease
-> pool
-> prohibit_list
&&
4537 permitted (packet
, ip_lease
-> pool
-> prohibit_list
)) ||
4538 (ip_lease
-> pool
-> permit_list
&&
4539 !permitted (packet
, ip_lease
-> pool
-> permit_list
)))) {
4540 if (!packet
->raw
->ciaddr
.s_addr
&&
4541 (ip_lease
->binding_state
== FTS_ACTIVE
))
4542 release_lease (ip_lease
, packet
);
4544 lease_dereference (&ip_lease
, MDL
);
4548 ((uid_lease
-> pool
-> prohibit_list
&&
4549 permitted (packet
, uid_lease
-> pool
-> prohibit_list
)) ||
4550 (uid_lease
-> pool
-> permit_list
&&
4551 !permitted (packet
, uid_lease
-> pool
-> permit_list
)))) {
4552 if (!packet
-> raw
-> ciaddr
.s_addr
)
4553 release_lease (uid_lease
, packet
);
4554 lease_dereference (&uid_lease
, MDL
);
4558 ((hw_lease
-> pool
-> prohibit_list
&&
4559 permitted (packet
, hw_lease
-> pool
-> prohibit_list
)) ||
4560 (hw_lease
-> pool
-> permit_list
&&
4561 !permitted (packet
, hw_lease
-> pool
-> permit_list
)))) {
4562 if (!packet
-> raw
-> ciaddr
.s_addr
)
4563 release_lease (hw_lease
, packet
);
4564 lease_dereference (&hw_lease
, MDL
);
4567 /* If we've already eliminated the lease, it wasn't there to
4568 begin with. If we have come up with a matching lease,
4569 set the message to bad network in case we have to throw it out. */
4571 strcpy (dhcp_message
, "requested address not available");
4574 /* If this is a DHCPREQUEST, make sure the lease we're going to return
4575 matches the requested IP address. If it doesn't, don't return a
4577 if (packet
-> packet_type
== DHCPREQUEST
&&
4578 !ip_lease
&& !fixed_lease
) {
4579 #if defined (DEBUG_FIND_LEASE)
4580 log_info ("no applicable lease found for DHCPREQUEST.");
4585 /* At this point, if fixed_lease is nonzero, we can assign it to
4588 lease_reference (&lease
, fixed_lease
, MDL
);
4589 lease_dereference (&fixed_lease
, MDL
);
4590 #if defined (DEBUG_FIND_LEASE)
4591 log_info ("choosing fixed address.");
4595 /* If we got a lease that matched the ip address and don't have
4596 a better offer, use that; otherwise, release it. */
4599 if (!packet
-> raw
-> ciaddr
.s_addr
)
4600 release_lease (ip_lease
, packet
);
4601 #if defined (DEBUG_FIND_LEASE)
4602 log_info ("not choosing requested address (!).");
4604 lease_dereference (&ip_lease
, MDL
);
4606 #if defined (DEBUG_FIND_LEASE)
4607 log_info ("choosing lease on requested address.");
4609 lease_reference (&lease
, ip_lease
, MDL
);
4611 host_dereference (&lease
-> host
, MDL
);
4615 /* If we got a lease that matched the client identifier, we may want
4616 to use it, but if we already have a lease we like, we must free
4617 the lease that matched the client identifier. */
4620 log_error("uid lease %s for client %s is duplicate "
4622 piaddr(uid_lease
->ip_addr
),
4623 print_hw_addr(packet
->raw
->htype
,
4625 packet
->raw
->chaddr
),
4626 uid_lease
->subnet
->shared_network
->name
);
4628 if (!packet
-> raw
-> ciaddr
.s_addr
&&
4629 packet
-> packet_type
== DHCPREQUEST
&&
4630 uid_lease
-> binding_state
== FTS_ACTIVE
)
4631 release_lease(uid_lease
, packet
);
4632 #if defined (DEBUG_FIND_LEASE)
4633 log_info ("not choosing uid lease.");
4636 lease_reference (&lease
, uid_lease
, MDL
);
4638 host_dereference (&lease
-> host
, MDL
);
4639 #if defined (DEBUG_FIND_LEASE)
4640 log_info ("choosing uid lease.");
4643 lease_dereference (&uid_lease
, MDL
);
4646 /* The lease that matched the hardware address is treated likewise. */
4649 #if defined (DEBUG_FIND_LEASE)
4650 log_info ("not choosing hardware lease.");
4653 /* We're a little lax here - if the client didn't
4654 send a client identifier and it's a bootp client,
4655 but the lease has a client identifier, we still
4656 let the client have a lease. */
4657 if (!hw_lease
-> uid_len
||
4658 (have_client_identifier
4659 ? (hw_lease
-> uid_len
==
4660 client_identifier
.len
&&
4661 !memcmp (hw_lease
-> uid
,
4662 client_identifier
.data
,
4663 client_identifier
.len
))
4664 : packet
-> packet_type
== 0)) {
4665 lease_reference (&lease
, hw_lease
, MDL
);
4667 host_dereference (&lease
-> host
, MDL
);
4668 #if defined (DEBUG_FIND_LEASE)
4669 log_info ("choosing hardware lease.");
4672 #if defined (DEBUG_FIND_LEASE)
4673 log_info ("not choosing hardware lease: %s.",
4678 lease_dereference (&hw_lease
, MDL
);
4682 * If we found a host_decl but no matching address, try to
4683 * find a host_decl that has no address, and if there is one,
4684 * hang it off the lease so that we can use the supplied
4687 if (lease
&& host
&& !lease
->host
) {
4688 struct host_decl
*p
= NULL
;
4689 struct host_decl
*n
= NULL
;
4691 host_reference(&p
, host
, MDL
);
4693 if (!p
->fixed_addr
) {
4695 * If the lease is currently active, then it
4696 * must be allocated to the present client.
4697 * We store a reference to the host record on
4698 * the lease to save a lookup later (in
4699 * ack_lease()). We mustn't refer to the host
4700 * record on non-active leases because the
4701 * client may be denied later.
4703 * XXX: Not having this reference (such as in
4704 * DHCPDISCOVER/INIT) means ack_lease will have
4705 * to perform this lookup a second time. This
4706 * hopefully isn't a problem as DHCPREQUEST is
4707 * more common than DHCPDISCOVER.
4709 if (lease
->binding_state
== FTS_ACTIVE
)
4710 host_reference(&lease
->host
, p
, MDL
);
4712 host_dereference(&p
, MDL
);
4715 if (p
->n_ipaddr
!= NULL
)
4716 host_reference(&n
, p
->n_ipaddr
, MDL
);
4717 host_dereference(&p
, MDL
);
4719 host_reference(&p
, n
, MDL
);
4720 host_dereference(&n
, MDL
);
4725 /* If we find an abandoned lease, but it's the one the client
4726 requested, we assume that previous bugginess on the part
4727 of the client, or a server database loss, caused the lease to
4728 be abandoned, so we reclaim it and let the client have it. */
4730 (lease
-> binding_state
== FTS_ABANDONED
) &&
4731 lease
== ip_lease
&&
4732 packet
-> packet_type
== DHCPREQUEST
) {
4733 log_error ("Reclaiming REQUESTed abandoned IP address %s.",
4734 piaddr (lease
-> ip_addr
));
4735 } else if (lease
&& (lease
-> binding_state
== FTS_ABANDONED
)) {
4736 /* Otherwise, if it's not the one the client requested, we do not
4737 return it - instead, we claim it's ours, causing a DHCPNAK to be
4738 sent if this lookup is for a DHCPREQUEST, and force the client
4739 to go back through the allocation process. */
4742 lease_dereference (&lease
, MDL
);
4746 if (have_client_identifier
)
4747 data_string_forget (&client_identifier
, MDL
);
4750 lease_dereference (&fixed_lease
, MDL
);
4752 lease_dereference (&hw_lease
, MDL
);
4754 lease_dereference (&uid_lease
, MDL
);
4756 lease_dereference (&ip_lease
, MDL
);
4758 host_dereference (&host
, MDL
);
4761 #if defined (DEBUG_FIND_LEASE)
4762 log_info ("Returning lease: %s.",
4763 piaddr (lease
-> ip_addr
));
4765 lease_reference (lp
, lease
, file
, line
);
4766 lease_dereference (&lease
, MDL
);
4769 #if defined (DEBUG_FIND_LEASE)
4770 log_info ("Not returning a lease.");
4775 /* Search the provided host_decl structure list for an address that's on
4776 the specified shared network. If one is found, mock up and return a
4777 lease structure for it; otherwise return the null pointer. */
4779 int mockup_lease (struct lease
**lp
, struct packet
*packet
,
4780 struct shared_network
*share
, struct host_decl
*hp
)
4782 struct lease
*lease
= (struct lease
*)0;
4783 struct host_decl
*rhp
= (struct host_decl
*)0;
4785 if (lease_allocate (&lease
, MDL
) != ISC_R_SUCCESS
)
4787 if (host_reference (&rhp
, hp
, MDL
) != ISC_R_SUCCESS
) {
4788 lease_dereference (&lease
, MDL
);
4791 if (!find_host_for_network (&lease
-> subnet
,
4792 &rhp
, &lease
-> ip_addr
, share
)) {
4793 lease_dereference (&lease
, MDL
);
4794 host_dereference (&rhp
, MDL
);
4797 host_reference (&lease
-> host
, rhp
, MDL
);
4798 if (rhp
-> client_identifier
.len
> sizeof lease
-> uid_buf
)
4799 lease
-> uid
= dmalloc (rhp
-> client_identifier
.len
, MDL
);
4801 lease
-> uid
= lease
-> uid_buf
;
4802 if (!lease
-> uid
) {
4803 lease_dereference (&lease
, MDL
);
4804 host_dereference (&rhp
, MDL
);
4807 memcpy (lease
-> uid
, rhp
-> client_identifier
.data
,
4808 rhp
-> client_identifier
.len
);
4809 lease
-> uid_len
= rhp
-> client_identifier
.len
;
4810 lease
-> hardware_addr
= rhp
-> interface
;
4811 lease
-> starts
= lease
-> cltt
= lease
-> ends
= MIN_TIME
;
4812 lease
-> flags
= STATIC_LEASE
;
4813 lease
-> binding_state
= FTS_FREE
;
4815 lease_reference (lp
, lease
, MDL
);
4817 lease_dereference (&lease
, MDL
);
4818 host_dereference (&rhp
, MDL
);
4822 /* Look through all the pools in a list starting with the specified pool
4823 for a free lease. We try to find a virgin lease if we can. If we
4824 don't find a virgin lease, we try to find a non-virgin lease that's
4825 free. If we can't find one of those, we try to reclaim an abandoned
4826 lease. If all of these possibilities fail to pan out, we don't return
4829 int allocate_lease (struct lease
**lp
, struct packet
*packet
,
4830 struct pool
*pool
, int *peer_has_leases
)
4832 struct lease
*lease
= NULL
;
4833 struct lease
*candl
= NULL
;
4835 for (; pool
; pool
= pool
-> next
) {
4836 if ((pool
-> prohibit_list
&&
4837 permitted (packet
, pool
-> prohibit_list
)) ||
4838 (pool
-> permit_list
&&
4839 !permitted (packet
, pool
-> permit_list
)))
4842 #if defined (FAILOVER_PROTOCOL)
4843 /* Peer_has_leases just says that we found at least one
4844 free lease. If no free lease is returned, the caller
4845 can deduce that this means the peer is hogging all the
4846 free leases, so we can print a better error message. */
4847 /* XXX Do we need code here to ignore PEER_IS_OWNER and
4848 * XXX just check tstp if we're in, e.g., PARTNER_DOWN?
4849 * XXX Where do we deal with CONFLICT_DETECTED, et al? */
4850 /* XXX This should be handled by the lease binding "state
4851 * XXX machine" - that is, when we get here, if a lease
4852 * XXX could be allocated, it will have the correct
4853 * XXX binding state so that the following code will
4854 * XXX result in its being allocated. */
4855 /* Skip to the most expired lease in the pool that is not
4856 * owned by a failover peer. */
4857 if (pool
->failover_peer
!= NULL
) {
4858 struct lease
*peerl
= NULL
;
4859 if (pool
->failover_peer
->i_am
== primary
) {
4860 candl
= LEASE_GET_FIRST(pool
->free
);
4863 * In normal operation, we never want to touch
4864 * the peer's leases. In partner-down
4865 * operation, we need to be able to pick up
4866 * the peer's leases after STOS+MCLT.
4868 peerl
= LEASE_GET_FIRST(pool
->backup
);
4869 if (peerl
!= NULL
) {
4870 if (((candl
== NULL
) ||
4871 (candl
->ends
> peerl
->ends
)) &&
4872 lease_mine_to_reallocate(peerl
)) {
4875 *peer_has_leases
= 1;
4879 candl
= LEASE_GET_FIRST(pool
->backup
);
4881 peerl
= LEASE_GET_FIRST(pool
->free
);
4882 if (peerl
!= NULL
) {
4883 if (((candl
== NULL
) ||
4884 (candl
->ends
> peerl
->ends
)) &&
4885 lease_mine_to_reallocate(peerl
)) {
4888 *peer_has_leases
= 1;
4893 /* Try abandoned leases as a last resort. */
4894 peerl
= LEASE_GET_FIRST(pool
->abandoned
);
4895 if ((candl
== NULL
) && (peerl
!= NULL
) &&
4896 lease_mine_to_reallocate(peerl
))
4901 if (LEASE_NOT_EMPTY(pool
->free
))
4902 candl
= LEASE_GET_FIRST(pool
->free
);
4904 candl
= LEASE_GET_FIRST(pool
->abandoned
);
4908 * XXX: This may not match with documented expectation.
4909 * It's expected that when we OFFER a lease, we set its
4910 * ends time forward 2 minutes so that it gets sorted to
4911 * the end of its free list (avoiding a similar allocation
4912 * to another client). It is not expected that we issue a
4913 * "no free leases" error when the last lease has been
4914 * offered, but it's not exactly broken either.
4917 (candl
->binding_state
!= FTS_ABANDONED
&&
4918 (candl
->ends
> cur_time
))) {
4928 * There are tiers of lease state preference, listed here in
4929 * reverse order (least to most preferential):
4934 * If the selected lease and candidate are both of the same
4935 * state, select the oldest (longest ago) expiration time
4936 * between the two. If the candidate lease is of a higher
4937 * preferred grade over the selected lease, use it.
4939 if ((lease
-> binding_state
== FTS_ABANDONED
) &&
4940 ((candl
-> binding_state
!= FTS_ABANDONED
) ||
4941 (candl
-> ends
< lease
-> ends
))) {
4944 } else if (candl
-> binding_state
== FTS_ABANDONED
)
4947 if ((lease
-> uid_len
|| lease
-> hardware_addr
.hlen
) &&
4948 ((!candl
-> uid_len
&& !candl
-> hardware_addr
.hlen
) ||
4949 (candl
-> ends
< lease
-> ends
))) {
4952 } else if (candl
-> uid_len
|| candl
-> hardware_addr
.hlen
)
4955 if (candl
-> ends
< lease
-> ends
)
4959 if (lease
!= NULL
) {
4960 if (lease
->binding_state
== FTS_ABANDONED
)
4961 log_error("Reclaiming abandoned lease %s.",
4962 piaddr(lease
->ip_addr
));
4965 * XXX: For reliability, we go ahead and remove the host
4966 * record and try to move on. For correctness, if there
4967 * are any other stale host vectors, we want to find them.
4969 if (lease
->host
!= NULL
) {
4970 log_debug("soft impossible condition (%s:%d): stale "
4971 "host \"%s\" found on lease %s", MDL
,
4973 piaddr(lease
->ip_addr
));
4974 host_dereference(&lease
->host
, MDL
);
4977 lease_reference (lp
, lease
, MDL
);
4984 /* Determine whether or not a permit exists on a particular permit list
4985 that matches the specified packet, returning nonzero if so, zero if
4988 int permitted (packet
, permit_list
)
4989 struct packet
*packet
;
4990 struct permit
*permit_list
;
4995 for (p
= permit_list
; p
; p
= p
-> next
) {
4996 switch (p
-> type
) {
4997 case permit_unknown_clients
:
4998 if (!packet
-> known
)
5002 case permit_known_clients
:
5003 if (packet
-> known
)
5007 case permit_authenticated_clients
:
5008 if (packet
-> authenticated
)
5012 case permit_unauthenticated_clients
:
5013 if (!packet
-> authenticated
)
5017 case permit_all_clients
:
5020 case permit_dynamic_bootp_clients
:
5021 if (!packet
-> options_valid
||
5022 !packet
-> packet_type
)
5027 for (i
= 0; i
< packet
-> class_count
; i
++) {
5028 if (p
-> class == packet
-> classes
[i
])
5030 if (packet
-> classes
[i
] &&
5031 packet
-> classes
[i
] -> superclass
&&
5032 (packet
-> classes
[i
] -> superclass
==
5039 if (cur_time
> p
->after
)
5047 #if defined(DHCPv6) && defined(DHCP4o6)
5048 static int locate_network6 (packet
)
5049 struct packet
*packet
;
5051 const struct packet
*chk_packet
;
5052 const struct in6_addr
*link_addr
, *first_link_addr
;
5054 struct data_string data
;
5055 struct subnet
*subnet
= NULL
;
5056 struct option_cache
*oc
;
5058 /* from locate_network() */
5060 /* See if there's a Relay Agent Link Selection Option, or a
5061 * Subnet Selection Option. The Link-Select and Subnet-Select
5062 * are formatted and used precisely the same, but we must prefer
5063 * the link-select over the subnet-select.
5064 * BTW in DHCPv4 over DHCPv6 no cross version relay was specified
5065 * so it is unlikely to see a link-select.
5067 if ((oc
= lookup_option(&agent_universe
, packet
->options
,
5068 RAI_LINK_SELECT
)) == NULL
)
5069 oc
= lookup_option(&dhcp_universe
, packet
->options
,
5070 DHO_SUBNET_SELECTION
);
5072 /* If there's an option indicating link connection or subnet
5073 * selection, and it's valid, use it to figure out the subnet.
5074 * If it's not valid, fail.
5077 memset(&data
, 0, sizeof data
);
5078 if (!evaluate_option_cache(&data
, packet
, NULL
, NULL
,
5079 packet
->options
, NULL
,
5080 &global_scope
, oc
, MDL
)) {
5083 if (data
.len
== 0) {
5086 if (data
.len
!= 4) {
5087 data_string_forget(&data
, MDL
);
5091 memcpy(ia
.iabuf
, data
.data
, 4);
5092 data_string_forget(&data
, MDL
);
5094 if (find_subnet(&subnet
, ia
, MDL
)) {
5095 shared_network_reference(&packet
->shared_network
,
5096 subnet
->shared_network
, MDL
);
5097 subnet_dereference(&subnet
, MDL
);
5103 /* See if there is a giaddr (still unlikely), if there is one
5104 * use it to figure out the subnet. If it's not valid, fail.
5106 if (packet
->raw
->giaddr
.s_addr
) {
5108 memcpy(ia
.iabuf
, &packet
->raw
->giaddr
, 4);
5110 if (find_subnet(&subnet
, ia
, MDL
)) {
5111 shared_network_reference(&packet
->shared_network
,
5112 subnet
->shared_network
, MDL
);
5113 subnet_dereference(&subnet
, MDL
);
5119 /* from shared_network_from_packet6() */
5121 /* First, find the link address where the packet from the client
5122 * first appeared (if this packet was relayed).
5124 first_link_addr
= NULL
;
5125 chk_packet
= packet
->dhcpv6_container_packet
;
5126 while (chk_packet
!= NULL
) {
5127 link_addr
= &chk_packet
->dhcpv6_link_address
;
5128 if (!IN6_IS_ADDR_UNSPECIFIED(link_addr
) &&
5129 !IN6_IS_ADDR_LINKLOCAL(link_addr
)) {
5130 first_link_addr
= link_addr
;
5133 chk_packet
= chk_packet
->dhcpv6_container_packet
;
5136 /* If there is a relayed link address, find the subnet associated
5137 * with that, and use that to get the appropriate shared_network.
5139 if (first_link_addr
!= NULL
) {
5140 ia
.len
= sizeof(*first_link_addr
);
5141 memcpy(ia
.iabuf
, first_link_addr
, sizeof(*first_link_addr
));
5142 if (find_subnet (&subnet
, ia
, MDL
)) {
5143 shared_network_reference(&packet
->shared_network
,
5144 subnet
->shared_network
, MDL
);
5145 subnet_dereference(&subnet
, MDL
);
5151 /* If there is no link address, we will use the interface
5152 * that this packet came in on to pick the shared_network.
5154 if (packet
->interface
!= NULL
) {
5155 if (packet
->interface
->shared_network
== NULL
)
5157 shared_network_reference(&packet
->shared_network
,
5158 packet
->interface
->shared_network
,
5163 /* We shouldn't be able to get here but if there is no link
5164 * address and no interface we don't know where to get the
5165 * shared_network from, log an error and return an error.
5167 log_error("No interface and no link address "
5168 "can't determine DHCP4o6 shared network");
5173 int locate_network (packet
)
5174 struct packet
*packet
;
5177 struct data_string data
;
5178 struct subnet
*subnet
= (struct subnet
*)0;
5179 struct option_cache
*oc
;
5181 #if defined(DHCPv6) && defined(DHCP4o6)
5182 if (dhcpv4_over_dhcpv6
&& (packet
->dhcp4o6_response
!= NULL
)) {
5183 return (locate_network6 (packet
));
5187 /* See if there's a Relay Agent Link Selection Option, or a
5188 * Subnet Selection Option. The Link-Select and Subnet-Select
5189 * are formatted and used precisely the same, but we must prefer
5190 * the link-select over the subnet-select.
5192 if ((oc
= lookup_option(&agent_universe
, packet
->options
,
5193 RAI_LINK_SELECT
)) == NULL
)
5194 oc
= lookup_option(&dhcp_universe
, packet
->options
,
5195 DHO_SUBNET_SELECTION
);
5197 /* If there's no SSO and no giaddr, then use the shared_network
5198 from the interface, if there is one. If not, fail. */
5199 if (!oc
&& !packet
-> raw
-> giaddr
.s_addr
) {
5200 if (packet
-> interface
-> shared_network
) {
5201 shared_network_reference
5202 (&packet
-> shared_network
,
5203 packet
-> interface
-> shared_network
, MDL
);
5209 /* If there's an option indicating link connection, and it's valid,
5210 * use it to figure out the subnet. If it's not valid, fail.
5213 memset (&data
, 0, sizeof data
);
5214 if (!evaluate_option_cache (&data
, packet
, (struct lease
*)0,
5215 (struct client_state
*)0,
5217 (struct option_state
*)0,
5218 &global_scope
, oc
, MDL
)) {
5221 if (data
.len
== 0) {
5224 if (data
.len
!= 4) {
5225 data_string_forget (&data
, MDL
);
5229 memcpy (ia
.iabuf
, data
.data
, 4);
5230 data_string_forget (&data
, MDL
);
5233 memcpy (ia
.iabuf
, &packet
-> raw
-> giaddr
, 4);
5236 /* If we know the subnet on which the IP address lives, use it. */
5237 if (find_subnet (&subnet
, ia
, MDL
)) {
5238 shared_network_reference (&packet
-> shared_network
,
5239 subnet
-> shared_network
, MDL
);
5240 subnet_dereference (&subnet
, MDL
);
5244 /* Otherwise, fail. */
5249 * Try to figure out the source address to send packets from.
5251 * from is the address structure we use to return any address
5254 * options is the option cache to search. This may include
5255 * options from the incoming packet and configuration information.
5257 * out_options is the outgoing option cache. This cache
5258 * may be the same as options. If out_options isn't NULL
5259 * we may save the server address option into it. We do so
5260 * if out_options is different than options or if the option
5261 * wasn't in options and we needed to find the address elsewhere.
5263 * packet is the state structure for the incoming packet
5265 * When finding the address we first check to see if it is
5266 * in the options list. If it isn't we use the first address
5267 * from the interface.
5269 * While this is slightly more complicated than I'd like it allows
5270 * us to use the same code in several different places. ack,
5271 * inform and lease query use it to find the address and fill
5272 * in the options if we get the address from the interface.
5273 * nack uses it to find the address and copy it to the outgoing
5274 * cache. dhcprequest uses it to find the address for comparison
5275 * and doesn't need to add it to an outgoing list.
5279 get_server_source_address(struct in_addr
*from
,
5280 struct option_state
*options
,
5281 struct option_state
*out_options
,
5282 struct packet
*packet
) {
5283 unsigned option_num
;
5284 struct option_cache
*oc
= NULL
;
5285 struct data_string d
;
5286 struct in_addr
*a
= NULL
;
5287 isc_boolean_t found
= ISC_FALSE
;
5290 memset(&d
, 0, sizeof(d
));
5291 memset(from
, 0, sizeof(*from
));
5293 option_num
= DHO_DHCP_SERVER_IDENTIFIER
;
5294 oc
= lookup_option(&dhcp_universe
, options
, option_num
);
5296 if (evaluate_option_cache(&d
, packet
, NULL
, NULL
,
5297 packet
->options
, options
,
5298 &global_scope
, oc
, MDL
)) {
5299 if (d
.len
== sizeof(*from
)) {
5301 memcpy(from
, d
.data
, sizeof(*from
));
5304 * Arrange to save a copy of the data
5305 * to the outgoing list.
5307 if ((out_options
!= NULL
) &&
5308 (options
!= out_options
)) {
5313 data_string_forget(&d
, MDL
);
5318 if ((found
== ISC_FALSE
) &&
5319 (packet
->interface
->address_count
> 0)) {
5320 *from
= packet
->interface
->addresses
[0];
5322 if (out_options
!= NULL
) {
5323 a
= &packet
->interface
->addresses
[0];
5328 (option_cache_allocate(&oc
, MDL
))) {
5329 if (make_const_data(&oc
->expression
,
5330 (unsigned char *)a
, sizeof(*a
),
5331 0, allocate
, MDL
)) {
5332 option_code_hash_lookup(&oc
->option
,
5333 dhcp_universe
.code_hash
,
5334 &option_num
, 0, MDL
);
5335 save_option(&dhcp_universe
, out_options
, oc
);
5337 option_cache_dereference(&oc
, MDL
);
5344 * \brief Builds option set from statements at the global and network scope
5346 * Set up an option state list based on the global and network scopes.
5347 * These are primarily used by NAK logic to locate dhcp-server-id and
5350 * We don't go through all possible options - in particualr we skip the hosts
5351 * and we don't include the lease to avoid making changes to it. This means
5352 * that using these, we won't get the correct server id if the admin puts them
5353 * on hosts or builds the server id with information from the lease.
5355 * As this is a fallback function (used to handle NAKs or sort out server id
5356 * mismatch in failover) and requires configuration by the admin, it should be
5359 * \param network_options option_state to which options will be added. If it
5360 * refers to NULL, it will be allocated. Caller is responsible to delete it.
5361 * \param packet inbound packet
5362 * \param network_group scope group to use if packet->shared_network is null.
5365 eval_network_statements(struct option_state
**network_options
,
5366 struct packet
*packet
,
5367 struct group
*network_group
) {
5369 if (*network_options
== NULL
) {
5370 option_state_allocate (network_options
, MDL
);
5373 /* Use the packet's shared_network if it has one. If not use
5374 * network_group and if it is null then use global scope. */
5375 if (packet
->shared_network
!= NULL
) {
5377 * If we have a subnet and group start with that else start
5378 * with the shared network group. The first will recurse and
5379 * include the second.
5381 if ((packet
->shared_network
->subnets
!= NULL
) &&
5382 (packet
->shared_network
->subnets
->group
!= NULL
)) {
5383 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5384 packet
->options
, *network_options
,
5386 packet
->shared_network
->subnets
->group
,
5389 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5390 packet
->options
, *network_options
,
5392 packet
->shared_network
->group
,
5396 /* do the pool if there is one */
5397 if (packet
->shared_network
->pools
!= NULL
) {
5398 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5399 packet
->options
, *network_options
,
5401 packet
->shared_network
->pools
->group
,
5402 packet
->shared_network
->group
,
5405 } else if (network_group
!= NULL
) {
5406 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5407 packet
->options
, *network_options
,
5408 &global_scope
, network_group
,
5411 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5412 packet
->options
, *network_options
,
5413 &global_scope
, root_group
,
5419 * Look for the lowest numbered site code number and
5420 * apply a log warning if it is less than 224. Do not
5421 * permit site codes less than 128 (old code never did).
5423 * Note that we could search option codes 224 down to 128
5424 * on the hash table, but the table is (probably) smaller
5425 * than that if it was declared as a standalone table with
5426 * defaults. So we traverse the option code hash.
5429 find_min_site_code(struct universe
*u
)
5431 if (u
->site_code_min
)
5432 return u
->site_code_min
;
5435 * Note that site_code_min has to be global as we can't pass an
5436 * argument through hash_foreach(). The value 224 is taken from
5439 site_code_min
= 224;
5440 option_code_hash_foreach(u
->code_hash
, lowest_site_code
);
5442 if (site_code_min
< 224) {
5443 log_error("WARNING: site-local option codes less than 224 have "
5444 "been deprecated by RFC3942. You have options "
5445 "listed in site local space %s that number as low as "
5446 "%d. Please investigate if these should be declared "
5447 "as regular options rather than site-local options, "
5448 "or migrated up past 224.",
5449 u
->name
, site_code_min
);
5453 * don't even bother logging, this is just silly, and never worked
5454 * on any old version of software.
5456 if (site_code_min
< 128)
5457 site_code_min
= 128;
5460 * Cache the determined minimum site code on the universe structure.
5461 * Note that due to the < 128 check above, a value of zero is
5464 u
->site_code_min
= site_code_min
;
5466 return site_code_min
;
5470 lowest_site_code(const void *key
, unsigned len
, void *object
)
5472 struct option
*option
= object
;
5474 if (option
->code
< site_code_min
)
5475 site_code_min
= option
->code
;
5477 return ISC_R_SUCCESS
;
5481 maybe_return_agent_options(struct packet
*packet
, struct option_state
*options
)
5483 /* If there were agent options in the incoming packet, return
5484 * them. Do not return the agent options if they were stashed
5485 * on the lease. We do not check giaddr to detect the presence of
5486 * a relay, as this excludes "l2" relay agents which have no giaddr
5489 * XXX: If the user configures options for the relay agent information
5490 * (state->options->universes[agent_universe.index] is not NULL),
5491 * we're still required to duplicate other values provided by the
5492 * relay agent. So we need to merge the old values not configured
5493 * by the user into the new state, not just give up.
5495 if (!packet
->agent_options_stashed
&&
5496 (packet
->options
!= NULL
) &&
5497 packet
->options
->universe_count
> agent_universe
.index
&&
5498 packet
->options
->universes
[agent_universe
.index
] != NULL
&&
5499 (options
->universe_count
<= agent_universe
.index
||
5500 options
->universes
[agent_universe
.index
] == NULL
)) {
5501 option_chain_head_reference
5502 ((struct option_chain_head
**)
5503 &(options
->universes
[agent_universe
.index
]),
5504 (struct option_chain_head
*)
5505 packet
->options
->universes
[agent_universe
.index
], MDL
);
5507 if (options
->universe_count
<= agent_universe
.index
)
5508 options
->universe_count
= agent_universe
.index
+ 1;
5513 * \brief Adds hostname option when use-host-decl-names is enabled.
5515 * Constructs a hostname option from the name of the host declaration if
5516 * there is one and no hostname has otherwise been provided and the
5517 * use-host-decl-names flag is set, then adds the new option to the given
5518 * option_state. This funciton is used for both bootp and dhcp.
5520 * \param packet inbound packet received from the client
5521 * \param lease lease associated with the client
5522 * \param options option state to search and update
5524 void use_host_decl_name(struct packet
* packet
,
5525 struct lease
*lease
,
5526 struct option_state
*options
) {
5527 unsigned int ocode
= SV_USE_HOST_DECL_NAMES
;
5528 if ((lease
->host
&& lease
->host
->name
) &&
5529 !lookup_option(&dhcp_universe
, options
, DHO_HOST_NAME
) &&
5530 (evaluate_boolean_option_cache(NULL
, packet
, lease
, NULL
,
5531 packet
->options
, options
,
5533 lookup_option(&server_universe
,
5536 struct option_cache
*oc
= NULL
;
5537 if (option_cache_allocate (&oc
, MDL
)) {
5538 if (make_const_data(&oc
-> expression
,
5539 ((unsigned char*)lease
->host
->name
),
5540 strlen(lease
->host
->name
),
5542 ocode
= DHO_HOST_NAME
;
5543 option_code_hash_lookup(&oc
->option
,
5544 dhcp_universe
.code_hash
,
5546 save_option(&dhcp_universe
, options
, oc
);
5548 option_cache_dereference(&oc
, MDL
);
5554 * \brief Checks and preps for lease resuse based on dhcp-cache-threshold
5556 * If dhcp-cache-threshold is enabled (i.e. greater than zero), this function
5557 * determines if the current lease is young enough to be reused. If the lease
5558 * can be resused the function returns 1, O if not. This function is called
5559 * by ack_lease when responding to both DISCOVERs and REQUESTS.
5561 * The current lease can be reused only if all of the following are true:
5562 * a. dhcp-cache-threshold is > 0
5563 * b. The current lease is active
5564 * c. The lease "age" is less than that allowed by the threshold
5565 * d. DNS updates are not being performed on the new lease.
5566 * e. Lease has not been otherwise disqualified for reuse (Ex: billing class
5567 * or hostname changed)
5568 * f. The host declaration has changed (either a new one was added
5569 * or an older one was found due to something like a change in the uid)
5570 * g. The UID or hardware address have changed.
5572 * Clients may renew leases using full DORA cycles or just RAs. This means
5573 * that reusability must be checked when acking both DISCOVERs and REQUESTs.
5574 * When a lease cannot be reused, ack_lease() calls supersede_lease() which
5575 * updates the lease start time (among other things). If this occurs on the
5576 * DISCOVER, then the lease will virtually always be seen as young enough to
5577 * reuse on the ensuing REQUEST and the lease updates will not get committed
5578 * to the lease file. The lease.cannot_reuse flag is used to handle this
5581 * \param packet inbound packet received from the client
5582 * \param new_lease candidate new lease to associate with the client
5583 * \param lease current lease associated with the client
5584 * \param options option state to search and update
5586 * \return 1 if the lease can be reused.
5589 reuse_lease (struct packet
* packet
,
5590 struct lease
* new_lease
,
5591 struct lease
* lease
,
5592 struct lease_state
*state
,
5596 /* To even consider reuse all of the following must be true:
5597 * 1 - reuse hasn't already disqualified
5598 * 2 - current lease is active
5599 * 3 - DNS info hasn't changed
5600 * 4 - the host declaration hasn't changed
5601 * 5 - the uid hasn't changed
5602 * 6 - the hardware address hasn't changed */
5603 if ((lease
->cannot_reuse
== 0) &&
5604 (lease
->binding_state
== FTS_ACTIVE
) &&
5605 (new_lease
->ddns_cb
== NULL
) &&
5606 (lease
->host
== new_lease
->host
) &&
5607 (lease
->uid_len
== new_lease
->uid_len
) &&
5608 (memcmp(lease
->uid
, new_lease
->uid
, lease
->uid_len
) == 0) &&
5609 (lease
->hardware_addr
.hlen
== new_lease
->hardware_addr
.hlen
) &&
5610 (memcmp(&lease
->hardware_addr
.hbuf
[0],
5611 &new_lease
->hardware_addr
.hbuf
[0],
5612 lease
->hardware_addr
.hlen
) == 0)) {
5613 int thresh
= DEFAULT_CACHE_THRESHOLD
;
5614 struct option_cache
* oc
= NULL
;
5615 struct data_string d1
;
5617 /* Look up threshold value */
5618 memset(&d1
, 0, sizeof(struct data_string
));
5619 if ((oc
= lookup_option(&server_universe
, state
->options
,
5620 SV_CACHE_THRESHOLD
)) &&
5621 (evaluate_option_cache(&d1
, packet
, new_lease
, NULL
,
5622 packet
->options
, state
->options
,
5623 &new_lease
->scope
, oc
, MDL
))) {
5624 if (d1
.len
== 1 && (d1
.data
[0] < 100))
5625 thresh
= d1
.data
[0];
5627 data_string_forget(&d1
, MDL
);
5630 /* If threshold is enabled, check lease age */
5633 int lease_length
= 0;
5636 /* Calculate limit in seconds */
5637 lease_length
= lease
->ends
- lease
->starts
;
5638 if (lease_length
<= (INT_MAX
/ thresh
))
5639 limit
= lease_length
* thresh
/ 100;
5641 limit
= lease_length
/ 100 * thresh
;
5643 /* Note new_lease->starts is really just cur_time */
5644 lease_age
= new_lease
->starts
- lease
->starts
;
5646 /* Is the lease young enough to reuse? */
5647 if (lease_age
<= limit
) {
5648 /* Restore expiry to its original value */
5649 state
->offered_expiry
= lease
->ends
;
5651 /* Restore bindings. This fixes 37368. */
5652 if (new_lease
->scope
!= NULL
) {
5653 if (lease
->scope
!= NULL
) {
5654 binding_scope_dereference(
5659 binding_scope_reference(&lease
->scope
,
5660 new_lease
->scope
, MDL
);
5663 /* restore client hostname, fixes 42849. */
5664 if (new_lease
->client_hostname
) {
5665 lease
->client_hostname
=
5666 new_lease
->client_hostname
;
5667 new_lease
->client_hostname
= NULL
;
5670 /* We're cleared to reuse it */
5671 log_debug("reuse_lease: lease age %ld (secs)"
5672 " under %d%% threshold, reply with "
5673 "unaltered, existing lease for %s",
5674 lease_age
, thresh
, piaddr(lease
->ip_addr
));
5681 /* If we can't reuse it and this is an offer disqualify reuse for
5682 * ensuing REQUEST, otherwise clear the flag. */
5683 lease
->cannot_reuse
= (!reusable
&& offer
== DHCPOFFER
);
5687 /* \brief Validates a proposed value for use as a lease time
5689 * Convenience function used for catching calculeated lease
5690 * times that overflow 4-byte times used in v4 protocol.
5692 * We use variables of type TIME in lots of places, which on
5693 * 64-bit systems is 8 bytes while on 32-bit OSs it is int32_t,
5694 * so we have all sorts of fun places to mess things up.
5695 * This function checks a calculated lease time for and if it
5696 * is unsuitable for use as a lease time, the given alternate
5697 * value is returned.
5701 * \returen either the calculated value if it is valid, or
5702 * the alternate value supplied
5704 TIME
leaseTimeCheck(TIME calculated
, TIME alternate
) {
5705 if ((sizeof(TIME
) > 4 && calculated
>= INFINITE_TIME
) ||
5706 (calculated
< cur_time
)) {
5710 return (calculated
);