3 DHCP Protocol engine. */
6 * Copyright (c) 2004-2019 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 * Newmarket, NH 03857 USA
25 * https://www.isc.org/
34 static void maybe_return_agent_options(struct packet
*packet
,
35 struct option_state
*options
);
37 static int reuse_lease (struct packet
* packet
, struct lease
* new_lease
,
38 struct lease
* lease
, struct lease_state
*state
,
39 int offer
, int* same_client
);
41 static int do_ping_check(struct packet
* packet
, struct lease_state
* state
,
42 struct lease
* lease
, TIME original_cltt
,
45 #if defined(DHCPv6) && defined(DHCP4o6)
46 static int locate_network6(struct packet
*packet
);
49 int outstanding_pings
;
51 #if defined(DELAYED_ACK)
52 static void delayed_ack_enqueue(struct lease
*);
53 static void delayed_acks_timer(void *);
56 struct leasequeue
*ackqueue_head
, *ackqueue_tail
;
57 static struct leasequeue
*free_ackqueue
;
58 static struct timeval max_fsync
;
61 int max_outstanding_acks
= DEFAULT_DELAYED_ACK
;
62 int max_ack_delay_secs
= DEFAULT_ACK_DELAY_SECS
;
63 int max_ack_delay_usecs
= DEFAULT_ACK_DELAY_USECS
;
64 int min_ack_delay_usecs
= DEFAULT_MIN_ACK_DELAY_USECS
;
67 static char dhcp_message
[256];
68 static int site_code_min
;
70 static int find_min_site_code(struct universe
*);
71 static isc_result_t
lowest_site_code(const void *, unsigned, void *);
73 static const char *dhcp_type_names
[] = {
84 "DHCPLEASEUNASSIGNED",
88 const int dhcp_type_name_max
= ((sizeof dhcp_type_names
) / sizeof (char *));
91 # define send_packet trace_packet_send
94 static TIME
leaseTimeCheck(TIME calculated
, TIME alternate
);
97 dhcp (struct packet
*packet
) {
99 struct option_cache
*oc
;
100 struct lease
*lease
= NULL
;
102 struct data_string data
;
104 if (!locate_network(packet
) &&
105 packet
->packet_type
!= DHCPREQUEST
&&
106 packet
->packet_type
!= DHCPINFORM
&&
107 packet
->packet_type
!= DHCPLEASEQUERY
) {
110 errmsg
= "unknown network segment";
113 if (packet
->packet_type
> 0 &&
114 packet
->packet_type
<= dhcp_type_name_max
) {
115 s
= dhcp_type_names
[packet
->packet_type
- 1];
117 /* %Audit% Cannot exceed 28 bytes. %2004.06.17,Safe% */
118 sprintf(typebuf
, "type %d", packet
->packet_type
);
122 #if defined(DHCPv6) && defined(DHCP4o6)
123 if (dhcpv4_over_dhcpv6
&& (packet
->dhcp4o6_response
!= NULL
)) {
124 log_info("DHCP4o6 %s from %s via %s: %s", s
,
126 ? print_hw_addr(packet
->raw
->htype
,
129 : "<no identifier>"),
130 piaddr(packet
->client_addr
),
136 log_info("%s from %s via %s: %s", s
,
138 ? print_hw_addr(packet
->raw
->htype
,
141 : "<no identifier>"),
142 packet
->raw
->giaddr
.s_addr
143 ? inet_ntoa(packet
->raw
->giaddr
)
144 : packet
->interface
->name
, errmsg
);
148 /* There is a problem with the relay agent information option,
149 * which is that in order for a normal relay agent to append
150 * this option, the relay agent has to have been involved in
151 * getting the packet from the client to the server. Note
152 * that this is the software entity known as the relay agent,
153 * _not_ the hardware entity known as a router in which the
154 * relay agent may be running, so the fact that a router has
155 * forwarded a packet does not mean that the relay agent in
156 * the router was involved.
158 * So when the client broadcasts (DHCPDISCOVER, or giaddr is set),
159 * we can be sure that there are either agent options in the
160 * packet, or there aren't supposed to be. When the giaddr is not
161 * set, it's still possible that the client is on a directly
162 * attached subnet, and agent options are being appended by an l2
163 * device that has no address, and so sets no giaddr.
165 * But in either case it's possible that the packets we receive
166 * from the client in RENEW state may not include the agent options,
167 * so if they are not in the packet we must "pretend" the last values
168 * we observed were provided.
170 if (packet
->packet_type
== DHCPREQUEST
&&
171 packet
->raw
->ciaddr
.s_addr
&& !packet
->raw
->giaddr
.s_addr
&&
172 (packet
->options
->universe_count
<= agent_universe
.index
||
173 packet
->options
->universes
[agent_universe
.index
] == NULL
))
177 cip
.len
= sizeof packet
-> raw
-> ciaddr
;
178 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
,
179 sizeof packet
-> raw
-> ciaddr
);
180 if (!find_lease_by_ip_addr (&lease
, cip
, MDL
))
183 /* If there are no agent options on the lease, it's not
185 if (!lease
-> agent_options
)
188 /* The client should not be unicasting a renewal if its lease
189 has expired, so make it go through the process of getting
190 its agent options legally. */
191 if (lease
-> ends
< cur_time
)
194 if (lease
-> uid_len
) {
195 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
196 DHO_DHCP_CLIENT_IDENTIFIER
);
200 memset (&data
, 0, sizeof data
);
201 if (!evaluate_option_cache (&data
,
202 packet
, (struct lease
*)0,
203 (struct client_state
*)0,
205 (struct option_state
*)0,
206 &global_scope
, oc
, MDL
))
208 if (lease
-> uid_len
!= data
.len
||
209 memcmp (lease
-> uid
, data
.data
, data
.len
)) {
210 data_string_forget (&data
, MDL
);
213 data_string_forget (&data
, MDL
);
215 if ((lease
-> hardware_addr
.hbuf
[0] !=
216 packet
-> raw
-> htype
) ||
217 (lease
-> hardware_addr
.hlen
- 1 !=
218 packet
-> raw
-> hlen
) ||
219 memcmp (&lease
-> hardware_addr
.hbuf
[1],
220 packet
-> raw
-> chaddr
,
221 packet
-> raw
-> hlen
))
224 /* Okay, so we found a lease that matches the client. */
225 option_chain_head_reference ((struct option_chain_head
**)
226 &(packet
-> options
-> universes
227 [agent_universe
.index
]),
228 lease
-> agent_options
, MDL
);
230 if (packet
->options
->universe_count
<= agent_universe
.index
)
231 packet
->options
->universe_count
=
232 agent_universe
.index
+ 1;
234 packet
->agent_options_stashed
= ISC_TRUE
;
238 /* If a client null terminates options it sends, it probably
239 * expects the server to reciprocate.
241 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
243 if (!oc
-> expression
)
244 ms_nulltp
= oc
->flags
& OPTION_HAD_NULLS
;
247 /* Classify the client. */
248 classify_client (packet
);
250 switch (packet
-> packet_type
) {
252 dhcpdiscover (packet
, ms_nulltp
);
256 dhcprequest (packet
, ms_nulltp
, lease
);
260 dhcprelease (packet
, ms_nulltp
);
264 dhcpdecline (packet
, ms_nulltp
);
268 dhcpinform (packet
, ms_nulltp
);
272 dhcpleasequery(packet
, ms_nulltp
);
278 case DHCPLEASEUNASSIGNED
:
279 case DHCPLEASEUNKNOWN
:
280 case DHCPLEASEACTIVE
:
284 errmsg
= "unknown packet type";
289 lease_dereference (&lease
, MDL
);
292 void dhcpdiscover (packet
, ms_nulltp
)
293 struct packet
*packet
;
296 struct lease
*lease
= (struct lease
*)0;
297 char msgbuf
[1024]; /* XXX */
300 int peer_has_leases
= 0;
301 #if defined (FAILOVER_PROTOCOL)
302 dhcp_failover_state_t
*peer
;
305 find_lease (&lease
, packet
, packet
-> shared_network
,
306 0, &peer_has_leases
, (struct lease
*)0, MDL
);
308 if (lease
&& lease
-> client_hostname
) {
309 if ((strlen (lease
-> client_hostname
) <= 64) &&
310 db_printable((unsigned char *)lease
->client_hostname
))
311 s
= lease
-> client_hostname
;
313 s
= "Hostname Unsuitable for Printing";
317 /* %Audit% This is log output. %2004.06.17,Safe%
318 * If we truncate we hope the user can get a hint from the log.
320 #if defined(DHCPv6) && defined(DHCP4o6)
321 if (dhcpv4_over_dhcpv6
&& (packet
->dhcp4o6_response
!= NULL
)) {
322 snprintf (msgbuf
, sizeof msgbuf
,
323 "DHCP4o6 DHCPDISCOVER from %s %s%s%svia %s",
324 (packet
-> raw
-> htype
325 ? print_hw_addr (packet
-> raw
-> htype
,
326 packet
-> raw
-> hlen
,
327 packet
-> raw
-> chaddr
)
329 ? print_hex_1(lease
->uid_len
, lease
->uid
, 60)
330 : "<no identifier>")),
331 s
? "(" : "", s
? s
: "", s
? ") " : "",
332 piaddr(packet
->client_addr
));
335 snprintf (msgbuf
, sizeof msgbuf
, "DHCPDISCOVER from %s %s%s%svia %s",
336 (packet
-> raw
-> htype
337 ? print_hw_addr (packet
-> raw
-> htype
,
338 packet
-> raw
-> hlen
,
339 packet
-> raw
-> chaddr
)
341 ? print_hex_1(lease
->uid_len
, lease
->uid
, 60)
342 : "<no identifier>")),
343 s
? "(" : "", s
? s
: "", s
? ") " : "",
344 packet
-> raw
-> giaddr
.s_addr
345 ? inet_ntoa (packet
-> raw
-> giaddr
)
346 : packet
-> interface
-> name
);
348 /* Sourceless packets don't make sense here. */
349 if (!packet
-> shared_network
) {
350 #if defined(DHCPv6) && defined(DHCP4o6)
351 if (dhcpv4_over_dhcpv6
&& (packet
->dhcp4o6_response
!= NULL
)) {
352 log_info ("DHCP4o6 packet from unknown subnet: %s",
353 piaddr(packet
->client_addr
));
356 log_info ("Packet from unknown subnet: %s",
357 inet_ntoa (packet
-> raw
-> giaddr
));
361 #if defined (FAILOVER_PROTOCOL)
362 if (lease
&& lease
-> pool
&& lease
-> pool
-> failover_peer
) {
363 peer
= lease
-> pool
-> failover_peer
;
366 * If the lease is ours to (re)allocate, then allocate it.
368 * If the lease is active, it belongs to the client. This
369 * is the right lease, if we are to offer one. We decide
370 * whether or not to offer later on.
372 * If the lease was last active, and we've reached this
373 * point, then it was last active with the same client. We
374 * can safely re-activate the lease with this client.
376 if (lease
->binding_state
== FTS_ACTIVE
||
377 lease
->rewind_binding_state
== FTS_ACTIVE
||
378 lease_mine_to_reallocate(lease
)) {
379 ; /* This space intentionally left blank. */
381 /* Otherwise, we can't let the client have this lease. */
383 #if defined (DEBUG_FIND_LEASE)
384 log_debug ("discarding %s - %s",
385 piaddr (lease
-> ip_addr
),
386 binding_state_print (lease
-> binding_state
));
388 lease_dereference (&lease
, MDL
);
393 /* If we didn't find a lease, try to allocate one... */
395 if (!allocate_lease (&lease
, packet
,
396 packet
-> shared_network
-> pools
,
399 log_error ("%s: peer holds all free leases",
402 log_error ("%s: network %s: no free leases",
404 packet
-> shared_network
-> name
);
409 #if defined (FAILOVER_PROTOCOL)
410 if (lease
&& lease
-> pool
&& lease
-> pool
-> failover_peer
) {
411 peer
= lease
-> pool
-> failover_peer
;
412 if (peer
-> service_state
== not_responding
||
413 peer
-> service_state
== service_startup
) {
414 log_info ("%s: not responding%s",
415 msgbuf
, peer
-> nrr
);
419 peer
= (dhcp_failover_state_t
*)0;
421 /* Do load balancing if configured. */
422 if (peer
&& (peer
-> service_state
== cooperating
) &&
423 !load_balance_mine (packet
, peer
)) {
424 if (peer_has_leases
) {
425 log_debug ("%s: load balance to peer %s",
426 msgbuf
, peer
-> name
);
429 log_debug ("%s: cancel load balance to peer %s - %s",
430 msgbuf
, peer
-> name
, "no free leases");
435 /* If it's an expired lease, get rid of any bindings. */
436 if (lease
-> ends
< cur_time
&& lease
-> scope
)
437 binding_scope_dereference (&lease
-> scope
, MDL
);
439 /* Set the lease to really expire in 2 minutes, unless it has
440 not yet expired, in which case leave its expiry time alone. */
441 when
= cur_time
+ 120;
442 if (when
< lease
-> ends
)
443 when
= lease
-> ends
;
445 ack_lease (packet
, lease
, DHCPOFFER
, when
, msgbuf
, ms_nulltp
,
446 (struct host_decl
*)0);
449 lease_dereference (&lease
, MDL
);
452 void dhcprequest (packet
, ms_nulltp
, ip_lease
)
453 struct packet
*packet
;
455 struct lease
*ip_lease
;
460 struct subnet
*subnet
;
462 struct option_cache
*oc
;
463 struct data_string data
;
464 char msgbuf
[1024]; /* XXX */
467 #if defined (FAILOVER_PROTOCOL)
468 dhcp_failover_state_t
*peer
;
470 int have_requested_addr
= 0;
472 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
473 DHO_DHCP_REQUESTED_ADDRESS
);
474 memset (&data
, 0, sizeof data
);
476 evaluate_option_cache (&data
, packet
, (struct lease
*)0,
477 (struct client_state
*)0,
478 packet
-> options
, (struct option_state
*)0,
479 &global_scope
, oc
, MDL
)) {
481 memcpy (cip
.iabuf
, data
.data
, 4);
482 data_string_forget (&data
, MDL
);
483 have_requested_addr
= 1;
485 oc
= (struct option_cache
*)0;
487 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
.s_addr
, 4);
490 /* Find the lease that matches the address requested by the
493 subnet
= (struct subnet
*)0;
494 lease
= (struct lease
*)0;
495 if (find_subnet (&subnet
, cip
, MDL
))
496 find_lease (&lease
, packet
,
497 subnet
-> shared_network
, &ours
, 0, ip_lease
, MDL
);
499 if (lease
&& lease
-> client_hostname
) {
500 if ((strlen (lease
-> client_hostname
) <= 64) &&
501 db_printable((unsigned char *)lease
->client_hostname
))
502 s
= lease
-> client_hostname
;
504 s
= "Hostname Unsuitable for Printing";
508 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
509 DHO_DHCP_SERVER_IDENTIFIER
);
510 memset (&data
, 0, sizeof data
);
512 evaluate_option_cache (&data
, packet
, (struct lease
*)0,
513 (struct client_state
*)0,
514 packet
-> options
, (struct option_state
*)0,
515 &global_scope
, oc
, MDL
)) {
517 memcpy (sip
.iabuf
, data
.data
, 4);
518 data_string_forget (&data
, MDL
);
519 /* piaddr() should not return more than a 15 byte string.
522 sprintf (smbuf
, " (%s)", piaddr (sip
));
528 /* %Audit% This is log output. %2004.06.17,Safe%
529 * If we truncate we hope the user can get a hint from the log.
531 #if defined(DHCPv6) && defined(DHCP4o6)
532 if (dhcpv4_over_dhcpv6
&& (packet
->dhcp4o6_response
!= NULL
)) {
533 snprintf (msgbuf
, sizeof msgbuf
,
534 "DHCP4o6 DHCPREQUEST for %s%s from %s %s%s%svia %s",
536 (packet
-> raw
-> htype
537 ? print_hw_addr (packet
-> raw
-> htype
,
538 packet
-> raw
-> hlen
,
539 packet
-> raw
-> chaddr
)
541 ? print_hex_1(lease
->uid_len
, lease
->uid
, 60)
542 : "<no identifier>")),
543 s
? "(" : "", s
? s
: "", s
? ") " : "",
544 piaddr(packet
->client_addr
));
547 snprintf (msgbuf
, sizeof msgbuf
,
548 "DHCPREQUEST for %s%s from %s %s%s%svia %s",
550 (packet
-> raw
-> htype
551 ? print_hw_addr (packet
-> raw
-> htype
,
552 packet
-> raw
-> hlen
,
553 packet
-> raw
-> chaddr
)
555 ? print_hex_1(lease
->uid_len
, lease
->uid
, 60)
556 : "<no identifier>")),
557 s
? "(" : "", s
? s
: "", s
? ") " : "",
558 packet
-> raw
-> giaddr
.s_addr
559 ? inet_ntoa (packet
-> raw
-> giaddr
)
560 : packet
-> interface
-> name
);
562 #if defined (FAILOVER_PROTOCOL)
563 if (lease
&& lease
-> pool
&& lease
-> pool
-> failover_peer
) {
564 peer
= lease
-> pool
-> failover_peer
;
565 if (peer
-> service_state
== not_responding
||
566 peer
-> service_state
== service_startup
) {
567 log_info ("%s: not responding%s",
568 msgbuf
, peer
-> nrr
);
572 /* "load balance to peer" - is not done at all for request.
574 * If it's RENEWING, we are the only server to hear it, so
575 * we have to serve it. If it's REBINDING, it's out of
576 * communication with the other server, so there's no point
577 * in waiting to serve it. However, if the lease we're
578 * offering is not a free lease, then we may be the only
579 * server that can offer it, so we can't load balance if
580 * the lease isn't in the free or backup state. If it is
581 * in the free or backup state, then that state is what
582 * mandates one server or the other should perform the
583 * allocation, not the LBA...we know the peer cannot
584 * allocate a request for an address in our free state.
586 * So our only compass is lease_mine_to_reallocate(). This
587 * effects both load balancing, and a sanity-check that we
588 * are not going to try to allocate a lease that isn't ours.
590 if ((lease
-> binding_state
== FTS_FREE
||
591 lease
-> binding_state
== FTS_BACKUP
) &&
592 !lease_mine_to_reallocate (lease
)) {
593 log_debug ("%s: lease owned by peer", msgbuf
);
598 * If the lease is in a transitional state, we can't
599 * renew it unless we can rewind it to a non-transitional
600 * state (active, free, or backup). lease_mine_to_reallocate()
601 * checks for free/backup, so we only need to check for active.
603 if ((lease
->binding_state
== FTS_RELEASED
||
604 lease
->binding_state
== FTS_EXPIRED
) &&
605 lease
->rewind_binding_state
!= FTS_ACTIVE
&&
606 !lease_mine_to_reallocate(lease
)) {
607 log_debug("%s: lease in transition state %s", msgbuf
,
608 (lease
->binding_state
== FTS_RELEASED
)
609 ? "released" : "expired");
613 /* It's actually very unlikely that we'll ever get here,
614 but if we do, tell the client to stop using the lease,
615 because the administrator reset it. */
616 if (lease
-> binding_state
== FTS_RESET
&&
617 !lease_mine_to_reallocate (lease
)) {
618 log_debug ("%s: lease reset by administrator", msgbuf
);
619 nak_lease (packet
, &cip
, lease
->subnet
->group
);
623 /* If server-id-check is enabled, verify that the client's
624 * server source address (sip from incoming packet) is ours.
625 * To avoid problems with confused clients we do some sanity
626 * checks to verify sip's length and that it isn't all zeros.
627 * We then get the server id we would likely use for this
628 * packet and compare them. If they don't match it we assume
629 * we didn't send the offer and so we don't process the
631 if ((server_id_check
== 1) && (sip
.len
== 4) &&
632 (memcmp(sip
.iabuf
, "\0\0\0\0", sip
.len
) != 0)) {
634 struct option_state
*eval_options
= NULL
;
636 eval_network_statements(&eval_options
, packet
, NULL
);
637 get_server_source_address(&from
, eval_options
,
639 option_state_dereference (&eval_options
, MDL
);
640 if (memcmp(sip
.iabuf
, &from
, sip
.len
) != 0) {
641 log_debug("%s: not our server id", msgbuf
);
646 /* At this point it's possible that we will get a broadcast
647 DHCPREQUEST for a lease that we didn't offer, because
648 both we and the peer are in a position to offer it.
649 In that case, we probably shouldn't answer. In order
650 to not answer, we would have to compare the server
651 identifier sent by the client with the list of possible
652 server identifiers we can send, and if the client's
653 identifier isn't on the list, drop the DHCPREQUEST.
654 We aren't currently doing that for two reasons - first,
655 it's not clear that all clients do the right thing
656 with respect to sending the client identifier, which
657 could mean that we might simply not respond to a client
658 that is depending on us to respond. Secondly, we allow
659 the user to specify the server identifier to send, and
660 we don't enforce that the server identifier should be
661 one of our IP addresses. This is probably not a big
662 deal, but it's theoretically an issue.
664 The reason we care about this is that if both servers
665 send a DHCPACK to the DHCPREQUEST, they are then going
666 to send dueling BNDUPD messages, which could cause
667 trouble. I think it causes no harm, but it seems
670 peer
= (dhcp_failover_state_t
*)0;
673 /* If a client on a given network REQUESTs a lease on an
674 address on a different network, NAK it. If the Requested
675 Address option was used, the protocol says that it must
676 have been broadcast, so we can trust the source network
679 If ciaddr was specified and Requested Address was not, then
680 we really only know for sure what network a packet came from
681 if it came through a BOOTP gateway - if it came through an
682 IP router, we'll just have to assume that it's cool.
684 If we don't think we know where the packet came from, it
685 came through a gateway from an unknown network, so it's not
686 from a RENEWING client. If we recognize the network it
687 *thinks* it's on, we can NAK it even though we don't
688 recognize the network it's *actually* on; otherwise we just
691 We don't currently try to take advantage of access to the
692 raw packet, because it's not available on all platforms.
693 So a packet that was unicast to us through a router from a
694 RENEWING client is going to look exactly like a packet that
695 was broadcast to us from an INIT-REBOOT client.
697 Since we can't tell the difference between these two kinds
698 of packets, if the packet appears to have come in off the
699 local wire, we have to treat it as if it's a RENEWING
700 client. This means that we can't NAK a RENEWING client on
701 the local wire that has a bogus address. The good news is
702 that we won't ACK it either, so it should revert to INIT
703 state and send us a DHCPDISCOVER, which we *can* work with.
705 Because we can't detect that a RENEWING client is on the
706 wrong wire, it's going to sit there trying to renew until
707 it gets to the REBIND state, when we *can* NAK it because
708 the packet will get to us through a BOOTP gateway. We
709 shouldn't actually see DHCPREQUEST packets from RENEWING
710 clients on the wrong wire anyway, since their idea of their
711 local router will be wrong. In any case, the protocol
712 doesn't really allow us to NAK a DHCPREQUEST from a
713 RENEWING client, so we can punt on this issue. */
715 if (!packet
-> shared_network
||
716 (packet
-> raw
-> ciaddr
.s_addr
&&
717 packet
-> raw
-> giaddr
.s_addr
) ||
718 (have_requested_addr
&& !packet
-> raw
-> ciaddr
.s_addr
)) {
720 /* If we don't know where it came from but we do know
721 where it claims to have come from, it didn't come
723 if (!packet
-> shared_network
) {
724 if (subnet
&& subnet
-> group
-> authoritative
) {
725 log_info ("%s: wrong network.", msgbuf
);
726 nak_lease (packet
, &cip
, NULL
);
729 /* Otherwise, ignore it. */
730 log_info ("%s: ignored (%s).", msgbuf
,
732 ? "not authoritative" : "unknown subnet"));
736 /* If we do know where it came from and it asked for an
737 address that is not on that shared network, nak it. */
739 subnet_dereference (&subnet
, MDL
);
740 if (!find_grouped_subnet (&subnet
, packet
-> shared_network
,
742 if (packet
-> shared_network
-> group
-> authoritative
)
744 log_info ("%s: wrong network.", msgbuf
);
745 nak_lease (packet
, &cip
, NULL
);
748 log_info ("%s: ignored (not authoritative).", msgbuf
);
753 /* If the address the client asked for is ours, but it wasn't
754 available for the client, NAK it. */
755 if (!lease
&& ours
) {
756 log_info ("%s: lease %s unavailable.", msgbuf
, piaddr (cip
));
757 nak_lease (packet
, &cip
, (subnet
? subnet
->group
: NULL
));
761 /* Otherwise, send the lease to the client if we found one. */
763 ack_lease (packet
, lease
, DHCPACK
, 0, msgbuf
, ms_nulltp
,
764 (struct host_decl
*)0);
766 log_info ("%s: unknown lease %s.", msgbuf
, piaddr (cip
));
770 subnet_dereference (&subnet
, MDL
);
772 lease_dereference (&lease
, MDL
);
776 void dhcprelease (packet
, ms_nulltp
)
777 struct packet
*packet
;
780 struct lease
*lease
= (struct lease
*)0, *next
= (struct lease
*)0;
782 struct option_cache
*oc
;
783 struct data_string data
;
785 char msgbuf
[1024], cstr
[16]; /* XXX */
788 /* DHCPRELEASE must not specify address in requested-address
789 option, but old protocol specs weren't explicit about this,
791 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
792 DHO_DHCP_REQUESTED_ADDRESS
))) {
793 log_info ("DHCPRELEASE from %s specified requested-address.",
794 print_hw_addr (packet
-> raw
-> htype
,
795 packet
-> raw
-> hlen
,
796 packet
-> raw
-> chaddr
));
799 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
800 DHO_DHCP_CLIENT_IDENTIFIER
);
801 memset (&data
, 0, sizeof data
);
803 evaluate_option_cache (&data
, packet
, (struct lease
*)0,
804 (struct client_state
*)0,
805 packet
-> options
, (struct option_state
*)0,
806 &global_scope
, oc
, MDL
)) {
807 find_lease_by_uid (&lease
, data
.data
, data
.len
, MDL
);
808 data_string_forget (&data
, MDL
);
810 /* See if we can find a lease that matches the IP address
811 the client is claiming. */
814 lease_reference (&next
, lease
-> n_uid
, MDL
);
815 if (!memcmp (&packet
-> raw
-> ciaddr
,
816 lease
-> ip_addr
.iabuf
, 4)) {
819 lease_dereference (&lease
, MDL
);
821 lease_reference (&lease
, next
, MDL
);
822 lease_dereference (&next
, MDL
);
826 lease_dereference (&next
, MDL
);
829 /* The client is supposed to pass a valid client-identifier,
830 but the spec on this has changed historically, so try the
831 IP address in ciaddr if the client-identifier fails. */
834 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
, 4);
835 find_lease_by_ip_addr (&lease
, cip
, MDL
);
839 /* If the hardware address doesn't match, don't do the release. */
841 (lease
-> hardware_addr
.hlen
!= packet
-> raw
-> hlen
+ 1 ||
842 lease
-> hardware_addr
.hbuf
[0] != packet
-> raw
-> htype
||
843 memcmp (&lease
-> hardware_addr
.hbuf
[1],
844 packet
-> raw
-> chaddr
, packet
-> raw
-> hlen
)))
845 lease_dereference (&lease
, MDL
);
847 if (lease
&& lease
-> client_hostname
) {
848 if ((strlen (lease
-> client_hostname
) <= 64) &&
849 db_printable((unsigned char *)lease
->client_hostname
))
850 s
= lease
-> client_hostname
;
852 s
= "Hostname Unsuitable for Printing";
856 /* %Audit% Cannot exceed 16 bytes. %2004.06.17,Safe%
857 * We copy this out to stack because we actually want to log two
858 * inet_ntoa()'s in this message.
860 strncpy(cstr
, inet_ntoa (packet
-> raw
-> ciaddr
), 15);
863 /* %Audit% This is log output. %2004.06.17,Safe%
864 * If we truncate we hope the user can get a hint from the log.
866 #if defined(DHCPv6) && defined(DHCP4o6)
867 if (dhcpv4_over_dhcpv6
&& (packet
->dhcp4o6_response
!= NULL
)) {
868 snprintf (msgbuf
, sizeof msgbuf
,
869 "DHCP4o6 DHCPRELEASE of %s from %s %s%s%svia "
872 (packet
-> raw
-> htype
873 ? print_hw_addr (packet
-> raw
-> htype
,
874 packet
-> raw
-> hlen
,
875 packet
-> raw
-> chaddr
)
877 ? print_hex_1(lease
->uid_len
, lease
->uid
, 60)
878 : "<no identifier>")),
879 s
? "(" : "", s
? s
: "", s
? ") " : "",
880 piaddr(packet
->client_addr
),
881 lease
? "" : "not ");
884 snprintf (msgbuf
, sizeof msgbuf
,
885 "DHCPRELEASE of %s from %s %s%s%svia %s (%sfound)",
887 (packet
-> raw
-> htype
888 ? print_hw_addr (packet
-> raw
-> htype
,
889 packet
-> raw
-> hlen
,
890 packet
-> raw
-> chaddr
)
892 ? print_hex_1(lease
->uid_len
, lease
->uid
, 60)
893 : "<no identifier>")),
894 s
? "(" : "", s
? s
: "", s
? ") " : "",
895 packet
-> raw
-> giaddr
.s_addr
896 ? inet_ntoa (packet
-> raw
-> giaddr
)
897 : packet
-> interface
-> name
,
898 lease
? "" : "not ");
900 #if defined (FAILOVER_PROTOCOL)
901 if (lease
&& lease
-> pool
&& lease
-> pool
-> failover_peer
) {
902 dhcp_failover_state_t
*peer
= lease
-> pool
-> failover_peer
;
903 if (peer
-> service_state
== not_responding
||
904 peer
-> service_state
== service_startup
) {
905 log_info ("%s: ignored%s",
906 peer
-> name
, peer
-> nrr
);
910 /* DHCPRELEASE messages are unicast, so if the client
911 sent the DHCPRELEASE to us, it's not going to send it
912 to the peer. Not sure why this would happen, and
913 if it does happen I think we still have to change the
914 lease state, so that's what we're doing.
915 XXX See what it says in the draft about this. */
919 /* If we found a lease, release it. */
920 if (lease
&& lease
-> ends
> cur_time
) {
921 release_lease (lease
, packet
);
923 log_info ("%s", msgbuf
);
924 #if defined(FAILOVER_PROTOCOL)
928 lease_dereference (&lease
, MDL
);
931 void dhcpdecline (packet
, ms_nulltp
)
932 struct packet
*packet
;
935 struct lease
*lease
= (struct lease
*)0;
936 struct option_state
*options
= (struct option_state
*)0;
941 char msgbuf
[1024]; /* XXX */
943 struct option_cache
*oc
;
944 struct data_string data
;
946 /* DHCPDECLINE must specify address. */
947 if (!(oc
= lookup_option (&dhcp_universe
, packet
-> options
,
948 DHO_DHCP_REQUESTED_ADDRESS
)))
950 memset (&data
, 0, sizeof data
);
951 if (!evaluate_option_cache (&data
, packet
, (struct lease
*)0,
952 (struct client_state
*)0,
954 (struct option_state
*)0,
955 &global_scope
, oc
, MDL
))
959 memcpy (cip
.iabuf
, data
.data
, 4);
960 data_string_forget (&data
, MDL
);
961 find_lease_by_ip_addr (&lease
, cip
, MDL
);
963 if (lease
&& lease
-> client_hostname
) {
964 if ((strlen (lease
-> client_hostname
) <= 64) &&
965 db_printable((unsigned char *)lease
->client_hostname
))
966 s
= lease
-> client_hostname
;
968 s
= "Hostname Unsuitable for Printing";
972 /* %Audit% This is log output. %2004.06.17,Safe%
973 * If we truncate we hope the user can get a hint from the log.
975 #if defined(DHCPv6) && defined(DHCP4o6)
976 if (dhcpv4_over_dhcpv6
&& (packet
->dhcp4o6_response
!= NULL
)) {
977 snprintf (msgbuf
, sizeof msgbuf
,
978 "DHCP4o6 DHCPDECLINE of %s from %s %s%s%svia %s",
980 (packet
-> raw
-> htype
981 ? print_hw_addr (packet
-> raw
-> htype
,
982 packet
-> raw
-> hlen
,
983 packet
-> raw
-> chaddr
)
985 ? print_hex_1(lease
->uid_len
, lease
->uid
, 60)
986 : "<no identifier>")),
987 s
? "(" : "", s
? s
: "", s
? ") " : "",
988 piaddr(packet
->client_addr
));
991 snprintf (msgbuf
, sizeof msgbuf
,
992 "DHCPDECLINE of %s from %s %s%s%svia %s",
994 (packet
-> raw
-> htype
995 ? print_hw_addr (packet
-> raw
-> htype
,
996 packet
-> raw
-> hlen
,
997 packet
-> raw
-> chaddr
)
999 ? print_hex_1(lease
->uid_len
, lease
->uid
, 60)
1000 : "<no identifier>")),
1001 s
? "(" : "", s
? s
: "", s
? ") " : "",
1002 packet
-> raw
-> giaddr
.s_addr
1003 ? inet_ntoa (packet
-> raw
-> giaddr
)
1004 : packet
-> interface
-> name
);
1006 option_state_allocate (&options
, MDL
);
1008 /* Execute statements in scope starting with the subnet scope. */
1010 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
1011 packet
->options
, options
,
1013 lease
->subnet
->group
,
1016 /* Execute statements in the class scopes. */
1017 for (i
= packet
-> class_count
; i
> 0; i
--) {
1018 execute_statements_in_scope
1019 (NULL
, packet
, NULL
, NULL
, packet
->options
, options
,
1020 &global_scope
, packet
->classes
[i
- 1]->group
,
1021 lease
? lease
->subnet
->group
: NULL
, NULL
);
1024 /* Drop the request if dhcpdeclines are being ignored. */
1025 oc
= lookup_option (&server_universe
, options
, SV_DECLINES
);
1027 evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
1028 (struct client_state
*)0,
1029 packet
-> options
, options
,
1030 &lease
-> scope
, oc
, MDL
)) {
1031 /* If we found a lease, mark it as unusable and complain. */
1033 #if defined (FAILOVER_PROTOCOL)
1034 if (lease
-> pool
&& lease
-> pool
-> failover_peer
) {
1035 dhcp_failover_state_t
*peer
=
1036 lease
-> pool
-> failover_peer
;
1037 if (peer
-> service_state
== not_responding
||
1038 peer
-> service_state
== service_startup
) {
1040 log_info ("%s: ignored%s",
1041 peer
-> name
, peer
-> nrr
);
1045 /* DHCPDECLINE messages are broadcast, so we can safely
1046 ignore the DHCPDECLINE if the peer has the lease.
1047 XXX Of course, at this point that information has been
1052 abandon_lease (lease
, "declined.");
1053 status
= "abandoned";
1055 status
= "not found";
1061 log_info ("%s: %s", msgbuf
, status
);
1063 #if defined(FAILOVER_PROTOCOL)
1067 option_state_dereference (&options
, MDL
);
1069 lease_dereference (&lease
, MDL
);
1072 #if defined(RELAY_PORT)
1073 u_int16_t
dhcp_check_relayport(packet
)
1074 struct packet
*packet
;
1076 if (lookup_option(&agent_universe
,
1078 RAI_RELAY_PORT
) != NULL
) {
1079 return (packet
->client_port
);
1086 void dhcpinform (packet
, ms_nulltp
)
1087 struct packet
*packet
;
1090 char msgbuf
[1024], *addr_type
;
1091 struct data_string d1
, prl
, fixed_addr
;
1092 struct option_cache
*oc
;
1093 struct option_state
*options
= NULL
;
1094 struct dhcp_packet raw
;
1095 struct packet outgoing
;
1096 unsigned char dhcpack
= DHCPACK
;
1097 struct subnet
*subnet
= NULL
;
1098 struct iaddr cip
, gip
, sip
;
1101 struct sockaddr_in to
;
1102 struct in_addr from
;
1103 isc_boolean_t zeroed_ciaddr
;
1104 struct interface_info
*interface
;
1105 int result
, h_m_client_ip
= 0;
1106 struct host_decl
*host
= NULL
, *hp
= NULL
, *h
;
1107 #if defined(RELAY_PORT)
1108 u_int16_t relay_port
= 0;
1110 #if defined (DEBUG_INFORM_HOST)
1111 int h_w_fixed_addr
= 0;
1114 /* The client should set ciaddr to its IP address, but apparently
1115 it's common for clients not to do this, so we'll use their IP
1116 source address if they didn't set ciaddr. */
1117 if (!packet
->raw
->ciaddr
.s_addr
) {
1118 zeroed_ciaddr
= ISC_TRUE
;
1119 /* With DHCPv4-over-DHCPv6 it can be an IPv6 address
1120 so we check its length. */
1121 if (packet
->client_addr
.len
== 4) {
1123 memcpy(cip
.iabuf
, &packet
->client_addr
.iabuf
, 4);
1124 addr_type
= "source";
1127 memset(cip
.iabuf
, 0, 4);
1131 zeroed_ciaddr
= ISC_FALSE
;
1133 memcpy(cip
.iabuf
, &packet
->raw
->ciaddr
, 4);
1134 addr_type
= "client";
1137 memcpy(sip
.iabuf
, cip
.iabuf
, 4);
1139 if (packet
->raw
->giaddr
.s_addr
) {
1141 memcpy(gip
.iabuf
, &packet
->raw
->giaddr
, 4);
1142 if (zeroed_ciaddr
== ISC_TRUE
) {
1143 addr_type
= "relay";
1144 memcpy(sip
.iabuf
, gip
.iabuf
, 4);
1149 /* %Audit% This is log output. %2004.06.17,Safe%
1150 * If we truncate we hope the user can get a hint from the log.
1152 #if defined(DHCPv6) && defined(DHCP4o6)
1153 if (dhcpv4_over_dhcpv6
&& (packet
->dhcp4o6_response
!= NULL
)) {
1154 snprintf(msgbuf
, sizeof(msgbuf
),
1155 "DHCP4o6 DHCPINFORM from %s via %s",
1157 piaddr(packet
->client_addr
));
1160 snprintf(msgbuf
, sizeof(msgbuf
), "DHCPINFORM from %s via %s",
1162 packet
->raw
->giaddr
.s_addr
?
1163 inet_ntoa(packet
->raw
->giaddr
) :
1164 packet
->interface
->name
);
1166 /* If the IP source address is zero, don't respond. */
1167 if (!memcmp(cip
.iabuf
, "\0\0\0", 4)) {
1168 log_info("%s: ignored (null source address).", msgbuf
);
1172 #if defined(RELAY_PORT)
1173 relay_port
= dhcp_check_relayport(packet
);
1176 /* Find the subnet that the client is on.
1177 * CC: Do the link selection / subnet selection
1180 option_state_allocate(&options
, MDL
);
1182 if ((oc
= lookup_option(&agent_universe
, packet
->options
,
1183 RAI_LINK_SELECT
)) == NULL
)
1184 oc
= lookup_option(&dhcp_universe
, packet
->options
,
1185 DHO_SUBNET_SELECTION
);
1187 memset(&d1
, 0, sizeof d1
);
1188 if (oc
&& evaluate_option_cache(&d1
, packet
, NULL
, NULL
,
1189 packet
->options
, NULL
,
1190 &global_scope
, oc
, MDL
)) {
1191 struct option_cache
*noc
= NULL
;
1194 log_info("%s: ignored (invalid subnet selection option).", msgbuf
);
1195 option_state_dereference(&options
, MDL
);
1196 data_string_forget(&d1
, MDL
);
1200 memcpy(sip
.iabuf
, d1
.data
, 4);
1201 data_string_forget(&d1
, MDL
);
1203 /* Make a copy of the data. */
1204 if (option_cache_allocate(&noc
, MDL
)) {
1206 data_string_copy(&noc
->data
, &oc
->data
, MDL
);
1208 expression_reference(&noc
->expression
,
1209 oc
->expression
, MDL
);
1211 option_reference(&(noc
->option
), oc
->option
,
1214 save_option(&dhcp_universe
, options
, noc
);
1215 option_cache_dereference(&noc
, MDL
);
1217 if ((zeroed_ciaddr
== ISC_TRUE
) && (gip
.len
!= 0))
1218 addr_type
= "relay link select";
1220 addr_type
= "selected";
1223 find_subnet(&subnet
, sip
, MDL
);
1225 if (subnet
== NULL
) {
1226 log_info("%s: unknown subnet for %s address %s",
1227 msgbuf
, addr_type
, piaddr(sip
));
1228 option_state_dereference(&options
, MDL
);
1232 /* We don't respond to DHCPINFORM packets if we're not authoritative.
1233 It would be nice if a per-host value could override this, but
1234 there's overhead involved in checking this, so let's see how people
1236 if (!subnet
->group
->authoritative
) {
1238 log_info("%s: not authoritative for subnet %s",
1239 msgbuf
, piaddr (subnet
-> net
));
1241 log_info("If this DHCP server is authoritative for%s",
1243 log_info("please write an `authoritative;' directi%s",
1244 "ve either in the");
1245 log_info("subnet declaration or in some scope that%s",
1247 log_info("subnet declaration - for example, write %s",
1249 log_info("of the dhcpd.conf file.");
1253 subnet_dereference(&subnet
, MDL
);
1254 option_state_dereference(&options
, MDL
);
1258 memset(&outgoing
, 0, sizeof outgoing
);
1259 memset(&raw
, 0, sizeof raw
);
1260 outgoing
.raw
= &raw
;
1262 maybe_return_agent_options(packet
, options
);
1264 /* Execute statements network statements starting at the subnet level */
1265 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
1266 packet
->options
, options
,
1267 &global_scope
, subnet
->group
,
1270 /* If we have ciaddr, find its lease so we can find its pool. */
1271 if (zeroed_ciaddr
== ISC_FALSE
) {
1272 struct lease
* cip_lease
= NULL
;
1274 find_lease_by_ip_addr (&cip_lease
, cip
, MDL
);
1276 /* Overlay with pool options if ciaddr mapped to a lease. */
1278 if (cip_lease
->pool
&& cip_lease
->pool
->group
) {
1279 execute_statements_in_scope(
1280 NULL
, packet
, NULL
, NULL
,
1281 packet
->options
, options
,
1283 cip_lease
->pool
->group
,
1284 cip_lease
->pool
->shared_network
->group
,
1288 lease_dereference (&cip_lease
, MDL
);
1292 /* Execute statements in the class scopes. */
1293 for (i
= packet
->class_count
; i
> 0; i
--) {
1294 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
1295 packet
->options
, options
,
1297 packet
->classes
[i
- 1]->group
,
1303 * Process host declarations during DHCPINFORM,
1304 * Try to find a matching host declaration by cli ID or HW addr.
1306 * Look through the host decls for one that matches the
1307 * client identifer or the hardware address. The preference
1309 * client id with matching ip address
1310 * hardware address with matching ip address
1311 * client id without a ip fixed address
1312 * hardware address without a fixed ip address
1313 * If found, set host to use its option definitions.
1315 oc
= lookup_option(&dhcp_universe
, packet
->options
,
1316 DHO_DHCP_CLIENT_IDENTIFIER
);
1317 memset(&d1
, 0, sizeof(d1
));
1319 evaluate_option_cache(&d1
, packet
, NULL
, NULL
,
1320 packet
->options
, NULL
,
1321 &global_scope
, oc
, MDL
)) {
1322 find_hosts_by_uid(&hp
, d1
.data
, d1
.len
, MDL
);
1323 data_string_forget(&d1
, MDL
);
1325 #if defined (DEBUG_INFORM_HOST)
1327 log_debug ("dhcpinform: found host by ID "
1328 "-- checking fixed-address match");
1330 /* check if we have one with fixed-address
1331 * matching the client ip first */
1332 for (h
= hp
; !h_m_client_ip
&& h
; h
= h
->n_ipaddr
) {
1336 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
1337 if (!evaluate_option_cache (&fixed_addr
, NULL
,
1338 NULL
, NULL
, NULL
, NULL
,
1340 h
->fixed_addr
, MDL
))
1343 #if defined (DEBUG_INFORM_HOST)
1347 (i
+ cip
.len
) <= fixed_addr
.len
;
1349 if (memcmp(fixed_addr
.data
+ i
,
1350 cip
.iabuf
, cip
.len
) == 0) {
1351 #if defined (DEBUG_INFORM_HOST)
1352 log_debug ("dhcpinform: found "
1353 "host with matching "
1354 "fixed-address by ID");
1356 host_reference(&host
, h
, MDL
);
1361 data_string_forget(&fixed_addr
, MDL
);
1364 /* fallback to a host without fixed-address */
1365 for (h
= hp
; !host
&& h
; h
= h
->n_ipaddr
) {
1369 #if defined (DEBUG_INFORM_HOST)
1370 log_debug ("dhcpinform: found host "
1371 "without fixed-address by ID");
1373 host_reference(&host
, h
, MDL
);
1377 host_dereference (&hp
, MDL
);
1379 if (!host
|| !h_m_client_ip
) {
1380 find_hosts_by_haddr(&hp
, packet
->raw
->htype
,
1381 packet
->raw
->chaddr
,
1382 packet
->raw
->hlen
, MDL
);
1384 #if defined (DEBUG_INFORM_HOST)
1386 log_debug ("dhcpinform: found host by HW "
1387 "-- checking fixed-address match");
1390 /* check if we have one with fixed-address
1391 * matching the client ip first */
1392 for (h
= hp
; !h_m_client_ip
&& h
; h
= h
->n_ipaddr
) {
1396 memset (&fixed_addr
, 0, sizeof(fixed_addr
));
1397 if (!evaluate_option_cache (&fixed_addr
, NULL
,
1398 NULL
, NULL
, NULL
, NULL
,
1400 h
->fixed_addr
, MDL
))
1403 #if defined (DEBUG_INFORM_HOST)
1407 (i
+ cip
.len
) <= fixed_addr
.len
;
1409 if (memcmp(fixed_addr
.data
+ i
,
1410 cip
.iabuf
, cip
.len
) == 0) {
1411 #if defined (DEBUG_INFORM_HOST)
1412 log_debug ("dhcpinform: found "
1413 "host with matching "
1414 "fixed-address by HW");
1417 * Hmm.. we've found one
1418 * without IP by ID and now
1419 * (better) one with IP by HW.
1422 host_dereference(&host
, MDL
);
1423 host_reference(&host
, h
, MDL
);
1428 data_string_forget(&fixed_addr
, MDL
);
1430 /* fallback to a host without fixed-address */
1431 for (h
= hp
; !host
&& h
; h
= h
->n_ipaddr
) {
1435 #if defined (DEBUG_INFORM_HOST)
1436 log_debug ("dhcpinform: found host without "
1437 "fixed-address by HW");
1439 host_reference (&host
, h
, MDL
);
1444 host_dereference (&hp
, MDL
);
1447 #if defined (DEBUG_INFORM_HOST)
1448 /* Hmm..: what when there is a host with a fixed-address,
1449 * that matches by hw or id, but the fixed-addresses
1450 * didn't match client ip?
1452 if (h_w_fixed_addr
&& !h_m_client_ip
) {
1453 log_info ("dhcpinform: matching host with "
1454 "fixed-address different than "
1455 "client IP detected?!");
1459 /* If we have a host_decl structure, run the options
1460 * associated with its group. Whether the host decl
1461 * struct is old or not. */
1463 #if defined (DEBUG_INFORM_HOST)
1464 log_info ("dhcpinform: applying host (group) options");
1466 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
1467 packet
->options
, options
,
1468 &global_scope
, host
->group
,
1471 host_dereference (&host
, MDL
);
1474 /* CC: end of host entry processing.... */
1476 /* Figure out the filename. */
1477 memset (&d1
, 0, sizeof d1
);
1478 oc
= lookup_option (&server_universe
, options
, SV_FILENAME
);
1480 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1481 (struct client_state
*)0,
1482 packet
-> options
, (struct option_state
*)0,
1483 &global_scope
, oc
, MDL
)) {
1485 if (i
>= sizeof(raw
.file
)) {
1486 log_info("file name longer than packet field "
1487 "truncated - field: %lu name: %d %.*s",
1488 (unsigned long)sizeof(raw
.file
), i
,
1490 i
= sizeof(raw
.file
);
1493 memcpy (raw
.file
, d1
.data
, i
);
1494 data_string_forget (&d1
, MDL
);
1497 /* Choose a server name as above. */
1498 oc
= lookup_option (&server_universe
, options
, SV_SERVER_NAME
);
1500 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1501 (struct client_state
*)0,
1502 packet
-> options
, (struct option_state
*)0,
1503 &global_scope
, oc
, MDL
)) {
1505 if (i
>= sizeof(raw
.sname
)) {
1506 log_info("server name longer than packet field "
1507 "truncated - field: %lu name: %d %.*s",
1508 (unsigned long)sizeof(raw
.sname
), i
,
1510 i
= sizeof(raw
.sname
);
1513 memcpy (raw
.sname
, d1
.data
, i
);
1514 data_string_forget (&d1
, MDL
);
1517 /* Set a flag if this client is a lame Microsoft client that NUL
1518 terminates string options and expects us to do likewise. */
1520 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
1522 if (!oc
->expression
)
1523 nulltp
= oc
->flags
& OPTION_HAD_NULLS
;
1526 /* Put in DHCP-specific options. */
1527 i
= DHO_DHCP_MESSAGE_TYPE
;
1528 oc
= (struct option_cache
*)0;
1529 if (option_cache_allocate (&oc
, MDL
)) {
1530 if (make_const_data (&oc
-> expression
,
1531 &dhcpack
, 1, 0, 0, MDL
)) {
1532 option_code_hash_lookup(&oc
->option
,
1533 dhcp_universe
.code_hash
,
1535 save_option (&dhcp_universe
, options
, oc
);
1537 option_cache_dereference (&oc
, MDL
);
1540 get_server_source_address(&from
, options
, options
, packet
);
1542 /* Use the subnet mask from the subnet declaration if no other
1543 mask has been provided. */
1544 i
= DHO_SUBNET_MASK
;
1545 if (subnet
&& !lookup_option (&dhcp_universe
, options
, i
)) {
1546 oc
= (struct option_cache
*)0;
1547 if (option_cache_allocate (&oc
, MDL
)) {
1548 if (make_const_data (&oc
-> expression
,
1549 subnet
-> netmask
.iabuf
,
1550 subnet
-> netmask
.len
,
1552 option_code_hash_lookup(&oc
->option
,
1553 dhcp_universe
.code_hash
,
1555 save_option (&dhcp_universe
, options
, oc
);
1557 option_cache_dereference (&oc
, MDL
);
1561 /* If a site option space has been specified, use that for
1562 site option codes. */
1563 i
= SV_SITE_OPTION_SPACE
;
1564 if ((oc
= lookup_option (&server_universe
, options
, i
)) &&
1565 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1566 (struct client_state
*)0,
1567 packet
-> options
, options
,
1568 &global_scope
, oc
, MDL
)) {
1569 struct universe
*u
= (struct universe
*)0;
1571 if (!universe_hash_lookup (&u
, universe_hash
,
1572 (const char *)d1
.data
, d1
.len
,
1574 log_error ("unknown option space %s.", d1
.data
);
1575 option_state_dereference (&options
, MDL
);
1577 subnet_dereference (&subnet
, MDL
);
1578 data_string_forget (&d1
, MDL
);
1582 options
-> site_universe
= u
-> index
;
1583 options
->site_code_min
= find_min_site_code(u
);
1584 data_string_forget (&d1
, MDL
);
1586 options
-> site_universe
= dhcp_universe
.index
;
1587 options
-> site_code_min
= 0; /* Trust me, it works. */
1590 memset (&prl
, 0, sizeof prl
);
1592 /* Use the parameter list from the scope if there is one. */
1593 oc
= lookup_option (&dhcp_universe
, options
,
1594 DHO_DHCP_PARAMETER_REQUEST_LIST
);
1596 /* Otherwise, if the client has provided a list of options
1597 that it wishes returned, use it to prioritize. Otherwise,
1598 prioritize based on the default priority list. */
1601 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
1602 DHO_DHCP_PARAMETER_REQUEST_LIST
);
1605 evaluate_option_cache (&prl
, packet
, (struct lease
*)0,
1606 (struct client_state
*)0,
1607 packet
-> options
, options
,
1608 &global_scope
, oc
, MDL
);
1611 dump_packet (packet
);
1612 dump_raw ((unsigned char *)packet
-> raw
, packet
-> packet_length
);
1615 log_info ("%s", msgbuf
);
1617 /* Figure out the address of the boot file server. */
1619 lookup_option (&server_universe
, options
, SV_NEXT_SERVER
))) {
1620 if (evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1621 (struct client_state
*)0,
1622 packet
-> options
, options
,
1623 &global_scope
, oc
, MDL
)) {
1624 /* If there was more than one answer,
1626 if (d1
.len
>= 4 && d1
.data
)
1627 memcpy (&raw
.siaddr
, d1
.data
, 4);
1628 data_string_forget (&d1
, MDL
);
1633 * Remove any time options, per section 3.4 RFC 2131
1635 delete_option(&dhcp_universe
, options
, DHO_DHCP_LEASE_TIME
);
1636 delete_option(&dhcp_universe
, options
, DHO_DHCP_RENEWAL_TIME
);
1637 delete_option(&dhcp_universe
, options
, DHO_DHCP_REBINDING_TIME
);
1639 /* Set up the option buffer... */
1640 outgoing
.packet_length
=
1641 cons_options (packet
, outgoing
.raw
, (struct lease
*)0,
1642 (struct client_state
*)0,
1643 0, packet
-> options
, options
, &global_scope
,
1645 prl
.len
? &prl
: (struct data_string
*)0,
1647 option_state_dereference (&options
, MDL
);
1648 data_string_forget (&prl
, MDL
);
1650 /* Make sure that the packet is at least as big as a BOOTP packet. */
1651 if (outgoing
.packet_length
< BOOTP_MIN_LEN
)
1652 outgoing
.packet_length
= BOOTP_MIN_LEN
;
1654 raw
.giaddr
= packet
-> raw
-> giaddr
;
1655 raw
.ciaddr
= packet
-> raw
-> ciaddr
;
1656 memcpy (raw
.chaddr
, packet
-> raw
-> chaddr
, sizeof raw
.chaddr
);
1657 raw
.hlen
= packet
-> raw
-> hlen
;
1658 raw
.htype
= packet
-> raw
-> htype
;
1660 raw
.xid
= packet
-> raw
-> xid
;
1661 raw
.secs
= packet
-> raw
-> secs
;
1662 raw
.flags
= packet
-> raw
-> flags
;
1663 raw
.hops
= packet
-> raw
-> hops
;
1667 dump_packet (&outgoing
);
1668 dump_raw ((unsigned char *)&raw
, outgoing
.packet_length
);
1671 #if defined(DHCPv6) && defined(DHCP4o6)
1672 if (dhcpv4_over_dhcpv6
&& (packet
->dhcp4o6_response
!= NULL
)) {
1673 /* Report what we're sending. */
1674 snprintf(msgbuf
, sizeof msgbuf
,
1675 "DHCP4o6 DHCPACK to %s (%s) via", piaddr(cip
),
1676 (packet
->raw
->htype
&& packet
->raw
->hlen
) ?
1677 print_hw_addr(packet
->raw
->htype
, packet
->raw
->hlen
,
1678 packet
->raw
->chaddr
) :
1679 "<no client hardware address>");
1680 log_info("%s %s", msgbuf
, piaddr(packet
->client_addr
));
1682 /* fill dhcp4o6_response */
1683 packet
->dhcp4o6_response
->len
= outgoing
.packet_length
;
1684 packet
->dhcp4o6_response
->buffer
= NULL
;
1685 if (!buffer_allocate(&packet
->dhcp4o6_response
->buffer
,
1686 outgoing
.packet_length
, MDL
)) {
1687 log_fatal("No memory to store DHCP4o6 reply.");
1689 packet
->dhcp4o6_response
->data
=
1690 packet
->dhcp4o6_response
->buffer
->data
;
1691 memcpy(packet
->dhcp4o6_response
->buffer
->data
,
1692 outgoing
.raw
, outgoing
.packet_length
);
1696 subnet_dereference (&subnet
, MDL
);
1701 /* Set up the common stuff... */
1702 to
.sin_family
= AF_INET
;
1704 to
.sin_len
= sizeof to
;
1706 memset (to
.sin_zero
, 0, sizeof to
.sin_zero
);
1708 /* RFC2131 states the server SHOULD unicast to ciaddr.
1709 * There are two wrinkles - relays, and when ciaddr is zero.
1710 * There's actually no mention of relays at all in rfc2131 in
1711 * regard to DHCPINFORM, except to say we might get packets from
1712 * clients via them. Note: relays unicast to clients to the
1713 * "yiaddr" address, which servers are forbidden to set when
1714 * answering an inform.
1716 * The solution: If ciaddr is zero, and giaddr is set, go via the
1717 * relay with the broadcast flag set to help the relay (with no
1718 * yiaddr and very likely no chaddr, it will have no idea where to
1721 * If the ciaddr is zero and giaddr is not set, go via the source
1722 * IP address (but you are permitted to barf on their shoes).
1724 * If ciaddr is not zero, send the packet there always.
1726 if (!raw
.ciaddr
.s_addr
&& gip
.len
) {
1727 memcpy(&to
.sin_addr
, gip
.iabuf
, 4);
1728 #if defined(RELAY_PORT)
1729 to
.sin_port
= relay_port
? relay_port
: local_port
;
1731 to
.sin_port
= local_port
;
1733 raw
.flags
|= htons(BOOTP_BROADCAST
);
1736 memcpy(&to
.sin_addr
, cip
.iabuf
, 4);
1737 to
.sin_port
= remote_port
;
1740 /* Report what we're sending. */
1741 snprintf(msgbuf
, sizeof msgbuf
, "DHCPACK to %s (%s) via", piaddr(cip
),
1742 (packet
->raw
->htype
&& packet
->raw
->hlen
) ?
1743 print_hw_addr(packet
->raw
->htype
, packet
->raw
->hlen
,
1744 packet
->raw
->chaddr
) :
1745 "<no client hardware address>");
1746 log_info("%s %s", msgbuf
, gip
.len
? piaddr(gip
) :
1747 packet
->interface
->name
);
1750 interface
= (fallback_interface
? fallback_interface
1751 : packet
-> interface
);
1752 result
= send_packet(interface
, &outgoing
, &raw
,
1753 outgoing
.packet_length
, from
, &to
, NULL
);
1755 log_error ("%s:%d: Failed to send %d byte long packet over %s "
1756 "interface.", MDL
, outgoing
.packet_length
,
1762 subnet_dereference (&subnet
, MDL
);
1766 * \brief Constructs and sends a DHCP Nak
1768 * In order to populate options such as dhcp-server-id and
1769 * dhcp-client-identifier, the function creates a temporary option cache
1770 * and evaluates options based on the packet's shared-network or the
1771 * network_group in its absence, as well as the packet->clasess (if any).
1773 * \param packet inbound packet received from the client
1774 * \param cip address requested by the client
1775 * \param network_group optional scope for use in setting up options
1777 void nak_lease (packet
, cip
, network_group
)
1778 struct packet
*packet
;
1780 struct group
*network_group
; /* scope to use for options */
1782 struct sockaddr_in to
;
1783 struct in_addr from
;
1785 struct dhcp_packet raw
;
1786 unsigned char nak
= DHCPNAK
;
1787 struct packet outgoing
;
1789 #if defined(RELAY_PORT)
1790 u_int16_t relay_port
= 0;
1792 struct option_state
*options
= (struct option_state
*)0;
1793 struct option_cache
*oc
= (struct option_cache
*)0;
1794 struct option_state
*eval_options
= NULL
;
1796 option_state_allocate (&options
, MDL
);
1797 memset (&outgoing
, 0, sizeof outgoing
);
1798 memset (&raw
, 0, sizeof raw
);
1799 outgoing
.raw
= &raw
;
1801 /* Set DHCP_MESSAGE_TYPE to DHCPNAK */
1802 if (!option_cache_allocate (&oc
, MDL
)) {
1803 log_error ("No memory for DHCPNAK message type.");
1804 option_state_dereference (&options
, MDL
);
1807 if (!make_const_data (&oc
-> expression
, &nak
, sizeof nak
,
1809 log_error ("No memory for expr_const expression.");
1810 option_cache_dereference (&oc
, MDL
);
1811 option_state_dereference (&options
, MDL
);
1814 i
= DHO_DHCP_MESSAGE_TYPE
;
1815 option_code_hash_lookup(&oc
->option
, dhcp_universe
.code_hash
,
1817 save_option (&dhcp_universe
, options
, oc
);
1818 option_cache_dereference (&oc
, MDL
);
1820 #if defined(RELAY_PORT)
1821 relay_port
= dhcp_check_relayport(packet
);
1824 /* Set DHCP_MESSAGE to whatever the message is */
1825 if (!option_cache_allocate (&oc
, MDL
)) {
1826 log_error ("No memory for DHCPNAK message type.");
1827 option_state_dereference (&options
, MDL
);
1830 if (!make_const_data (&oc
-> expression
,
1831 (unsigned char *)dhcp_message
,
1832 strlen (dhcp_message
), 1, 0, MDL
)) {
1833 log_error ("No memory for expr_const expression.");
1834 option_cache_dereference (&oc
, MDL
);
1835 option_state_dereference (&options
, MDL
);
1838 i
= DHO_DHCP_MESSAGE
;
1839 option_code_hash_lookup(&oc
->option
, dhcp_universe
.code_hash
,
1841 save_option (&dhcp_universe
, options
, oc
);
1842 option_cache_dereference (&oc
, MDL
);
1844 /* Setup the options at the global and subnet scopes. These
1845 * may be used to locate sever id option if enabled as well
1846 * for echo-client-id further on. (This allocates eval_options). */
1847 eval_network_statements(&eval_options
, packet
, network_group
);
1849 #if defined(SERVER_ID_FOR_NAK)
1850 /* Pass in the evaluated options so they can be searched for
1851 * server-id, otherwise source address comes from the interface
1853 get_server_source_address(&from
, eval_options
, options
, packet
);
1855 /* Get server source address from the interface address */
1856 get_server_source_address(&from
, NULL
, options
, packet
);
1857 #endif /* if defined(SERVER_ID_FOR_NAK) */
1859 /* If there were agent options in the incoming packet, return
1860 * them. We do not check giaddr to detect the presence of a
1861 * relay, as this excludes "l2" relay agents which have no
1864 if (packet
->options
->universe_count
> agent_universe
.index
&&
1865 packet
->options
->universes
[agent_universe
.index
]) {
1866 option_chain_head_reference
1867 ((struct option_chain_head
**)
1868 &(options
-> universes
[agent_universe
.index
]),
1869 (struct option_chain_head
*)
1870 packet
-> options
-> universes
[agent_universe
.index
],
1874 /* echo-client-id can specified at the class level so add class-scoped
1875 * options into eval_options. */
1876 for (i
= packet
->class_count
; i
> 0; i
--) {
1877 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
1878 packet
->options
, eval_options
,
1880 packet
->classes
[i
- 1]->group
,
1884 /* Echo client id if we received and it's enabled */
1885 echo_client_id(packet
, NULL
, eval_options
, options
);
1886 option_state_dereference (&eval_options
, MDL
);
1888 /* Do not use the client's requested parameter list. */
1889 delete_option (&dhcp_universe
, packet
-> options
,
1890 DHO_DHCP_PARAMETER_REQUEST_LIST
);
1892 /* Set up the option buffer... */
1893 outgoing
.packet_length
=
1894 cons_options (packet
, outgoing
.raw
, (struct lease
*)0,
1895 (struct client_state
*)0,
1896 0, packet
-> options
, options
, &global_scope
,
1897 0, 0, 0, (struct data_string
*)0, (char *)0);
1898 option_state_dereference (&options
, MDL
);
1900 /* memset (&raw.ciaddr, 0, sizeof raw.ciaddr);*/
1901 raw
.giaddr
= packet
-> raw
-> giaddr
;
1902 memcpy (raw
.chaddr
, packet
-> raw
-> chaddr
, sizeof raw
.chaddr
);
1903 raw
.hlen
= packet
-> raw
-> hlen
;
1904 raw
.htype
= packet
-> raw
-> htype
;
1906 raw
.xid
= packet
-> raw
-> xid
;
1907 raw
.secs
= packet
-> raw
-> secs
;
1908 raw
.flags
= packet
-> raw
-> flags
| htons (BOOTP_BROADCAST
);
1909 raw
.hops
= packet
-> raw
-> hops
;
1912 /* Make sure that the packet is at least as big as a BOOTP packet. */
1913 if (outgoing
.packet_length
< BOOTP_MIN_LEN
)
1914 outgoing
.packet_length
= BOOTP_MIN_LEN
;
1916 /* Report what we're sending... */
1917 #if defined(DHCPv6) && defined(DHCP4o6)
1918 if (dhcpv4_over_dhcpv6
&& (packet
->dhcp4o6_response
!= NULL
)) {
1919 log_info ("DHCP4o6 DHCPNAK on %s to %s via %s",
1921 print_hw_addr (packet
-> raw
-> htype
,
1922 packet
-> raw
-> hlen
,
1923 packet
-> raw
-> chaddr
),
1924 piaddr(packet
->client_addr
));
1927 log_info ("DHCPNAK on %s to %s via %s",
1929 print_hw_addr (packet
-> raw
-> htype
,
1930 packet
-> raw
-> hlen
,
1931 packet
-> raw
-> chaddr
),
1932 packet
-> raw
-> giaddr
.s_addr
1933 ? inet_ntoa (packet
-> raw
-> giaddr
)
1934 : packet
-> interface
-> name
);
1937 dump_packet (packet
);
1938 dump_raw ((unsigned char *)packet
-> raw
, packet
-> packet_length
);
1939 dump_packet (&outgoing
);
1940 dump_raw ((unsigned char *)&raw
, outgoing
.packet_length
);
1943 #if defined(DHCPv6) && defined(DHCP4o6)
1944 if (dhcpv4_over_dhcpv6
&& (packet
->dhcp4o6_response
!= NULL
)) {
1945 /* fill dhcp4o6_response */
1946 packet
->dhcp4o6_response
->len
= outgoing
.packet_length
;
1947 packet
->dhcp4o6_response
->buffer
= NULL
;
1948 if (!buffer_allocate(&packet
->dhcp4o6_response
->buffer
,
1949 outgoing
.packet_length
, MDL
)) {
1950 log_fatal("No memory to store DHCP4o6 reply.");
1952 packet
->dhcp4o6_response
->data
=
1953 packet
->dhcp4o6_response
->buffer
->data
;
1954 memcpy(packet
->dhcp4o6_response
->buffer
->data
,
1955 outgoing
.raw
, outgoing
.packet_length
);
1960 /* Set up the common stuff... */
1961 to
.sin_family
= AF_INET
;
1963 to
.sin_len
= sizeof to
;
1965 memset (to
.sin_zero
, 0, sizeof to
.sin_zero
);
1967 /* If this was gatewayed, send it back to the gateway.
1968 Otherwise, broadcast it on the local network. */
1969 if (raw
.giaddr
.s_addr
) {
1970 to
.sin_addr
= raw
.giaddr
;
1971 if (raw
.giaddr
.s_addr
!= htonl (INADDR_LOOPBACK
))
1972 #if defined(RELAY_PORT)
1973 to
.sin_port
= relay_port
? relay_port
: local_port
;
1975 to
.sin_port
= local_port
;
1978 to
.sin_port
= remote_port
; /* for testing. */
1980 if (fallback_interface
) {
1981 result
= send_packet(fallback_interface
, packet
, &raw
,
1982 outgoing
.packet_length
, from
, &to
,
1985 log_error ("%s:%d: Failed to send %d byte long "
1986 "packet over %s interface.", MDL
,
1987 outgoing
.packet_length
,
1988 fallback_interface
->name
);
1994 to
.sin_addr
= limited_broadcast
;
1995 to
.sin_port
= remote_port
;
1999 result
= send_packet(packet
->interface
, packet
, &raw
,
2000 outgoing
.packet_length
, from
, &to
, NULL
);
2002 log_error ("%s:%d: Failed to send %d byte long packet over %s "
2003 "interface.", MDL
, outgoing
.packet_length
,
2004 packet
->interface
->name
);
2010 * \brief Adds a dhcp-client-id option to a set of options
2011 * Given a set of input options, it searches for echo-client-id. If it is
2012 * defined and enabled, the given packet is searched for dhcp-client-id. If
2013 * the option is found it is replicated into the given set of output options.
2014 * This allows us to provide compliance with RFC 6842. It is called when we ack
2015 * or nak a lease. In the latter case we may or may not have created the
2016 * requisite scope to lookup echo-client-id.
2018 * Note the flag packet.sv_echo_client_id is set to reflect the configuration
2019 * option. This bypases inaccessiblity of server_universe in cons_options()
2020 * which must amend the PRL (when not empty) if echoing is enabled.
2022 * \param packet inbound packet received from the client
2023 * \param lease lease associated with this client (if one)
2024 * \param in_options options in which to search for echo-client-id
2025 * \param out_options options to which to save the client-id
2027 void echo_client_id(packet
, lease
, in_options
, out_options
)
2028 struct packet
*packet
;
2029 struct lease
*lease
;
2030 struct option_state
*in_options
;
2031 struct option_state
*out_options
;
2033 struct option_cache
*oc
;
2036 /* Check if echo-client-id is enabled */
2037 oc
= lookup_option(&server_universe
, in_options
, SV_ECHO_CLIENT_ID
);
2038 if (oc
&& evaluate_boolean_option_cache(&ignorep
, packet
, lease
,
2039 NULL
, packet
->options
,
2041 (lease
? &lease
->scope
: NULL
),
2043 struct data_string client_id
;
2044 unsigned int opcode
= DHO_DHCP_CLIENT_IDENTIFIER
;
2046 /* Save knowledge that echo is enabled to the packet */
2047 packet
->sv_echo_client_id
= ISC_TRUE
;
2049 /* Now see if inbound packet contains client-id */
2050 oc
= lookup_option(&dhcp_universe
, packet
->options
, opcode
);
2051 memset(&client_id
, 0, sizeof client_id
);
2052 if (oc
&& evaluate_option_cache(&client_id
,
2054 packet
->options
, NULL
,
2055 (lease
? &lease
->scope
: NULL
),
2057 /* Packet contained client-id, add it to out_options. */
2059 if (option_cache_allocate(&oc
, MDL
)) {
2060 if (make_const_data(&oc
->expression
,
2064 option_code_hash_lookup(&oc
->option
,
2069 save_option(&dhcp_universe
,
2072 option_cache_dereference(&oc
, MDL
);
2078 void check_pool_threshold (packet
, lease
, state
)
2079 struct packet
*packet
;
2080 struct lease
*lease
;
2081 struct lease_state
*state
;
2085 struct pool
*pool
= lease
->pool
;
2086 int used
, count
, high_threshold
, poolhigh
= 0, poollow
= 0;
2087 char *shared_name
= "no name";
2092 /* get a pointer to the name if we have one */
2093 if ((pool
->shared_network
!= NULL
) &&
2094 (pool
->shared_network
->name
!= NULL
)) {
2095 shared_name
= pool
->shared_network
->name
;
2098 count
= pool
->lease_count
;
2099 used
= count
- (pool
->free_leases
+ pool
->backup_leases
);
2101 /* The logged flag indicates if we have already crossed the high
2102 * threshold and emitted a log message. If it is set we check to
2103 * see if we have re-crossed the low threshold and need to reset
2104 * things. When we cross the high threshold we determine what
2105 * the low threshold is and save it into the low_threshold value.
2106 * When we cross that threshold we reset the logged flag and
2107 * the low_threshold to 0 which allows the high threshold message
2108 * to be emitted once again.
2109 * if we haven't recrossed the boundry we don't need to do anything.
2111 if (pool
->logged
!=0) {
2112 if (used
<= pool
->low_threshold
) {
2113 pool
->low_threshold
= 0;
2115 log_error("Pool threshold reset - shared subnet: %s; "
2116 "address: %s; low threshold %d/%d.",
2117 shared_name
, piaddr(lease
->ip_addr
),
2123 /* find the high threshold */
2124 if (get_option_int(&poolhigh
, &server_universe
, packet
, lease
, NULL
,
2125 packet
->options
, state
->options
, state
->options
,
2126 &lease
->scope
, SV_LOG_THRESHOLD_HIGH
, MDL
) == 0) {
2127 /* no threshold bail out */
2131 /* We do have a threshold for this pool, see if its valid */
2132 if ((poolhigh
<= 0) || (poolhigh
> 100)) {
2137 /* we have a valid value, have we exceeded it */
2138 high_threshold
= FIND_PERCENT(count
, poolhigh
);
2139 if (used
< high_threshold
) {
2140 /* nope, no more to do */
2144 /* we've exceeded it, output a message */
2145 log_error("Pool threshold exceeded - shared subnet: %s; "
2146 "address: %s; high threshold %d%% %d/%d.",
2147 shared_name
, piaddr(lease
->ip_addr
),
2148 poolhigh
, used
, count
);
2150 /* handle the low threshold now, if we don't
2151 * have a valid one we default to 0. */
2152 if ((get_option_int(&poollow
, &server_universe
, packet
, lease
, NULL
,
2153 packet
->options
, state
->options
, state
->options
,
2154 &lease
->scope
, SV_LOG_THRESHOLD_LOW
, MDL
) == 0) ||
2160 * If the low theshold is higher than the high threshold we continue to log
2161 * If it isn't then we set the flag saying we already logged and determine
2162 * what the reset threshold is.
2164 if (poollow
< poolhigh
) {
2166 pool
->low_threshold
= FIND_PERCENT(count
, poollow
);
2170 void ack_lease (packet
, lease
, offer
, when
, msg
, ms_nulltp
, hp
)
2171 struct packet
*packet
;
2172 struct lease
*lease
;
2177 struct host_decl
*hp
;
2180 struct lease_state
*state
;
2182 struct host_decl
*host
= (struct host_decl
*)0;
2184 TIME offered_lease_time
;
2185 struct data_string d1
;
2186 TIME min_lease_time
;
2187 TIME max_lease_time
;
2188 TIME default_lease_time
;
2189 struct option_cache
*oc
;
2190 isc_result_t result
;
2192 struct in_addr from
;
2193 TIME remaining_time
;
2195 #if defined(DELAYED_ACK)
2196 /* By default we don't do the enqueue */
2197 isc_boolean_t enqueue
= ISC_FALSE
;
2199 int use_old_lease
= 0;
2200 int same_client
= 0;
2206 /* If we're already acking this lease, don't do it again. */
2210 /* Save original cltt for comparison later. */
2211 original_cltt
= lease
->cltt
;
2213 /* If the lease carries a host record, remember it. */
2215 host_reference (&host
, hp
, MDL
);
2216 else if (lease
-> host
)
2217 host_reference (&host
, lease
-> host
, MDL
);
2219 /* Allocate a lease state structure... */
2220 state
= new_lease_state (MDL
);
2222 log_fatal ("unable to allocate lease state!");
2223 state
-> got_requested_address
= packet
-> got_requested_address
;
2224 shared_network_reference (&state
-> shared_network
,
2225 packet
-> interface
-> shared_network
, MDL
);
2227 /* See if we got a server identifier option. */
2228 if (lookup_option (&dhcp_universe
,
2229 packet
-> options
, DHO_DHCP_SERVER_IDENTIFIER
))
2230 state
-> got_server_identifier
= 1;
2232 maybe_return_agent_options(packet
, state
->options
);
2234 /* If we are offering a lease that is still currently valid, preserve
2235 the events. We need to do this because if the client does not
2236 REQUEST our offer, it will expire in 2 minutes, overriding the
2237 expire time in the currently in force lease. We want the expire
2238 events to be executed at that point. */
2239 if (lease
->ends
<= cur_time
&& offer
!= DHCPOFFER
) {
2240 /* Get rid of any old expiry or release statements - by
2241 executing the statements below, we will be inserting new
2242 ones if there are any to insert. */
2243 if (lease
->on_star
.on_expiry
)
2244 executable_statement_dereference
2245 (&lease
->on_star
.on_expiry
, MDL
);
2246 if (lease
->on_star
.on_commit
)
2247 executable_statement_dereference
2248 (&lease
->on_star
.on_commit
, MDL
);
2249 if (lease
->on_star
.on_release
)
2250 executable_statement_dereference
2251 (&lease
->on_star
.on_release
, MDL
);
2254 /* Execute statements in scope starting with the subnet scope. */
2255 execute_statements_in_scope (NULL
, packet
, lease
,
2256 NULL
, packet
->options
,
2257 state
->options
, &lease
->scope
,
2258 lease
->subnet
->group
, NULL
, NULL
);
2260 /* If the lease is from a pool, run the pool scope. */
2262 (execute_statements_in_scope(NULL
, packet
, lease
, NULL
,
2263 packet
->options
, state
->options
,
2264 &lease
->scope
, lease
->pool
->group
,
2266 shared_network
->group
,
2269 /* Execute statements from class scopes. */
2270 for (i
= packet
-> class_count
; i
> 0; i
--) {
2271 execute_statements_in_scope(NULL
, packet
, lease
, NULL
,
2272 packet
->options
, state
->options
,
2274 packet
->classes
[i
- 1]->group
,
2275 (lease
->pool
? lease
->pool
->group
2276 : lease
->subnet
->group
),
2280 /* See if the client is only supposed to have one lease at a time,
2281 and if so, find its other leases and release them. We can only
2282 do this on DHCPREQUEST. It's a little weird to do this before
2283 looking at permissions, because the client might not actually
2284 _get_ a lease after we've done the permission check, but the
2285 assumption for this option is that the client has exactly one
2286 network interface, and will only ever remember one lease. So
2287 if it sends a DHCPREQUEST, and doesn't get the lease, it's already
2288 forgotten about its old lease, so we can too. */
2289 if (packet
-> packet_type
== DHCPREQUEST
&&
2290 (oc
= lookup_option (&server_universe
, state
-> options
,
2291 SV_ONE_LEASE_PER_CLIENT
)) &&
2292 evaluate_boolean_option_cache (&ignorep
,
2294 (struct client_state
*)0,
2296 state
-> options
, &lease
-> scope
,
2299 if (lease
-> uid_len
) {
2301 seek
= (struct lease
*)0;
2302 find_lease_by_uid (&seek
, lease
-> uid
,
2303 lease
-> uid_len
, MDL
);
2306 if (seek
== lease
&& !seek
-> n_uid
) {
2307 lease_dereference (&seek
, MDL
);
2310 next
= (struct lease
*)0;
2312 /* Don't release expired leases, and don't
2313 release the lease we're going to assign. */
2314 next
= (struct lease
*)0;
2317 lease_reference (&next
, seek
-> n_uid
, MDL
);
2318 if (seek
!= lease
&&
2319 seek
-> binding_state
!= FTS_RELEASED
&&
2320 seek
-> binding_state
!= FTS_EXPIRED
&&
2321 seek
-> binding_state
!= FTS_RESET
&&
2322 seek
-> binding_state
!= FTS_FREE
&&
2323 seek
-> binding_state
!= FTS_BACKUP
)
2325 lease_dereference (&seek
, MDL
);
2327 lease_reference (&seek
, next
, MDL
);
2328 lease_dereference (&next
, MDL
);
2332 lease_dereference (&next
, MDL
);
2334 release_lease (seek
, packet
);
2335 lease_dereference (&seek
, MDL
);
2340 if (!lease
-> uid_len
||
2342 !host
-> client_identifier
.len
&&
2343 (oc
= lookup_option (&server_universe
, state
-> options
,
2345 !evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
2346 (struct client_state
*)0,
2352 seek
= (struct lease
*)0;
2353 find_lease_by_hw_addr
2354 (&seek
, lease
-> hardware_addr
.hbuf
,
2355 lease
-> hardware_addr
.hlen
, MDL
);
2358 if (seek
== lease
&& !seek
-> n_hw
) {
2359 lease_dereference (&seek
, MDL
);
2362 next
= (struct lease
*)0;
2365 lease_reference (&next
, seek
-> n_hw
, MDL
);
2366 if (seek
!= lease
&&
2367 seek
-> binding_state
!= FTS_RELEASED
&&
2368 seek
-> binding_state
!= FTS_EXPIRED
&&
2369 seek
-> binding_state
!= FTS_RESET
&&
2370 seek
-> binding_state
!= FTS_FREE
&&
2371 seek
-> binding_state
!= FTS_BACKUP
)
2373 lease_dereference (&seek
, MDL
);
2375 lease_reference (&seek
, next
, MDL
);
2376 lease_dereference (&next
, MDL
);
2380 lease_dereference (&next
, MDL
);
2382 release_lease (seek
, packet
);
2383 lease_dereference (&seek
, MDL
);
2391 /* Make sure this packet satisfies the configured minimum
2392 number of seconds. */
2393 memset (&d1
, 0, sizeof d1
);
2394 if (offer
== DHCPOFFER
&&
2395 (oc
= lookup_option (&server_universe
, state
-> options
,
2397 if (evaluate_option_cache (&d1
, packet
, lease
,
2398 (struct client_state
*)0,
2399 packet
-> options
, state
-> options
,
2400 &lease
-> scope
, oc
, MDL
)) {
2402 ntohs (packet
-> raw
-> secs
) < d1
.data
[0]) {
2403 log_info("%s: configured min-secs value (%d) "
2404 "is greater than secs field (%d). "
2405 "message dropped.", msg
, d1
.data
[0],
2406 ntohs(packet
->raw
->secs
));
2407 data_string_forget (&d1
, MDL
);
2408 free_lease_state (state
, MDL
);
2410 host_dereference (&host
, MDL
);
2413 data_string_forget (&d1
, MDL
);
2417 /* Try to find a matching host declaration for this lease.
2420 struct host_decl
*hp
= (struct host_decl
*)0;
2421 struct host_decl
*h
;
2423 /* Try to find a host_decl that matches the client
2424 identifier or hardware address on the packet, and
2425 has no fixed IP address. If there is one, hang
2426 it off the lease so that its option definitions
2428 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
2429 DHO_DHCP_CLIENT_IDENTIFIER
);
2431 evaluate_option_cache (&d1
, packet
, lease
,
2432 (struct client_state
*)0,
2433 packet
-> options
, state
-> options
,
2434 &lease
-> scope
, oc
, MDL
)) {
2435 find_hosts_by_uid (&hp
, d1
.data
, d1
.len
, MDL
);
2436 data_string_forget (&d1
, MDL
);
2437 for (h
= hp
; h
; h
= h
-> n_ipaddr
) {
2438 if (!h
-> fixed_addr
)
2442 host_reference (&host
, h
, MDL
);
2444 host_dereference(&hp
, MDL
);
2447 find_hosts_by_haddr (&hp
,
2448 packet
-> raw
-> htype
,
2449 packet
-> raw
-> chaddr
,
2450 packet
-> raw
-> hlen
,
2452 for (h
= hp
; h
; h
= h
-> n_ipaddr
) {
2453 if (!h
-> fixed_addr
)
2457 host_reference (&host
, h
, MDL
);
2459 host_dereference(&hp
, MDL
);
2462 find_hosts_by_option(&hp
, packet
,
2463 packet
->options
, MDL
);
2464 for (h
= hp
; h
; h
= h
-> n_ipaddr
) {
2465 if (!h
-> fixed_addr
)
2469 host_reference (&host
, h
, MDL
);
2471 host_dereference(&hp
, MDL
);
2475 /* If we have a host_decl structure, run the options associated
2476 with its group. Whether the host decl struct is old or not. */
2478 execute_statements_in_scope (NULL
, packet
, lease
, NULL
,
2479 packet
->options
, state
->options
,
2480 &lease
->scope
, host
->group
,
2482 ? lease
->pool
->group
2483 : lease
->subnet
->group
),
2486 /* Drop the request if it's not allowed for this client. By
2487 default, unknown clients are allowed. */
2489 (oc
= lookup_option (&server_universe
, state
-> options
,
2490 SV_BOOT_UNKNOWN_CLIENTS
)) &&
2491 !evaluate_boolean_option_cache (&ignorep
,
2493 (struct client_state
*)0,
2496 &lease
-> scope
, oc
, MDL
)) {
2498 log_info ("%s: unknown client", msg
);
2499 free_lease_state (state
, MDL
);
2501 host_dereference (&host
, MDL
);
2505 /* Drop the request if it's not allowed for this client. */
2507 (oc
= lookup_option (&server_universe
, state
-> options
,
2509 !evaluate_boolean_option_cache (&ignorep
,
2511 (struct client_state
*)0,
2514 &lease
-> scope
, oc
, MDL
)) {
2516 log_info ("%s: bootp disallowed", msg
);
2517 free_lease_state (state
, MDL
);
2519 host_dereference (&host
, MDL
);
2523 /* Drop the request if booting is specifically denied. */
2524 oc
= lookup_option (&server_universe
, state
-> options
,
2527 !evaluate_boolean_option_cache (&ignorep
,
2529 (struct client_state
*)0,
2532 &lease
-> scope
, oc
, MDL
)) {
2534 log_info ("%s: booting disallowed", msg
);
2535 free_lease_state (state
, MDL
);
2537 host_dereference (&host
, MDL
);
2541 /* If we are configured to do per-class billing, do it. */
2542 if (have_billing_classes
&& !(lease
-> flags
& STATIC_LEASE
)) {
2543 /* See if the lease is currently being billed to a
2544 class, and if so, whether or not it can continue to
2545 be billed to that class. */
2546 if (lease
-> billing_class
) {
2547 for (i
= 0; i
< packet
-> class_count
; i
++)
2548 if (packet
-> classes
[i
] ==
2549 lease
-> billing_class
)
2551 if (i
== packet
-> class_count
) {
2552 unbill_class(lease
);
2553 /* Active lease billing change negates reuse */
2554 if (lease
->binding_state
== FTS_ACTIVE
) {
2555 lease
->cannot_reuse
= 1;
2560 /* If we don't have an active billing, see if we need
2561 one, and if we do, try to do so. */
2562 if (lease
->billing_class
== NULL
) {
2566 for (i
= 0; i
< packet
->class_count
; i
++) {
2567 struct class *billclass
, *superclass
;
2569 billclass
= packet
->classes
[i
];
2570 if (billclass
->lease_limit
) {
2572 if (bill_class(lease
, billclass
))
2575 superclass
= billclass
->superclass
;
2576 if (superclass
!= NULL
)
2577 cname
= superclass
->name
;
2579 cname
= billclass
->name
;
2582 if (bill
!= 0 && i
== packet
->class_count
) {
2583 log_info("%s: no available billing: lease "
2584 "limit reached in all matching "
2585 "classes (last: '%s')", msg
, cname
);
2586 free_lease_state(state
, MDL
);
2588 host_dereference(&host
, MDL
);
2593 * If this is an offer, undo the billing. We go
2594 * through all the steps above to bill a class so
2595 * we can hit the 'no available billing' mark and
2596 * abort without offering. But it just doesn't make
2597 * sense to permanently bill a class for a non-active
2598 * lease. This means on REQUEST, we will bill this
2599 * lease again (if there is a REQUEST).
2601 if (offer
== DHCPOFFER
&&
2602 lease
->billing_class
!= NULL
&&
2603 lease
->binding_state
!= FTS_ACTIVE
)
2604 unbill_class(lease
);
2606 /* Lease billing change negates reuse */
2607 if (lease
->billing_class
!= NULL
) {
2608 lease
->cannot_reuse
= 1;
2613 /* Figure out the filename. */
2614 oc
= lookup_option (&server_universe
, state
-> options
, SV_FILENAME
);
2616 evaluate_option_cache (&state
-> filename
, packet
, lease
,
2617 (struct client_state
*)0,
2618 packet
-> options
, state
-> options
,
2619 &lease
-> scope
, oc
, MDL
);
2621 /* Choose a server name as above. */
2622 oc
= lookup_option (&server_universe
, state
-> options
,
2625 evaluate_option_cache (&state
-> server_name
, packet
, lease
,
2626 (struct client_state
*)0,
2627 packet
-> options
, state
-> options
,
2628 &lease
-> scope
, oc
, MDL
);
2630 /* At this point, we have a lease that we can offer the client.
2631 Now we construct a lease structure that contains what we want,
2632 and call supersede_lease to do the right thing with it. */
2633 lt
= (struct lease
*)0;
2634 result
= lease_allocate (<
, MDL
);
2635 if (result
!= ISC_R_SUCCESS
) {
2636 log_info ("%s: can't allocate temporary lease structure: %s",
2637 msg
, isc_result_totext (result
));
2638 free_lease_state (state
, MDL
);
2640 host_dereference (&host
, MDL
);
2644 /* Use the ip address of the lease that we finally found in
2646 lt
-> ip_addr
= lease
-> ip_addr
;
2649 lt
-> starts
= cur_time
;
2651 /* Figure out how long a lease to assign. If this is a
2652 dynamic BOOTP lease, its duration must be infinite. */
2654 lt
->flags
&= ~BOOTP_LEASE
;
2656 default_lease_time
= DEFAULT_DEFAULT_LEASE_TIME
;
2657 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2658 SV_DEFAULT_LEASE_TIME
))) {
2659 if (evaluate_option_cache (&d1
, packet
, lease
,
2660 (struct client_state
*)0,
2663 &lease
-> scope
, oc
, MDL
)) {
2664 if (d1
.len
== sizeof (u_int32_t
))
2665 default_lease_time
=
2667 data_string_forget (&d1
, MDL
);
2671 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
2672 DHO_DHCP_LEASE_TIME
)))
2673 s1
= evaluate_option_cache (&d1
, packet
, lease
,
2674 (struct client_state
*)0,
2677 &lease
-> scope
, oc
, MDL
);
2681 if (s1
&& (d1
.len
== 4)) {
2682 u_int32_t ones
= 0xffffffff;
2684 /* One potential use of reserved leases is to allow
2685 * clients to signal reservation of their lease. They
2686 * can kinda sorta do this, if you squint hard enough,
2687 * by supplying an 'infinite' requested-lease-time
2688 * option. This is generally bad practice...you want
2689 * clients to return to the server on at least some
2690 * period (days, months, years) to get up-to-date
2693 * 1) A client requests 0xffffffff lease-time.
2694 * 2) The server reserves the lease, and assigns a
2695 * <= max_lease_time lease-time to the client, which
2696 * we presume is much smaller than 0xffffffff.
2697 * 3) The client ultimately fails to renew its lease
2698 * (all clients go offline at some point).
2699 * 4) The server retains the reservation, although
2700 * the lease expires and passes through those states
2701 * as normal, it's placed in the 'reserved' queue,
2702 * and is under no circumstances allocated to any
2705 * Whether the client knows its reserving its lease or
2706 * not, this can be a handy tool for a sysadmin.
2708 if ((memcmp(d1
.data
, &ones
, 4) == 0) &&
2709 (oc
= lookup_option(&server_universe
,
2711 SV_RESERVE_INFINITE
)) &&
2712 evaluate_boolean_option_cache(&ignorep
, packet
,
2713 lease
, NULL
, packet
->options
,
2714 state
->options
, &lease
->scope
,
2716 lt
->flags
|= RESERVED_LEASE
;
2718 log_info("Infinite-leasetime "
2719 "reservation made on %s.",
2720 piaddr(lt
->ip_addr
));
2723 lease_time
= getULong (d1
.data
);
2725 lease_time
= default_lease_time
;
2728 data_string_forget(&d1
, MDL
);
2730 /* See if there's a maximum lease time. */
2731 max_lease_time
= DEFAULT_MAX_LEASE_TIME
;
2732 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2733 SV_MAX_LEASE_TIME
))) {
2734 if (evaluate_option_cache (&d1
, packet
, lease
,
2735 (struct client_state
*)0,
2738 &lease
-> scope
, oc
, MDL
)) {
2739 if (d1
.len
== sizeof (u_int32_t
))
2742 data_string_forget (&d1
, MDL
);
2746 /* Enforce the maximum lease length. */
2747 if (lease_time
< 0 /* XXX */
2748 || lease_time
> max_lease_time
)
2749 lease_time
= max_lease_time
;
2751 min_lease_time
= DEFAULT_MIN_LEASE_TIME
;
2752 if (min_lease_time
> max_lease_time
)
2753 min_lease_time
= max_lease_time
;
2755 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2756 SV_MIN_LEASE_TIME
))) {
2757 if (evaluate_option_cache (&d1
, packet
, lease
,
2758 (struct client_state
*)0,
2761 &lease
-> scope
, oc
, MDL
)) {
2762 if (d1
.len
== sizeof (u_int32_t
))
2763 min_lease_time
= getULong (d1
.data
);
2764 data_string_forget (&d1
, MDL
);
2768 /* CC: If there are less than
2769 adaptive-lease-time-threshold % free leases,
2770 hand out only short term leases */
2772 memset(&d1
, 0, sizeof(d1
));
2774 (oc
= lookup_option(&server_universe
, state
->options
,
2775 SV_ADAPTIVE_LEASE_TIME_THRESHOLD
)) &&
2776 evaluate_option_cache(&d1
, packet
, lease
, NULL
,
2777 packet
->options
, state
->options
,
2778 &lease
->scope
, oc
, MDL
)) {
2779 if (d1
.len
== 1 && d1
.data
[0] > 0 &&
2782 int poolfilled
, total
, count
;
2785 adaptive_time
= min_lease_time
;
2787 adaptive_time
= DEFAULT_MIN_LEASE_TIME
;
2789 /* Allow the client to keep its lease. */
2790 if (lease
->ends
- cur_time
> adaptive_time
)
2791 adaptive_time
= lease
->ends
- cur_time
;
2793 count
= lease
->pool
->lease_count
;
2794 total
= count
- (lease
->pool
->free_leases
+
2795 lease
->pool
->backup_leases
);
2797 poolfilled
= (total
> (INT_MAX
/ 100)) ?
2798 total
/ (count
/ 100) :
2799 (total
* 100) / count
;
2801 log_debug("Adap-lease: Total: %d, Free: %d, "
2802 "Ends: %d, Adaptive: %d, Fill: %d, "
2804 lease
->pool
->lease_count
,
2805 lease
->pool
->free_leases
,
2806 (int)(lease
->ends
- cur_time
),
2807 (int)adaptive_time
, poolfilled
,
2810 if (poolfilled
>= d1
.data
[0] &&
2811 lease_time
> adaptive_time
) {
2812 log_info("Pool over threshold, time "
2813 "for %s reduced from %d to "
2814 "%d.", piaddr(lease
->ip_addr
),
2816 (int)adaptive_time
);
2818 lease_time
= adaptive_time
;
2821 data_string_forget(&d1
, MDL
);
2826 * If this is an ack check to see if we have used enough of
2827 * the pool to want to log a message
2829 if (offer
== DHCPACK
)
2830 check_pool_threshold(packet
, lease
, state
);
2832 /* a client requests an address which is not yet active*/
2833 if (lease
->pool
&& lease
->pool
->valid_from
&&
2834 cur_time
< lease
->pool
->valid_from
) {
2835 /* NAK leases before pool activation date */
2837 memcpy (cip
.iabuf
, <
->ip_addr
.iabuf
, 4);
2838 nak_lease(packet
, &cip
, lease
->subnet
->group
);
2839 free_lease_state (state
, MDL
);
2840 lease_dereference (<
, MDL
);
2842 host_dereference (&host
, MDL
);
2848 a) NAK current lease if past the expiration date
2849 b) extend lease only up to the expiration date, but not
2850 below min-lease-time
2851 Setting min-lease-time is essential for this to work!
2852 The value of min-lease-time determines the length
2853 of the transition window:
2854 A client renewing a second before the deadline will
2855 get a min-lease-time lease. Since the current ip might not
2856 be routable after the deadline, the client will
2857 be offline until it DISCOVERS again. Otherwise it will
2858 receive a NAK at T/2.
2859 A min-lease-time of 6 seconds effectively switches over
2860 all clients in this pool very quickly.
2863 if (lease
->pool
&& lease
->pool
->valid_until
) {
2864 if (cur_time
>= lease
->pool
->valid_until
) {
2865 /* NAK leases after pool expiration date */
2867 memcpy (cip
.iabuf
, <
->ip_addr
.iabuf
, 4);
2868 nak_lease(packet
, &cip
, lease
->subnet
->group
);
2869 free_lease_state (state
, MDL
);
2870 lease_dereference (<
, MDL
);
2872 host_dereference (&host
, MDL
);
2875 remaining_time
= lease
->pool
->valid_until
- cur_time
;
2876 if (lease_time
> remaining_time
)
2877 lease_time
= remaining_time
;
2880 if (lease_time
< min_lease_time
) {
2882 lease_time
= min_lease_time
;
2884 lease_time
= default_lease_time
;
2888 #if defined (FAILOVER_PROTOCOL)
2889 /* Okay, we know the lease duration. Now check the
2890 failover state, if any. */
2891 if (lease
-> pool
&& lease
-> pool
-> failover_peer
) {
2892 TIME new_lease_time
= lease_time
;
2893 dhcp_failover_state_t
*peer
=
2894 lease
-> pool
-> failover_peer
;
2896 /* Copy previous lease failover ack-state. */
2897 lt
->tsfp
= lease
->tsfp
;
2898 lt
->atsfp
= lease
->atsfp
;
2900 /* cltt set below */
2902 /* Lease times less than MCLT are not a concern. */
2903 if (lease_time
> peer
->mclt
) {
2904 /* Each server can only offer a lease time
2905 * that is either equal to MCLT (at least),
2906 * or up to TSFP+MCLT. Only if the desired
2907 * lease time falls within TSFP+MCLT, can
2908 * the server allow it.
2910 if (lt
->tsfp
<= cur_time
)
2911 new_lease_time
= peer
->mclt
;
2912 else if ((cur_time
+ lease_time
) >
2913 (lt
->tsfp
+ peer
->mclt
))
2914 new_lease_time
= (lt
->tsfp
- cur_time
)
2918 /* Update potential expiry. Allow for the desired
2919 * lease time plus one half the actual (whether
2920 * modified downward or not) lease time, which is
2921 * actually an estimate of when the client will
2922 * renew. This way, the client will be able to get
2923 * the desired lease time upon renewal.
2925 if (offer
== DHCPACK
) {
2926 if (lease_time
== INFINITE_TIME
) {
2927 lt
->tstp
= MAX_TIME
;
2931 (cur_time
+ lease_time
2932 + (new_lease_time
/ 2)),
2936 /* If we reduced the potential expiry time,
2937 * make sure we don't offer an old-expiry-time
2938 * lease for this lease before the change is
2941 if (lt
->tstp
< lt
->tsfp
)
2942 lt
->tsfp
= lt
->tstp
;
2944 lt
->tstp
= lease
->tstp
;
2946 /* Use failover-modified lease time. */
2947 lease_time
= new_lease_time
;
2949 #endif /* FAILOVER_PROTOCOL */
2951 if (lease_time
== INFINITE_TIME
) {
2952 state
->offered_expiry
= MAX_TIME
;
2954 /* If the lease duration causes the time value to wrap,
2955 use the maximum expiry time. */
2956 state
->offered_expiry
2957 = leaseTimeCheck(cur_time
+ lease_time
,
2964 lt
-> ends
= state
-> offered_expiry
;
2966 /* Don't make lease active until we actually get a
2968 if (offer
== DHCPACK
)
2969 lt
-> next_binding_state
= FTS_ACTIVE
;
2971 lt
-> next_binding_state
= lease
-> binding_state
;
2973 lt
->flags
|= BOOTP_LEASE
;
2975 lease_time
= MAX_TIME
- cur_time
;
2977 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2978 SV_BOOTP_LEASE_LENGTH
))) {
2979 if (evaluate_option_cache (&d1
, packet
, lease
,
2980 (struct client_state
*)0,
2983 &lease
-> scope
, oc
, MDL
)) {
2984 if (d1
.len
== sizeof (u_int32_t
))
2985 lease_time
= getULong (d1
.data
);
2986 data_string_forget (&d1
, MDL
);
2990 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2991 SV_BOOTP_LEASE_CUTOFF
))) {
2992 if (evaluate_option_cache (&d1
, packet
, lease
,
2993 (struct client_state
*)0,
2996 &lease
-> scope
, oc
, MDL
)) {
2997 if (d1
.len
== sizeof (u_int32_t
))
2998 lease_time
= (getULong (d1
.data
) -
3000 data_string_forget (&d1
, MDL
);
3004 lt
-> ends
= state
-> offered_expiry
= cur_time
+ lease_time
;
3005 lt
-> next_binding_state
= FTS_ACTIVE
;
3008 /* Update Client Last Transaction Time. */
3009 lt
->cltt
= cur_time
;
3011 /* See if we want to record the uid for this client */
3012 oc
= lookup_option(&server_universe
, state
->options
,
3013 SV_IGNORE_CLIENT_UIDS
);
3015 !evaluate_boolean_option_cache(&ignorep
, packet
, lease
, NULL
,
3016 packet
->options
, state
->options
,
3017 &lease
->scope
, oc
, MDL
)) {
3019 /* Record the uid, if given... */
3020 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
3021 DHO_DHCP_CLIENT_IDENTIFIER
);
3023 evaluate_option_cache(&d1
, packet
, lease
, NULL
,
3024 packet
->options
, state
->options
,
3025 &lease
->scope
, oc
, MDL
)) {
3026 if (d1
.len
<= sizeof(lt
->uid_buf
)) {
3027 memcpy(lt
->uid_buf
, d1
.data
, d1
.len
);
3028 lt
->uid
= lt
->uid_buf
;
3029 lt
->uid_max
= sizeof(lt
->uid_buf
);
3030 lt
->uid_len
= d1
.len
;
3032 unsigned char *tuid
;
3033 lt
->uid_max
= d1
.len
;
3034 lt
->uid_len
= d1
.len
;
3035 tuid
= (unsigned char *)dmalloc(lt
->uid_max
,
3039 log_fatal ("no memory for large uid.");
3040 memcpy(tuid
, d1
.data
, lt
->uid_len
);
3043 data_string_forget (&d1
, MDL
);
3048 host_reference (<
-> host
, host
, MDL
);
3049 host_dereference (&host
, MDL
);
3051 if (lease
-> subnet
)
3052 subnet_reference (<
-> subnet
, lease
-> subnet
, MDL
);
3053 if (lease
-> billing_class
)
3054 class_reference (<
-> billing_class
,
3055 lease
-> billing_class
, MDL
);
3057 /* Set a flag if this client is a broken client that NUL
3058 terminates string options and expects us to do likewise. */
3060 lease
-> flags
|= MS_NULL_TERMINATION
;
3062 lease
-> flags
&= ~MS_NULL_TERMINATION
;
3064 /* Save any bindings. */
3065 if (lease
-> scope
) {
3066 binding_scope_reference (<
-> scope
, lease
-> scope
, MDL
);
3067 binding_scope_dereference (&lease
-> scope
, MDL
);
3069 if (lease
-> agent_options
)
3070 option_chain_head_reference (<
-> agent_options
,
3071 lease
-> agent_options
, MDL
);
3073 /* Save the vendor-class-identifier for DHCPLEASEQUERY. */
3074 oc
= lookup_option(&dhcp_universe
, packet
->options
,
3075 DHO_VENDOR_CLASS_IDENTIFIER
);
3077 evaluate_option_cache(&d1
, packet
, NULL
, NULL
, packet
->options
,
3078 NULL
, <
->scope
, oc
, MDL
)) {
3080 bind_ds_value(<
->scope
, "vendor-class-identifier",
3084 data_string_forget(&d1
, MDL
);
3087 /* If we got relay agent information options from the packet, then
3088 * cache them for renewal in case the relay agent can't supply them
3089 * when the client unicasts. The options may be from an addressed
3090 * "l3" relay, or from an unaddressed "l2" relay which does not set
3093 if (!packet
->agent_options_stashed
&&
3094 (packet
->options
!= NULL
) &&
3095 packet
->options
->universe_count
> agent_universe
.index
&&
3096 packet
->options
->universes
[agent_universe
.index
] != NULL
) {
3097 oc
= lookup_option (&server_universe
, state
-> options
,
3098 SV_STASH_AGENT_OPTIONS
);
3100 evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
3101 (struct client_state
*)0,
3104 &lease
-> scope
, oc
, MDL
)) {
3105 if (lt
-> agent_options
)
3106 option_chain_head_dereference (<
-> agent_options
, MDL
);
3107 option_chain_head_reference
3108 (<
-> agent_options
,
3109 (struct option_chain_head
*)
3110 packet
-> options
-> universes
[agent_universe
.index
],
3115 /* Replace the old lease hostname with the new one, if it's changed. */
3116 oc
= lookup_option (&dhcp_universe
, packet
-> options
, DHO_HOST_NAME
);
3118 s1
= evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
3119 (struct client_state
*)0,
3121 (struct option_state
*)0,
3122 &global_scope
, oc
, MDL
);
3127 lease
-> client_hostname
&&
3128 strlen (lease
-> client_hostname
) == d1
.len
&&
3129 !memcmp (lease
-> client_hostname
, d1
.data
, d1
.len
)) {
3130 /* Hasn't changed. */
3131 data_string_forget (&d1
, MDL
);
3132 lt
-> client_hostname
= lease
-> client_hostname
;
3133 lease
-> client_hostname
= (char *)0;
3134 } else if (oc
&& s1
) {
3135 lt
-> client_hostname
= dmalloc (d1
.len
+ 1, MDL
);
3136 if (!lt
-> client_hostname
)
3137 log_error ("no memory for client hostname.");
3139 memcpy (lt
-> client_hostname
, d1
.data
, d1
.len
);
3140 lt
-> client_hostname
[d1
.len
] = 0;
3142 data_string_forget (&d1
, MDL
);
3143 /* hostname changed, can't reuse lease */
3144 lease
->cannot_reuse
= 1;
3147 /* Record the hardware address, if given... */
3148 lt
-> hardware_addr
.hlen
= packet
-> raw
-> hlen
+ 1;
3149 lt
-> hardware_addr
.hbuf
[0] = packet
-> raw
-> htype
;
3150 memcpy (<
-> hardware_addr
.hbuf
[1], packet
-> raw
-> chaddr
,
3151 sizeof packet
-> raw
-> chaddr
);
3154 * If client has requested the lease become infinite, then it
3155 * doens't qualify for reuse even if it's younger than the
3156 * dhcp-cache-threshold.
3158 if ((lt
->flags
& RESERVED_LEASE
) && !(lease
->flags
& RESERVED_LEASE
)) {
3159 log_debug ("Cannot reuse: lease is changing to RESERVED");
3160 lease
->cannot_reuse
= 1;
3163 lt
->flags
|= lease
->flags
& ~PERSISTENT_FLAGS
;
3165 /* If there are statements to execute when the lease is
3166 committed, execute them. */
3167 if (lease
->on_star
.on_commit
&& (!offer
|| offer
== DHCPACK
)) {
3168 execute_statements (NULL
, packet
, lt
, NULL
, packet
->options
,
3169 state
->options
, <
->scope
,
3170 lease
->on_star
.on_commit
, NULL
);
3171 if (lease
->on_star
.on_commit
)
3172 executable_statement_dereference
3173 (&lease
->on_star
.on_commit
, MDL
);
3177 /* Perform DDNS updates, if configured to. */
3178 if ((!offer
|| offer
== DHCPACK
) &&
3179 (!(oc
= lookup_option (&server_universe
, state
-> options
,
3180 SV_DDNS_UPDATES
)) ||
3181 evaluate_boolean_option_cache (&ignorep
, packet
, lt
,
3182 (struct client_state
*)0,
3185 <
-> scope
, oc
, MDL
))) {
3186 ddns_updates(packet
, lt
, lease
, NULL
, NULL
, state
->options
);
3188 #endif /* NSUPDATE */
3190 /* Don't call supersede_lease on a mocked-up lease. */
3191 if (lease
-> flags
& STATIC_LEASE
) {
3192 /* Copy the hardware address into the static lease
3194 lease
-> hardware_addr
.hlen
= packet
-> raw
-> hlen
+ 1;
3195 lease
-> hardware_addr
.hbuf
[0] = packet
-> raw
-> htype
;
3196 memcpy (&lease
-> hardware_addr
.hbuf
[1],
3197 packet
-> raw
-> chaddr
,
3198 sizeof packet
-> raw
-> chaddr
); /* XXX */
3200 int commit
= (!offer
|| (offer
== DHCPACK
));
3202 /* If dhcp-cache-threshold is enabled, see if "lease" can
3204 use_old_lease
= reuse_lease(packet
, lt
, lease
, state
, offer
,
3206 if (use_old_lease
== 1) {
3210 #if !defined(DELAYED_ACK)
3211 /* Install the new information on 'lt' onto the lease at
3212 * 'lease'. If this is a DHCPOFFER, it is a 'soft' promise,
3213 * if it is a DHCPACK, it is a 'hard' binding, so it needs
3214 * to be recorded and propogated immediately. If the update
3215 * fails, don't ACK it (or BOOTREPLY) either; we may give
3216 * the same lease to another client later, and that would be
3219 if ((use_old_lease
== 0) &&
3220 !supersede_lease(lease
, lt
, commit
,
3221 offer
== DHCPACK
, offer
== DHCPACK
, 0)) {
3222 #else /* defined(DELAYED_ACK) */
3224 * If there already isn't a need for a lease commit, and we
3225 * can just answer right away, set a flag to indicate this.
3230 /* Install the new information on 'lt' onto the lease at
3231 * 'lease'. We will not 'commit' this information to disk
3232 * yet (fsync()), we will 'propogate' the information if
3233 * this is BOOTP or a DHCPACK, but we will not 'pimmediate'ly
3234 * transmit failover binding updates (this is delayed until
3235 * after the fsync()). If the update fails, don't ACK it (or
3236 * BOOTREPLY either); we may give the same lease out to a
3237 * different client, and that would be a conflict.
3239 if ((use_old_lease
== 0) &&
3240 !supersede_lease(lease
, lt
, 0,
3241 !offer
|| offer
== DHCPACK
, 0, 0)) {
3243 log_info ("%s: database update failed", msg
);
3244 free_lease_state (state
, MDL
);
3245 lease_dereference (<
, MDL
);
3249 lease_dereference (<
, MDL
);
3251 /* Remember the interface on which the packet arrived. */
3252 state
-> ip
= packet
-> interface
;
3254 /* Remember the giaddr, xid, secs, flags and hops. */
3255 state
-> giaddr
= packet
-> raw
-> giaddr
;
3256 state
-> ciaddr
= packet
-> raw
-> ciaddr
;
3257 state
-> xid
= packet
-> raw
-> xid
;
3258 state
-> secs
= packet
-> raw
-> secs
;
3259 state
-> bootp_flags
= packet
-> raw
-> flags
;
3260 state
-> hops
= packet
-> raw
-> hops
;
3261 state
-> offer
= offer
;
3263 /* If we're always supposed to broadcast to this client, set
3264 the broadcast bit in the bootp flags field. */
3265 if ((oc
= lookup_option (&server_universe
, state
-> options
,
3266 SV_ALWAYS_BROADCAST
)) &&
3267 evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
3268 (struct client_state
*)0,
3269 packet
-> options
, state
-> options
,
3270 &lease
-> scope
, oc
, MDL
))
3271 state
-> bootp_flags
|= htons (BOOTP_BROADCAST
);
3273 /* Get the Maximum Message Size option from the packet, if one
3275 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
3276 DHO_DHCP_MAX_MESSAGE_SIZE
);
3278 evaluate_option_cache (&d1
, packet
, lease
,
3279 (struct client_state
*)0,
3280 packet
-> options
, state
-> options
,
3281 &lease
-> scope
, oc
, MDL
)) {
3282 if (d1
.len
== sizeof (u_int16_t
))
3283 state
-> max_message_size
= getUShort (d1
.data
);
3284 data_string_forget (&d1
, MDL
);
3286 oc
= lookup_option (&dhcp_universe
, state
-> options
,
3287 DHO_DHCP_MAX_MESSAGE_SIZE
);
3289 evaluate_option_cache (&d1
, packet
, lease
,
3290 (struct client_state
*)0,
3291 packet
-> options
, state
-> options
,
3292 &lease
-> scope
, oc
, MDL
)) {
3293 if (d1
.len
== sizeof (u_int16_t
))
3294 state
-> max_message_size
=
3295 getUShort (d1
.data
);
3296 data_string_forget (&d1
, MDL
);
3300 /* Get the Subnet Selection option from the packet, if one
3302 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
3303 DHO_SUBNET_SELECTION
))) {
3305 /* Make a copy of the data. */
3306 struct option_cache
*noc
= (struct option_cache
*)0;
3307 if (option_cache_allocate (&noc
, MDL
)) {
3309 data_string_copy (&noc
-> data
,
3311 if (oc
-> expression
)
3312 expression_reference (&noc
-> expression
,
3313 oc
-> expression
, MDL
);
3315 option_reference(&(noc
->option
), oc
->option
,
3318 save_option (&dhcp_universe
, state
-> options
, noc
);
3319 option_cache_dereference (&noc
, MDL
);
3323 /* Now, if appropriate, put in DHCP-specific options that
3325 if (state
-> offer
) {
3326 i
= DHO_DHCP_MESSAGE_TYPE
;
3327 oc
= (struct option_cache
*)0;
3328 if (option_cache_allocate (&oc
, MDL
)) {
3329 if (make_const_data (&oc
-> expression
,
3330 &state
-> offer
, 1, 0, 0, MDL
)) {
3331 option_code_hash_lookup(&oc
->option
,
3332 dhcp_universe
.code_hash
,
3334 save_option (&dhcp_universe
,
3335 state
-> options
, oc
);
3337 option_cache_dereference (&oc
, MDL
);
3340 get_server_source_address(&from
, state
->options
,
3341 state
->options
, packet
);
3342 memcpy(state
->from
.iabuf
, &from
, sizeof(from
));
3343 state
->from
.len
= sizeof(from
);
3345 offered_lease_time
=
3346 state
-> offered_expiry
- cur_time
;
3348 putULong(state
->expiry
, (u_int32_t
)offered_lease_time
);
3349 i
= DHO_DHCP_LEASE_TIME
;
3350 oc
= (struct option_cache
*)0;
3351 if (option_cache_allocate (&oc
, MDL
)) {
3352 if (make_const_data(&oc
->expression
, state
->expiry
,
3354 option_code_hash_lookup(&oc
->option
,
3355 dhcp_universe
.code_hash
,
3357 save_option (&dhcp_universe
,
3358 state
-> options
, oc
);
3360 option_cache_dereference (&oc
, MDL
);
3364 * Validate any configured renew or rebinding times against
3365 * the determined lease time. Do rebinding first so that
3366 * the renew time can be validated against the rebind time.
3368 if ((oc
= lookup_option(&dhcp_universe
, state
->options
,
3369 DHO_DHCP_REBINDING_TIME
)) != NULL
&&
3370 evaluate_option_cache(&d1
, packet
, lease
, NULL
,
3371 packet
->options
, state
->options
,
3372 &lease
->scope
, oc
, MDL
)) {
3373 TIME rebind_time
= getULong(d1
.data
);
3375 /* Drop the configured (invalid) rebinding time. */
3376 if (rebind_time
>= offered_lease_time
)
3377 delete_option(&dhcp_universe
, state
->options
,
3378 DHO_DHCP_REBINDING_TIME
);
3379 else /* XXX: variable is reused. */
3380 offered_lease_time
= rebind_time
;
3382 data_string_forget(&d1
, MDL
);
3385 if ((oc
= lookup_option(&dhcp_universe
, state
->options
,
3386 DHO_DHCP_RENEWAL_TIME
)) != NULL
&&
3387 evaluate_option_cache(&d1
, packet
, lease
, NULL
,
3388 packet
->options
, state
->options
,
3389 &lease
->scope
, oc
, MDL
)) {
3390 if (getULong(d1
.data
) >= offered_lease_time
)
3391 delete_option(&dhcp_universe
, state
->options
,
3392 DHO_DHCP_RENEWAL_TIME
);
3394 data_string_forget(&d1
, MDL
);
3397 /* XXXSK: should we use get_server_source_address() here? */
3398 if (state
-> ip
-> address_count
) {
3400 sizeof state
-> ip
-> addresses
[0];
3401 memcpy (state
-> from
.iabuf
,
3402 &state
-> ip
-> addresses
[0],
3407 /* Figure out the address of the boot file server. */
3408 memset (&state
-> siaddr
, 0, sizeof state
-> siaddr
);
3410 lookup_option (&server_universe
,
3411 state
-> options
, SV_NEXT_SERVER
))) {
3412 if (evaluate_option_cache (&d1
, packet
, lease
,
3413 (struct client_state
*)0,
3414 packet
-> options
, state
-> options
,
3415 &lease
-> scope
, oc
, MDL
)) {
3416 /* If there was more than one answer,
3418 if (d1
.len
>= 4 && d1
.data
)
3419 memcpy (&state
-> siaddr
, d1
.data
, 4);
3420 data_string_forget (&d1
, MDL
);
3424 /* Use the subnet mask from the subnet declaration if no other
3425 mask has been provided. */
3426 i
= DHO_SUBNET_MASK
;
3427 if (!lookup_option (&dhcp_universe
, state
-> options
, i
)) {
3428 oc
= (struct option_cache
*)0;
3429 if (option_cache_allocate (&oc
, MDL
)) {
3430 if (make_const_data (&oc
-> expression
,
3431 lease
-> subnet
-> netmask
.iabuf
,
3432 lease
-> subnet
-> netmask
.len
,
3434 option_code_hash_lookup(&oc
->option
,
3435 dhcp_universe
.code_hash
,
3437 save_option (&dhcp_universe
,
3438 state
-> options
, oc
);
3440 option_cache_dereference (&oc
, MDL
);
3444 /* Use the name of the host declaration if there is one
3445 and no hostname has otherwise been provided, and if the
3446 use-host-decl-name flag is set. */
3447 use_host_decl_name(packet
, lease
, state
->options
);
3449 /* Send client_id back if we received it and echo-client-id is on. */
3450 echo_client_id(packet
, lease
, state
->options
, state
->options
);
3452 /* If we don't have a hostname yet, and we've been asked to do
3453 a reverse lookup to find the hostname, do it. */
3455 j
= SV_GET_LEASE_HOSTNAMES
;
3456 if (!lookup_option(&dhcp_universe
, state
->options
, i
) &&
3457 evaluate_boolean_option_cache
3458 (&ignorep
, packet
, lease
, NULL
,
3459 packet
->options
, state
->options
, &lease
->scope
,
3460 lookup_option (&server_universe
, state
->options
, j
), MDL
)) {
3464 memcpy (&ia
, lease
-> ip_addr
.iabuf
, 4);
3466 h
= gethostbyaddr ((char *)&ia
, sizeof ia
, AF_INET
);
3468 log_error ("No hostname for %s", inet_ntoa (ia
));
3470 oc
= (struct option_cache
*)0;
3471 if (option_cache_allocate (&oc
, MDL
)) {
3472 if (make_const_data (&oc
-> expression
,
3475 strlen (h
-> h_name
) + 1,
3477 option_code_hash_lookup(&oc
->option
,
3478 dhcp_universe
.code_hash
,
3480 save_option (&dhcp_universe
,
3481 state
-> options
, oc
);
3483 option_cache_dereference (&oc
, MDL
);
3488 /* If so directed, use the leased IP address as the router address.
3489 This supposedly makes Win95 machines ARP for all IP addresses,
3490 so if the local router does proxy arp, you win. */
3492 if (evaluate_boolean_option_cache
3493 (&ignorep
, packet
, lease
, (struct client_state
*)0,
3494 packet
-> options
, state
-> options
, &lease
-> scope
,
3495 lookup_option (&server_universe
, state
-> options
,
3496 SV_USE_LEASE_ADDR_FOR_DEFAULT_ROUTE
), MDL
)) {
3498 oc
= lookup_option (&dhcp_universe
, state
-> options
, i
);
3500 oc
= (struct option_cache
*)0;
3501 if (option_cache_allocate (&oc
, MDL
)) {
3502 if (make_const_data (&oc
-> expression
,
3503 lease
-> ip_addr
.iabuf
,
3504 lease
-> ip_addr
.len
,
3506 option_code_hash_lookup(&oc
->option
,
3507 dhcp_universe
.code_hash
,
3509 save_option (&dhcp_universe
,
3510 state
-> options
, oc
);
3512 option_cache_dereference (&oc
, MDL
);
3517 /* If a site option space has been specified, use that for
3518 site option codes. */
3519 i
= SV_SITE_OPTION_SPACE
;
3520 if ((oc
= lookup_option (&server_universe
, state
-> options
, i
)) &&
3521 evaluate_option_cache (&d1
, packet
, lease
,
3522 (struct client_state
*)0,
3523 packet
-> options
, state
-> options
,
3524 &lease
-> scope
, oc
, MDL
)) {
3525 struct universe
*u
= (struct universe
*)0;
3527 if (!universe_hash_lookup (&u
, universe_hash
,
3528 (const char *)d1
.data
, d1
.len
,
3530 log_error ("unknown option space %s.", d1
.data
);
3531 data_string_forget (&d1
, MDL
);
3535 state
-> options
-> site_universe
= u
-> index
;
3536 state
->options
->site_code_min
= find_min_site_code(u
);
3537 data_string_forget (&d1
, MDL
);
3539 state
-> options
-> site_code_min
= 0;
3540 state
-> options
-> site_universe
= dhcp_universe
.index
;
3543 /* If the client has provided a list of options that it wishes
3544 returned, use it to prioritize. If there's a parameter
3545 request list in scope, use that in preference. Otherwise
3546 use the default priority list. */
3548 oc
= lookup_option (&dhcp_universe
, state
-> options
,
3549 DHO_DHCP_PARAMETER_REQUEST_LIST
);
3552 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
3553 DHO_DHCP_PARAMETER_REQUEST_LIST
);
3555 evaluate_option_cache (&state
-> parameter_request_list
,
3556 packet
, lease
, (struct client_state
*)0,
3557 packet
-> options
, state
-> options
,
3558 &lease
-> scope
, oc
, MDL
);
3561 dump_packet (packet
);
3562 dump_raw ((unsigned char *)packet
-> raw
, packet
-> packet_length
);
3565 lease
-> state
= state
;
3567 log_info ("%s", msg
);
3569 /* Hang the packet off the lease state. */
3570 packet_reference (&lease
-> state
-> packet
, packet
, MDL
);
3572 /* If this is a DHCPOFFER, send a ping (if appropriate) to the
3573 * lease address before actually we send the offer. */
3574 if ((offer
== DHCPOFFER
) &&
3575 do_ping_check(packet
, state
, lease
, original_cltt
, same_client
)) {
3576 ++outstanding_pings
;
3578 lease
->cltt
= cur_time
;
3579 #if defined(DELAYED_ACK)
3581 delayed_ack_enqueue(lease
);
3589 * \brief Sends a ping to the lease ip_addr when appropriate
3591 * A ping will be sent if all of the following are true:
3593 * 1. Ping checks are enabled
3594 * 2. The lease is neither active nor static
3595 * 3. Any of the following is true:
3596 * a. The lease state is ABANDONED
3597 * b. This is the first offer of this lease (CLTT = 0)
3598 * c. The lease is being offered to a client other than its previous
3600 * d. The lease is being offered to its previous owner and more than
3601 * cltt-secs have elapsed since CLTT of the original lease.
3603 * \param packet inbound packet received from the client
3604 * \param state lease options state
3605 * \param lease lease to be offered (if one)
3606 * \param original_cltt CLTT of the original lease
3607 * \param same_client flag indicating if the client to be offered the
3608 * lease is its previous owner
3609 * \return Returns 1 if ping has been sent, 0 otherwise
3611 int do_ping_check(struct packet
* packet
, struct lease_state
* state
,
3612 struct lease
* lease
, TIME original_cltt
,
3614 TIME ping_timeout
= DEFAULT_PING_TIMEOUT
;
3615 TIME ping_timeout_ms
= DEFAULT_PING_TIMEOUT_MS
;
3616 struct option_cache
*oc
= NULL
;
3617 struct data_string ds
;
3623 // Don't go any further if lease is active or static.
3624 if (lease
->binding_state
== FTS_ACTIVE
|| lease
->flags
& STATIC_LEASE
) {
3628 // If pings aren't enabled, punt.
3629 oc
= lookup_option (&server_universe
, state
-> options
, SV_PING_CHECKS
);
3631 !(evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
3632 0, packet
->options
, state
->options
,
3633 &lease
->scope
, oc
, MDL
))) {
3637 // If it's not the first time for the same client and not an
3638 // abandoned lease, we need to check the cltt threshold
3639 if (same_client
&& original_cltt
&&
3640 lease
->binding_state
!= FTS_ABANDONED
) {
3641 TIME cltt_secs
= DEFAULT_PING_CLTT_SECS
;
3642 memset(&ds
, 0, sizeof(ds
));
3643 oc
= lookup_option (&server_universe
, state
->options
,
3646 (evaluate_option_cache (&ds
, packet
, lease
, 0,
3647 packet
->options
, state
->options
,
3648 &lease
->scope
, oc
, MDL
))) {
3649 if (ds
.len
== sizeof (u_int32_t
)) {
3650 cltt_secs
= getULong (ds
.data
);
3653 data_string_forget (&ds
, MDL
);
3656 // Punt if it is too soon.
3657 if (cur_time
- original_cltt
< cltt_secs
) {
3663 icmp_echorequest (&lease
->ip_addr
);
3665 /* Determine whether to use configured or default ping timeout. */
3666 memset(&ds
, 0, sizeof(ds
));
3668 oc
= lookup_option (&server_universe
, state
->options
, SV_PING_TIMEOUT
);
3670 (evaluate_option_cache (&ds
, packet
, lease
, 0,
3671 packet
->options
, state
->options
,
3672 &lease
->scope
, oc
, MDL
))) {
3673 if (ds
.len
== sizeof (u_int32_t
)) {
3674 ping_timeout
= getULong (ds
.data
);
3677 data_string_forget (&ds
, MDL
);
3680 oc
= lookup_option (&server_universe
, state
->options
, SV_PING_TIMEOUT_MS
);
3682 (evaluate_option_cache (&ds
, packet
, lease
, 0,
3683 packet
->options
, state
->options
,
3684 &lease
->scope
, oc
, MDL
))) {
3685 if (ds
.len
== sizeof (u_int32_t
)) {
3686 ping_timeout_ms
= getULong (ds
.data
);
3689 data_string_forget (&ds
, MDL
);
3693 * Set the timeout for the ping to the current timeval plus
3694 * the configured time out. Use ping-timeout-ms if it is > 0.
3695 * This overrides ping-timeout allowing users to specify it in
3698 if (ping_timeout_ms
> 0) {
3699 timeout_secs
= ping_timeout_ms
/ 1000;
3700 timeout_ms
= ping_timeout_ms
% 1000;
3702 timeout_secs
= ping_timeout
;
3707 tv
.tv_sec
= cur_tv
.tv_sec
+ timeout_secs
;
3708 tv
.tv_usec
= cur_tv
.tv_usec
+ (timeout_ms
* 1000);
3711 log_debug ("Pinging:%s, state: %d, same client? %s, "
3712 " orig_cltt %s, elasped: %ld, timeout in: %d.%d secs" ,
3713 piaddr(lease
->ip_addr
),
3714 lease
->binding_state
,
3715 (same_client
? "y" : "n"),
3716 (original_cltt
? print_time(original_cltt
) : "0"),
3717 (original_cltt
? (long)(cur_time
- original_cltt
) : 0),
3718 timeout_secs
, timeout_ms
);
3722 add_timeout (&tv
, lease_ping_timeout
, lease
, (tvref_t
)lease_reference
,
3723 (tvunref_t
)lease_dereference
);
3729 #if defined(DELAYED_ACK)
3732 * CC: queue single ACK:
3733 * - write the lease (but do not fsync it yet)
3734 * - add to double linked list
3735 * - commit if more than xx ACKs pending
3736 * - if necessary set the max timer and bump the next timer
3737 * but only up to the max timer value.
3741 delayed_ack_enqueue(struct lease
*lease
)
3743 struct leasequeue
*q
;
3745 if (!write_lease(lease
))
3747 if (free_ackqueue
) {
3749 free_ackqueue
= q
->next
;
3751 q
= ((struct leasequeue
*)
3752 dmalloc(sizeof(struct leasequeue
), MDL
));
3754 log_fatal("delayed_ack_enqueue: no memory!");
3756 memset(q
, 0, sizeof *q
);
3757 /* prepend to ackqueue*/
3758 lease_reference(&q
->lease
, lease
, MDL
);
3759 q
->next
= ackqueue_head
;
3767 if (outstanding_acks
> max_outstanding_acks
) {
3768 /* Cancel any pending timeout and call handler directly */
3769 cancel_timeout(delayed_acks_timer
, NULL
);
3770 delayed_acks_timer(NULL
);
3772 struct timeval next_fsync
;
3774 if (max_fsync
.tv_sec
== 0 && max_fsync
.tv_usec
== 0) {
3775 /* set the maximum time we'll wait */
3776 max_fsync
.tv_sec
= cur_tv
.tv_sec
+ max_ack_delay_secs
;
3777 max_fsync
.tv_usec
= cur_tv
.tv_usec
+
3778 max_ack_delay_usecs
;
3780 if (max_fsync
.tv_usec
>= 1000000) {
3782 max_fsync
.tv_usec
-= 1000000;
3786 /* Set the timeout */
3787 next_fsync
.tv_sec
= cur_tv
.tv_sec
;
3788 next_fsync
.tv_usec
= cur_tv
.tv_usec
+ min_ack_delay_usecs
;
3789 if (next_fsync
.tv_usec
>= 1000000) {
3790 next_fsync
.tv_sec
++;
3791 next_fsync
.tv_usec
-= 1000000;
3793 /* but not more than the max */
3794 if ((next_fsync
.tv_sec
> max_fsync
.tv_sec
) ||
3795 ((next_fsync
.tv_sec
== max_fsync
.tv_sec
) &&
3796 (next_fsync
.tv_usec
> max_fsync
.tv_usec
))) {
3797 next_fsync
.tv_sec
= max_fsync
.tv_sec
;
3798 next_fsync
.tv_usec
= max_fsync
.tv_usec
;
3801 add_timeout(&next_fsync
, delayed_acks_timer
, NULL
,
3802 (tvref_t
) NULL
, (tvunref_t
) NULL
);
3806 /* Processes any delayed acks:
3807 * Commits the leases and then for each delayed ack:
3808 * - Update the failover peer if we're in failover
3809 * - Send the REPLY to the client
3812 delayed_acks_timer(void *foo
)
3814 struct leasequeue
*ack
, *p
;
3816 /* Reset max fsync */
3817 memset(&max_fsync
, 0, sizeof(max_fsync
));
3819 if (!outstanding_acks
) {
3820 /* Nothing to do, so punt, shouldn't happen? */
3824 /* Commit the leases first */
3827 /* Now process the delayed ACKs
3828 - update failover peer
3829 - send out the ACK packets
3830 - move the queue slots to the free list
3833 /* process from bottom to retain packet order */
3834 for (ack
= ackqueue_tail
; ack
; ack
= p
) {
3837 #if defined(FAILOVER_PROTOCOL)
3838 /* If we're in failover we need to send any deferred
3839 * bind updates as well as the replies */
3840 if (ack
->lease
->pool
) {
3841 dhcp_failover_state_t
*fpeer
;
3843 fpeer
= ack
->lease
->pool
->failover_peer
;
3844 if (fpeer
&& fpeer
->link_to_peer
) {
3845 dhcp_failover_send_updates(fpeer
);
3850 /* dhcp_reply() requires that the reply state still be valid */
3851 if (ack
->lease
->state
== NULL
)
3852 log_error("delayed ack for %s has gone stale",
3853 piaddr(ack
->lease
->ip_addr
));
3855 dhcp_reply(ack
->lease
);
3858 lease_dereference(&ack
->lease
, MDL
);
3859 ack
->next
= free_ackqueue
;
3860 free_ackqueue
= ack
;
3863 ackqueue_head
= NULL
;
3864 ackqueue_tail
= NULL
;
3865 outstanding_acks
= 0;
3868 #if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
3870 relinquish_ackqueue(void)
3872 struct leasequeue
*q
, *n
;
3874 for (q
= ackqueue_head
; q
; q
= n
) {
3878 for (q
= free_ackqueue
; q
; q
= n
) {
3885 #endif /* defined(DELAYED_ACK) */
3887 void dhcp_reply (lease
)
3888 struct lease
*lease
;
3891 unsigned packet_length
;
3892 struct dhcp_packet raw
;
3893 struct sockaddr_in to
;
3894 struct in_addr from
;
3895 struct hardware hto
;
3897 struct lease_state
*state
= lease
-> state
;
3898 int nulltp
, bootpp
, unicastp
= 1;
3899 #if defined(RELAY_PORT)
3900 u_int16_t relay_port
= 0;
3902 struct data_string d1
;
3906 log_fatal ("dhcp_reply was supplied lease with no state!");
3908 /* Compose a response for the client... */
3909 memset (&raw
, 0, sizeof raw
);
3910 memset (&d1
, 0, sizeof d1
);
3912 /* Copy in the filename if given; otherwise, flag the filename
3913 buffer as available for options. */
3914 if (state
-> filename
.len
&& state
-> filename
.data
) {
3916 state
-> filename
.data
,
3917 state
-> filename
.len
> sizeof raw
.file
3918 ? sizeof raw
.file
: state
-> filename
.len
);
3919 if (sizeof raw
.file
> state
-> filename
.len
)
3920 memset (&raw
.file
[state
-> filename
.len
], 0,
3921 (sizeof raw
.file
) - state
-> filename
.len
);
3923 log_info("file name longer than packet field "
3924 "truncated - field: %lu name: %d %.*s",
3925 (unsigned long)sizeof(raw
.file
),
3926 state
->filename
.len
, (int)state
->filename
.len
,
3927 state
->filename
.data
);
3931 /* Copy in the server name if given; otherwise, flag the
3932 server_name buffer as available for options. */
3933 if (state
-> server_name
.len
&& state
-> server_name
.data
) {
3935 state
-> server_name
.data
,
3936 state
-> server_name
.len
> sizeof raw
.sname
3937 ? sizeof raw
.sname
: state
-> server_name
.len
);
3938 if (sizeof raw
.sname
> state
-> server_name
.len
)
3939 memset (&raw
.sname
[state
-> server_name
.len
], 0,
3940 (sizeof raw
.sname
) - state
-> server_name
.len
);
3942 log_info("server name longer than packet field "
3943 "truncated - field: %lu name: %d %.*s",
3944 (unsigned long)sizeof(raw
.sname
),
3945 state
->server_name
.len
,
3946 (int)state
->server_name
.len
,
3947 state
->server_name
.data
);
3949 bufs
|= 2; /* XXX */
3952 &lease
-> hardware_addr
.hbuf
[1], sizeof raw
.chaddr
);
3953 raw
.hlen
= lease
-> hardware_addr
.hlen
- 1;
3954 raw
.htype
= lease
-> hardware_addr
.hbuf
[0];
3956 /* See if this is a Microsoft client that NUL-terminates its
3957 strings and expects us to do likewise... */
3958 if (lease
-> flags
& MS_NULL_TERMINATION
)
3963 /* See if this is a bootp client... */
3969 /* Insert such options as will fit into the buffer. */
3970 packet_length
= cons_options (state
-> packet
, &raw
, lease
,
3971 (struct client_state
*)0,
3972 state
-> max_message_size
,
3973 state
-> packet
-> options
,
3974 state
-> options
, &global_scope
,
3975 bufs
, nulltp
, bootpp
,
3976 &state
-> parameter_request_list
,
3979 memcpy (&raw
.ciaddr
, &state
-> ciaddr
, sizeof raw
.ciaddr
);
3980 memcpy (&raw
.yiaddr
, lease
-> ip_addr
.iabuf
, 4);
3981 raw
.siaddr
= state
-> siaddr
;
3982 raw
.giaddr
= state
-> giaddr
;
3984 raw
.xid
= state
-> xid
;
3985 raw
.secs
= state
-> secs
;
3986 raw
.flags
= state
-> bootp_flags
;
3987 raw
.hops
= state
-> hops
;
3990 if (lease
-> client_hostname
) {
3991 if ((strlen (lease
-> client_hostname
) <= 64) &&
3992 db_printable((unsigned char *)lease
->client_hostname
))
3993 s
= lease
-> client_hostname
;
3995 s
= "Hostname Unsuitable for Printing";
3999 /* Make sure outgoing packets are at least as big
4000 as a BOOTP packet. */
4001 if (packet_length
< BOOTP_MIN_LEN
)
4002 packet_length
= BOOTP_MIN_LEN
;
4004 #if defined(DHCPv6) && defined(DHCP4o6)
4005 if (dhcpv4_over_dhcpv6
&& (state
->packet
->dhcp4o6_response
!= NULL
)) {
4006 /* Say what we're doing... */
4007 log_info ("DHCP4o6 %s on %s to %s %s%s%svia %s",
4009 ? (state
-> offer
== DHCPACK
4010 ? "DHCPACK" : "DHCPOFFER")
4012 piaddr (lease
-> ip_addr
),
4013 (lease
-> hardware_addr
.hlen
4014 ? print_hw_addr (lease
-> hardware_addr
.hbuf
[0],
4015 lease
-> hardware_addr
.hlen
- 1,
4016 &lease
-> hardware_addr
.hbuf
[1])
4017 : print_hex_1(lease
->uid_len
, lease
->uid
, 60)),
4018 s
? "(" : "", s
? s
: "", s
? ") " : "",
4019 piaddr(state
->packet
->client_addr
));
4021 /* fill dhcp4o6_response */
4022 state
->packet
->dhcp4o6_response
->len
= packet_length
;
4023 state
->packet
->dhcp4o6_response
->buffer
= NULL
;
4024 if (!buffer_allocate(&state
->packet
->dhcp4o6_response
->buffer
,
4025 packet_length
, MDL
)) {
4026 log_fatal("No memory to store DHCP4o6 reply.");
4028 state
->packet
->dhcp4o6_response
->data
=
4029 state
->packet
->dhcp4o6_response
->buffer
->data
;
4030 memcpy(state
->packet
->dhcp4o6_response
->buffer
->data
,
4031 &raw
, packet_length
);
4034 free_lease_state (state
, MDL
);
4035 lease
-> state
= (struct lease_state
*)0;
4041 /* Say what we're doing... */
4042 log_info ("%s on %s to %s %s%s%svia %s",
4044 ? (state
-> offer
== DHCPACK
? "DHCPACK" : "DHCPOFFER")
4046 piaddr (lease
-> ip_addr
),
4047 (lease
-> hardware_addr
.hlen
4048 ? print_hw_addr (lease
-> hardware_addr
.hbuf
[0],
4049 lease
-> hardware_addr
.hlen
- 1,
4050 &lease
-> hardware_addr
.hbuf
[1])
4051 : print_hex_1(lease
->uid_len
, lease
->uid
, 60)),
4052 s
? "(" : "", s
? s
: "", s
? ") " : "",
4053 (state
-> giaddr
.s_addr
4054 ? inet_ntoa (state
-> giaddr
)
4055 : state
-> ip
-> name
));
4058 dump_raw ((unsigned char *)&raw
, packet_length
);
4061 /* Set up the hardware address... */
4062 hto
.hlen
= lease
-> hardware_addr
.hlen
;
4063 memcpy (hto
.hbuf
, lease
-> hardware_addr
.hbuf
, hto
.hlen
);
4065 to
.sin_family
= AF_INET
;
4067 to
.sin_len
= sizeof to
;
4069 memset (to
.sin_zero
, 0, sizeof to
.sin_zero
);
4071 #if defined(RELAY_PORT)
4072 relay_port
= dhcp_check_relayport(state
->packet
);
4075 /* If this was gatewayed, send it back to the gateway... */
4076 if (raw
.giaddr
.s_addr
) {
4077 to
.sin_addr
= raw
.giaddr
;
4078 if (raw
.giaddr
.s_addr
!= htonl (INADDR_LOOPBACK
))
4079 #if defined(RELAY_PORT)
4080 to
.sin_port
= relay_port
? relay_port
: local_port
;
4082 to
.sin_port
= local_port
;
4085 to
.sin_port
= remote_port
; /* For debugging. */
4087 if (fallback_interface
) {
4088 result
= send_packet(fallback_interface
, NULL
, &raw
,
4089 packet_length
, raw
.siaddr
, &to
,
4092 log_error ("%s:%d: Failed to send %d byte long "
4093 "packet over %s interface.", MDL
,
4095 fallback_interface
->name
);
4099 free_lease_state (state
, MDL
);
4100 lease
-> state
= (struct lease_state
*)0;
4104 /* If the client is RENEWING, unicast to the client using the
4105 regular IP stack. Some clients, particularly those that
4106 follow RFC1541, are buggy, and send both ciaddr and server
4107 identifier. We deal with this situation by assuming that
4108 if we got both dhcp-server-identifier and ciaddr, and
4109 giaddr was not set, then the client is on the local
4110 network, and we can therefore unicast or broadcast to it
4111 successfully. A client in REQUESTING state on another
4112 network that's making this mistake will have set giaddr,
4113 and will therefore get a relayed response from the above
4115 } else if (raw
.ciaddr
.s_addr
&&
4116 !((state
-> got_server_identifier
||
4117 (raw
.flags
& htons (BOOTP_BROADCAST
))) &&
4118 /* XXX This won't work if giaddr isn't zero, but it is: */
4119 (state
-> shared_network
==
4120 lease
-> subnet
-> shared_network
)) &&
4121 state
-> offer
== DHCPACK
) {
4122 to
.sin_addr
= raw
.ciaddr
;
4123 to
.sin_port
= remote_port
;
4125 if (fallback_interface
) {
4126 result
= send_packet(fallback_interface
, NULL
, &raw
,
4127 packet_length
, raw
.siaddr
, &to
,
4130 log_error("%s:%d: Failed to send %d byte long"
4131 " packet over %s interface.", MDL
,
4133 fallback_interface
->name
);
4136 free_lease_state (state
, MDL
);
4137 lease
-> state
= (struct lease_state
*)0;
4141 /* If it comes from a client that already knows its address
4142 and is not requesting a broadcast response, and we can
4143 unicast to a client without using the ARP protocol, sent it
4144 directly to that client. */
4145 } else if (!(raw
.flags
& htons (BOOTP_BROADCAST
)) &&
4146 can_unicast_without_arp (state
-> ip
)) {
4147 to
.sin_addr
= raw
.yiaddr
;
4148 to
.sin_port
= remote_port
;
4150 /* Otherwise, broadcast it on the local network. */
4152 to
.sin_addr
= limited_broadcast
;
4153 to
.sin_port
= remote_port
;
4154 if (!(lease
-> flags
& UNICAST_BROADCAST_HACK
))
4158 memcpy (&from
, state
-> from
.iabuf
, sizeof from
);
4160 result
= send_packet(state
->ip
, NULL
, &raw
, packet_length
,
4161 from
, &to
, unicastp
? &hto
: NULL
);
4163 log_error ("%s:%d: Failed to send %d byte long "
4164 "packet over %s interface.", MDL
,
4165 packet_length
, state
->ip
->name
);
4169 /* Free all of the entries in the option_state structure
4170 now that we're done with them. */
4172 free_lease_state (state
, MDL
);
4173 lease
-> state
= (struct lease_state
*)0;
4176 int find_lease (struct lease
**lp
,
4177 struct packet
*packet
, struct shared_network
*share
, int *ours
,
4178 int *peer_has_leases
, struct lease
*ip_lease_in
,
4179 const char *file
, int line
)
4181 struct lease
*uid_lease
= (struct lease
*)0;
4182 struct lease
*ip_lease
= (struct lease
*)0;
4183 struct lease
*hw_lease
= (struct lease
*)0;
4184 struct lease
*lease
= (struct lease
*)0;
4186 struct host_decl
*hp
= (struct host_decl
*)0;
4187 struct host_decl
*host
= (struct host_decl
*)0;
4188 struct lease
*fixed_lease
= (struct lease
*)0;
4189 struct lease
*next
= (struct lease
*)0;
4190 struct option_cache
*oc
;
4191 struct data_string d1
;
4192 int have_client_identifier
= 0;
4193 struct data_string client_identifier
;
4196 #if defined(FAILOVER_PROTOCOL)
4197 /* Quick check to see if the peer has leases. */
4198 if (peer_has_leases
) {
4201 for (pool
= share
->pools
; pool
; pool
= pool
->next
) {
4202 dhcp_failover_state_t
*peer
= pool
->failover_peer
;
4205 ((peer
->i_am
== primary
&& pool
->backup_leases
) ||
4206 (peer
->i_am
== secondary
&& pool
->free_leases
))) {
4207 *peer_has_leases
= 1;
4212 #endif /* FAILOVER_PROTOCOL */
4214 if (packet
-> raw
-> ciaddr
.s_addr
) {
4216 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
, 4);
4218 /* Look up the requested address. */
4219 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
4220 DHO_DHCP_REQUESTED_ADDRESS
);
4221 memset (&d1
, 0, sizeof d1
);
4223 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
4224 (struct client_state
*)0,
4226 (struct option_state
*)0,
4227 &global_scope
, oc
, MDL
)) {
4228 packet
-> got_requested_address
= 1;
4230 memcpy (cip
.iabuf
, d1
.data
, cip
.len
);
4231 data_string_forget (&d1
, MDL
);
4236 /* Try to find a host or lease that's been assigned to the
4237 specified unique client identifier. */
4238 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
4239 DHO_DHCP_CLIENT_IDENTIFIER
);
4240 memset (&client_identifier
, 0, sizeof client_identifier
);
4242 evaluate_option_cache (&client_identifier
,
4243 packet
, (struct lease
*)0,
4244 (struct client_state
*)0,
4245 packet
-> options
, (struct option_state
*)0,
4246 &global_scope
, oc
, MDL
)) {
4247 /* Remember this for later. */
4248 have_client_identifier
= 1;
4250 /* First, try to find a fixed host entry for the specified
4251 client identifier... */
4252 if (find_hosts_by_uid (&hp
, client_identifier
.data
,
4253 client_identifier
.len
, MDL
)) {
4254 /* Remember if we know of this client. */
4255 packet
-> known
= 1;
4256 mockup_lease (&fixed_lease
, packet
, share
, hp
);
4259 #if defined (DEBUG_FIND_LEASE)
4261 log_info ("Found host for client identifier: %s.",
4262 piaddr (fixed_lease
-> ip_addr
));
4266 if (!fixed_lease
) /* Save the host if we found one. */
4267 host_reference (&host
, hp
, MDL
);
4268 host_dereference (&hp
, MDL
);
4271 find_lease_by_uid (&uid_lease
, client_identifier
.data
,
4272 client_identifier
.len
, MDL
);
4275 /* If we didn't find a fixed lease using the uid, try doing
4276 it with the hardware address... */
4277 if (!fixed_lease
&& !host
) {
4278 if (find_hosts_by_haddr (&hp
, packet
-> raw
-> htype
,
4279 packet
-> raw
-> chaddr
,
4280 packet
-> raw
-> hlen
, MDL
)) {
4281 /* Remember if we know of this client. */
4282 packet
-> known
= 1;
4284 host_dereference (&host
, MDL
);
4285 host_reference (&host
, hp
, MDL
);
4286 host_dereference (&hp
, MDL
);
4287 mockup_lease (&fixed_lease
, packet
, share
, host
);
4288 #if defined (DEBUG_FIND_LEASE)
4290 log_info ("Found host for link address: %s.",
4291 piaddr (fixed_lease
-> ip_addr
));
4297 /* Finally, if we haven't found anything yet try again with the
4298 * host-identifier option ... */
4299 if (!fixed_lease
&& !host
) {
4300 if (find_hosts_by_option(&hp
, packet
,
4301 packet
->options
, MDL
) == 1) {
4304 host_dereference(&host
, MDL
);
4305 host_reference(&host
, hp
, MDL
);
4306 host_dereference(&hp
, MDL
);
4307 mockup_lease (&fixed_lease
, packet
, share
, host
);
4308 #if defined (DEBUG_FIND_LEASE)
4310 log_info ("Found host via host-identifier");
4316 /* If fixed_lease is present but does not match the requested
4317 IP address, and this is a DHCPREQUEST, then we can't return
4318 any other lease, so we might as well return now. */
4319 if (packet
-> packet_type
== DHCPREQUEST
&& fixed_lease
&&
4320 (fixed_lease
-> ip_addr
.len
!= cip
.len
||
4321 memcmp (fixed_lease
-> ip_addr
.iabuf
,
4322 cip
.iabuf
, cip
.len
))) {
4325 strcpy (dhcp_message
, "requested address is incorrect");
4326 #if defined (DEBUG_FIND_LEASE)
4327 log_info ("Client's fixed-address %s doesn't match %s%s",
4328 piaddr (fixed_lease
-> ip_addr
), "request ",
4329 print_dotted_quads (cip
.len
, cip
.iabuf
));
4335 * If we found leases matching the client identifier, loop through
4336 * the n_uid pointer looking for one that's actually valid. We
4337 * can't do this until we get here because we depend on
4338 * packet -> known, which may be set by either the uid host
4339 * lookup or the haddr host lookup.
4341 * Note that the n_uid lease chain is sorted in order of
4342 * preference, so the first one is the best one.
4345 isc_boolean_t do_release
= !packet
->raw
->ciaddr
.s_addr
;
4346 #if defined (DEBUG_FIND_LEASE)
4347 log_info ("trying next lease matching client id: %s",
4348 piaddr (uid_lease
-> ip_addr
));
4351 #if defined (FAILOVER_PROTOCOL)
4353 * When we lookup a lease by uid, we know the client identifier
4354 * matches the lease's record. If it is active, or was last
4355 * active with the same client, we can trivially extend it.
4356 * If is not or was not active, we can allocate it to this
4357 * client if it matches the usual free/backup criteria (which
4358 * is contained in lease_mine_to_reallocate()).
4360 if (uid_lease
->binding_state
!= FTS_ACTIVE
&&
4361 uid_lease
->rewind_binding_state
!= FTS_ACTIVE
&&
4362 !lease_mine_to_reallocate(uid_lease
)) {
4363 #if defined (DEBUG_FIND_LEASE)
4364 log_info("not active or not mine to allocate: %s",
4365 piaddr(uid_lease
->ip_addr
));
4371 if (uid_lease
-> subnet
-> shared_network
!= share
) {
4372 #if defined (DEBUG_FIND_LEASE)
4373 log_info ("wrong network segment: %s",
4374 piaddr (uid_lease
-> ip_addr
));
4376 /* Allow multiple leases using the same UID
4377 on different subnetworks. */
4378 do_release
= ISC_FALSE
;
4382 if ((uid_lease
-> pool
-> prohibit_list
&&
4383 permitted (packet
, uid_lease
-> pool
-> prohibit_list
)) ||
4384 (uid_lease
-> pool
-> permit_list
&&
4385 !permitted (packet
, uid_lease
-> pool
-> permit_list
))) {
4386 #if defined (DEBUG_FIND_LEASE)
4387 log_info ("not permitted: %s",
4388 piaddr (uid_lease
-> ip_addr
));
4391 if (uid_lease
-> n_uid
)
4392 lease_reference (&next
,
4393 uid_lease
-> n_uid
, MDL
);
4395 release_lease (uid_lease
, packet
);
4396 lease_dereference (&uid_lease
, MDL
);
4398 lease_reference (&uid_lease
, next
, MDL
);
4399 lease_dereference (&next
, MDL
);
4405 #if defined (DEBUG_FIND_LEASE)
4407 log_info ("Found lease for client id: %s.",
4408 piaddr (uid_lease
-> ip_addr
));
4411 /* Find a lease whose hardware address matches, whose client
4412 * identifier matches (or equally doesn't have one), that's
4413 * permitted, and that's on the correct subnet.
4415 * Note that the n_hw chain is sorted in order of preference, so
4416 * the first one found is the best one.
4418 h
.hlen
= packet
-> raw
-> hlen
+ 1;
4419 h
.hbuf
[0] = packet
-> raw
-> htype
;
4420 memcpy (&h
.hbuf
[1], packet
-> raw
-> chaddr
, packet
-> raw
-> hlen
);
4421 find_lease_by_hw_addr (&hw_lease
, h
.hbuf
, h
.hlen
, MDL
);
4423 #if defined (DEBUG_FIND_LEASE)
4424 log_info ("trying next lease matching hw addr: %s",
4425 piaddr (hw_lease
-> ip_addr
));
4427 #if defined (FAILOVER_PROTOCOL)
4429 * When we lookup a lease by chaddr, we know the MAC address
4430 * matches the lease record (we will check if the lease has a
4431 * client-id the client does not next). If the lease is
4432 * currently active or was last active with this client, we can
4433 * trivially extend it. Otherwise, there are a set of rules
4434 * that govern if we can reallocate this lease to any client
4435 * ("lease_mine_to_reallocate()") including this one.
4437 if (hw_lease
->binding_state
!= FTS_ACTIVE
&&
4438 hw_lease
->rewind_binding_state
!= FTS_ACTIVE
&&
4439 !lease_mine_to_reallocate(hw_lease
)) {
4440 #if defined (DEBUG_FIND_LEASE)
4441 log_info("not active or not mine to allocate: %s",
4442 piaddr(hw_lease
->ip_addr
));
4449 * This conditional skips "potentially active" leases (leases
4450 * we think are expired may be extended by the peer, etc) that
4451 * may be assigned to a differently /client-identified/ client
4452 * with the same MAC address.
4454 if (hw_lease
-> binding_state
!= FTS_FREE
&&
4455 hw_lease
-> binding_state
!= FTS_BACKUP
&&
4457 (!have_client_identifier
||
4458 hw_lease
-> uid_len
!= client_identifier
.len
||
4459 memcmp (hw_lease
-> uid
, client_identifier
.data
,
4460 hw_lease
-> uid_len
))) {
4461 #if defined (DEBUG_FIND_LEASE)
4462 log_info ("wrong client identifier: %s",
4463 piaddr (hw_lease
-> ip_addr
));
4467 if (hw_lease
-> subnet
-> shared_network
!= share
) {
4468 #if defined (DEBUG_FIND_LEASE)
4469 log_info ("wrong network segment: %s",
4470 piaddr (hw_lease
-> ip_addr
));
4474 if ((hw_lease
-> pool
-> prohibit_list
&&
4475 permitted (packet
, hw_lease
-> pool
-> prohibit_list
)) ||
4476 (hw_lease
-> pool
-> permit_list
&&
4477 !permitted (packet
, hw_lease
-> pool
-> permit_list
))) {
4478 #if defined (DEBUG_FIND_LEASE)
4479 log_info ("not permitted: %s",
4480 piaddr (hw_lease
-> ip_addr
));
4482 if (!packet
-> raw
-> ciaddr
.s_addr
)
4483 release_lease (hw_lease
, packet
);
4485 if (hw_lease
-> n_hw
)
4486 lease_reference (&next
, hw_lease
-> n_hw
, MDL
);
4487 lease_dereference (&hw_lease
, MDL
);
4489 lease_reference (&hw_lease
, next
, MDL
);
4490 lease_dereference (&next
, MDL
);
4496 #if defined (DEBUG_FIND_LEASE)
4498 log_info ("Found lease for hardware address: %s.",
4499 piaddr (hw_lease
-> ip_addr
));
4502 /* Try to find a lease that's been allocated to the client's
4505 lease_reference (&ip_lease
, ip_lease_in
, MDL
);
4507 find_lease_by_ip_addr (&ip_lease
, cip
, MDL
);
4509 #if defined (DEBUG_FIND_LEASE)
4511 log_info ("Found lease for requested address: %s.",
4512 piaddr (ip_lease
-> ip_addr
));
4515 /* If ip_lease is valid at this point, set ours to one, so that
4516 even if we choose a different lease, we know that the address
4517 the client was requesting was ours, and thus we can NAK it. */
4518 if (ip_lease
&& ours
)
4521 /* If the requested IP address isn't on the network the packet
4522 came from, don't use it. Allow abandoned leases to be matched
4523 here - if the client is requesting it, there's a decent chance
4524 that it's because the lease database got trashed and a client
4525 that thought it had this lease answered an ARP or PING, causing the
4526 lease to be abandoned. If so, this request probably came from
4528 if (ip_lease
&& (ip_lease
-> subnet
-> shared_network
!= share
)) {
4531 #if defined (DEBUG_FIND_LEASE)
4532 log_info ("...but it was on the wrong shared network.");
4534 strcpy (dhcp_message
, "requested address on bad subnet");
4535 lease_dereference (&ip_lease
, MDL
);
4539 * If the requested address is in use (or potentially in use) by
4540 * a different client, it can't be granted.
4542 * This first conditional only detects if the lease is currently
4543 * identified to a different client (client-id and/or chaddr
4544 * mismatch). In this case we may not want to give the client the
4545 * lease, if doing so may potentially be an addressing conflict.
4549 (!have_client_identifier
||
4550 ip_lease
-> uid_len
!= client_identifier
.len
||
4551 memcmp (ip_lease
-> uid
, client_identifier
.data
,
4552 ip_lease
-> uid_len
)) :
4553 (ip_lease
-> hardware_addr
.hbuf
[0] != packet
-> raw
-> htype
||
4554 ip_lease
-> hardware_addr
.hlen
!= packet
-> raw
-> hlen
+ 1 ||
4555 memcmp (&ip_lease
-> hardware_addr
.hbuf
[1],
4556 packet
-> raw
-> chaddr
,
4557 (unsigned)(ip_lease
-> hardware_addr
.hlen
- 1))))) {
4559 * A lease is unavailable for allocation to a new client if
4560 * it is not in the FREE or BACKUP state. There may be
4561 * leases that are in the expired state with a rewinding
4562 * state that is free or backup, but these will be processed
4563 * into the free or backup states by expiration processes, so
4564 * checking for them here is superfluous.
4566 if (ip_lease
-> binding_state
!= FTS_FREE
&&
4567 ip_lease
-> binding_state
!= FTS_BACKUP
) {
4568 #if defined (DEBUG_FIND_LEASE)
4569 log_info ("rejecting lease for requested address.");
4571 /* If we're rejecting it because the peer has
4572 it, don't set "ours", because we shouldn't NAK. */
4573 if (ours
&& ip_lease
-> binding_state
!= FTS_ACTIVE
)
4575 lease_dereference (&ip_lease
, MDL
);
4580 * If we got an ip_lease and a uid_lease or hw_lease, and ip_lease
4581 * is/was not active, and is not ours to reallocate, forget about it.
4583 if (ip_lease
&& (uid_lease
|| hw_lease
) &&
4584 ip_lease
->binding_state
!= FTS_ACTIVE
&&
4585 ip_lease
->rewind_binding_state
!= FTS_ACTIVE
&&
4586 #if defined(FAILOVER_PROTOCOL)
4587 !lease_mine_to_reallocate(ip_lease
) &&
4589 packet
->packet_type
== DHCPDISCOVER
) {
4590 #if defined (DEBUG_FIND_LEASE)
4591 log_info("ip lease not active or not ours to offer.");
4593 lease_dereference(&ip_lease
, MDL
);
4596 /* If for some reason the client has more than one lease
4597 on the subnet that matches its uid, pick the one that
4598 it asked for and (if we can) free the other. */
4599 if (ip_lease
&& ip_lease
->binding_state
== FTS_ACTIVE
&&
4600 ip_lease
->uid
&& ip_lease
!= uid_lease
) {
4601 if (have_client_identifier
&&
4602 (ip_lease
-> uid_len
== client_identifier
.len
) &&
4603 !memcmp (client_identifier
.data
,
4604 ip_lease
-> uid
, ip_lease
-> uid_len
)) {
4606 if (uid_lease
->binding_state
== FTS_ACTIVE
) {
4607 log_error ("client %s has duplicate%s on %s",
4609 (packet
-> raw
-> htype
,
4610 packet
-> raw
-> hlen
,
4611 packet
-> raw
-> chaddr
)),
4613 (ip_lease
-> subnet
->
4614 shared_network
-> name
));
4616 /* If the client is REQUESTing the lease,
4617 it shouldn't still be using the old
4618 one, so we can free it for allocation. */
4620 uid_lease
->binding_state
== FTS_ACTIVE
&&
4621 !packet
-> raw
-> ciaddr
.s_addr
&&
4623 uid_lease
-> subnet
-> shared_network
) &&
4624 packet
-> packet_type
== DHCPREQUEST
)
4625 release_lease (uid_lease
, packet
);
4627 lease_dereference (&uid_lease
, MDL
);
4628 lease_reference (&uid_lease
, ip_lease
, MDL
);
4632 /* If we get to here and fixed_lease is not null, that means
4633 that there are both a dynamic lease and a fixed-address
4634 declaration for the same IP address. */
4635 if (packet
-> packet_type
== DHCPREQUEST
&& fixed_lease
) {
4636 lease_dereference (&fixed_lease
, MDL
);
4638 log_error ("Dynamic and static leases present for %s.",
4640 log_error ("Remove host declaration %s or remove %s",
4641 (fixed_lease
&& fixed_lease
-> host
4642 ? (fixed_lease
-> host
-> name
4643 ? fixed_lease
-> host
-> name
4647 log_error ("from the dynamic address pool for %s",
4648 ip_lease
-> subnet
-> shared_network
-> name
4651 lease_dereference (&ip_lease
, MDL
);
4652 strcpy (dhcp_message
,
4653 "database conflict - call for help!");
4656 if (ip_lease
&& ip_lease
!= uid_lease
) {
4657 #if defined (DEBUG_FIND_LEASE)
4658 log_info ("requested address not available.");
4660 lease_dereference (&ip_lease
, MDL
);
4664 /* If we get to here with both fixed_lease and ip_lease not
4665 null, then we have a configuration file bug. */
4666 if (packet
-> packet_type
== DHCPREQUEST
&& fixed_lease
&& ip_lease
)
4669 /* Toss extra pointers to the same lease... */
4670 if (hw_lease
&& hw_lease
== uid_lease
) {
4671 #if defined (DEBUG_FIND_LEASE)
4672 log_info ("hardware lease and uid lease are identical.");
4674 lease_dereference (&hw_lease
, MDL
);
4676 if (ip_lease
&& ip_lease
== hw_lease
) {
4677 lease_dereference (&hw_lease
, MDL
);
4678 #if defined (DEBUG_FIND_LEASE)
4679 log_info ("hardware lease and ip lease are identical.");
4682 if (ip_lease
&& ip_lease
== uid_lease
) {
4683 lease_dereference (&uid_lease
, MDL
);
4684 #if defined (DEBUG_FIND_LEASE)
4685 log_info ("uid lease and ip lease are identical.");
4689 /* Make sure the client is permitted to use the requested lease. */
4691 ((ip_lease
-> pool
-> prohibit_list
&&
4692 permitted (packet
, ip_lease
-> pool
-> prohibit_list
)) ||
4693 (ip_lease
-> pool
-> permit_list
&&
4694 !permitted (packet
, ip_lease
-> pool
-> permit_list
)))) {
4695 if (!packet
->raw
->ciaddr
.s_addr
&&
4696 (ip_lease
->binding_state
== FTS_ACTIVE
))
4697 release_lease (ip_lease
, packet
);
4699 lease_dereference (&ip_lease
, MDL
);
4703 ((uid_lease
-> pool
-> prohibit_list
&&
4704 permitted (packet
, uid_lease
-> pool
-> prohibit_list
)) ||
4705 (uid_lease
-> pool
-> permit_list
&&
4706 !permitted (packet
, uid_lease
-> pool
-> permit_list
)))) {
4707 if (!packet
-> raw
-> ciaddr
.s_addr
)
4708 release_lease (uid_lease
, packet
);
4709 lease_dereference (&uid_lease
, MDL
);
4713 ((hw_lease
-> pool
-> prohibit_list
&&
4714 permitted (packet
, hw_lease
-> pool
-> prohibit_list
)) ||
4715 (hw_lease
-> pool
-> permit_list
&&
4716 !permitted (packet
, hw_lease
-> pool
-> permit_list
)))) {
4717 if (!packet
-> raw
-> ciaddr
.s_addr
)
4718 release_lease (hw_lease
, packet
);
4719 lease_dereference (&hw_lease
, MDL
);
4722 /* If we've already eliminated the lease, it wasn't there to
4723 begin with. If we have come up with a matching lease,
4724 set the message to bad network in case we have to throw it out. */
4726 strcpy (dhcp_message
, "requested address not available");
4729 /* If this is a DHCPREQUEST, make sure the lease we're going to return
4730 matches the requested IP address. If it doesn't, don't return a
4732 if (packet
-> packet_type
== DHCPREQUEST
&&
4733 !ip_lease
&& !fixed_lease
) {
4734 #if defined (DEBUG_FIND_LEASE)
4735 log_info ("no applicable lease found for DHCPREQUEST.");
4740 /* At this point, if fixed_lease is nonzero, we can assign it to
4743 lease_reference (&lease
, fixed_lease
, MDL
);
4744 lease_dereference (&fixed_lease
, MDL
);
4745 #if defined (DEBUG_FIND_LEASE)
4746 log_info ("choosing fixed address.");
4750 /* If we got a lease that matched the ip address and don't have
4751 a better offer, use that; otherwise, release it. */
4754 if (!packet
-> raw
-> ciaddr
.s_addr
)
4755 release_lease (ip_lease
, packet
);
4756 #if defined (DEBUG_FIND_LEASE)
4757 log_info ("not choosing requested address (!).");
4759 lease_dereference (&ip_lease
, MDL
);
4761 #if defined (DEBUG_FIND_LEASE)
4762 log_info ("choosing lease on requested address.");
4764 lease_reference (&lease
, ip_lease
, MDL
);
4766 host_dereference (&lease
-> host
, MDL
);
4770 /* If we got a lease that matched the client identifier, we may want
4771 to use it, but if we already have a lease we like, we must free
4772 the lease that matched the client identifier. */
4775 log_error("uid lease %s for client %s is duplicate "
4777 piaddr(uid_lease
->ip_addr
),
4778 print_hw_addr(packet
->raw
->htype
,
4780 packet
->raw
->chaddr
),
4781 uid_lease
->subnet
->shared_network
->name
);
4783 if (!packet
-> raw
-> ciaddr
.s_addr
&&
4784 packet
-> packet_type
== DHCPREQUEST
&&
4785 uid_lease
-> binding_state
== FTS_ACTIVE
)
4786 release_lease(uid_lease
, packet
);
4787 #if defined (DEBUG_FIND_LEASE)
4788 log_info ("not choosing uid lease.");
4791 lease_reference (&lease
, uid_lease
, MDL
);
4793 host_dereference (&lease
-> host
, MDL
);
4794 #if defined (DEBUG_FIND_LEASE)
4795 log_info ("choosing uid lease.");
4798 lease_dereference (&uid_lease
, MDL
);
4801 /* The lease that matched the hardware address is treated likewise. */
4804 #if defined (DEBUG_FIND_LEASE)
4805 log_info ("not choosing hardware lease.");
4808 /* We're a little lax here - if the client didn't
4809 send a client identifier and it's a bootp client,
4810 but the lease has a client identifier, we still
4811 let the client have a lease. */
4812 if (!hw_lease
-> uid_len
||
4813 (have_client_identifier
4814 ? (hw_lease
-> uid_len
==
4815 client_identifier
.len
&&
4816 !memcmp (hw_lease
-> uid
,
4817 client_identifier
.data
,
4818 client_identifier
.len
))
4819 : packet
-> packet_type
== 0)) {
4820 lease_reference (&lease
, hw_lease
, MDL
);
4822 host_dereference (&lease
-> host
, MDL
);
4823 #if defined (DEBUG_FIND_LEASE)
4824 log_info ("choosing hardware lease.");
4827 #if defined (DEBUG_FIND_LEASE)
4828 log_info ("not choosing hardware lease: %s.",
4833 lease_dereference (&hw_lease
, MDL
);
4837 * If we found a host_decl but no matching address, try to
4838 * find a host_decl that has no address, and if there is one,
4839 * hang it off the lease so that we can use the supplied
4842 if (lease
&& host
&& !lease
->host
) {
4843 struct host_decl
*p
= NULL
;
4844 struct host_decl
*n
= NULL
;
4846 host_reference(&p
, host
, MDL
);
4848 if (!p
->fixed_addr
) {
4850 * If the lease is currently active, then it
4851 * must be allocated to the present client.
4852 * We store a reference to the host record on
4853 * the lease to save a lookup later (in
4854 * ack_lease()). We mustn't refer to the host
4855 * record on non-active leases because the
4856 * client may be denied later.
4858 * XXX: Not having this reference (such as in
4859 * DHCPDISCOVER/INIT) means ack_lease will have
4860 * to perform this lookup a second time. This
4861 * hopefully isn't a problem as DHCPREQUEST is
4862 * more common than DHCPDISCOVER.
4864 if (lease
->binding_state
== FTS_ACTIVE
)
4865 host_reference(&lease
->host
, p
, MDL
);
4867 host_dereference(&p
, MDL
);
4870 if (p
->n_ipaddr
!= NULL
)
4871 host_reference(&n
, p
->n_ipaddr
, MDL
);
4872 host_dereference(&p
, MDL
);
4874 host_reference(&p
, n
, MDL
);
4875 host_dereference(&n
, MDL
);
4880 /* If we find an abandoned lease, but it's the one the client
4881 requested, we assume that previous bugginess on the part
4882 of the client, or a server database loss, caused the lease to
4883 be abandoned, so we reclaim it and let the client have it. */
4885 (lease
-> binding_state
== FTS_ABANDONED
) &&
4886 lease
== ip_lease
&&
4887 packet
-> packet_type
== DHCPREQUEST
) {
4888 log_error ("Reclaiming REQUESTed abandoned IP address %s.",
4889 piaddr (lease
-> ip_addr
));
4890 } else if (lease
&& (lease
-> binding_state
== FTS_ABANDONED
)) {
4891 /* Otherwise, if it's not the one the client requested, we do not
4892 return it - instead, we claim it's ours, causing a DHCPNAK to be
4893 sent if this lookup is for a DHCPREQUEST, and force the client
4894 to go back through the allocation process. */
4897 lease_dereference (&lease
, MDL
);
4901 if (have_client_identifier
)
4902 data_string_forget (&client_identifier
, MDL
);
4905 lease_dereference (&fixed_lease
, MDL
);
4907 lease_dereference (&hw_lease
, MDL
);
4909 lease_dereference (&uid_lease
, MDL
);
4911 lease_dereference (&ip_lease
, MDL
);
4913 host_dereference (&host
, MDL
);
4916 #if defined (DEBUG_FIND_LEASE)
4917 log_info ("Returning lease: %s.",
4918 piaddr (lease
-> ip_addr
));
4920 lease_reference (lp
, lease
, file
, line
);
4921 lease_dereference (&lease
, MDL
);
4924 #if defined (DEBUG_FIND_LEASE)
4925 log_info ("Not returning a lease.");
4930 /* Search the provided host_decl structure list for an address that's on
4931 the specified shared network. If one is found, mock up and return a
4932 lease structure for it; otherwise return the null pointer. */
4934 int mockup_lease (struct lease
**lp
, struct packet
*packet
,
4935 struct shared_network
*share
, struct host_decl
*hp
)
4937 struct lease
*lease
= (struct lease
*)0;
4938 struct host_decl
*rhp
= (struct host_decl
*)0;
4940 if (lease_allocate (&lease
, MDL
) != ISC_R_SUCCESS
)
4942 if (host_reference (&rhp
, hp
, MDL
) != ISC_R_SUCCESS
) {
4943 lease_dereference (&lease
, MDL
);
4946 if (!find_host_for_network (&lease
-> subnet
,
4947 &rhp
, &lease
-> ip_addr
, share
)) {
4948 lease_dereference (&lease
, MDL
);
4949 host_dereference (&rhp
, MDL
);
4952 host_reference (&lease
-> host
, rhp
, MDL
);
4953 if (rhp
-> client_identifier
.len
> sizeof lease
-> uid_buf
)
4954 lease
-> uid
= dmalloc (rhp
-> client_identifier
.len
, MDL
);
4956 lease
-> uid
= lease
-> uid_buf
;
4957 if (!lease
-> uid
) {
4958 lease_dereference (&lease
, MDL
);
4959 host_dereference (&rhp
, MDL
);
4962 memcpy (lease
-> uid
, rhp
-> client_identifier
.data
,
4963 rhp
-> client_identifier
.len
);
4964 lease
-> uid_len
= rhp
-> client_identifier
.len
;
4965 lease
-> hardware_addr
= rhp
-> interface
;
4966 lease
-> starts
= lease
-> cltt
= lease
-> ends
= MIN_TIME
;
4967 lease
-> flags
= STATIC_LEASE
;
4968 lease
-> binding_state
= FTS_FREE
;
4970 lease_reference (lp
, lease
, MDL
);
4972 lease_dereference (&lease
, MDL
);
4973 host_dereference (&rhp
, MDL
);
4977 /* Look through all the pools in a list starting with the specified pool
4978 for a free lease. We try to find a virgin lease if we can. If we
4979 don't find a virgin lease, we try to find a non-virgin lease that's
4980 free. If we can't find one of those, we try to reclaim an abandoned
4981 lease. If all of these possibilities fail to pan out, we don't return
4984 int allocate_lease (struct lease
**lp
, struct packet
*packet
,
4985 struct pool
*pool
, int *peer_has_leases
)
4987 struct lease
*lease
= NULL
;
4988 struct lease
*candl
= NULL
;
4990 for (; pool
; pool
= pool
-> next
) {
4991 if ((pool
-> prohibit_list
&&
4992 permitted (packet
, pool
-> prohibit_list
)) ||
4993 (pool
-> permit_list
&&
4994 !permitted (packet
, pool
-> permit_list
)))
4997 #if defined (FAILOVER_PROTOCOL)
4998 /* Peer_has_leases just says that we found at least one
4999 free lease. If no free lease is returned, the caller
5000 can deduce that this means the peer is hogging all the
5001 free leases, so we can print a better error message. */
5002 /* XXX Do we need code here to ignore PEER_IS_OWNER and
5003 * XXX just check tstp if we're in, e.g., PARTNER_DOWN?
5004 * XXX Where do we deal with CONFLICT_DETECTED, et al? */
5005 /* XXX This should be handled by the lease binding "state
5006 * XXX machine" - that is, when we get here, if a lease
5007 * XXX could be allocated, it will have the correct
5008 * XXX binding state so that the following code will
5009 * XXX result in its being allocated. */
5010 /* Skip to the most expired lease in the pool that is not
5011 * owned by a failover peer. */
5012 if (pool
->failover_peer
!= NULL
) {
5013 struct lease
*peerl
= NULL
;
5014 if (pool
->failover_peer
->i_am
== primary
) {
5015 candl
= LEASE_GET_FIRST(pool
->free
);
5018 * In normal operation, we never want to touch
5019 * the peer's leases. In partner-down
5020 * operation, we need to be able to pick up
5021 * the peer's leases after STOS+MCLT.
5023 peerl
= LEASE_GET_FIRST(pool
->backup
);
5024 if (peerl
!= NULL
) {
5025 if (((candl
== NULL
) ||
5026 (candl
->ends
> peerl
->ends
)) &&
5027 lease_mine_to_reallocate(peerl
)) {
5030 *peer_has_leases
= 1;
5034 candl
= LEASE_GET_FIRST(pool
->backup
);
5036 peerl
= LEASE_GET_FIRST(pool
->free
);
5037 if (peerl
!= NULL
) {
5038 if (((candl
== NULL
) ||
5039 (candl
->ends
> peerl
->ends
)) &&
5040 lease_mine_to_reallocate(peerl
)) {
5043 *peer_has_leases
= 1;
5048 /* Try abandoned leases as a last resort. */
5049 peerl
= LEASE_GET_FIRST(pool
->abandoned
);
5050 if ((candl
== NULL
) && (peerl
!= NULL
) &&
5051 lease_mine_to_reallocate(peerl
))
5056 if (LEASE_NOT_EMPTY(pool
->free
))
5057 candl
= LEASE_GET_FIRST(pool
->free
);
5059 candl
= LEASE_GET_FIRST(pool
->abandoned
);
5063 * XXX: This may not match with documented expectation.
5064 * It's expected that when we OFFER a lease, we set its
5065 * ends time forward 2 minutes so that it gets sorted to
5066 * the end of its free list (avoiding a similar allocation
5067 * to another client). It is not expected that we issue a
5068 * "no free leases" error when the last lease has been
5069 * offered, but it's not exactly broken either.
5072 (candl
->binding_state
!= FTS_ABANDONED
&&
5073 (candl
->ends
> cur_time
))) {
5083 * There are tiers of lease state preference, listed here in
5084 * reverse order (least to most preferential):
5089 * If the selected lease and candidate are both of the same
5090 * state, select the oldest (longest ago) expiration time
5091 * between the two. If the candidate lease is of a higher
5092 * preferred grade over the selected lease, use it.
5094 if ((lease
-> binding_state
== FTS_ABANDONED
) &&
5095 ((candl
-> binding_state
!= FTS_ABANDONED
) ||
5096 (candl
-> ends
< lease
-> ends
))) {
5099 } else if (candl
-> binding_state
== FTS_ABANDONED
)
5102 if ((lease
-> uid_len
|| lease
-> hardware_addr
.hlen
) &&
5103 ((!candl
-> uid_len
&& !candl
-> hardware_addr
.hlen
) ||
5104 (candl
-> ends
< lease
-> ends
))) {
5107 } else if (candl
-> uid_len
|| candl
-> hardware_addr
.hlen
)
5110 if (candl
-> ends
< lease
-> ends
)
5114 if (lease
!= NULL
) {
5115 if (lease
->binding_state
== FTS_ABANDONED
)
5116 log_error("Reclaiming abandoned lease %s.",
5117 piaddr(lease
->ip_addr
));
5120 * XXX: For reliability, we go ahead and remove the host
5121 * record and try to move on. For correctness, if there
5122 * are any other stale host vectors, we want to find them.
5124 if (lease
->host
!= NULL
) {
5125 log_debug("soft impossible condition (%s:%d): stale "
5126 "host \"%s\" found on lease %s", MDL
,
5128 piaddr(lease
->ip_addr
));
5129 host_dereference(&lease
->host
, MDL
);
5132 lease_reference (lp
, lease
, MDL
);
5139 /* Determine whether or not a permit exists on a particular permit list
5140 that matches the specified packet, returning nonzero if so, zero if
5143 int permitted (packet
, permit_list
)
5144 struct packet
*packet
;
5145 struct permit
*permit_list
;
5150 for (p
= permit_list
; p
; p
= p
-> next
) {
5151 switch (p
-> type
) {
5152 case permit_unknown_clients
:
5153 if (!packet
-> known
)
5157 case permit_known_clients
:
5158 if (packet
-> known
)
5162 case permit_authenticated_clients
:
5163 if (packet
-> authenticated
)
5167 case permit_unauthenticated_clients
:
5168 if (!packet
-> authenticated
)
5172 case permit_all_clients
:
5175 case permit_dynamic_bootp_clients
:
5176 if (!packet
-> options_valid
||
5177 !packet
-> packet_type
)
5182 for (i
= 0; i
< packet
-> class_count
; i
++) {
5183 if (p
-> class == packet
-> classes
[i
])
5185 if (packet
-> classes
[i
] &&
5186 packet
-> classes
[i
] -> superclass
&&
5187 (packet
-> classes
[i
] -> superclass
==
5194 if (cur_time
> p
->after
)
5202 #if defined(DHCPv6) && defined(DHCP4o6)
5203 static int locate_network6 (packet
)
5204 struct packet
*packet
;
5206 const struct packet
*chk_packet
;
5207 const struct in6_addr
*link_addr
, *first_link_addr
;
5209 struct data_string data
;
5210 struct subnet
*subnet
= NULL
;
5211 struct option_cache
*oc
;
5213 /* from locate_network() */
5215 /* See if there's a Relay Agent Link Selection Option, or a
5216 * Subnet Selection Option. The Link-Select and Subnet-Select
5217 * are formatted and used precisely the same, but we must prefer
5218 * the link-select over the subnet-select.
5219 * BTW in DHCPv4 over DHCPv6 no cross version relay was specified
5220 * so it is unlikely to see a link-select.
5222 if ((oc
= lookup_option(&agent_universe
, packet
->options
,
5223 RAI_LINK_SELECT
)) == NULL
)
5224 oc
= lookup_option(&dhcp_universe
, packet
->options
,
5225 DHO_SUBNET_SELECTION
);
5227 /* If there's an option indicating link connection or subnet
5228 * selection, and it's valid, use it to figure out the subnet.
5229 * If it's not valid, fail.
5232 memset(&data
, 0, sizeof data
);
5233 if (!evaluate_option_cache(&data
, packet
, NULL
, NULL
,
5234 packet
->options
, NULL
,
5235 &global_scope
, oc
, MDL
)) {
5238 if (data
.len
== 0) {
5241 if (data
.len
!= 4) {
5242 data_string_forget(&data
, MDL
);
5246 memcpy(ia
.iabuf
, data
.data
, 4);
5247 data_string_forget(&data
, MDL
);
5249 if (find_subnet(&subnet
, ia
, MDL
)) {
5250 shared_network_reference(&packet
->shared_network
,
5251 subnet
->shared_network
, MDL
);
5252 subnet_dereference(&subnet
, MDL
);
5258 /* See if there is a giaddr (still unlikely), if there is one
5259 * use it to figure out the subnet. If it's not valid, fail.
5261 if (packet
->raw
->giaddr
.s_addr
) {
5263 memcpy(ia
.iabuf
, &packet
->raw
->giaddr
, 4);
5265 if (find_subnet(&subnet
, ia
, MDL
)) {
5266 shared_network_reference(&packet
->shared_network
,
5267 subnet
->shared_network
, MDL
);
5268 subnet_dereference(&subnet
, MDL
);
5274 /* from shared_network_from_packet6() */
5276 /* First, find the link address where the packet from the client
5277 * first appeared (if this packet was relayed).
5279 first_link_addr
= NULL
;
5280 chk_packet
= packet
->dhcpv6_container_packet
;
5281 while (chk_packet
!= NULL
) {
5282 link_addr
= &chk_packet
->dhcpv6_link_address
;
5283 if (!IN6_IS_ADDR_UNSPECIFIED(link_addr
) &&
5284 !IN6_IS_ADDR_LINKLOCAL(link_addr
)) {
5285 first_link_addr
= link_addr
;
5288 chk_packet
= chk_packet
->dhcpv6_container_packet
;
5291 /* If there is a relayed link address, find the subnet associated
5292 * with that, and use that to get the appropriate shared_network.
5294 if (first_link_addr
!= NULL
) {
5295 ia
.len
= sizeof(*first_link_addr
);
5296 memcpy(ia
.iabuf
, first_link_addr
, sizeof(*first_link_addr
));
5297 if (find_subnet (&subnet
, ia
, MDL
)) {
5298 shared_network_reference(&packet
->shared_network
,
5299 subnet
->shared_network
, MDL
);
5300 subnet_dereference(&subnet
, MDL
);
5306 /* If there is no link address, we will use the interface
5307 * that this packet came in on to pick the shared_network.
5309 if (packet
->interface
!= NULL
) {
5310 if (packet
->interface
->shared_network
== NULL
)
5312 shared_network_reference(&packet
->shared_network
,
5313 packet
->interface
->shared_network
,
5318 /* We shouldn't be able to get here but if there is no link
5319 * address and no interface we don't know where to get the
5320 * shared_network from, log an error and return an error.
5322 log_error("No interface and no link address "
5323 "can't determine DHCP4o6 shared network");
5328 int locate_network (packet
)
5329 struct packet
*packet
;
5332 struct data_string data
;
5333 struct subnet
*subnet
= (struct subnet
*)0;
5334 struct option_cache
*oc
;
5336 #if defined(DHCPv6) && defined(DHCP4o6)
5337 if (dhcpv4_over_dhcpv6
&& (packet
->dhcp4o6_response
!= NULL
)) {
5338 return (locate_network6 (packet
));
5342 /* See if there's a Relay Agent Link Selection Option, or a
5343 * Subnet Selection Option. The Link-Select and Subnet-Select
5344 * are formatted and used precisely the same, but we must prefer
5345 * the link-select over the subnet-select.
5347 if ((oc
= lookup_option(&agent_universe
, packet
->options
,
5348 RAI_LINK_SELECT
)) == NULL
)
5349 oc
= lookup_option(&dhcp_universe
, packet
->options
,
5350 DHO_SUBNET_SELECTION
);
5352 /* If there's no SSO and no giaddr, then use the shared_network
5353 from the interface, if there is one. If not, fail. */
5354 if (!oc
&& !packet
-> raw
-> giaddr
.s_addr
) {
5355 if (packet
-> interface
-> shared_network
) {
5356 shared_network_reference
5357 (&packet
-> shared_network
,
5358 packet
-> interface
-> shared_network
, MDL
);
5364 /* If there's an option indicating link connection, and it's valid,
5365 * use it to figure out the subnet. If it's not valid, fail.
5368 memset (&data
, 0, sizeof data
);
5369 if (!evaluate_option_cache (&data
, packet
, (struct lease
*)0,
5370 (struct client_state
*)0,
5372 (struct option_state
*)0,
5373 &global_scope
, oc
, MDL
)) {
5377 if (data
.len
!= 4) {
5378 data_string_forget (&data
, MDL
);
5383 memcpy (ia
.iabuf
, data
.data
, 4);
5384 data_string_forget (&data
, MDL
);
5387 memcpy (ia
.iabuf
, &packet
-> raw
-> giaddr
, 4);
5390 /* If we know the subnet on which the IP address lives, use it. */
5391 if (find_subnet (&subnet
, ia
, MDL
)) {
5392 shared_network_reference (&packet
-> shared_network
,
5393 subnet
-> shared_network
, MDL
);
5394 subnet_dereference (&subnet
, MDL
);
5398 /* Otherwise, fail. */
5403 * Try to figure out the source address to send packets from.
5405 * from is the address structure we use to return any address
5408 * options is the option cache to search. This may include
5409 * options from the incoming packet and configuration information.
5411 * out_options is the outgoing option cache. This cache
5412 * may be the same as options. If out_options isn't NULL
5413 * we may save the server address option into it. We do so
5414 * if out_options is different than options or if the option
5415 * wasn't in options and we needed to find the address elsewhere.
5417 * packet is the state structure for the incoming packet
5419 * When finding the address we first check to see if it is
5420 * in the options list. If it isn't we use the first address
5421 * from the interface.
5423 * While this is slightly more complicated than I'd like it allows
5424 * us to use the same code in several different places. ack,
5425 * inform and lease query use it to find the address and fill
5426 * in the options if we get the address from the interface.
5427 * nack uses it to find the address and copy it to the outgoing
5428 * cache. dhcprequest uses it to find the address for comparison
5429 * and doesn't need to add it to an outgoing list.
5433 get_server_source_address(struct in_addr
*from
,
5434 struct option_state
*options
,
5435 struct option_state
*out_options
,
5436 struct packet
*packet
) {
5437 unsigned option_num
;
5438 struct option_cache
*oc
= NULL
;
5439 struct data_string d
;
5440 struct in_addr
*a
= NULL
;
5441 isc_boolean_t found
= ISC_FALSE
;
5444 memset(&d
, 0, sizeof(d
));
5445 memset(from
, 0, sizeof(*from
));
5447 option_num
= DHO_DHCP_SERVER_IDENTIFIER
;
5448 oc
= lookup_option(&dhcp_universe
, options
, option_num
);
5450 if (evaluate_option_cache(&d
, packet
, NULL
, NULL
,
5451 packet
->options
, options
,
5452 &global_scope
, oc
, MDL
)) {
5453 if (d
.len
== sizeof(*from
)) {
5455 memcpy(from
, d
.data
, sizeof(*from
));
5458 * Arrange to save a copy of the data
5459 * to the outgoing list.
5461 if ((out_options
!= NULL
) &&
5462 (options
!= out_options
)) {
5467 data_string_forget(&d
, MDL
);
5472 if ((found
== ISC_FALSE
) &&
5473 (packet
->interface
->address_count
> 0)) {
5474 *from
= packet
->interface
->addresses
[0];
5476 if (out_options
!= NULL
) {
5477 a
= &packet
->interface
->addresses
[0];
5482 (option_cache_allocate(&oc
, MDL
))) {
5483 if (make_const_data(&oc
->expression
,
5484 (unsigned char *)a
, sizeof(*a
),
5485 0, allocate
, MDL
)) {
5486 option_code_hash_lookup(&oc
->option
,
5487 dhcp_universe
.code_hash
,
5488 &option_num
, 0, MDL
);
5489 save_option(&dhcp_universe
, out_options
, oc
);
5491 option_cache_dereference(&oc
, MDL
);
5498 * \brief Builds option set from statements at the global and network scope
5500 * Set up an option state list based on the global and network scopes.
5501 * These are primarily used by NAK logic to locate dhcp-server-id and
5504 * We don't go through all possible options - in particualr we skip the hosts
5505 * and we don't include the lease to avoid making changes to it. This means
5506 * that using these, we won't get the correct server id if the admin puts them
5507 * on hosts or builds the server id with information from the lease.
5509 * As this is a fallback function (used to handle NAKs or sort out server id
5510 * mismatch in failover) and requires configuration by the admin, it should be
5513 * \param network_options option_state to which options will be added. If it
5514 * refers to NULL, it will be allocated. Caller is responsible to delete it.
5515 * \param packet inbound packet
5516 * \param network_group scope group to use if packet->shared_network is null.
5519 eval_network_statements(struct option_state
**network_options
,
5520 struct packet
*packet
,
5521 struct group
*network_group
) {
5523 if (*network_options
== NULL
) {
5524 option_state_allocate (network_options
, MDL
);
5527 /* Use the packet's shared_network if it has one. If not use
5528 * network_group and if it is null then use global scope. */
5529 if (packet
->shared_network
!= NULL
) {
5531 * If we have a subnet and group start with that else start
5532 * with the shared network group. The first will recurse and
5533 * include the second.
5535 if ((packet
->shared_network
->subnets
!= NULL
) &&
5536 (packet
->shared_network
->subnets
->group
!= NULL
)) {
5537 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5538 packet
->options
, *network_options
,
5540 packet
->shared_network
->subnets
->group
,
5543 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5544 packet
->options
, *network_options
,
5546 packet
->shared_network
->group
,
5550 /* do the pool if there is one */
5551 if (packet
->shared_network
->pools
!= NULL
) {
5552 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5553 packet
->options
, *network_options
,
5555 packet
->shared_network
->pools
->group
,
5556 packet
->shared_network
->group
,
5559 } else if (network_group
!= NULL
) {
5560 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5561 packet
->options
, *network_options
,
5562 &global_scope
, network_group
,
5565 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5566 packet
->options
, *network_options
,
5567 &global_scope
, root_group
,
5573 * Look for the lowest numbered site code number and
5574 * apply a log warning if it is less than 224. Do not
5575 * permit site codes less than 128 (old code never did).
5577 * Note that we could search option codes 224 down to 128
5578 * on the hash table, but the table is (probably) smaller
5579 * than that if it was declared as a standalone table with
5580 * defaults. So we traverse the option code hash.
5583 find_min_site_code(struct universe
*u
)
5585 if (u
->site_code_min
)
5586 return u
->site_code_min
;
5589 * Note that site_code_min has to be global as we can't pass an
5590 * argument through hash_foreach(). The value 224 is taken from
5593 site_code_min
= 224;
5594 option_code_hash_foreach(u
->code_hash
, lowest_site_code
);
5596 if (site_code_min
< 224) {
5597 log_error("WARNING: site-local option codes less than 224 have "
5598 "been deprecated by RFC3942. You have options "
5599 "listed in site local space %s that number as low as "
5600 "%d. Please investigate if these should be declared "
5601 "as regular options rather than site-local options, "
5602 "or migrated up past 224.",
5603 u
->name
, site_code_min
);
5607 * don't even bother logging, this is just silly, and never worked
5608 * on any old version of software.
5610 if (site_code_min
< 128)
5611 site_code_min
= 128;
5614 * Cache the determined minimum site code on the universe structure.
5615 * Note that due to the < 128 check above, a value of zero is
5618 u
->site_code_min
= site_code_min
;
5620 return site_code_min
;
5624 lowest_site_code(const void *key
, unsigned len
, void *object
)
5626 struct option
*option
= object
;
5628 if (option
->code
< site_code_min
)
5629 site_code_min
= option
->code
;
5631 return ISC_R_SUCCESS
;
5635 maybe_return_agent_options(struct packet
*packet
, struct option_state
*options
)
5637 /* If there were agent options in the incoming packet, return
5638 * them. Do not return the agent options if they were stashed
5639 * on the lease. We do not check giaddr to detect the presence of
5640 * a relay, as this excludes "l2" relay agents which have no giaddr
5643 * XXX: If the user configures options for the relay agent information
5644 * (state->options->universes[agent_universe.index] is not NULL),
5645 * we're still required to duplicate other values provided by the
5646 * relay agent. So we need to merge the old values not configured
5647 * by the user into the new state, not just give up.
5649 if (!packet
->agent_options_stashed
&&
5650 (packet
->options
!= NULL
) &&
5651 packet
->options
->universe_count
> agent_universe
.index
&&
5652 packet
->options
->universes
[agent_universe
.index
] != NULL
&&
5653 (options
->universe_count
<= agent_universe
.index
||
5654 options
->universes
[agent_universe
.index
] == NULL
)) {
5655 option_chain_head_reference
5656 ((struct option_chain_head
**)
5657 &(options
->universes
[agent_universe
.index
]),
5658 (struct option_chain_head
*)
5659 packet
->options
->universes
[agent_universe
.index
], MDL
);
5661 if (options
->universe_count
<= agent_universe
.index
)
5662 options
->universe_count
= agent_universe
.index
+ 1;
5667 * \brief Adds hostname option when use-host-decl-names is enabled.
5669 * Constructs a hostname option from the name of the host declaration if
5670 * there is one and no hostname has otherwise been provided and the
5671 * use-host-decl-names flag is set, then adds the new option to the given
5672 * option_state. This funciton is used for both bootp and dhcp.
5674 * \param packet inbound packet received from the client
5675 * \param lease lease associated with the client
5676 * \param options option state to search and update
5678 void use_host_decl_name(struct packet
* packet
,
5679 struct lease
*lease
,
5680 struct option_state
*options
) {
5681 unsigned int ocode
= SV_USE_HOST_DECL_NAMES
;
5682 if ((lease
->host
&& lease
->host
->name
) &&
5683 !lookup_option(&dhcp_universe
, options
, DHO_HOST_NAME
) &&
5684 (evaluate_boolean_option_cache(NULL
, packet
, lease
, NULL
,
5685 packet
->options
, options
,
5687 lookup_option(&server_universe
,
5690 struct option_cache
*oc
= NULL
;
5691 if (option_cache_allocate (&oc
, MDL
)) {
5692 if (make_const_data(&oc
-> expression
,
5693 ((unsigned char*)lease
->host
->name
),
5694 strlen(lease
->host
->name
),
5696 ocode
= DHO_HOST_NAME
;
5697 option_code_hash_lookup(&oc
->option
,
5698 dhcp_universe
.code_hash
,
5700 save_option(&dhcp_universe
, options
, oc
);
5702 option_cache_dereference(&oc
, MDL
);
5708 * \brief Checks and preps for lease resuse based on dhcp-cache-threshold
5710 * If dhcp-cache-threshold is enabled (i.e. greater than zero), this function
5711 * determines if the current lease is young enough to be reused. If the lease
5712 * can be resused the function returns 1, O if not. This function is called
5713 * by ack_lease when responding to both DISCOVERs and REQUESTS.
5715 * The current lease can be reused only if all of the following are true:
5716 * a. dhcp-cache-threshold is > 0
5717 * b. The current lease is active
5718 * c. The lease "age" is less than that allowed by the threshold
5719 * d. DNS updates are not being performed on the new lease.
5720 * e. Lease has not been otherwise disqualified for reuse (Ex: billing class
5721 * or hostname changed)
5722 * f. The host declaration has changed (either a new one was added
5723 * or an older one was found due to something like a change in the uid)
5724 * g. The UID or hardware address have changed.
5726 * Clients may renew leases using full DORA cycles or just RAs. This means
5727 * that reusability must be checked when acking both DISCOVERs and REQUESTs.
5728 * When a lease cannot be reused, ack_lease() calls supersede_lease() which
5729 * updates the lease start time (among other things). If this occurs on the
5730 * DISCOVER, then the lease will virtually always be seen as young enough to
5731 * reuse on the ensuing REQUEST and the lease updates will not get committed
5732 * to the lease file. The lease.cannot_reuse flag is used to handle this
5735 * \param packet inbound packet received from the client
5736 * \param new_lease candidate new lease to associate with the client
5737 * \param lease current lease associated with the client
5738 * \param lease_state lease state to search and update
5739 * \param offer type of DHCP response we're building
5740 * \param[out] same_client pointer to int, that will be set to 1 if
5741 * the two leases refer to the same client, 0 if not. Must NOT be null.
5743 * \return 1 if the lease can be reused.
5746 reuse_lease (struct packet
* packet
,
5747 struct lease
* new_lease
,
5748 struct lease
* lease
,
5749 struct lease_state
*state
,
5754 /* To even consider reuse all of the following must be true:
5755 * 1 - reuse hasn't already disqualified
5756 * 2 - current lease is active
5757 * 3 - DNS info hasn't changed
5758 * 4 - the host declaration hasn't changed
5759 * 5 - the uid hasn't changed
5760 * 6 - the hardware address hasn't changed */
5762 /* Check client equality separately so we can pass the result out. */
5764 (((lease
->host
== new_lease
->host
) &&
5765 (lease
->uid_len
== new_lease
->uid_len
) &&
5766 (memcmp(lease
->uid
, new_lease
->uid
, new_lease
->uid_len
) == 0) &&
5767 (lease
->hardware_addr
.hlen
== new_lease
->hardware_addr
.hlen
) &&
5768 (memcmp(&lease
->hardware_addr
.hbuf
[0],
5769 &new_lease
->hardware_addr
.hbuf
[0],
5770 lease
->hardware_addr
.hlen
) == 0)) ? 1 : 0);
5772 if ((lease
->cannot_reuse
== 0) &&
5773 (lease
->binding_state
== FTS_ACTIVE
) &&
5774 (new_lease
->ddns_cb
== NULL
) && *same_client
) {
5775 int thresh
= DEFAULT_CACHE_THRESHOLD
;
5776 struct option_cache
* oc
= NULL
;
5777 struct data_string d1
;
5779 /* Look up threshold value */
5780 memset(&d1
, 0, sizeof(struct data_string
));
5781 if ((oc
= lookup_option(&server_universe
, state
->options
,
5782 SV_CACHE_THRESHOLD
)) &&
5783 (evaluate_option_cache(&d1
, packet
, new_lease
, NULL
,
5784 packet
->options
, state
->options
,
5785 &new_lease
->scope
, oc
, MDL
))) {
5786 if (d1
.len
== 1 && (d1
.data
[0] < 100))
5787 thresh
= d1
.data
[0];
5789 data_string_forget(&d1
, MDL
);
5792 /* If threshold is enabled, check lease age */
5795 int lease_length
= 0;
5798 /* Calculate limit in seconds */
5799 lease_length
= lease
->ends
- lease
->starts
;
5800 if (lease_length
<= (INT_MAX
/ thresh
))
5801 limit
= lease_length
* thresh
/ 100;
5803 limit
= lease_length
/ 100 * thresh
;
5805 /* Note new_lease->starts is really just cur_time */
5806 lease_age
= new_lease
->starts
- lease
->starts
;
5808 /* Is the lease young enough to reuse? */
5809 if (lease_age
<= limit
) {
5810 /* Restore expiry to its original value */
5811 state
->offered_expiry
= lease
->ends
;
5813 /* Restore bindings. This fixes 37368. */
5814 if (new_lease
->scope
!= NULL
) {
5815 if (lease
->scope
!= NULL
) {
5816 binding_scope_dereference(
5821 binding_scope_reference(&lease
->scope
,
5822 new_lease
->scope
, MDL
);
5825 /* restore client hostname, fixes 42849. */
5826 if (new_lease
->client_hostname
) {
5827 lease
->client_hostname
=
5828 new_lease
->client_hostname
;
5829 new_lease
->client_hostname
= NULL
;
5832 /* We're cleared to reuse it */
5833 log_debug("reuse_lease: lease age %ld (secs)"
5834 " under %d%% threshold, reply with "
5835 "unaltered, existing lease for %s",
5836 lease_age
, thresh
, piaddr(lease
->ip_addr
));
5843 /* If we can't reuse it and this is an offer disqualify reuse for
5844 * ensuing REQUEST, otherwise clear the flag. */
5845 lease
->cannot_reuse
= (!reusable
&& offer
== DHCPOFFER
);
5849 /* \brief Validates a proposed value for use as a lease time
5851 * Convenience function used for catching calculeated lease
5852 * times that overflow 4-byte times used in v4 protocol.
5854 * We use variables of type TIME in lots of places, which on
5855 * 64-bit systems is 8 bytes while on 32-bit OSs it is int32_t,
5856 * so we have all sorts of fun places to mess things up.
5857 * This function checks a calculated lease time for and if it
5858 * is unsuitable for use as a lease time, the given alternate
5859 * value is returned.
5863 * \returen either the calculated value if it is valid, or
5864 * the alternate value supplied
5866 TIME
leaseTimeCheck(TIME calculated
, TIME alternate
) {
5867 if ((sizeof(TIME
) > 4 && calculated
>= INFINITE_TIME
) ||
5868 (calculated
< cur_time
)) {
5872 return (calculated
);