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 * Redwood City, CA 94063
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
);
1199 memcpy(sip
.iabuf
, d1
.data
, 4);
1200 data_string_forget(&d1
, MDL
);
1202 /* Make a copy of the data. */
1203 if (option_cache_allocate(&noc
, MDL
)) {
1205 data_string_copy(&noc
->data
, &oc
->data
, MDL
);
1207 expression_reference(&noc
->expression
,
1208 oc
->expression
, MDL
);
1210 option_reference(&(noc
->option
), oc
->option
,
1213 save_option(&dhcp_universe
, options
, noc
);
1214 option_cache_dereference(&noc
, MDL
);
1216 if ((zeroed_ciaddr
== ISC_TRUE
) && (gip
.len
!= 0))
1217 addr_type
= "relay link select";
1219 addr_type
= "selected";
1222 find_subnet(&subnet
, sip
, MDL
);
1224 if (subnet
== NULL
) {
1225 log_info("%s: unknown subnet for %s address %s",
1226 msgbuf
, addr_type
, piaddr(sip
));
1227 option_state_dereference(&options
, MDL
);
1231 /* We don't respond to DHCPINFORM packets if we're not authoritative.
1232 It would be nice if a per-host value could override this, but
1233 there's overhead involved in checking this, so let's see how people
1235 if (!subnet
->group
->authoritative
) {
1237 log_info("%s: not authoritative for subnet %s",
1238 msgbuf
, piaddr (subnet
-> net
));
1240 log_info("If this DHCP server is authoritative for%s",
1242 log_info("please write an `authoritative;' directi%s",
1243 "ve either in the");
1244 log_info("subnet declaration or in some scope that%s",
1246 log_info("subnet declaration - for example, write %s",
1248 log_info("of the dhcpd.conf file.");
1252 subnet_dereference(&subnet
, MDL
);
1253 option_state_dereference(&options
, MDL
);
1257 memset(&outgoing
, 0, sizeof outgoing
);
1258 memset(&raw
, 0, sizeof raw
);
1259 outgoing
.raw
= &raw
;
1261 maybe_return_agent_options(packet
, options
);
1263 /* Execute statements network statements starting at the subnet level */
1264 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
1265 packet
->options
, options
,
1266 &global_scope
, subnet
->group
,
1269 /* If we have ciaddr, find its lease so we can find its pool. */
1270 if (zeroed_ciaddr
== ISC_FALSE
) {
1271 struct lease
* cip_lease
= NULL
;
1273 find_lease_by_ip_addr (&cip_lease
, cip
, MDL
);
1275 /* Overlay with pool options if ciaddr mapped to a lease. */
1277 if (cip_lease
->pool
&& cip_lease
->pool
->group
) {
1278 execute_statements_in_scope(
1279 NULL
, packet
, NULL
, NULL
,
1280 packet
->options
, options
,
1282 cip_lease
->pool
->group
,
1283 cip_lease
->pool
->shared_network
->group
,
1287 lease_dereference (&cip_lease
, MDL
);
1291 /* Execute statements in the class scopes. */
1292 for (i
= packet
->class_count
; i
> 0; i
--) {
1293 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
1294 packet
->options
, options
,
1296 packet
->classes
[i
- 1]->group
,
1302 * Process host declarations during DHCPINFORM,
1303 * Try to find a matching host declaration by cli ID or HW addr.
1305 * Look through the host decls for one that matches the
1306 * client identifer or the hardware address. The preference
1308 * client id with matching ip address
1309 * hardware address with matching ip address
1310 * client id without a ip fixed address
1311 * hardware address without a fixed ip address
1312 * If found, set host to use its option definitions.
1314 oc
= lookup_option(&dhcp_universe
, packet
->options
,
1315 DHO_DHCP_CLIENT_IDENTIFIER
);
1316 memset(&d1
, 0, sizeof(d1
));
1318 evaluate_option_cache(&d1
, packet
, NULL
, NULL
,
1319 packet
->options
, NULL
,
1320 &global_scope
, oc
, MDL
)) {
1321 find_hosts_by_uid(&hp
, d1
.data
, d1
.len
, MDL
);
1322 data_string_forget(&d1
, MDL
);
1324 #if defined (DEBUG_INFORM_HOST)
1326 log_debug ("dhcpinform: found host by ID "
1327 "-- checking fixed-address match");
1329 /* check if we have one with fixed-address
1330 * matching the client ip first */
1331 for (h
= hp
; !h_m_client_ip
&& h
; h
= h
->n_ipaddr
) {
1335 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
1336 if (!evaluate_option_cache (&fixed_addr
, NULL
,
1337 NULL
, NULL
, NULL
, NULL
,
1339 h
->fixed_addr
, MDL
))
1342 #if defined (DEBUG_INFORM_HOST)
1346 (i
+ cip
.len
) <= fixed_addr
.len
;
1348 if (memcmp(fixed_addr
.data
+ i
,
1349 cip
.iabuf
, cip
.len
) == 0) {
1350 #if defined (DEBUG_INFORM_HOST)
1351 log_debug ("dhcpinform: found "
1352 "host with matching "
1353 "fixed-address by ID");
1355 host_reference(&host
, h
, MDL
);
1360 data_string_forget(&fixed_addr
, MDL
);
1363 /* fallback to a host without fixed-address */
1364 for (h
= hp
; !host
&& h
; h
= h
->n_ipaddr
) {
1368 #if defined (DEBUG_INFORM_HOST)
1369 log_debug ("dhcpinform: found host "
1370 "without fixed-address by ID");
1372 host_reference(&host
, h
, MDL
);
1376 host_dereference (&hp
, MDL
);
1378 if (!host
|| !h_m_client_ip
) {
1379 find_hosts_by_haddr(&hp
, packet
->raw
->htype
,
1380 packet
->raw
->chaddr
,
1381 packet
->raw
->hlen
, MDL
);
1383 #if defined (DEBUG_INFORM_HOST)
1385 log_debug ("dhcpinform: found host by HW "
1386 "-- checking fixed-address match");
1389 /* check if we have one with fixed-address
1390 * matching the client ip first */
1391 for (h
= hp
; !h_m_client_ip
&& h
; h
= h
->n_ipaddr
) {
1395 memset (&fixed_addr
, 0, sizeof(fixed_addr
));
1396 if (!evaluate_option_cache (&fixed_addr
, NULL
,
1397 NULL
, NULL
, NULL
, NULL
,
1399 h
->fixed_addr
, MDL
))
1402 #if defined (DEBUG_INFORM_HOST)
1406 (i
+ cip
.len
) <= fixed_addr
.len
;
1408 if (memcmp(fixed_addr
.data
+ i
,
1409 cip
.iabuf
, cip
.len
) == 0) {
1410 #if defined (DEBUG_INFORM_HOST)
1411 log_debug ("dhcpinform: found "
1412 "host with matching "
1413 "fixed-address by HW");
1416 * Hmm.. we've found one
1417 * without IP by ID and now
1418 * (better) one with IP by HW.
1421 host_dereference(&host
, MDL
);
1422 host_reference(&host
, h
, MDL
);
1427 data_string_forget(&fixed_addr
, MDL
);
1429 /* fallback to a host without fixed-address */
1430 for (h
= hp
; !host
&& h
; h
= h
->n_ipaddr
) {
1434 #if defined (DEBUG_INFORM_HOST)
1435 log_debug ("dhcpinform: found host without "
1436 "fixed-address by HW");
1438 host_reference (&host
, h
, MDL
);
1443 host_dereference (&hp
, MDL
);
1446 #if defined (DEBUG_INFORM_HOST)
1447 /* Hmm..: what when there is a host with a fixed-address,
1448 * that matches by hw or id, but the fixed-addresses
1449 * didn't match client ip?
1451 if (h_w_fixed_addr
&& !h_m_client_ip
) {
1452 log_info ("dhcpinform: matching host with "
1453 "fixed-address different than "
1454 "client IP detected?!");
1458 /* If we have a host_decl structure, run the options
1459 * associated with its group. Whether the host decl
1460 * struct is old or not. */
1462 #if defined (DEBUG_INFORM_HOST)
1463 log_info ("dhcpinform: applying host (group) options");
1465 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
1466 packet
->options
, options
,
1467 &global_scope
, host
->group
,
1470 host_dereference (&host
, MDL
);
1473 /* CC: end of host entry processing.... */
1475 /* Figure out the filename. */
1476 memset (&d1
, 0, sizeof d1
);
1477 oc
= lookup_option (&server_universe
, options
, SV_FILENAME
);
1479 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1480 (struct client_state
*)0,
1481 packet
-> options
, (struct option_state
*)0,
1482 &global_scope
, oc
, MDL
)) {
1484 if (i
>= sizeof(raw
.file
)) {
1485 log_info("file name longer than packet field "
1486 "truncated - field: %lu name: %d %.*s",
1487 (unsigned long)sizeof(raw
.file
), i
,
1489 i
= sizeof(raw
.file
);
1492 memcpy (raw
.file
, d1
.data
, i
);
1493 data_string_forget (&d1
, MDL
);
1496 /* Choose a server name as above. */
1497 oc
= lookup_option (&server_universe
, options
, SV_SERVER_NAME
);
1499 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1500 (struct client_state
*)0,
1501 packet
-> options
, (struct option_state
*)0,
1502 &global_scope
, oc
, MDL
)) {
1504 if (i
>= sizeof(raw
.sname
)) {
1505 log_info("server name longer than packet field "
1506 "truncated - field: %lu name: %d %.*s",
1507 (unsigned long)sizeof(raw
.sname
), i
,
1509 i
= sizeof(raw
.sname
);
1512 memcpy (raw
.sname
, d1
.data
, i
);
1513 data_string_forget (&d1
, MDL
);
1516 /* Set a flag if this client is a lame Microsoft client that NUL
1517 terminates string options and expects us to do likewise. */
1519 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
1521 if (!oc
->expression
)
1522 nulltp
= oc
->flags
& OPTION_HAD_NULLS
;
1525 /* Put in DHCP-specific options. */
1526 i
= DHO_DHCP_MESSAGE_TYPE
;
1527 oc
= (struct option_cache
*)0;
1528 if (option_cache_allocate (&oc
, MDL
)) {
1529 if (make_const_data (&oc
-> expression
,
1530 &dhcpack
, 1, 0, 0, MDL
)) {
1531 option_code_hash_lookup(&oc
->option
,
1532 dhcp_universe
.code_hash
,
1534 save_option (&dhcp_universe
, options
, oc
);
1536 option_cache_dereference (&oc
, MDL
);
1539 get_server_source_address(&from
, options
, options
, packet
);
1541 /* Use the subnet mask from the subnet declaration if no other
1542 mask has been provided. */
1543 i
= DHO_SUBNET_MASK
;
1544 if (subnet
&& !lookup_option (&dhcp_universe
, options
, i
)) {
1545 oc
= (struct option_cache
*)0;
1546 if (option_cache_allocate (&oc
, MDL
)) {
1547 if (make_const_data (&oc
-> expression
,
1548 subnet
-> netmask
.iabuf
,
1549 subnet
-> netmask
.len
,
1551 option_code_hash_lookup(&oc
->option
,
1552 dhcp_universe
.code_hash
,
1554 save_option (&dhcp_universe
, options
, oc
);
1556 option_cache_dereference (&oc
, MDL
);
1560 /* If a site option space has been specified, use that for
1561 site option codes. */
1562 i
= SV_SITE_OPTION_SPACE
;
1563 if ((oc
= lookup_option (&server_universe
, options
, i
)) &&
1564 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1565 (struct client_state
*)0,
1566 packet
-> options
, options
,
1567 &global_scope
, oc
, MDL
)) {
1568 struct universe
*u
= (struct universe
*)0;
1570 if (!universe_hash_lookup (&u
, universe_hash
,
1571 (const char *)d1
.data
, d1
.len
,
1573 log_error ("unknown option space %s.", d1
.data
);
1574 option_state_dereference (&options
, MDL
);
1576 subnet_dereference (&subnet
, MDL
);
1580 options
-> site_universe
= u
-> index
;
1581 options
->site_code_min
= find_min_site_code(u
);
1582 data_string_forget (&d1
, MDL
);
1584 options
-> site_universe
= dhcp_universe
.index
;
1585 options
-> site_code_min
= 0; /* Trust me, it works. */
1588 memset (&prl
, 0, sizeof prl
);
1590 /* Use the parameter list from the scope if there is one. */
1591 oc
= lookup_option (&dhcp_universe
, options
,
1592 DHO_DHCP_PARAMETER_REQUEST_LIST
);
1594 /* Otherwise, if the client has provided a list of options
1595 that it wishes returned, use it to prioritize. Otherwise,
1596 prioritize based on the default priority list. */
1599 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
1600 DHO_DHCP_PARAMETER_REQUEST_LIST
);
1603 evaluate_option_cache (&prl
, packet
, (struct lease
*)0,
1604 (struct client_state
*)0,
1605 packet
-> options
, options
,
1606 &global_scope
, oc
, MDL
);
1609 dump_packet (packet
);
1610 dump_raw ((unsigned char *)packet
-> raw
, packet
-> packet_length
);
1613 log_info ("%s", msgbuf
);
1615 /* Figure out the address of the boot file server. */
1617 lookup_option (&server_universe
, options
, SV_NEXT_SERVER
))) {
1618 if (evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1619 (struct client_state
*)0,
1620 packet
-> options
, options
,
1621 &global_scope
, oc
, MDL
)) {
1622 /* If there was more than one answer,
1624 if (d1
.len
>= 4 && d1
.data
)
1625 memcpy (&raw
.siaddr
, d1
.data
, 4);
1626 data_string_forget (&d1
, MDL
);
1631 * Remove any time options, per section 3.4 RFC 2131
1633 delete_option(&dhcp_universe
, options
, DHO_DHCP_LEASE_TIME
);
1634 delete_option(&dhcp_universe
, options
, DHO_DHCP_RENEWAL_TIME
);
1635 delete_option(&dhcp_universe
, options
, DHO_DHCP_REBINDING_TIME
);
1637 /* Set up the option buffer... */
1638 outgoing
.packet_length
=
1639 cons_options (packet
, outgoing
.raw
, (struct lease
*)0,
1640 (struct client_state
*)0,
1641 0, packet
-> options
, options
, &global_scope
,
1643 prl
.len
? &prl
: (struct data_string
*)0,
1645 option_state_dereference (&options
, MDL
);
1646 data_string_forget (&prl
, MDL
);
1648 /* Make sure that the packet is at least as big as a BOOTP packet. */
1649 if (outgoing
.packet_length
< BOOTP_MIN_LEN
)
1650 outgoing
.packet_length
= BOOTP_MIN_LEN
;
1652 raw
.giaddr
= packet
-> raw
-> giaddr
;
1653 raw
.ciaddr
= packet
-> raw
-> ciaddr
;
1654 memcpy (raw
.chaddr
, packet
-> raw
-> chaddr
, sizeof raw
.chaddr
);
1655 raw
.hlen
= packet
-> raw
-> hlen
;
1656 raw
.htype
= packet
-> raw
-> htype
;
1658 raw
.xid
= packet
-> raw
-> xid
;
1659 raw
.secs
= packet
-> raw
-> secs
;
1660 raw
.flags
= packet
-> raw
-> flags
;
1661 raw
.hops
= packet
-> raw
-> hops
;
1665 dump_packet (&outgoing
);
1666 dump_raw ((unsigned char *)&raw
, outgoing
.packet_length
);
1669 #if defined(DHCPv6) && defined(DHCP4o6)
1670 if (dhcpv4_over_dhcpv6
&& (packet
->dhcp4o6_response
!= NULL
)) {
1671 /* Report what we're sending. */
1672 snprintf(msgbuf
, sizeof msgbuf
,
1673 "DHCP4o6 DHCPACK to %s (%s) via", piaddr(cip
),
1674 (packet
->raw
->htype
&& packet
->raw
->hlen
) ?
1675 print_hw_addr(packet
->raw
->htype
, packet
->raw
->hlen
,
1676 packet
->raw
->chaddr
) :
1677 "<no client hardware address>");
1678 log_info("%s %s", msgbuf
, piaddr(packet
->client_addr
));
1680 /* fill dhcp4o6_response */
1681 packet
->dhcp4o6_response
->len
= outgoing
.packet_length
;
1682 packet
->dhcp4o6_response
->buffer
= NULL
;
1683 if (!buffer_allocate(&packet
->dhcp4o6_response
->buffer
,
1684 outgoing
.packet_length
, MDL
)) {
1685 log_fatal("No memory to store DHCP4o6 reply.");
1687 packet
->dhcp4o6_response
->data
=
1688 packet
->dhcp4o6_response
->buffer
->data
;
1689 memcpy(packet
->dhcp4o6_response
->buffer
->data
,
1690 outgoing
.raw
, outgoing
.packet_length
);
1694 subnet_dereference (&subnet
, MDL
);
1699 /* Set up the common stuff... */
1700 to
.sin_family
= AF_INET
;
1702 to
.sin_len
= sizeof to
;
1704 memset (to
.sin_zero
, 0, sizeof to
.sin_zero
);
1706 /* RFC2131 states the server SHOULD unicast to ciaddr.
1707 * There are two wrinkles - relays, and when ciaddr is zero.
1708 * There's actually no mention of relays at all in rfc2131 in
1709 * regard to DHCPINFORM, except to say we might get packets from
1710 * clients via them. Note: relays unicast to clients to the
1711 * "yiaddr" address, which servers are forbidden to set when
1712 * answering an inform.
1714 * The solution: If ciaddr is zero, and giaddr is set, go via the
1715 * relay with the broadcast flag set to help the relay (with no
1716 * yiaddr and very likely no chaddr, it will have no idea where to
1719 * If the ciaddr is zero and giaddr is not set, go via the source
1720 * IP address (but you are permitted to barf on their shoes).
1722 * If ciaddr is not zero, send the packet there always.
1724 if (!raw
.ciaddr
.s_addr
&& gip
.len
) {
1725 memcpy(&to
.sin_addr
, gip
.iabuf
, 4);
1726 #if defined(RELAY_PORT)
1727 to
.sin_port
= relay_port
? relay_port
: local_port
;
1729 to
.sin_port
= local_port
;
1731 raw
.flags
|= htons(BOOTP_BROADCAST
);
1734 memcpy(&to
.sin_addr
, cip
.iabuf
, 4);
1735 to
.sin_port
= remote_port
;
1738 /* Report what we're sending. */
1739 snprintf(msgbuf
, sizeof msgbuf
, "DHCPACK to %s (%s) via", piaddr(cip
),
1740 (packet
->raw
->htype
&& packet
->raw
->hlen
) ?
1741 print_hw_addr(packet
->raw
->htype
, packet
->raw
->hlen
,
1742 packet
->raw
->chaddr
) :
1743 "<no client hardware address>");
1744 log_info("%s %s", msgbuf
, gip
.len
? piaddr(gip
) :
1745 packet
->interface
->name
);
1748 interface
= (fallback_interface
? fallback_interface
1749 : packet
-> interface
);
1750 result
= send_packet(interface
, &outgoing
, &raw
,
1751 outgoing
.packet_length
, from
, &to
, NULL
);
1753 log_error ("%s:%d: Failed to send %d byte long packet over %s "
1754 "interface.", MDL
, outgoing
.packet_length
,
1760 subnet_dereference (&subnet
, MDL
);
1764 * \brief Constructs and sends a DHCP Nak
1766 * In order to populate options such as dhcp-server-id and
1767 * dhcp-client-identifier, the function creates a temporary option cache
1768 * and evaluates options based on the packet's shared-network or the
1769 * network_group in its absence, as well as the packet->clasess (if any).
1771 * \param packet inbound packet received from the client
1772 * \param cip address requested by the client
1773 * \param network_group optional scope for use in setting up options
1775 void nak_lease (packet
, cip
, network_group
)
1776 struct packet
*packet
;
1778 struct group
*network_group
; /* scope to use for options */
1780 struct sockaddr_in to
;
1781 struct in_addr from
;
1783 struct dhcp_packet raw
;
1784 unsigned char nak
= DHCPNAK
;
1785 struct packet outgoing
;
1787 #if defined(RELAY_PORT)
1788 u_int16_t relay_port
= 0;
1790 struct option_state
*options
= (struct option_state
*)0;
1791 struct option_cache
*oc
= (struct option_cache
*)0;
1792 struct option_state
*eval_options
= NULL
;
1794 option_state_allocate (&options
, MDL
);
1795 memset (&outgoing
, 0, sizeof outgoing
);
1796 memset (&raw
, 0, sizeof raw
);
1797 outgoing
.raw
= &raw
;
1799 /* Set DHCP_MESSAGE_TYPE to DHCPNAK */
1800 if (!option_cache_allocate (&oc
, MDL
)) {
1801 log_error ("No memory for DHCPNAK message type.");
1802 option_state_dereference (&options
, MDL
);
1805 if (!make_const_data (&oc
-> expression
, &nak
, sizeof nak
,
1807 log_error ("No memory for expr_const expression.");
1808 option_cache_dereference (&oc
, MDL
);
1809 option_state_dereference (&options
, MDL
);
1812 i
= DHO_DHCP_MESSAGE_TYPE
;
1813 option_code_hash_lookup(&oc
->option
, dhcp_universe
.code_hash
,
1815 save_option (&dhcp_universe
, options
, oc
);
1816 option_cache_dereference (&oc
, MDL
);
1818 #if defined(RELAY_PORT)
1819 relay_port
= dhcp_check_relayport(packet
);
1822 /* Set DHCP_MESSAGE to whatever the message is */
1823 if (!option_cache_allocate (&oc
, MDL
)) {
1824 log_error ("No memory for DHCPNAK message type.");
1825 option_state_dereference (&options
, MDL
);
1828 if (!make_const_data (&oc
-> expression
,
1829 (unsigned char *)dhcp_message
,
1830 strlen (dhcp_message
), 1, 0, MDL
)) {
1831 log_error ("No memory for expr_const expression.");
1832 option_cache_dereference (&oc
, MDL
);
1833 option_state_dereference (&options
, MDL
);
1836 i
= DHO_DHCP_MESSAGE
;
1837 option_code_hash_lookup(&oc
->option
, dhcp_universe
.code_hash
,
1839 save_option (&dhcp_universe
, options
, oc
);
1840 option_cache_dereference (&oc
, MDL
);
1842 /* Setup the options at the global and subnet scopes. These
1843 * may be used to locate sever id option if enabled as well
1844 * for echo-client-id further on. (This allocates eval_options). */
1845 eval_network_statements(&eval_options
, packet
, network_group
);
1847 #if defined(SERVER_ID_FOR_NAK)
1848 /* Pass in the evaluated options so they can be searched for
1849 * server-id, otherwise source address comes from the interface
1851 get_server_source_address(&from
, eval_options
, options
, packet
);
1853 /* Get server source address from the interface address */
1854 get_server_source_address(&from
, NULL
, options
, packet
);
1855 #endif /* if defined(SERVER_ID_FOR_NAK) */
1857 /* If there were agent options in the incoming packet, return
1858 * them. We do not check giaddr to detect the presence of a
1859 * relay, as this excludes "l2" relay agents which have no
1862 if (packet
->options
->universe_count
> agent_universe
.index
&&
1863 packet
->options
->universes
[agent_universe
.index
]) {
1864 option_chain_head_reference
1865 ((struct option_chain_head
**)
1866 &(options
-> universes
[agent_universe
.index
]),
1867 (struct option_chain_head
*)
1868 packet
-> options
-> universes
[agent_universe
.index
],
1872 /* echo-client-id can specified at the class level so add class-scoped
1873 * options into eval_options. */
1874 for (i
= packet
->class_count
; i
> 0; i
--) {
1875 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
1876 packet
->options
, eval_options
,
1878 packet
->classes
[i
- 1]->group
,
1882 /* Echo client id if we received and it's enabled */
1883 echo_client_id(packet
, NULL
, eval_options
, options
);
1884 option_state_dereference (&eval_options
, MDL
);
1886 /* Do not use the client's requested parameter list. */
1887 delete_option (&dhcp_universe
, packet
-> options
,
1888 DHO_DHCP_PARAMETER_REQUEST_LIST
);
1890 /* Set up the option buffer... */
1891 outgoing
.packet_length
=
1892 cons_options (packet
, outgoing
.raw
, (struct lease
*)0,
1893 (struct client_state
*)0,
1894 0, packet
-> options
, options
, &global_scope
,
1895 0, 0, 0, (struct data_string
*)0, (char *)0);
1896 option_state_dereference (&options
, MDL
);
1898 /* memset (&raw.ciaddr, 0, sizeof raw.ciaddr);*/
1899 raw
.giaddr
= packet
-> raw
-> giaddr
;
1900 memcpy (raw
.chaddr
, packet
-> raw
-> chaddr
, sizeof raw
.chaddr
);
1901 raw
.hlen
= packet
-> raw
-> hlen
;
1902 raw
.htype
= packet
-> raw
-> htype
;
1904 raw
.xid
= packet
-> raw
-> xid
;
1905 raw
.secs
= packet
-> raw
-> secs
;
1906 raw
.flags
= packet
-> raw
-> flags
| htons (BOOTP_BROADCAST
);
1907 raw
.hops
= packet
-> raw
-> hops
;
1910 /* Make sure that the packet is at least as big as a BOOTP packet. */
1911 if (outgoing
.packet_length
< BOOTP_MIN_LEN
)
1912 outgoing
.packet_length
= BOOTP_MIN_LEN
;
1914 /* Report what we're sending... */
1915 #if defined(DHCPv6) && defined(DHCP4o6)
1916 if (dhcpv4_over_dhcpv6
&& (packet
->dhcp4o6_response
!= NULL
)) {
1917 log_info ("DHCP4o6 DHCPNAK on %s to %s via %s",
1919 print_hw_addr (packet
-> raw
-> htype
,
1920 packet
-> raw
-> hlen
,
1921 packet
-> raw
-> chaddr
),
1922 piaddr(packet
->client_addr
));
1925 log_info ("DHCPNAK on %s to %s via %s",
1927 print_hw_addr (packet
-> raw
-> htype
,
1928 packet
-> raw
-> hlen
,
1929 packet
-> raw
-> chaddr
),
1930 packet
-> raw
-> giaddr
.s_addr
1931 ? inet_ntoa (packet
-> raw
-> giaddr
)
1932 : packet
-> interface
-> name
);
1935 dump_packet (packet
);
1936 dump_raw ((unsigned char *)packet
-> raw
, packet
-> packet_length
);
1937 dump_packet (&outgoing
);
1938 dump_raw ((unsigned char *)&raw
, outgoing
.packet_length
);
1941 #if defined(DHCPv6) && defined(DHCP4o6)
1942 if (dhcpv4_over_dhcpv6
&& (packet
->dhcp4o6_response
!= NULL
)) {
1943 /* fill dhcp4o6_response */
1944 packet
->dhcp4o6_response
->len
= outgoing
.packet_length
;
1945 packet
->dhcp4o6_response
->buffer
= NULL
;
1946 if (!buffer_allocate(&packet
->dhcp4o6_response
->buffer
,
1947 outgoing
.packet_length
, MDL
)) {
1948 log_fatal("No memory to store DHCP4o6 reply.");
1950 packet
->dhcp4o6_response
->data
=
1951 packet
->dhcp4o6_response
->buffer
->data
;
1952 memcpy(packet
->dhcp4o6_response
->buffer
->data
,
1953 outgoing
.raw
, outgoing
.packet_length
);
1958 /* Set up the common stuff... */
1959 to
.sin_family
= AF_INET
;
1961 to
.sin_len
= sizeof to
;
1963 memset (to
.sin_zero
, 0, sizeof to
.sin_zero
);
1965 /* If this was gatewayed, send it back to the gateway.
1966 Otherwise, broadcast it on the local network. */
1967 if (raw
.giaddr
.s_addr
) {
1968 to
.sin_addr
= raw
.giaddr
;
1969 if (raw
.giaddr
.s_addr
!= htonl (INADDR_LOOPBACK
))
1970 #if defined(RELAY_PORT)
1971 to
.sin_port
= relay_port
? relay_port
: local_port
;
1973 to
.sin_port
= local_port
;
1976 to
.sin_port
= remote_port
; /* for testing. */
1978 if (fallback_interface
) {
1979 result
= send_packet(fallback_interface
, packet
, &raw
,
1980 outgoing
.packet_length
, from
, &to
,
1983 log_error ("%s:%d: Failed to send %d byte long "
1984 "packet over %s interface.", MDL
,
1985 outgoing
.packet_length
,
1986 fallback_interface
->name
);
1992 to
.sin_addr
= limited_broadcast
;
1993 to
.sin_port
= remote_port
;
1997 result
= send_packet(packet
->interface
, packet
, &raw
,
1998 outgoing
.packet_length
, from
, &to
, NULL
);
2000 log_error ("%s:%d: Failed to send %d byte long packet over %s "
2001 "interface.", MDL
, outgoing
.packet_length
,
2002 packet
->interface
->name
);
2008 * \brief Adds a dhcp-client-id option to a set of options
2009 * Given a set of input options, it searches for echo-client-id. If it is
2010 * defined and enabled, the given packet is searched for dhcp-client-id. If
2011 * the option is found it is replicated into the given set of output options.
2012 * This allows us to provide compliance with RFC 6842. It is called when we ack
2013 * or nak a lease. In the latter case we may or may not have created the
2014 * requisite scope to lookup echo-client-id.
2016 * Note the flag packet.sv_echo_client_id is set to reflect the configuration
2017 * option. This bypases inaccessiblity of server_universe in cons_options()
2018 * which must amend the PRL (when not empty) if echoing is enabled.
2020 * \param packet inbound packet received from the client
2021 * \param lease lease associated with this client (if one)
2022 * \param in_options options in which to search for echo-client-id
2023 * \param out_options options to which to save the client-id
2025 void echo_client_id(packet
, lease
, in_options
, out_options
)
2026 struct packet
*packet
;
2027 struct lease
*lease
;
2028 struct option_state
*in_options
;
2029 struct option_state
*out_options
;
2031 struct option_cache
*oc
;
2034 /* Check if echo-client-id is enabled */
2035 oc
= lookup_option(&server_universe
, in_options
, SV_ECHO_CLIENT_ID
);
2036 if (oc
&& evaluate_boolean_option_cache(&ignorep
, packet
, lease
,
2037 NULL
, packet
->options
,
2039 (lease
? &lease
->scope
: NULL
),
2041 struct data_string client_id
;
2042 unsigned int opcode
= DHO_DHCP_CLIENT_IDENTIFIER
;
2044 /* Save knowledge that echo is enabled to the packet */
2045 packet
->sv_echo_client_id
= ISC_TRUE
;
2047 /* Now see if inbound packet contains client-id */
2048 oc
= lookup_option(&dhcp_universe
, packet
->options
, opcode
);
2049 memset(&client_id
, 0, sizeof client_id
);
2050 if (oc
&& evaluate_option_cache(&client_id
,
2052 packet
->options
, NULL
,
2053 (lease
? &lease
->scope
: NULL
),
2055 /* Packet contained client-id, add it to out_options. */
2057 if (option_cache_allocate(&oc
, MDL
)) {
2058 if (make_const_data(&oc
->expression
,
2062 option_code_hash_lookup(&oc
->option
,
2067 save_option(&dhcp_universe
,
2070 option_cache_dereference(&oc
, MDL
);
2076 void check_pool_threshold (packet
, lease
, state
)
2077 struct packet
*packet
;
2078 struct lease
*lease
;
2079 struct lease_state
*state
;
2083 struct pool
*pool
= lease
->pool
;
2084 int used
, count
, high_threshold
, poolhigh
= 0, poollow
= 0;
2085 char *shared_name
= "no name";
2090 /* get a pointer to the name if we have one */
2091 if ((pool
->shared_network
!= NULL
) &&
2092 (pool
->shared_network
->name
!= NULL
)) {
2093 shared_name
= pool
->shared_network
->name
;
2096 count
= pool
->lease_count
;
2097 used
= count
- (pool
->free_leases
+ pool
->backup_leases
);
2099 /* The logged flag indicates if we have already crossed the high
2100 * threshold and emitted a log message. If it is set we check to
2101 * see if we have re-crossed the low threshold and need to reset
2102 * things. When we cross the high threshold we determine what
2103 * the low threshold is and save it into the low_threshold value.
2104 * When we cross that threshold we reset the logged flag and
2105 * the low_threshold to 0 which allows the high threshold message
2106 * to be emitted once again.
2107 * if we haven't recrossed the boundry we don't need to do anything.
2109 if (pool
->logged
!=0) {
2110 if (used
<= pool
->low_threshold
) {
2111 pool
->low_threshold
= 0;
2113 log_error("Pool threshold reset - shared subnet: %s; "
2114 "address: %s; low threshold %d/%d.",
2115 shared_name
, piaddr(lease
->ip_addr
),
2121 /* find the high threshold */
2122 if (get_option_int(&poolhigh
, &server_universe
, packet
, lease
, NULL
,
2123 packet
->options
, state
->options
, state
->options
,
2124 &lease
->scope
, SV_LOG_THRESHOLD_HIGH
, MDL
) == 0) {
2125 /* no threshold bail out */
2129 /* We do have a threshold for this pool, see if its valid */
2130 if ((poolhigh
<= 0) || (poolhigh
> 100)) {
2135 /* we have a valid value, have we exceeded it */
2136 high_threshold
= FIND_PERCENT(count
, poolhigh
);
2137 if (used
< high_threshold
) {
2138 /* nope, no more to do */
2142 /* we've exceeded it, output a message */
2143 log_error("Pool threshold exceeded - shared subnet: %s; "
2144 "address: %s; high threshold %d%% %d/%d.",
2145 shared_name
, piaddr(lease
->ip_addr
),
2146 poolhigh
, used
, count
);
2148 /* handle the low threshold now, if we don't
2149 * have a valid one we default to 0. */
2150 if ((get_option_int(&poollow
, &server_universe
, packet
, lease
, NULL
,
2151 packet
->options
, state
->options
, state
->options
,
2152 &lease
->scope
, SV_LOG_THRESHOLD_LOW
, MDL
) == 0) ||
2158 * If the low theshold is higher than the high threshold we continue to log
2159 * If it isn't then we set the flag saying we already logged and determine
2160 * what the reset threshold is.
2162 if (poollow
< poolhigh
) {
2164 pool
->low_threshold
= FIND_PERCENT(count
, poollow
);
2168 void ack_lease (packet
, lease
, offer
, when
, msg
, ms_nulltp
, hp
)
2169 struct packet
*packet
;
2170 struct lease
*lease
;
2175 struct host_decl
*hp
;
2178 struct lease_state
*state
;
2180 struct host_decl
*host
= (struct host_decl
*)0;
2182 TIME offered_lease_time
;
2183 struct data_string d1
;
2184 TIME min_lease_time
;
2185 TIME max_lease_time
;
2186 TIME default_lease_time
;
2187 struct option_cache
*oc
;
2188 isc_result_t result
;
2190 struct in_addr from
;
2191 TIME remaining_time
;
2193 #if defined(DELAYED_ACK)
2194 /* By default we don't do the enqueue */
2195 isc_boolean_t enqueue
= ISC_FALSE
;
2197 int use_old_lease
= 0;
2198 int same_client
= 0;
2204 /* If we're already acking this lease, don't do it again. */
2208 /* Save original cltt for comparison later. */
2209 original_cltt
= lease
->cltt
;
2211 /* If the lease carries a host record, remember it. */
2213 host_reference (&host
, hp
, MDL
);
2214 else if (lease
-> host
)
2215 host_reference (&host
, lease
-> host
, MDL
);
2217 /* Allocate a lease state structure... */
2218 state
= new_lease_state (MDL
);
2220 log_fatal ("unable to allocate lease state!");
2221 state
-> got_requested_address
= packet
-> got_requested_address
;
2222 shared_network_reference (&state
-> shared_network
,
2223 packet
-> interface
-> shared_network
, MDL
);
2225 /* See if we got a server identifier option. */
2226 if (lookup_option (&dhcp_universe
,
2227 packet
-> options
, DHO_DHCP_SERVER_IDENTIFIER
))
2228 state
-> got_server_identifier
= 1;
2230 maybe_return_agent_options(packet
, state
->options
);
2232 /* If we are offering a lease that is still currently valid, preserve
2233 the events. We need to do this because if the client does not
2234 REQUEST our offer, it will expire in 2 minutes, overriding the
2235 expire time in the currently in force lease. We want the expire
2236 events to be executed at that point. */
2237 if (lease
->ends
<= cur_time
&& offer
!= DHCPOFFER
) {
2238 /* Get rid of any old expiry or release statements - by
2239 executing the statements below, we will be inserting new
2240 ones if there are any to insert. */
2241 if (lease
->on_star
.on_expiry
)
2242 executable_statement_dereference
2243 (&lease
->on_star
.on_expiry
, MDL
);
2244 if (lease
->on_star
.on_commit
)
2245 executable_statement_dereference
2246 (&lease
->on_star
.on_commit
, MDL
);
2247 if (lease
->on_star
.on_release
)
2248 executable_statement_dereference
2249 (&lease
->on_star
.on_release
, MDL
);
2252 /* Execute statements in scope starting with the subnet scope. */
2253 execute_statements_in_scope (NULL
, packet
, lease
,
2254 NULL
, packet
->options
,
2255 state
->options
, &lease
->scope
,
2256 lease
->subnet
->group
, NULL
, NULL
);
2258 /* If the lease is from a pool, run the pool scope. */
2260 (execute_statements_in_scope(NULL
, packet
, lease
, NULL
,
2261 packet
->options
, state
->options
,
2262 &lease
->scope
, lease
->pool
->group
,
2264 shared_network
->group
,
2267 /* Execute statements from class scopes. */
2268 for (i
= packet
-> class_count
; i
> 0; i
--) {
2269 execute_statements_in_scope(NULL
, packet
, lease
, NULL
,
2270 packet
->options
, state
->options
,
2272 packet
->classes
[i
- 1]->group
,
2273 (lease
->pool
? lease
->pool
->group
2274 : lease
->subnet
->group
),
2278 /* See if the client is only supposed to have one lease at a time,
2279 and if so, find its other leases and release them. We can only
2280 do this on DHCPREQUEST. It's a little weird to do this before
2281 looking at permissions, because the client might not actually
2282 _get_ a lease after we've done the permission check, but the
2283 assumption for this option is that the client has exactly one
2284 network interface, and will only ever remember one lease. So
2285 if it sends a DHCPREQUEST, and doesn't get the lease, it's already
2286 forgotten about its old lease, so we can too. */
2287 if (packet
-> packet_type
== DHCPREQUEST
&&
2288 (oc
= lookup_option (&server_universe
, state
-> options
,
2289 SV_ONE_LEASE_PER_CLIENT
)) &&
2290 evaluate_boolean_option_cache (&ignorep
,
2292 (struct client_state
*)0,
2294 state
-> options
, &lease
-> scope
,
2297 if (lease
-> uid_len
) {
2299 seek
= (struct lease
*)0;
2300 find_lease_by_uid (&seek
, lease
-> uid
,
2301 lease
-> uid_len
, MDL
);
2304 if (seek
== lease
&& !seek
-> n_uid
) {
2305 lease_dereference (&seek
, MDL
);
2308 next
= (struct lease
*)0;
2310 /* Don't release expired leases, and don't
2311 release the lease we're going to assign. */
2312 next
= (struct lease
*)0;
2315 lease_reference (&next
, seek
-> n_uid
, MDL
);
2316 if (seek
!= lease
&&
2317 seek
-> binding_state
!= FTS_RELEASED
&&
2318 seek
-> binding_state
!= FTS_EXPIRED
&&
2319 seek
-> binding_state
!= FTS_RESET
&&
2320 seek
-> binding_state
!= FTS_FREE
&&
2321 seek
-> binding_state
!= FTS_BACKUP
)
2323 lease_dereference (&seek
, MDL
);
2325 lease_reference (&seek
, next
, MDL
);
2326 lease_dereference (&next
, MDL
);
2330 lease_dereference (&next
, MDL
);
2332 release_lease (seek
, packet
);
2333 lease_dereference (&seek
, MDL
);
2338 if (!lease
-> uid_len
||
2340 !host
-> client_identifier
.len
&&
2341 (oc
= lookup_option (&server_universe
, state
-> options
,
2343 !evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
2344 (struct client_state
*)0,
2350 seek
= (struct lease
*)0;
2351 find_lease_by_hw_addr
2352 (&seek
, lease
-> hardware_addr
.hbuf
,
2353 lease
-> hardware_addr
.hlen
, MDL
);
2356 if (seek
== lease
&& !seek
-> n_hw
) {
2357 lease_dereference (&seek
, MDL
);
2360 next
= (struct lease
*)0;
2363 lease_reference (&next
, seek
-> n_hw
, MDL
);
2364 if (seek
!= lease
&&
2365 seek
-> binding_state
!= FTS_RELEASED
&&
2366 seek
-> binding_state
!= FTS_EXPIRED
&&
2367 seek
-> binding_state
!= FTS_RESET
&&
2368 seek
-> binding_state
!= FTS_FREE
&&
2369 seek
-> binding_state
!= FTS_BACKUP
)
2371 lease_dereference (&seek
, MDL
);
2373 lease_reference (&seek
, next
, MDL
);
2374 lease_dereference (&next
, MDL
);
2378 lease_dereference (&next
, MDL
);
2380 release_lease (seek
, packet
);
2381 lease_dereference (&seek
, MDL
);
2389 /* Make sure this packet satisfies the configured minimum
2390 number of seconds. */
2391 memset (&d1
, 0, sizeof d1
);
2392 if (offer
== DHCPOFFER
&&
2393 (oc
= lookup_option (&server_universe
, state
-> options
,
2395 if (evaluate_option_cache (&d1
, packet
, lease
,
2396 (struct client_state
*)0,
2397 packet
-> options
, state
-> options
,
2398 &lease
-> scope
, oc
, MDL
)) {
2400 ntohs (packet
-> raw
-> secs
) < d1
.data
[0]) {
2401 log_info("%s: configured min-secs value (%d) "
2402 "is greater than secs field (%d). "
2403 "message dropped.", msg
, d1
.data
[0],
2404 ntohs(packet
->raw
->secs
));
2405 data_string_forget (&d1
, MDL
);
2406 free_lease_state (state
, MDL
);
2408 host_dereference (&host
, MDL
);
2411 data_string_forget (&d1
, MDL
);
2415 /* Try to find a matching host declaration for this lease.
2418 struct host_decl
*hp
= (struct host_decl
*)0;
2419 struct host_decl
*h
;
2421 /* Try to find a host_decl that matches the client
2422 identifier or hardware address on the packet, and
2423 has no fixed IP address. If there is one, hang
2424 it off the lease so that its option definitions
2426 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
2427 DHO_DHCP_CLIENT_IDENTIFIER
);
2429 evaluate_option_cache (&d1
, packet
, lease
,
2430 (struct client_state
*)0,
2431 packet
-> options
, state
-> options
,
2432 &lease
-> scope
, oc
, MDL
)) {
2433 find_hosts_by_uid (&hp
, d1
.data
, d1
.len
, MDL
);
2434 data_string_forget (&d1
, MDL
);
2435 for (h
= hp
; h
; h
= h
-> n_ipaddr
) {
2436 if (!h
-> fixed_addr
)
2440 host_reference (&host
, h
, MDL
);
2442 host_dereference(&hp
, MDL
);
2445 find_hosts_by_haddr (&hp
,
2446 packet
-> raw
-> htype
,
2447 packet
-> raw
-> chaddr
,
2448 packet
-> raw
-> hlen
,
2450 for (h
= hp
; h
; h
= h
-> n_ipaddr
) {
2451 if (!h
-> fixed_addr
)
2455 host_reference (&host
, h
, MDL
);
2457 host_dereference(&hp
, MDL
);
2460 find_hosts_by_option(&hp
, packet
,
2461 packet
->options
, MDL
);
2462 for (h
= hp
; h
; h
= h
-> n_ipaddr
) {
2463 if (!h
-> fixed_addr
)
2467 host_reference (&host
, h
, MDL
);
2469 host_dereference(&hp
, MDL
);
2473 /* If we have a host_decl structure, run the options associated
2474 with its group. Whether the host decl struct is old or not. */
2476 execute_statements_in_scope (NULL
, packet
, lease
, NULL
,
2477 packet
->options
, state
->options
,
2478 &lease
->scope
, host
->group
,
2480 ? lease
->pool
->group
2481 : lease
->subnet
->group
),
2484 /* Drop the request if it's not allowed for this client. By
2485 default, unknown clients are allowed. */
2487 (oc
= lookup_option (&server_universe
, state
-> options
,
2488 SV_BOOT_UNKNOWN_CLIENTS
)) &&
2489 !evaluate_boolean_option_cache (&ignorep
,
2491 (struct client_state
*)0,
2494 &lease
-> scope
, oc
, MDL
)) {
2496 log_info ("%s: unknown client", msg
);
2497 free_lease_state (state
, MDL
);
2499 host_dereference (&host
, MDL
);
2503 /* Drop the request if it's not allowed for this client. */
2505 (oc
= lookup_option (&server_universe
, state
-> options
,
2507 !evaluate_boolean_option_cache (&ignorep
,
2509 (struct client_state
*)0,
2512 &lease
-> scope
, oc
, MDL
)) {
2514 log_info ("%s: bootp disallowed", msg
);
2515 free_lease_state (state
, MDL
);
2517 host_dereference (&host
, MDL
);
2521 /* Drop the request if booting is specifically denied. */
2522 oc
= lookup_option (&server_universe
, state
-> options
,
2525 !evaluate_boolean_option_cache (&ignorep
,
2527 (struct client_state
*)0,
2530 &lease
-> scope
, oc
, MDL
)) {
2532 log_info ("%s: booting disallowed", msg
);
2533 free_lease_state (state
, MDL
);
2535 host_dereference (&host
, MDL
);
2539 /* If we are configured to do per-class billing, do it. */
2540 if (have_billing_classes
&& !(lease
-> flags
& STATIC_LEASE
)) {
2541 /* See if the lease is currently being billed to a
2542 class, and if so, whether or not it can continue to
2543 be billed to that class. */
2544 if (lease
-> billing_class
) {
2545 for (i
= 0; i
< packet
-> class_count
; i
++)
2546 if (packet
-> classes
[i
] ==
2547 lease
-> billing_class
)
2549 if (i
== packet
-> class_count
) {
2550 unbill_class(lease
);
2551 /* Active lease billing change negates reuse */
2552 if (lease
->binding_state
== FTS_ACTIVE
) {
2553 lease
->cannot_reuse
= 1;
2558 /* If we don't have an active billing, see if we need
2559 one, and if we do, try to do so. */
2560 if (lease
->billing_class
== NULL
) {
2564 for (i
= 0; i
< packet
->class_count
; i
++) {
2565 struct class *billclass
, *subclass
;
2567 billclass
= packet
->classes
[i
];
2568 if (billclass
->lease_limit
) {
2570 if (bill_class(lease
, billclass
))
2573 subclass
= billclass
->superclass
;
2574 if (subclass
== NULL
)
2575 cname
= subclass
->name
;
2577 cname
= billclass
->name
;
2580 if (bill
!= 0 && i
== packet
->class_count
) {
2581 log_info("%s: no available billing: lease "
2582 "limit reached in all matching "
2583 "classes (last: '%s')", msg
, cname
);
2584 free_lease_state(state
, MDL
);
2586 host_dereference(&host
, MDL
);
2591 * If this is an offer, undo the billing. We go
2592 * through all the steps above to bill a class so
2593 * we can hit the 'no available billing' mark and
2594 * abort without offering. But it just doesn't make
2595 * sense to permanently bill a class for a non-active
2596 * lease. This means on REQUEST, we will bill this
2597 * lease again (if there is a REQUEST).
2599 if (offer
== DHCPOFFER
&&
2600 lease
->billing_class
!= NULL
&&
2601 lease
->binding_state
!= FTS_ACTIVE
)
2602 unbill_class(lease
);
2604 /* Lease billing change negates reuse */
2605 if (lease
->billing_class
!= NULL
) {
2606 lease
->cannot_reuse
= 1;
2611 /* Figure out the filename. */
2612 oc
= lookup_option (&server_universe
, state
-> options
, SV_FILENAME
);
2614 evaluate_option_cache (&state
-> filename
, packet
, lease
,
2615 (struct client_state
*)0,
2616 packet
-> options
, state
-> options
,
2617 &lease
-> scope
, oc
, MDL
);
2619 /* Choose a server name as above. */
2620 oc
= lookup_option (&server_universe
, state
-> options
,
2623 evaluate_option_cache (&state
-> server_name
, packet
, lease
,
2624 (struct client_state
*)0,
2625 packet
-> options
, state
-> options
,
2626 &lease
-> scope
, oc
, MDL
);
2628 /* At this point, we have a lease that we can offer the client.
2629 Now we construct a lease structure that contains what we want,
2630 and call supersede_lease to do the right thing with it. */
2631 lt
= (struct lease
*)0;
2632 result
= lease_allocate (<
, MDL
);
2633 if (result
!= ISC_R_SUCCESS
) {
2634 log_info ("%s: can't allocate temporary lease structure: %s",
2635 msg
, isc_result_totext (result
));
2636 free_lease_state (state
, MDL
);
2638 host_dereference (&host
, MDL
);
2642 /* Use the ip address of the lease that we finally found in
2644 lt
-> ip_addr
= lease
-> ip_addr
;
2647 lt
-> starts
= cur_time
;
2649 /* Figure out how long a lease to assign. If this is a
2650 dynamic BOOTP lease, its duration must be infinite. */
2652 lt
->flags
&= ~BOOTP_LEASE
;
2654 default_lease_time
= DEFAULT_DEFAULT_LEASE_TIME
;
2655 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2656 SV_DEFAULT_LEASE_TIME
))) {
2657 if (evaluate_option_cache (&d1
, packet
, lease
,
2658 (struct client_state
*)0,
2661 &lease
-> scope
, oc
, MDL
)) {
2662 if (d1
.len
== sizeof (u_int32_t
))
2663 default_lease_time
=
2665 data_string_forget (&d1
, MDL
);
2669 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
2670 DHO_DHCP_LEASE_TIME
)))
2671 s1
= evaluate_option_cache (&d1
, packet
, lease
,
2672 (struct client_state
*)0,
2675 &lease
-> scope
, oc
, MDL
);
2679 if (s1
&& (d1
.len
== 4)) {
2680 u_int32_t ones
= 0xffffffff;
2682 /* One potential use of reserved leases is to allow
2683 * clients to signal reservation of their lease. They
2684 * can kinda sorta do this, if you squint hard enough,
2685 * by supplying an 'infinite' requested-lease-time
2686 * option. This is generally bad practice...you want
2687 * clients to return to the server on at least some
2688 * period (days, months, years) to get up-to-date
2691 * 1) A client requests 0xffffffff lease-time.
2692 * 2) The server reserves the lease, and assigns a
2693 * <= max_lease_time lease-time to the client, which
2694 * we presume is much smaller than 0xffffffff.
2695 * 3) The client ultimately fails to renew its lease
2696 * (all clients go offline at some point).
2697 * 4) The server retains the reservation, although
2698 * the lease expires and passes through those states
2699 * as normal, it's placed in the 'reserved' queue,
2700 * and is under no circumstances allocated to any
2703 * Whether the client knows its reserving its lease or
2704 * not, this can be a handy tool for a sysadmin.
2706 if ((memcmp(d1
.data
, &ones
, 4) == 0) &&
2707 (oc
= lookup_option(&server_universe
,
2709 SV_RESERVE_INFINITE
)) &&
2710 evaluate_boolean_option_cache(&ignorep
, packet
,
2711 lease
, NULL
, packet
->options
,
2712 state
->options
, &lease
->scope
,
2714 lt
->flags
|= RESERVED_LEASE
;
2716 log_info("Infinite-leasetime "
2717 "reservation made on %s.",
2718 piaddr(lt
->ip_addr
));
2721 lease_time
= getULong (d1
.data
);
2723 lease_time
= default_lease_time
;
2726 data_string_forget(&d1
, MDL
);
2728 /* See if there's a maximum lease time. */
2729 max_lease_time
= DEFAULT_MAX_LEASE_TIME
;
2730 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2731 SV_MAX_LEASE_TIME
))) {
2732 if (evaluate_option_cache (&d1
, packet
, lease
,
2733 (struct client_state
*)0,
2736 &lease
-> scope
, oc
, MDL
)) {
2737 if (d1
.len
== sizeof (u_int32_t
))
2740 data_string_forget (&d1
, MDL
);
2744 /* Enforce the maximum lease length. */
2745 if (lease_time
< 0 /* XXX */
2746 || lease_time
> max_lease_time
)
2747 lease_time
= max_lease_time
;
2749 min_lease_time
= DEFAULT_MIN_LEASE_TIME
;
2750 if (min_lease_time
> max_lease_time
)
2751 min_lease_time
= max_lease_time
;
2753 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2754 SV_MIN_LEASE_TIME
))) {
2755 if (evaluate_option_cache (&d1
, packet
, lease
,
2756 (struct client_state
*)0,
2759 &lease
-> scope
, oc
, MDL
)) {
2760 if (d1
.len
== sizeof (u_int32_t
))
2761 min_lease_time
= getULong (d1
.data
);
2762 data_string_forget (&d1
, MDL
);
2766 /* CC: If there are less than
2767 adaptive-lease-time-threshold % free leases,
2768 hand out only short term leases */
2770 memset(&d1
, 0, sizeof(d1
));
2772 (oc
= lookup_option(&server_universe
, state
->options
,
2773 SV_ADAPTIVE_LEASE_TIME_THRESHOLD
)) &&
2774 evaluate_option_cache(&d1
, packet
, lease
, NULL
,
2775 packet
->options
, state
->options
,
2776 &lease
->scope
, oc
, MDL
)) {
2777 if (d1
.len
== 1 && d1
.data
[0] > 0 &&
2780 int poolfilled
, total
, count
;
2783 adaptive_time
= min_lease_time
;
2785 adaptive_time
= DEFAULT_MIN_LEASE_TIME
;
2787 /* Allow the client to keep its lease. */
2788 if (lease
->ends
- cur_time
> adaptive_time
)
2789 adaptive_time
= lease
->ends
- cur_time
;
2791 count
= lease
->pool
->lease_count
;
2792 total
= count
- (lease
->pool
->free_leases
+
2793 lease
->pool
->backup_leases
);
2795 poolfilled
= (total
> (INT_MAX
/ 100)) ?
2796 total
/ (count
/ 100) :
2797 (total
* 100) / count
;
2799 log_debug("Adap-lease: Total: %d, Free: %d, "
2800 "Ends: %d, Adaptive: %d, Fill: %d, "
2802 lease
->pool
->lease_count
,
2803 lease
->pool
->free_leases
,
2804 (int)(lease
->ends
- cur_time
),
2805 (int)adaptive_time
, poolfilled
,
2808 if (poolfilled
>= d1
.data
[0] &&
2809 lease_time
> adaptive_time
) {
2810 log_info("Pool over threshold, time "
2811 "for %s reduced from %d to "
2812 "%d.", piaddr(lease
->ip_addr
),
2814 (int)adaptive_time
);
2816 lease_time
= adaptive_time
;
2819 data_string_forget(&d1
, MDL
);
2824 * If this is an ack check to see if we have used enough of
2825 * the pool to want to log a message
2827 if (offer
== DHCPACK
)
2828 check_pool_threshold(packet
, lease
, state
);
2830 /* a client requests an address which is not yet active*/
2831 if (lease
->pool
&& lease
->pool
->valid_from
&&
2832 cur_time
< lease
->pool
->valid_from
) {
2833 /* NAK leases before pool activation date */
2835 memcpy (cip
.iabuf
, <
->ip_addr
.iabuf
, 4);
2836 nak_lease(packet
, &cip
, lease
->subnet
->group
);
2837 free_lease_state (state
, MDL
);
2838 lease_dereference (<
, MDL
);
2840 host_dereference (&host
, MDL
);
2846 a) NAK current lease if past the expiration date
2847 b) extend lease only up to the expiration date, but not
2848 below min-lease-time
2849 Setting min-lease-time is essential for this to work!
2850 The value of min-lease-time determines the length
2851 of the transition window:
2852 A client renewing a second before the deadline will
2853 get a min-lease-time lease. Since the current ip might not
2854 be routable after the deadline, the client will
2855 be offline until it DISCOVERS again. Otherwise it will
2856 receive a NAK at T/2.
2857 A min-lease-time of 6 seconds effectively switches over
2858 all clients in this pool very quickly.
2861 if (lease
->pool
&& lease
->pool
->valid_until
) {
2862 if (cur_time
>= lease
->pool
->valid_until
) {
2863 /* NAK leases after pool expiration date */
2865 memcpy (cip
.iabuf
, <
->ip_addr
.iabuf
, 4);
2866 nak_lease(packet
, &cip
, lease
->subnet
->group
);
2867 free_lease_state (state
, MDL
);
2868 lease_dereference (<
, MDL
);
2870 host_dereference (&host
, MDL
);
2873 remaining_time
= lease
->pool
->valid_until
- cur_time
;
2874 if (lease_time
> remaining_time
)
2875 lease_time
= remaining_time
;
2878 if (lease_time
< min_lease_time
) {
2880 lease_time
= min_lease_time
;
2882 lease_time
= default_lease_time
;
2886 #if defined (FAILOVER_PROTOCOL)
2887 /* Okay, we know the lease duration. Now check the
2888 failover state, if any. */
2889 if (lease
-> pool
&& lease
-> pool
-> failover_peer
) {
2890 TIME new_lease_time
= lease_time
;
2891 dhcp_failover_state_t
*peer
=
2892 lease
-> pool
-> failover_peer
;
2894 /* Copy previous lease failover ack-state. */
2895 lt
->tsfp
= lease
->tsfp
;
2896 lt
->atsfp
= lease
->atsfp
;
2898 /* cltt set below */
2900 /* Lease times less than MCLT are not a concern. */
2901 if (lease_time
> peer
->mclt
) {
2902 /* Each server can only offer a lease time
2903 * that is either equal to MCLT (at least),
2904 * or up to TSFP+MCLT. Only if the desired
2905 * lease time falls within TSFP+MCLT, can
2906 * the server allow it.
2908 if (lt
->tsfp
<= cur_time
)
2909 new_lease_time
= peer
->mclt
;
2910 else if ((cur_time
+ lease_time
) >
2911 (lt
->tsfp
+ peer
->mclt
))
2912 new_lease_time
= (lt
->tsfp
- cur_time
)
2916 /* Update potential expiry. Allow for the desired
2917 * lease time plus one half the actual (whether
2918 * modified downward or not) lease time, which is
2919 * actually an estimate of when the client will
2920 * renew. This way, the client will be able to get
2921 * the desired lease time upon renewal.
2923 if (offer
== DHCPACK
) {
2924 if (lease_time
== INFINITE_TIME
) {
2925 lt
->tstp
= MAX_TIME
;
2929 (cur_time
+ lease_time
2930 + (new_lease_time
/ 2)),
2934 /* If we reduced the potential expiry time,
2935 * make sure we don't offer an old-expiry-time
2936 * lease for this lease before the change is
2939 if (lt
->tstp
< lt
->tsfp
)
2940 lt
->tsfp
= lt
->tstp
;
2942 lt
->tstp
= lease
->tstp
;
2944 /* Use failover-modified lease time. */
2945 lease_time
= new_lease_time
;
2947 #endif /* FAILOVER_PROTOCOL */
2949 if (lease_time
== INFINITE_TIME
) {
2950 state
->offered_expiry
= MAX_TIME
;
2952 /* If the lease duration causes the time value to wrap,
2953 use the maximum expiry time. */
2954 state
->offered_expiry
2955 = leaseTimeCheck(cur_time
+ lease_time
,
2962 lt
-> ends
= state
-> offered_expiry
;
2964 /* Don't make lease active until we actually get a
2966 if (offer
== DHCPACK
)
2967 lt
-> next_binding_state
= FTS_ACTIVE
;
2969 lt
-> next_binding_state
= lease
-> binding_state
;
2971 lt
->flags
|= BOOTP_LEASE
;
2973 lease_time
= MAX_TIME
- cur_time
;
2975 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2976 SV_BOOTP_LEASE_LENGTH
))) {
2977 if (evaluate_option_cache (&d1
, packet
, lease
,
2978 (struct client_state
*)0,
2981 &lease
-> scope
, oc
, MDL
)) {
2982 if (d1
.len
== sizeof (u_int32_t
))
2983 lease_time
= getULong (d1
.data
);
2984 data_string_forget (&d1
, MDL
);
2988 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2989 SV_BOOTP_LEASE_CUTOFF
))) {
2990 if (evaluate_option_cache (&d1
, packet
, lease
,
2991 (struct client_state
*)0,
2994 &lease
-> scope
, oc
, MDL
)) {
2995 if (d1
.len
== sizeof (u_int32_t
))
2996 lease_time
= (getULong (d1
.data
) -
2998 data_string_forget (&d1
, MDL
);
3002 lt
-> ends
= state
-> offered_expiry
= cur_time
+ lease_time
;
3003 lt
-> next_binding_state
= FTS_ACTIVE
;
3006 /* Update Client Last Transaction Time. */
3007 lt
->cltt
= cur_time
;
3009 /* See if we want to record the uid for this client */
3010 oc
= lookup_option(&server_universe
, state
->options
,
3011 SV_IGNORE_CLIENT_UIDS
);
3013 !evaluate_boolean_option_cache(&ignorep
, packet
, lease
, NULL
,
3014 packet
->options
, state
->options
,
3015 &lease
->scope
, oc
, MDL
)) {
3017 /* Record the uid, if given... */
3018 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
3019 DHO_DHCP_CLIENT_IDENTIFIER
);
3021 evaluate_option_cache(&d1
, packet
, lease
, NULL
,
3022 packet
->options
, state
->options
,
3023 &lease
->scope
, oc
, MDL
)) {
3024 if (d1
.len
<= sizeof(lt
->uid_buf
)) {
3025 memcpy(lt
->uid_buf
, d1
.data
, d1
.len
);
3026 lt
->uid
= lt
->uid_buf
;
3027 lt
->uid_max
= sizeof(lt
->uid_buf
);
3028 lt
->uid_len
= d1
.len
;
3030 unsigned char *tuid
;
3031 lt
->uid_max
= d1
.len
;
3032 lt
->uid_len
= d1
.len
;
3033 tuid
= (unsigned char *)dmalloc(lt
->uid_max
,
3037 log_fatal ("no memory for large uid.");
3038 memcpy(tuid
, d1
.data
, lt
->uid_len
);
3041 data_string_forget (&d1
, MDL
);
3046 host_reference (<
-> host
, host
, MDL
);
3047 host_dereference (&host
, MDL
);
3049 if (lease
-> subnet
)
3050 subnet_reference (<
-> subnet
, lease
-> subnet
, MDL
);
3051 if (lease
-> billing_class
)
3052 class_reference (<
-> billing_class
,
3053 lease
-> billing_class
, MDL
);
3055 /* Set a flag if this client is a broken client that NUL
3056 terminates string options and expects us to do likewise. */
3058 lease
-> flags
|= MS_NULL_TERMINATION
;
3060 lease
-> flags
&= ~MS_NULL_TERMINATION
;
3062 /* Save any bindings. */
3063 if (lease
-> scope
) {
3064 binding_scope_reference (<
-> scope
, lease
-> scope
, MDL
);
3065 binding_scope_dereference (&lease
-> scope
, MDL
);
3067 if (lease
-> agent_options
)
3068 option_chain_head_reference (<
-> agent_options
,
3069 lease
-> agent_options
, MDL
);
3071 /* Save the vendor-class-identifier for DHCPLEASEQUERY. */
3072 oc
= lookup_option(&dhcp_universe
, packet
->options
,
3073 DHO_VENDOR_CLASS_IDENTIFIER
);
3075 evaluate_option_cache(&d1
, packet
, NULL
, NULL
, packet
->options
,
3076 NULL
, <
->scope
, oc
, MDL
)) {
3078 bind_ds_value(<
->scope
, "vendor-class-identifier",
3082 data_string_forget(&d1
, MDL
);
3085 /* If we got relay agent information options from the packet, then
3086 * cache them for renewal in case the relay agent can't supply them
3087 * when the client unicasts. The options may be from an addressed
3088 * "l3" relay, or from an unaddressed "l2" relay which does not set
3091 if (!packet
->agent_options_stashed
&&
3092 (packet
->options
!= NULL
) &&
3093 packet
->options
->universe_count
> agent_universe
.index
&&
3094 packet
->options
->universes
[agent_universe
.index
] != NULL
) {
3095 oc
= lookup_option (&server_universe
, state
-> options
,
3096 SV_STASH_AGENT_OPTIONS
);
3098 evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
3099 (struct client_state
*)0,
3102 &lease
-> scope
, oc
, MDL
)) {
3103 if (lt
-> agent_options
)
3104 option_chain_head_dereference (<
-> agent_options
, MDL
);
3105 option_chain_head_reference
3106 (<
-> agent_options
,
3107 (struct option_chain_head
*)
3108 packet
-> options
-> universes
[agent_universe
.index
],
3113 /* Replace the old lease hostname with the new one, if it's changed. */
3114 oc
= lookup_option (&dhcp_universe
, packet
-> options
, DHO_HOST_NAME
);
3116 s1
= evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
3117 (struct client_state
*)0,
3119 (struct option_state
*)0,
3120 &global_scope
, oc
, MDL
);
3125 lease
-> client_hostname
&&
3126 strlen (lease
-> client_hostname
) == d1
.len
&&
3127 !memcmp (lease
-> client_hostname
, d1
.data
, d1
.len
)) {
3128 /* Hasn't changed. */
3129 data_string_forget (&d1
, MDL
);
3130 lt
-> client_hostname
= lease
-> client_hostname
;
3131 lease
-> client_hostname
= (char *)0;
3132 } else if (oc
&& s1
) {
3133 lt
-> client_hostname
= dmalloc (d1
.len
+ 1, MDL
);
3134 if (!lt
-> client_hostname
)
3135 log_error ("no memory for client hostname.");
3137 memcpy (lt
-> client_hostname
, d1
.data
, d1
.len
);
3138 lt
-> client_hostname
[d1
.len
] = 0;
3140 data_string_forget (&d1
, MDL
);
3141 /* hostname changed, can't reuse lease */
3142 lease
->cannot_reuse
= 1;
3145 /* Record the hardware address, if given... */
3146 lt
-> hardware_addr
.hlen
= packet
-> raw
-> hlen
+ 1;
3147 lt
-> hardware_addr
.hbuf
[0] = packet
-> raw
-> htype
;
3148 memcpy (<
-> hardware_addr
.hbuf
[1], packet
-> raw
-> chaddr
,
3149 sizeof packet
-> raw
-> chaddr
);
3152 * If client has requested the lease become infinite, then it
3153 * doens't qualify for reuse even if it's younger than the
3154 * dhcp-cache-threshold.
3156 if ((lt
->flags
& RESERVED_LEASE
) && !(lease
->flags
& RESERVED_LEASE
)) {
3157 log_debug ("Cannot reuse: lease is changing to RESERVED");
3158 lease
->cannot_reuse
= 1;
3161 lt
->flags
|= lease
->flags
& ~PERSISTENT_FLAGS
;
3163 /* If there are statements to execute when the lease is
3164 committed, execute them. */
3165 if (lease
->on_star
.on_commit
&& (!offer
|| offer
== DHCPACK
)) {
3166 execute_statements (NULL
, packet
, lt
, NULL
, packet
->options
,
3167 state
->options
, <
->scope
,
3168 lease
->on_star
.on_commit
, NULL
);
3169 if (lease
->on_star
.on_commit
)
3170 executable_statement_dereference
3171 (&lease
->on_star
.on_commit
, MDL
);
3175 /* Perform DDNS updates, if configured to. */
3176 if ((!offer
|| offer
== DHCPACK
) &&
3177 (!(oc
= lookup_option (&server_universe
, state
-> options
,
3178 SV_DDNS_UPDATES
)) ||
3179 evaluate_boolean_option_cache (&ignorep
, packet
, lt
,
3180 (struct client_state
*)0,
3183 <
-> scope
, oc
, MDL
))) {
3184 ddns_updates(packet
, lt
, lease
, NULL
, NULL
, state
->options
);
3186 #endif /* NSUPDATE */
3188 /* Don't call supersede_lease on a mocked-up lease. */
3189 if (lease
-> flags
& STATIC_LEASE
) {
3190 /* Copy the hardware address into the static lease
3192 lease
-> hardware_addr
.hlen
= packet
-> raw
-> hlen
+ 1;
3193 lease
-> hardware_addr
.hbuf
[0] = packet
-> raw
-> htype
;
3194 memcpy (&lease
-> hardware_addr
.hbuf
[1],
3195 packet
-> raw
-> chaddr
,
3196 sizeof packet
-> raw
-> chaddr
); /* XXX */
3198 int commit
= (!offer
|| (offer
== DHCPACK
));
3200 /* If dhcp-cache-threshold is enabled, see if "lease" can
3202 use_old_lease
= reuse_lease(packet
, lt
, lease
, state
, offer
,
3204 if (use_old_lease
== 1) {
3208 #if !defined(DELAYED_ACK)
3209 /* Install the new information on 'lt' onto the lease at
3210 * 'lease'. If this is a DHCPOFFER, it is a 'soft' promise,
3211 * if it is a DHCPACK, it is a 'hard' binding, so it needs
3212 * to be recorded and propogated immediately. If the update
3213 * fails, don't ACK it (or BOOTREPLY) either; we may give
3214 * the same lease to another client later, and that would be
3217 if ((use_old_lease
== 0) &&
3218 !supersede_lease(lease
, lt
, commit
,
3219 offer
== DHCPACK
, offer
== DHCPACK
, 0)) {
3220 #else /* defined(DELAYED_ACK) */
3222 * If there already isn't a need for a lease commit, and we
3223 * can just answer right away, set a flag to indicate this.
3228 /* Install the new information on 'lt' onto the lease at
3229 * 'lease'. We will not 'commit' this information to disk
3230 * yet (fsync()), we will 'propogate' the information if
3231 * this is BOOTP or a DHCPACK, but we will not 'pimmediate'ly
3232 * transmit failover binding updates (this is delayed until
3233 * after the fsync()). If the update fails, don't ACK it (or
3234 * BOOTREPLY either); we may give the same lease out to a
3235 * different client, and that would be a conflict.
3237 if ((use_old_lease
== 0) &&
3238 !supersede_lease(lease
, lt
, 0,
3239 !offer
|| offer
== DHCPACK
, 0, 0)) {
3241 log_info ("%s: database update failed", msg
);
3242 free_lease_state (state
, MDL
);
3243 lease_dereference (<
, MDL
);
3247 lease_dereference (<
, MDL
);
3249 /* Remember the interface on which the packet arrived. */
3250 state
-> ip
= packet
-> interface
;
3252 /* Remember the giaddr, xid, secs, flags and hops. */
3253 state
-> giaddr
= packet
-> raw
-> giaddr
;
3254 state
-> ciaddr
= packet
-> raw
-> ciaddr
;
3255 state
-> xid
= packet
-> raw
-> xid
;
3256 state
-> secs
= packet
-> raw
-> secs
;
3257 state
-> bootp_flags
= packet
-> raw
-> flags
;
3258 state
-> hops
= packet
-> raw
-> hops
;
3259 state
-> offer
= offer
;
3261 /* If we're always supposed to broadcast to this client, set
3262 the broadcast bit in the bootp flags field. */
3263 if ((oc
= lookup_option (&server_universe
, state
-> options
,
3264 SV_ALWAYS_BROADCAST
)) &&
3265 evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
3266 (struct client_state
*)0,
3267 packet
-> options
, state
-> options
,
3268 &lease
-> scope
, oc
, MDL
))
3269 state
-> bootp_flags
|= htons (BOOTP_BROADCAST
);
3271 /* Get the Maximum Message Size option from the packet, if one
3273 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
3274 DHO_DHCP_MAX_MESSAGE_SIZE
);
3276 evaluate_option_cache (&d1
, packet
, lease
,
3277 (struct client_state
*)0,
3278 packet
-> options
, state
-> options
,
3279 &lease
-> scope
, oc
, MDL
)) {
3280 if (d1
.len
== sizeof (u_int16_t
))
3281 state
-> max_message_size
= getUShort (d1
.data
);
3282 data_string_forget (&d1
, MDL
);
3284 oc
= lookup_option (&dhcp_universe
, state
-> options
,
3285 DHO_DHCP_MAX_MESSAGE_SIZE
);
3287 evaluate_option_cache (&d1
, packet
, lease
,
3288 (struct client_state
*)0,
3289 packet
-> options
, state
-> options
,
3290 &lease
-> scope
, oc
, MDL
)) {
3291 if (d1
.len
== sizeof (u_int16_t
))
3292 state
-> max_message_size
=
3293 getUShort (d1
.data
);
3294 data_string_forget (&d1
, MDL
);
3298 /* Get the Subnet Selection option from the packet, if one
3300 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
3301 DHO_SUBNET_SELECTION
))) {
3303 /* Make a copy of the data. */
3304 struct option_cache
*noc
= (struct option_cache
*)0;
3305 if (option_cache_allocate (&noc
, MDL
)) {
3307 data_string_copy (&noc
-> data
,
3309 if (oc
-> expression
)
3310 expression_reference (&noc
-> expression
,
3311 oc
-> expression
, MDL
);
3313 option_reference(&(noc
->option
), oc
->option
,
3316 save_option (&dhcp_universe
, state
-> options
, noc
);
3317 option_cache_dereference (&noc
, MDL
);
3321 /* Now, if appropriate, put in DHCP-specific options that
3323 if (state
-> offer
) {
3324 i
= DHO_DHCP_MESSAGE_TYPE
;
3325 oc
= (struct option_cache
*)0;
3326 if (option_cache_allocate (&oc
, MDL
)) {
3327 if (make_const_data (&oc
-> expression
,
3328 &state
-> offer
, 1, 0, 0, MDL
)) {
3329 option_code_hash_lookup(&oc
->option
,
3330 dhcp_universe
.code_hash
,
3332 save_option (&dhcp_universe
,
3333 state
-> options
, oc
);
3335 option_cache_dereference (&oc
, MDL
);
3338 get_server_source_address(&from
, state
->options
,
3339 state
->options
, packet
);
3340 memcpy(state
->from
.iabuf
, &from
, sizeof(from
));
3341 state
->from
.len
= sizeof(from
);
3343 offered_lease_time
=
3344 state
-> offered_expiry
- cur_time
;
3346 putULong(state
->expiry
, (u_int32_t
)offered_lease_time
);
3347 i
= DHO_DHCP_LEASE_TIME
;
3348 oc
= (struct option_cache
*)0;
3349 if (option_cache_allocate (&oc
, MDL
)) {
3350 if (make_const_data(&oc
->expression
, state
->expiry
,
3352 option_code_hash_lookup(&oc
->option
,
3353 dhcp_universe
.code_hash
,
3355 save_option (&dhcp_universe
,
3356 state
-> options
, oc
);
3358 option_cache_dereference (&oc
, MDL
);
3362 * Validate any configured renew or rebinding times against
3363 * the determined lease time. Do rebinding first so that
3364 * the renew time can be validated against the rebind time.
3366 if ((oc
= lookup_option(&dhcp_universe
, state
->options
,
3367 DHO_DHCP_REBINDING_TIME
)) != NULL
&&
3368 evaluate_option_cache(&d1
, packet
, lease
, NULL
,
3369 packet
->options
, state
->options
,
3370 &lease
->scope
, oc
, MDL
)) {
3371 TIME rebind_time
= getULong(d1
.data
);
3373 /* Drop the configured (invalid) rebinding time. */
3374 if (rebind_time
>= offered_lease_time
)
3375 delete_option(&dhcp_universe
, state
->options
,
3376 DHO_DHCP_REBINDING_TIME
);
3377 else /* XXX: variable is reused. */
3378 offered_lease_time
= rebind_time
;
3380 data_string_forget(&d1
, MDL
);
3383 if ((oc
= lookup_option(&dhcp_universe
, state
->options
,
3384 DHO_DHCP_RENEWAL_TIME
)) != NULL
&&
3385 evaluate_option_cache(&d1
, packet
, lease
, NULL
,
3386 packet
->options
, state
->options
,
3387 &lease
->scope
, oc
, MDL
)) {
3388 if (getULong(d1
.data
) >= offered_lease_time
)
3389 delete_option(&dhcp_universe
, state
->options
,
3390 DHO_DHCP_RENEWAL_TIME
);
3392 data_string_forget(&d1
, MDL
);
3395 /* XXXSK: should we use get_server_source_address() here? */
3396 if (state
-> ip
-> address_count
) {
3398 sizeof state
-> ip
-> addresses
[0];
3399 memcpy (state
-> from
.iabuf
,
3400 &state
-> ip
-> addresses
[0],
3405 /* Figure out the address of the boot file server. */
3406 memset (&state
-> siaddr
, 0, sizeof state
-> siaddr
);
3408 lookup_option (&server_universe
,
3409 state
-> options
, SV_NEXT_SERVER
))) {
3410 if (evaluate_option_cache (&d1
, packet
, lease
,
3411 (struct client_state
*)0,
3412 packet
-> options
, state
-> options
,
3413 &lease
-> scope
, oc
, MDL
)) {
3414 /* If there was more than one answer,
3416 if (d1
.len
>= 4 && d1
.data
)
3417 memcpy (&state
-> siaddr
, d1
.data
, 4);
3418 data_string_forget (&d1
, MDL
);
3422 /* Use the subnet mask from the subnet declaration if no other
3423 mask has been provided. */
3424 i
= DHO_SUBNET_MASK
;
3425 if (!lookup_option (&dhcp_universe
, state
-> options
, i
)) {
3426 oc
= (struct option_cache
*)0;
3427 if (option_cache_allocate (&oc
, MDL
)) {
3428 if (make_const_data (&oc
-> expression
,
3429 lease
-> subnet
-> netmask
.iabuf
,
3430 lease
-> subnet
-> netmask
.len
,
3432 option_code_hash_lookup(&oc
->option
,
3433 dhcp_universe
.code_hash
,
3435 save_option (&dhcp_universe
,
3436 state
-> options
, oc
);
3438 option_cache_dereference (&oc
, MDL
);
3442 /* Use the name of the host declaration if there is one
3443 and no hostname has otherwise been provided, and if the
3444 use-host-decl-name flag is set. */
3445 use_host_decl_name(packet
, lease
, state
->options
);
3447 /* Send client_id back if we received it and echo-client-id is on. */
3448 echo_client_id(packet
, lease
, state
->options
, state
->options
);
3450 /* If we don't have a hostname yet, and we've been asked to do
3451 a reverse lookup to find the hostname, do it. */
3453 j
= SV_GET_LEASE_HOSTNAMES
;
3454 if (!lookup_option(&dhcp_universe
, state
->options
, i
) &&
3455 evaluate_boolean_option_cache
3456 (&ignorep
, packet
, lease
, NULL
,
3457 packet
->options
, state
->options
, &lease
->scope
,
3458 lookup_option (&server_universe
, state
->options
, j
), MDL
)) {
3462 memcpy (&ia
, lease
-> ip_addr
.iabuf
, 4);
3464 h
= gethostbyaddr ((char *)&ia
, sizeof ia
, AF_INET
);
3466 log_error ("No hostname for %s", inet_ntoa (ia
));
3468 oc
= (struct option_cache
*)0;
3469 if (option_cache_allocate (&oc
, MDL
)) {
3470 if (make_const_data (&oc
-> expression
,
3473 strlen (h
-> h_name
) + 1,
3475 option_code_hash_lookup(&oc
->option
,
3476 dhcp_universe
.code_hash
,
3478 save_option (&dhcp_universe
,
3479 state
-> options
, oc
);
3481 option_cache_dereference (&oc
, MDL
);
3486 /* If so directed, use the leased IP address as the router address.
3487 This supposedly makes Win95 machines ARP for all IP addresses,
3488 so if the local router does proxy arp, you win. */
3490 if (evaluate_boolean_option_cache
3491 (&ignorep
, packet
, lease
, (struct client_state
*)0,
3492 packet
-> options
, state
-> options
, &lease
-> scope
,
3493 lookup_option (&server_universe
, state
-> options
,
3494 SV_USE_LEASE_ADDR_FOR_DEFAULT_ROUTE
), MDL
)) {
3496 oc
= lookup_option (&dhcp_universe
, state
-> options
, i
);
3498 oc
= (struct option_cache
*)0;
3499 if (option_cache_allocate (&oc
, MDL
)) {
3500 if (make_const_data (&oc
-> expression
,
3501 lease
-> ip_addr
.iabuf
,
3502 lease
-> ip_addr
.len
,
3504 option_code_hash_lookup(&oc
->option
,
3505 dhcp_universe
.code_hash
,
3507 save_option (&dhcp_universe
,
3508 state
-> options
, oc
);
3510 option_cache_dereference (&oc
, MDL
);
3515 /* If a site option space has been specified, use that for
3516 site option codes. */
3517 i
= SV_SITE_OPTION_SPACE
;
3518 if ((oc
= lookup_option (&server_universe
, state
-> options
, i
)) &&
3519 evaluate_option_cache (&d1
, packet
, lease
,
3520 (struct client_state
*)0,
3521 packet
-> options
, state
-> options
,
3522 &lease
-> scope
, oc
, MDL
)) {
3523 struct universe
*u
= (struct universe
*)0;
3525 if (!universe_hash_lookup (&u
, universe_hash
,
3526 (const char *)d1
.data
, d1
.len
,
3528 log_error ("unknown option space %s.", d1
.data
);
3532 state
-> options
-> site_universe
= u
-> index
;
3533 state
->options
->site_code_min
= find_min_site_code(u
);
3534 data_string_forget (&d1
, MDL
);
3536 state
-> options
-> site_code_min
= 0;
3537 state
-> options
-> site_universe
= dhcp_universe
.index
;
3540 /* If the client has provided a list of options that it wishes
3541 returned, use it to prioritize. If there's a parameter
3542 request list in scope, use that in preference. Otherwise
3543 use the default priority list. */
3545 oc
= lookup_option (&dhcp_universe
, state
-> options
,
3546 DHO_DHCP_PARAMETER_REQUEST_LIST
);
3549 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
3550 DHO_DHCP_PARAMETER_REQUEST_LIST
);
3552 evaluate_option_cache (&state
-> parameter_request_list
,
3553 packet
, lease
, (struct client_state
*)0,
3554 packet
-> options
, state
-> options
,
3555 &lease
-> scope
, oc
, MDL
);
3558 dump_packet (packet
);
3559 dump_raw ((unsigned char *)packet
-> raw
, packet
-> packet_length
);
3562 lease
-> state
= state
;
3564 log_info ("%s", msg
);
3566 /* Hang the packet off the lease state. */
3567 packet_reference (&lease
-> state
-> packet
, packet
, MDL
);
3569 /* If this is a DHCPOFFER, send a ping (if appropriate) to the
3570 * lease address before actually we send the offer. */
3571 if ((offer
== DHCPOFFER
) &&
3572 do_ping_check(packet
, state
, lease
, original_cltt
, same_client
)) {
3573 ++outstanding_pings
;
3575 lease
->cltt
= cur_time
;
3576 #if defined(DELAYED_ACK)
3578 delayed_ack_enqueue(lease
);
3586 * \brief Sends a ping to the lease ip_addr when appropriate
3588 * A ping will be sent if all of the following are true:
3590 * 1. Ping checks are enabled
3591 * 2. The lease is neither active nor static
3592 * 3. Any of the following is true:
3593 * a. The lease state is ABANDONED
3594 * b. This is the first offer of this lease (CLTT = 0)
3595 * c. The lease is being offered to a client other than its previous
3597 * d. The lease is being offered to its previous owner and more than
3598 * cltt-secs have elapsed since CLTT of the original lease.
3600 * \param packet inbound packet received from the client
3601 * \param state lease options state
3602 * \param lease lease to be offered (if one)
3603 * \param original_cltt CLTT of the original lease
3604 * \param same_client flag indicating if the client to be offered the
3605 * lease is its previous owner
3606 * \return Returns 1 if ping has been sent, 0 otherwise
3608 int do_ping_check(struct packet
* packet
, struct lease_state
* state
,
3609 struct lease
* lease
, TIME original_cltt
,
3611 TIME ping_timeout
= DEFAULT_PING_TIMEOUT
;
3612 TIME ping_timeout_ms
= DEFAULT_PING_TIMEOUT_MS
;
3613 struct option_cache
*oc
= NULL
;
3614 struct data_string ds
;
3620 // Don't go any further if lease is active or static.
3621 if (lease
->binding_state
== FTS_ACTIVE
|| lease
->flags
& STATIC_LEASE
) {
3625 // If pings aren't enabled, punt.
3626 oc
= lookup_option (&server_universe
, state
-> options
, SV_PING_CHECKS
);
3628 !(evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
3629 0, packet
->options
, state
->options
,
3630 &lease
->scope
, oc
, MDL
))) {
3634 // If it's not the first time for the same client and not an
3635 // abandoned lease, we need to check the cltt threshold
3636 if (same_client
&& original_cltt
&&
3637 lease
->binding_state
!= FTS_ABANDONED
) {
3638 TIME cltt_secs
= DEFAULT_PING_CLTT_SECS
;
3639 memset(&ds
, 0, sizeof(ds
));
3640 oc
= lookup_option (&server_universe
, state
->options
,
3643 (evaluate_option_cache (&ds
, packet
, lease
, 0,
3644 packet
->options
, state
->options
,
3645 &lease
->scope
, oc
, MDL
))) {
3646 if (ds
.len
== sizeof (u_int32_t
)) {
3647 cltt_secs
= getULong (ds
.data
);
3650 data_string_forget (&ds
, MDL
);
3653 // Punt if it is too soon.
3654 if (cur_time
- original_cltt
< cltt_secs
) {
3660 icmp_echorequest (&lease
->ip_addr
);
3662 /* Determine whether to use configured or default ping timeout. */
3663 memset(&ds
, 0, sizeof(ds
));
3665 oc
= lookup_option (&server_universe
, state
->options
, SV_PING_TIMEOUT
);
3667 (evaluate_option_cache (&ds
, packet
, lease
, 0,
3668 packet
->options
, state
->options
,
3669 &lease
->scope
, oc
, MDL
))) {
3670 if (ds
.len
== sizeof (u_int32_t
)) {
3671 ping_timeout
= getULong (ds
.data
);
3674 data_string_forget (&ds
, MDL
);
3677 oc
= lookup_option (&server_universe
, state
->options
, SV_PING_TIMEOUT_MS
);
3679 (evaluate_option_cache (&ds
, packet
, lease
, 0,
3680 packet
->options
, state
->options
,
3681 &lease
->scope
, oc
, MDL
))) {
3682 if (ds
.len
== sizeof (u_int32_t
)) {
3683 ping_timeout_ms
= getULong (ds
.data
);
3686 data_string_forget (&ds
, MDL
);
3690 * Set the timeout for the ping to the current timeval plus
3691 * the configured time out. Use ping-timeout-ms if it is > 0.
3692 * This overrides ping-timeout allowing users to specify it in
3695 if (ping_timeout_ms
> 0) {
3696 timeout_secs
= ping_timeout_ms
/ 1000;
3697 timeout_ms
= ping_timeout_ms
% 1000;
3699 timeout_secs
= ping_timeout
;
3704 tv
.tv_sec
= cur_tv
.tv_sec
+ timeout_secs
;
3705 tv
.tv_usec
= cur_tv
.tv_usec
+ (timeout_ms
* 1000);
3708 log_debug ("Pinging:%s, state: %d, same client? %s, "
3709 " orig_cltt %s, elasped: %ld, timeout in: %d.%d secs" ,
3710 piaddr(lease
->ip_addr
),
3711 lease
->binding_state
,
3712 (same_client
? "y" : "n"),
3713 (original_cltt
? print_time(original_cltt
) : "0"),
3714 (original_cltt
? (long)(cur_time
- original_cltt
) : 0),
3715 timeout_secs
, timeout_ms
);
3719 add_timeout (&tv
, lease_ping_timeout
, lease
, (tvref_t
)lease_reference
,
3720 (tvunref_t
)lease_dereference
);
3726 #if defined(DELAYED_ACK)
3729 * CC: queue single ACK:
3730 * - write the lease (but do not fsync it yet)
3731 * - add to double linked list
3732 * - commit if more than xx ACKs pending
3733 * - if necessary set the max timer and bump the next timer
3734 * but only up to the max timer value.
3738 delayed_ack_enqueue(struct lease
*lease
)
3740 struct leasequeue
*q
;
3742 if (!write_lease(lease
))
3744 if (free_ackqueue
) {
3746 free_ackqueue
= q
->next
;
3748 q
= ((struct leasequeue
*)
3749 dmalloc(sizeof(struct leasequeue
), MDL
));
3751 log_fatal("delayed_ack_enqueue: no memory!");
3753 memset(q
, 0, sizeof *q
);
3754 /* prepend to ackqueue*/
3755 lease_reference(&q
->lease
, lease
, MDL
);
3756 q
->next
= ackqueue_head
;
3764 if (outstanding_acks
> max_outstanding_acks
) {
3765 /* Cancel any pending timeout and call handler directly */
3766 cancel_timeout(delayed_acks_timer
, NULL
);
3767 delayed_acks_timer(NULL
);
3769 struct timeval next_fsync
;
3771 if (max_fsync
.tv_sec
== 0 && max_fsync
.tv_usec
== 0) {
3772 /* set the maximum time we'll wait */
3773 max_fsync
.tv_sec
= cur_tv
.tv_sec
+ max_ack_delay_secs
;
3774 max_fsync
.tv_usec
= cur_tv
.tv_usec
+
3775 max_ack_delay_usecs
;
3777 if (max_fsync
.tv_usec
>= 1000000) {
3779 max_fsync
.tv_usec
-= 1000000;
3783 /* Set the timeout */
3784 next_fsync
.tv_sec
= cur_tv
.tv_sec
;
3785 next_fsync
.tv_usec
= cur_tv
.tv_usec
+ min_ack_delay_usecs
;
3786 if (next_fsync
.tv_usec
>= 1000000) {
3787 next_fsync
.tv_sec
++;
3788 next_fsync
.tv_usec
-= 1000000;
3790 /* but not more than the max */
3791 if ((next_fsync
.tv_sec
> max_fsync
.tv_sec
) ||
3792 ((next_fsync
.tv_sec
== max_fsync
.tv_sec
) &&
3793 (next_fsync
.tv_usec
> max_fsync
.tv_usec
))) {
3794 next_fsync
.tv_sec
= max_fsync
.tv_sec
;
3795 next_fsync
.tv_usec
= max_fsync
.tv_usec
;
3798 add_timeout(&next_fsync
, delayed_acks_timer
, NULL
,
3799 (tvref_t
) NULL
, (tvunref_t
) NULL
);
3803 /* Processes any delayed acks:
3804 * Commits the leases and then for each delayed ack:
3805 * - Update the failover peer if we're in failover
3806 * - Send the REPLY to the client
3809 delayed_acks_timer(void *foo
)
3811 struct leasequeue
*ack
, *p
;
3813 /* Reset max fsync */
3814 memset(&max_fsync
, 0, sizeof(max_fsync
));
3816 if (!outstanding_acks
) {
3817 /* Nothing to do, so punt, shouldn't happen? */
3821 /* Commit the leases first */
3824 /* Now process the delayed ACKs
3825 - update failover peer
3826 - send out the ACK packets
3827 - move the queue slots to the free list
3830 /* process from bottom to retain packet order */
3831 for (ack
= ackqueue_tail
; ack
; ack
= p
) {
3834 #if defined(FAILOVER_PROTOCOL)
3835 /* If we're in failover we need to send any deferred
3836 * bind updates as well as the replies */
3837 if (ack
->lease
->pool
) {
3838 dhcp_failover_state_t
*fpeer
;
3840 fpeer
= ack
->lease
->pool
->failover_peer
;
3841 if (fpeer
&& fpeer
->link_to_peer
) {
3842 dhcp_failover_send_updates(fpeer
);
3847 /* dhcp_reply() requires that the reply state still be valid */
3848 if (ack
->lease
->state
== NULL
)
3849 log_error("delayed ack for %s has gone stale",
3850 piaddr(ack
->lease
->ip_addr
));
3852 dhcp_reply(ack
->lease
);
3855 lease_dereference(&ack
->lease
, MDL
);
3856 ack
->next
= free_ackqueue
;
3857 free_ackqueue
= ack
;
3860 ackqueue_head
= NULL
;
3861 ackqueue_tail
= NULL
;
3862 outstanding_acks
= 0;
3865 #if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
3867 relinquish_ackqueue(void)
3869 struct leasequeue
*q
, *n
;
3871 for (q
= ackqueue_head
; q
; q
= n
) {
3875 for (q
= free_ackqueue
; q
; q
= n
) {
3882 #endif /* defined(DELAYED_ACK) */
3884 void dhcp_reply (lease
)
3885 struct lease
*lease
;
3888 unsigned packet_length
;
3889 struct dhcp_packet raw
;
3890 struct sockaddr_in to
;
3891 struct in_addr from
;
3892 struct hardware hto
;
3894 struct lease_state
*state
= lease
-> state
;
3895 int nulltp
, bootpp
, unicastp
= 1;
3896 #if defined(RELAY_PORT)
3897 u_int16_t relay_port
= 0;
3899 struct data_string d1
;
3903 log_fatal ("dhcp_reply was supplied lease with no state!");
3905 /* Compose a response for the client... */
3906 memset (&raw
, 0, sizeof raw
);
3907 memset (&d1
, 0, sizeof d1
);
3909 /* Copy in the filename if given; otherwise, flag the filename
3910 buffer as available for options. */
3911 if (state
-> filename
.len
&& state
-> filename
.data
) {
3913 state
-> filename
.data
,
3914 state
-> filename
.len
> sizeof raw
.file
3915 ? sizeof raw
.file
: state
-> filename
.len
);
3916 if (sizeof raw
.file
> state
-> filename
.len
)
3917 memset (&raw
.file
[state
-> filename
.len
], 0,
3918 (sizeof raw
.file
) - state
-> filename
.len
);
3920 log_info("file name longer than packet field "
3921 "truncated - field: %lu name: %d %.*s",
3922 (unsigned long)sizeof(raw
.file
),
3923 state
->filename
.len
, (int)state
->filename
.len
,
3924 state
->filename
.data
);
3928 /* Copy in the server name if given; otherwise, flag the
3929 server_name buffer as available for options. */
3930 if (state
-> server_name
.len
&& state
-> server_name
.data
) {
3932 state
-> server_name
.data
,
3933 state
-> server_name
.len
> sizeof raw
.sname
3934 ? sizeof raw
.sname
: state
-> server_name
.len
);
3935 if (sizeof raw
.sname
> state
-> server_name
.len
)
3936 memset (&raw
.sname
[state
-> server_name
.len
], 0,
3937 (sizeof raw
.sname
) - state
-> server_name
.len
);
3939 log_info("server name longer than packet field "
3940 "truncated - field: %lu name: %d %.*s",
3941 (unsigned long)sizeof(raw
.sname
),
3942 state
->server_name
.len
,
3943 (int)state
->server_name
.len
,
3944 state
->server_name
.data
);
3946 bufs
|= 2; /* XXX */
3949 &lease
-> hardware_addr
.hbuf
[1], sizeof raw
.chaddr
);
3950 raw
.hlen
= lease
-> hardware_addr
.hlen
- 1;
3951 raw
.htype
= lease
-> hardware_addr
.hbuf
[0];
3953 /* See if this is a Microsoft client that NUL-terminates its
3954 strings and expects us to do likewise... */
3955 if (lease
-> flags
& MS_NULL_TERMINATION
)
3960 /* See if this is a bootp client... */
3966 /* Insert such options as will fit into the buffer. */
3967 packet_length
= cons_options (state
-> packet
, &raw
, lease
,
3968 (struct client_state
*)0,
3969 state
-> max_message_size
,
3970 state
-> packet
-> options
,
3971 state
-> options
, &global_scope
,
3972 bufs
, nulltp
, bootpp
,
3973 &state
-> parameter_request_list
,
3976 memcpy (&raw
.ciaddr
, &state
-> ciaddr
, sizeof raw
.ciaddr
);
3977 memcpy (&raw
.yiaddr
, lease
-> ip_addr
.iabuf
, 4);
3978 raw
.siaddr
= state
-> siaddr
;
3979 raw
.giaddr
= state
-> giaddr
;
3981 raw
.xid
= state
-> xid
;
3982 raw
.secs
= state
-> secs
;
3983 raw
.flags
= state
-> bootp_flags
;
3984 raw
.hops
= state
-> hops
;
3987 if (lease
-> client_hostname
) {
3988 if ((strlen (lease
-> client_hostname
) <= 64) &&
3989 db_printable((unsigned char *)lease
->client_hostname
))
3990 s
= lease
-> client_hostname
;
3992 s
= "Hostname Unsuitable for Printing";
3996 /* Make sure outgoing packets are at least as big
3997 as a BOOTP packet. */
3998 if (packet_length
< BOOTP_MIN_LEN
)
3999 packet_length
= BOOTP_MIN_LEN
;
4001 #if defined(DHCPv6) && defined(DHCP4o6)
4002 if (dhcpv4_over_dhcpv6
&& (state
->packet
->dhcp4o6_response
!= NULL
)) {
4003 /* Say what we're doing... */
4004 log_info ("DHCP4o6 %s on %s to %s %s%s%svia %s",
4006 ? (state
-> offer
== DHCPACK
4007 ? "DHCPACK" : "DHCPOFFER")
4009 piaddr (lease
-> ip_addr
),
4010 (lease
-> hardware_addr
.hlen
4011 ? print_hw_addr (lease
-> hardware_addr
.hbuf
[0],
4012 lease
-> hardware_addr
.hlen
- 1,
4013 &lease
-> hardware_addr
.hbuf
[1])
4014 : print_hex_1(lease
->uid_len
, lease
->uid
, 60)),
4015 s
? "(" : "", s
? s
: "", s
? ") " : "",
4016 piaddr(state
->packet
->client_addr
));
4018 /* fill dhcp4o6_response */
4019 state
->packet
->dhcp4o6_response
->len
= packet_length
;
4020 state
->packet
->dhcp4o6_response
->buffer
= NULL
;
4021 if (!buffer_allocate(&state
->packet
->dhcp4o6_response
->buffer
,
4022 packet_length
, MDL
)) {
4023 log_fatal("No memory to store DHCP4o6 reply.");
4025 state
->packet
->dhcp4o6_response
->data
=
4026 state
->packet
->dhcp4o6_response
->buffer
->data
;
4027 memcpy(state
->packet
->dhcp4o6_response
->buffer
->data
,
4028 &raw
, packet_length
);
4031 free_lease_state (state
, MDL
);
4032 lease
-> state
= (struct lease_state
*)0;
4038 /* Say what we're doing... */
4039 log_info ("%s on %s to %s %s%s%svia %s",
4041 ? (state
-> offer
== DHCPACK
? "DHCPACK" : "DHCPOFFER")
4043 piaddr (lease
-> ip_addr
),
4044 (lease
-> hardware_addr
.hlen
4045 ? print_hw_addr (lease
-> hardware_addr
.hbuf
[0],
4046 lease
-> hardware_addr
.hlen
- 1,
4047 &lease
-> hardware_addr
.hbuf
[1])
4048 : print_hex_1(lease
->uid_len
, lease
->uid
, 60)),
4049 s
? "(" : "", s
? s
: "", s
? ") " : "",
4050 (state
-> giaddr
.s_addr
4051 ? inet_ntoa (state
-> giaddr
)
4052 : state
-> ip
-> name
));
4055 dump_raw ((unsigned char *)&raw
, packet_length
);
4058 /* Set up the hardware address... */
4059 hto
.hlen
= lease
-> hardware_addr
.hlen
;
4060 memcpy (hto
.hbuf
, lease
-> hardware_addr
.hbuf
, hto
.hlen
);
4062 to
.sin_family
= AF_INET
;
4064 to
.sin_len
= sizeof to
;
4066 memset (to
.sin_zero
, 0, sizeof to
.sin_zero
);
4068 #if defined(RELAY_PORT)
4069 relay_port
= dhcp_check_relayport(state
->packet
);
4072 /* If this was gatewayed, send it back to the gateway... */
4073 if (raw
.giaddr
.s_addr
) {
4074 to
.sin_addr
= raw
.giaddr
;
4075 if (raw
.giaddr
.s_addr
!= htonl (INADDR_LOOPBACK
))
4076 #if defined(RELAY_PORT)
4077 to
.sin_port
= relay_port
? relay_port
: local_port
;
4079 to
.sin_port
= local_port
;
4082 to
.sin_port
= remote_port
; /* For debugging. */
4084 if (fallback_interface
) {
4085 result
= send_packet(fallback_interface
, NULL
, &raw
,
4086 packet_length
, raw
.siaddr
, &to
,
4089 log_error ("%s:%d: Failed to send %d byte long "
4090 "packet over %s interface.", MDL
,
4092 fallback_interface
->name
);
4096 free_lease_state (state
, MDL
);
4097 lease
-> state
= (struct lease_state
*)0;
4101 /* If the client is RENEWING, unicast to the client using the
4102 regular IP stack. Some clients, particularly those that
4103 follow RFC1541, are buggy, and send both ciaddr and server
4104 identifier. We deal with this situation by assuming that
4105 if we got both dhcp-server-identifier and ciaddr, and
4106 giaddr was not set, then the client is on the local
4107 network, and we can therefore unicast or broadcast to it
4108 successfully. A client in REQUESTING state on another
4109 network that's making this mistake will have set giaddr,
4110 and will therefore get a relayed response from the above
4112 } else if (raw
.ciaddr
.s_addr
&&
4113 !((state
-> got_server_identifier
||
4114 (raw
.flags
& htons (BOOTP_BROADCAST
))) &&
4115 /* XXX This won't work if giaddr isn't zero, but it is: */
4116 (state
-> shared_network
==
4117 lease
-> subnet
-> shared_network
)) &&
4118 state
-> offer
== DHCPACK
) {
4119 to
.sin_addr
= raw
.ciaddr
;
4120 to
.sin_port
= remote_port
;
4122 if (fallback_interface
) {
4123 result
= send_packet(fallback_interface
, NULL
, &raw
,
4124 packet_length
, raw
.siaddr
, &to
,
4127 log_error("%s:%d: Failed to send %d byte long"
4128 " packet over %s interface.", MDL
,
4130 fallback_interface
->name
);
4133 free_lease_state (state
, MDL
);
4134 lease
-> state
= (struct lease_state
*)0;
4138 /* If it comes from a client that already knows its address
4139 and is not requesting a broadcast response, and we can
4140 unicast to a client without using the ARP protocol, sent it
4141 directly to that client. */
4142 } else if (!(raw
.flags
& htons (BOOTP_BROADCAST
)) &&
4143 can_unicast_without_arp (state
-> ip
)) {
4144 to
.sin_addr
= raw
.yiaddr
;
4145 to
.sin_port
= remote_port
;
4147 /* Otherwise, broadcast it on the local network. */
4149 to
.sin_addr
= limited_broadcast
;
4150 to
.sin_port
= remote_port
;
4151 if (!(lease
-> flags
& UNICAST_BROADCAST_HACK
))
4155 memcpy (&from
, state
-> from
.iabuf
, sizeof from
);
4157 result
= send_packet(state
->ip
, NULL
, &raw
, packet_length
,
4158 from
, &to
, unicastp
? &hto
: NULL
);
4160 log_error ("%s:%d: Failed to send %d byte long "
4161 "packet over %s interface.", MDL
,
4162 packet_length
, state
->ip
->name
);
4166 /* Free all of the entries in the option_state structure
4167 now that we're done with them. */
4169 free_lease_state (state
, MDL
);
4170 lease
-> state
= (struct lease_state
*)0;
4173 int find_lease (struct lease
**lp
,
4174 struct packet
*packet
, struct shared_network
*share
, int *ours
,
4175 int *peer_has_leases
, struct lease
*ip_lease_in
,
4176 const char *file
, int line
)
4178 struct lease
*uid_lease
= (struct lease
*)0;
4179 struct lease
*ip_lease
= (struct lease
*)0;
4180 struct lease
*hw_lease
= (struct lease
*)0;
4181 struct lease
*lease
= (struct lease
*)0;
4183 struct host_decl
*hp
= (struct host_decl
*)0;
4184 struct host_decl
*host
= (struct host_decl
*)0;
4185 struct lease
*fixed_lease
= (struct lease
*)0;
4186 struct lease
*next
= (struct lease
*)0;
4187 struct option_cache
*oc
;
4188 struct data_string d1
;
4189 int have_client_identifier
= 0;
4190 struct data_string client_identifier
;
4193 #if defined(FAILOVER_PROTOCOL)
4194 /* Quick check to see if the peer has leases. */
4195 if (peer_has_leases
) {
4198 for (pool
= share
->pools
; pool
; pool
= pool
->next
) {
4199 dhcp_failover_state_t
*peer
= pool
->failover_peer
;
4202 ((peer
->i_am
== primary
&& pool
->backup_leases
) ||
4203 (peer
->i_am
== secondary
&& pool
->free_leases
))) {
4204 *peer_has_leases
= 1;
4209 #endif /* FAILOVER_PROTOCOL */
4211 if (packet
-> raw
-> ciaddr
.s_addr
) {
4213 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
, 4);
4215 /* Look up the requested address. */
4216 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
4217 DHO_DHCP_REQUESTED_ADDRESS
);
4218 memset (&d1
, 0, sizeof d1
);
4220 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
4221 (struct client_state
*)0,
4223 (struct option_state
*)0,
4224 &global_scope
, oc
, MDL
)) {
4225 packet
-> got_requested_address
= 1;
4227 memcpy (cip
.iabuf
, d1
.data
, cip
.len
);
4228 data_string_forget (&d1
, MDL
);
4233 /* Try to find a host or lease that's been assigned to the
4234 specified unique client identifier. */
4235 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
4236 DHO_DHCP_CLIENT_IDENTIFIER
);
4237 memset (&client_identifier
, 0, sizeof client_identifier
);
4239 evaluate_option_cache (&client_identifier
,
4240 packet
, (struct lease
*)0,
4241 (struct client_state
*)0,
4242 packet
-> options
, (struct option_state
*)0,
4243 &global_scope
, oc
, MDL
)) {
4244 /* Remember this for later. */
4245 have_client_identifier
= 1;
4247 /* First, try to find a fixed host entry for the specified
4248 client identifier... */
4249 if (find_hosts_by_uid (&hp
, client_identifier
.data
,
4250 client_identifier
.len
, MDL
)) {
4251 /* Remember if we know of this client. */
4252 packet
-> known
= 1;
4253 mockup_lease (&fixed_lease
, packet
, share
, hp
);
4256 #if defined (DEBUG_FIND_LEASE)
4258 log_info ("Found host for client identifier: %s.",
4259 piaddr (fixed_lease
-> ip_addr
));
4263 if (!fixed_lease
) /* Save the host if we found one. */
4264 host_reference (&host
, hp
, MDL
);
4265 host_dereference (&hp
, MDL
);
4268 find_lease_by_uid (&uid_lease
, client_identifier
.data
,
4269 client_identifier
.len
, MDL
);
4272 /* If we didn't find a fixed lease using the uid, try doing
4273 it with the hardware address... */
4274 if (!fixed_lease
&& !host
) {
4275 if (find_hosts_by_haddr (&hp
, packet
-> raw
-> htype
,
4276 packet
-> raw
-> chaddr
,
4277 packet
-> raw
-> hlen
, MDL
)) {
4278 /* Remember if we know of this client. */
4279 packet
-> known
= 1;
4281 host_dereference (&host
, MDL
);
4282 host_reference (&host
, hp
, MDL
);
4283 host_dereference (&hp
, MDL
);
4284 mockup_lease (&fixed_lease
, packet
, share
, host
);
4285 #if defined (DEBUG_FIND_LEASE)
4287 log_info ("Found host for link address: %s.",
4288 piaddr (fixed_lease
-> ip_addr
));
4294 /* Finally, if we haven't found anything yet try again with the
4295 * host-identifier option ... */
4296 if (!fixed_lease
&& !host
) {
4297 if (find_hosts_by_option(&hp
, packet
,
4298 packet
->options
, MDL
) == 1) {
4301 host_dereference(&host
, MDL
);
4302 host_reference(&host
, hp
, MDL
);
4303 host_dereference(&hp
, MDL
);
4304 mockup_lease (&fixed_lease
, packet
, share
, host
);
4305 #if defined (DEBUG_FIND_LEASE)
4307 log_info ("Found host via host-identifier");
4313 /* If fixed_lease is present but does not match the requested
4314 IP address, and this is a DHCPREQUEST, then we can't return
4315 any other lease, so we might as well return now. */
4316 if (packet
-> packet_type
== DHCPREQUEST
&& fixed_lease
&&
4317 (fixed_lease
-> ip_addr
.len
!= cip
.len
||
4318 memcmp (fixed_lease
-> ip_addr
.iabuf
,
4319 cip
.iabuf
, cip
.len
))) {
4322 strcpy (dhcp_message
, "requested address is incorrect");
4323 #if defined (DEBUG_FIND_LEASE)
4324 log_info ("Client's fixed-address %s doesn't match %s%s",
4325 piaddr (fixed_lease
-> ip_addr
), "request ",
4326 print_dotted_quads (cip
.len
, cip
.iabuf
));
4332 * If we found leases matching the client identifier, loop through
4333 * the n_uid pointer looking for one that's actually valid. We
4334 * can't do this until we get here because we depend on
4335 * packet -> known, which may be set by either the uid host
4336 * lookup or the haddr host lookup.
4338 * Note that the n_uid lease chain is sorted in order of
4339 * preference, so the first one is the best one.
4342 isc_boolean_t do_release
= !packet
->raw
->ciaddr
.s_addr
;
4343 #if defined (DEBUG_FIND_LEASE)
4344 log_info ("trying next lease matching client id: %s",
4345 piaddr (uid_lease
-> ip_addr
));
4348 #if defined (FAILOVER_PROTOCOL)
4350 * When we lookup a lease by uid, we know the client identifier
4351 * matches the lease's record. If it is active, or was last
4352 * active with the same client, we can trivially extend it.
4353 * If is not or was not active, we can allocate it to this
4354 * client if it matches the usual free/backup criteria (which
4355 * is contained in lease_mine_to_reallocate()).
4357 if (uid_lease
->binding_state
!= FTS_ACTIVE
&&
4358 uid_lease
->rewind_binding_state
!= FTS_ACTIVE
&&
4359 !lease_mine_to_reallocate(uid_lease
)) {
4360 #if defined (DEBUG_FIND_LEASE)
4361 log_info("not active or not mine to allocate: %s",
4362 piaddr(uid_lease
->ip_addr
));
4368 if (uid_lease
-> subnet
-> shared_network
!= share
) {
4369 #if defined (DEBUG_FIND_LEASE)
4370 log_info ("wrong network segment: %s",
4371 piaddr (uid_lease
-> ip_addr
));
4373 /* Allow multiple leases using the same UID
4374 on different subnetworks. */
4375 do_release
= ISC_FALSE
;
4379 if ((uid_lease
-> pool
-> prohibit_list
&&
4380 permitted (packet
, uid_lease
-> pool
-> prohibit_list
)) ||
4381 (uid_lease
-> pool
-> permit_list
&&
4382 !permitted (packet
, uid_lease
-> pool
-> permit_list
))) {
4383 #if defined (DEBUG_FIND_LEASE)
4384 log_info ("not permitted: %s",
4385 piaddr (uid_lease
-> ip_addr
));
4388 if (uid_lease
-> n_uid
)
4389 lease_reference (&next
,
4390 uid_lease
-> n_uid
, MDL
);
4392 release_lease (uid_lease
, packet
);
4393 lease_dereference (&uid_lease
, MDL
);
4395 lease_reference (&uid_lease
, next
, MDL
);
4396 lease_dereference (&next
, MDL
);
4402 #if defined (DEBUG_FIND_LEASE)
4404 log_info ("Found lease for client id: %s.",
4405 piaddr (uid_lease
-> ip_addr
));
4408 /* Find a lease whose hardware address matches, whose client
4409 * identifier matches (or equally doesn't have one), that's
4410 * permitted, and that's on the correct subnet.
4412 * Note that the n_hw chain is sorted in order of preference, so
4413 * the first one found is the best one.
4415 h
.hlen
= packet
-> raw
-> hlen
+ 1;
4416 h
.hbuf
[0] = packet
-> raw
-> htype
;
4417 memcpy (&h
.hbuf
[1], packet
-> raw
-> chaddr
, packet
-> raw
-> hlen
);
4418 find_lease_by_hw_addr (&hw_lease
, h
.hbuf
, h
.hlen
, MDL
);
4420 #if defined (DEBUG_FIND_LEASE)
4421 log_info ("trying next lease matching hw addr: %s",
4422 piaddr (hw_lease
-> ip_addr
));
4424 #if defined (FAILOVER_PROTOCOL)
4426 * When we lookup a lease by chaddr, we know the MAC address
4427 * matches the lease record (we will check if the lease has a
4428 * client-id the client does not next). If the lease is
4429 * currently active or was last active with this client, we can
4430 * trivially extend it. Otherwise, there are a set of rules
4431 * that govern if we can reallocate this lease to any client
4432 * ("lease_mine_to_reallocate()") including this one.
4434 if (hw_lease
->binding_state
!= FTS_ACTIVE
&&
4435 hw_lease
->rewind_binding_state
!= FTS_ACTIVE
&&
4436 !lease_mine_to_reallocate(hw_lease
)) {
4437 #if defined (DEBUG_FIND_LEASE)
4438 log_info("not active or not mine to allocate: %s",
4439 piaddr(hw_lease
->ip_addr
));
4446 * This conditional skips "potentially active" leases (leases
4447 * we think are expired may be extended by the peer, etc) that
4448 * may be assigned to a differently /client-identified/ client
4449 * with the same MAC address.
4451 if (hw_lease
-> binding_state
!= FTS_FREE
&&
4452 hw_lease
-> binding_state
!= FTS_BACKUP
&&
4454 (!have_client_identifier
||
4455 hw_lease
-> uid_len
!= client_identifier
.len
||
4456 memcmp (hw_lease
-> uid
, client_identifier
.data
,
4457 hw_lease
-> uid_len
))) {
4458 #if defined (DEBUG_FIND_LEASE)
4459 log_info ("wrong client identifier: %s",
4460 piaddr (hw_lease
-> ip_addr
));
4464 if (hw_lease
-> subnet
-> shared_network
!= share
) {
4465 #if defined (DEBUG_FIND_LEASE)
4466 log_info ("wrong network segment: %s",
4467 piaddr (hw_lease
-> ip_addr
));
4471 if ((hw_lease
-> pool
-> prohibit_list
&&
4472 permitted (packet
, hw_lease
-> pool
-> prohibit_list
)) ||
4473 (hw_lease
-> pool
-> permit_list
&&
4474 !permitted (packet
, hw_lease
-> pool
-> permit_list
))) {
4475 #if defined (DEBUG_FIND_LEASE)
4476 log_info ("not permitted: %s",
4477 piaddr (hw_lease
-> ip_addr
));
4479 if (!packet
-> raw
-> ciaddr
.s_addr
)
4480 release_lease (hw_lease
, packet
);
4482 if (hw_lease
-> n_hw
)
4483 lease_reference (&next
, hw_lease
-> n_hw
, MDL
);
4484 lease_dereference (&hw_lease
, MDL
);
4486 lease_reference (&hw_lease
, next
, MDL
);
4487 lease_dereference (&next
, MDL
);
4493 #if defined (DEBUG_FIND_LEASE)
4495 log_info ("Found lease for hardware address: %s.",
4496 piaddr (hw_lease
-> ip_addr
));
4499 /* Try to find a lease that's been allocated to the client's
4502 lease_reference (&ip_lease
, ip_lease_in
, MDL
);
4504 find_lease_by_ip_addr (&ip_lease
, cip
, MDL
);
4506 #if defined (DEBUG_FIND_LEASE)
4508 log_info ("Found lease for requested address: %s.",
4509 piaddr (ip_lease
-> ip_addr
));
4512 /* If ip_lease is valid at this point, set ours to one, so that
4513 even if we choose a different lease, we know that the address
4514 the client was requesting was ours, and thus we can NAK it. */
4515 if (ip_lease
&& ours
)
4518 /* If the requested IP address isn't on the network the packet
4519 came from, don't use it. Allow abandoned leases to be matched
4520 here - if the client is requesting it, there's a decent chance
4521 that it's because the lease database got trashed and a client
4522 that thought it had this lease answered an ARP or PING, causing the
4523 lease to be abandoned. If so, this request probably came from
4525 if (ip_lease
&& (ip_lease
-> subnet
-> shared_network
!= share
)) {
4528 #if defined (DEBUG_FIND_LEASE)
4529 log_info ("...but it was on the wrong shared network.");
4531 strcpy (dhcp_message
, "requested address on bad subnet");
4532 lease_dereference (&ip_lease
, MDL
);
4536 * If the requested address is in use (or potentially in use) by
4537 * a different client, it can't be granted.
4539 * This first conditional only detects if the lease is currently
4540 * identified to a different client (client-id and/or chaddr
4541 * mismatch). In this case we may not want to give the client the
4542 * lease, if doing so may potentially be an addressing conflict.
4546 (!have_client_identifier
||
4547 ip_lease
-> uid_len
!= client_identifier
.len
||
4548 memcmp (ip_lease
-> uid
, client_identifier
.data
,
4549 ip_lease
-> uid_len
)) :
4550 (ip_lease
-> hardware_addr
.hbuf
[0] != packet
-> raw
-> htype
||
4551 ip_lease
-> hardware_addr
.hlen
!= packet
-> raw
-> hlen
+ 1 ||
4552 memcmp (&ip_lease
-> hardware_addr
.hbuf
[1],
4553 packet
-> raw
-> chaddr
,
4554 (unsigned)(ip_lease
-> hardware_addr
.hlen
- 1))))) {
4556 * A lease is unavailable for allocation to a new client if
4557 * it is not in the FREE or BACKUP state. There may be
4558 * leases that are in the expired state with a rewinding
4559 * state that is free or backup, but these will be processed
4560 * into the free or backup states by expiration processes, so
4561 * checking for them here is superfluous.
4563 if (ip_lease
-> binding_state
!= FTS_FREE
&&
4564 ip_lease
-> binding_state
!= FTS_BACKUP
) {
4565 #if defined (DEBUG_FIND_LEASE)
4566 log_info ("rejecting lease for requested address.");
4568 /* If we're rejecting it because the peer has
4569 it, don't set "ours", because we shouldn't NAK. */
4570 if (ours
&& ip_lease
-> binding_state
!= FTS_ACTIVE
)
4572 lease_dereference (&ip_lease
, MDL
);
4577 * If we got an ip_lease and a uid_lease or hw_lease, and ip_lease
4578 * is/was not active, and is not ours to reallocate, forget about it.
4580 if (ip_lease
&& (uid_lease
|| hw_lease
) &&
4581 ip_lease
->binding_state
!= FTS_ACTIVE
&&
4582 ip_lease
->rewind_binding_state
!= FTS_ACTIVE
&&
4583 #if defined(FAILOVER_PROTOCOL)
4584 !lease_mine_to_reallocate(ip_lease
) &&
4586 packet
->packet_type
== DHCPDISCOVER
) {
4587 #if defined (DEBUG_FIND_LEASE)
4588 log_info("ip lease not active or not ours to offer.");
4590 lease_dereference(&ip_lease
, MDL
);
4593 /* If for some reason the client has more than one lease
4594 on the subnet that matches its uid, pick the one that
4595 it asked for and (if we can) free the other. */
4596 if (ip_lease
&& ip_lease
->binding_state
== FTS_ACTIVE
&&
4597 ip_lease
->uid
&& ip_lease
!= uid_lease
) {
4598 if (have_client_identifier
&&
4599 (ip_lease
-> uid_len
== client_identifier
.len
) &&
4600 !memcmp (client_identifier
.data
,
4601 ip_lease
-> uid
, ip_lease
-> uid_len
)) {
4603 if (uid_lease
->binding_state
== FTS_ACTIVE
) {
4604 log_error ("client %s has duplicate%s on %s",
4606 (packet
-> raw
-> htype
,
4607 packet
-> raw
-> hlen
,
4608 packet
-> raw
-> chaddr
)),
4610 (ip_lease
-> subnet
->
4611 shared_network
-> name
));
4613 /* If the client is REQUESTing the lease,
4614 it shouldn't still be using the old
4615 one, so we can free it for allocation. */
4617 uid_lease
->binding_state
== FTS_ACTIVE
&&
4618 !packet
-> raw
-> ciaddr
.s_addr
&&
4620 uid_lease
-> subnet
-> shared_network
) &&
4621 packet
-> packet_type
== DHCPREQUEST
)
4622 release_lease (uid_lease
, packet
);
4624 lease_dereference (&uid_lease
, MDL
);
4625 lease_reference (&uid_lease
, ip_lease
, MDL
);
4629 /* If we get to here and fixed_lease is not null, that means
4630 that there are both a dynamic lease and a fixed-address
4631 declaration for the same IP address. */
4632 if (packet
-> packet_type
== DHCPREQUEST
&& fixed_lease
) {
4633 lease_dereference (&fixed_lease
, MDL
);
4635 log_error ("Dynamic and static leases present for %s.",
4637 log_error ("Remove host declaration %s or remove %s",
4638 (fixed_lease
&& fixed_lease
-> host
4639 ? (fixed_lease
-> host
-> name
4640 ? fixed_lease
-> host
-> name
4644 log_error ("from the dynamic address pool for %s",
4645 ip_lease
-> subnet
-> shared_network
-> name
4648 lease_dereference (&ip_lease
, MDL
);
4649 strcpy (dhcp_message
,
4650 "database conflict - call for help!");
4653 if (ip_lease
&& ip_lease
!= uid_lease
) {
4654 #if defined (DEBUG_FIND_LEASE)
4655 log_info ("requested address not available.");
4657 lease_dereference (&ip_lease
, MDL
);
4661 /* If we get to here with both fixed_lease and ip_lease not
4662 null, then we have a configuration file bug. */
4663 if (packet
-> packet_type
== DHCPREQUEST
&& fixed_lease
&& ip_lease
)
4666 /* Toss extra pointers to the same lease... */
4667 if (hw_lease
&& hw_lease
== uid_lease
) {
4668 #if defined (DEBUG_FIND_LEASE)
4669 log_info ("hardware lease and uid lease are identical.");
4671 lease_dereference (&hw_lease
, MDL
);
4673 if (ip_lease
&& ip_lease
== hw_lease
) {
4674 lease_dereference (&hw_lease
, MDL
);
4675 #if defined (DEBUG_FIND_LEASE)
4676 log_info ("hardware lease and ip lease are identical.");
4679 if (ip_lease
&& ip_lease
== uid_lease
) {
4680 lease_dereference (&uid_lease
, MDL
);
4681 #if defined (DEBUG_FIND_LEASE)
4682 log_info ("uid lease and ip lease are identical.");
4686 /* Make sure the client is permitted to use the requested lease. */
4688 ((ip_lease
-> pool
-> prohibit_list
&&
4689 permitted (packet
, ip_lease
-> pool
-> prohibit_list
)) ||
4690 (ip_lease
-> pool
-> permit_list
&&
4691 !permitted (packet
, ip_lease
-> pool
-> permit_list
)))) {
4692 if (!packet
->raw
->ciaddr
.s_addr
&&
4693 (ip_lease
->binding_state
== FTS_ACTIVE
))
4694 release_lease (ip_lease
, packet
);
4696 lease_dereference (&ip_lease
, MDL
);
4700 ((uid_lease
-> pool
-> prohibit_list
&&
4701 permitted (packet
, uid_lease
-> pool
-> prohibit_list
)) ||
4702 (uid_lease
-> pool
-> permit_list
&&
4703 !permitted (packet
, uid_lease
-> pool
-> permit_list
)))) {
4704 if (!packet
-> raw
-> ciaddr
.s_addr
)
4705 release_lease (uid_lease
, packet
);
4706 lease_dereference (&uid_lease
, MDL
);
4710 ((hw_lease
-> pool
-> prohibit_list
&&
4711 permitted (packet
, hw_lease
-> pool
-> prohibit_list
)) ||
4712 (hw_lease
-> pool
-> permit_list
&&
4713 !permitted (packet
, hw_lease
-> pool
-> permit_list
)))) {
4714 if (!packet
-> raw
-> ciaddr
.s_addr
)
4715 release_lease (hw_lease
, packet
);
4716 lease_dereference (&hw_lease
, MDL
);
4719 /* If we've already eliminated the lease, it wasn't there to
4720 begin with. If we have come up with a matching lease,
4721 set the message to bad network in case we have to throw it out. */
4723 strcpy (dhcp_message
, "requested address not available");
4726 /* If this is a DHCPREQUEST, make sure the lease we're going to return
4727 matches the requested IP address. If it doesn't, don't return a
4729 if (packet
-> packet_type
== DHCPREQUEST
&&
4730 !ip_lease
&& !fixed_lease
) {
4731 #if defined (DEBUG_FIND_LEASE)
4732 log_info ("no applicable lease found for DHCPREQUEST.");
4737 /* At this point, if fixed_lease is nonzero, we can assign it to
4740 lease_reference (&lease
, fixed_lease
, MDL
);
4741 lease_dereference (&fixed_lease
, MDL
);
4742 #if defined (DEBUG_FIND_LEASE)
4743 log_info ("choosing fixed address.");
4747 /* If we got a lease that matched the ip address and don't have
4748 a better offer, use that; otherwise, release it. */
4751 if (!packet
-> raw
-> ciaddr
.s_addr
)
4752 release_lease (ip_lease
, packet
);
4753 #if defined (DEBUG_FIND_LEASE)
4754 log_info ("not choosing requested address (!).");
4756 lease_dereference (&ip_lease
, MDL
);
4758 #if defined (DEBUG_FIND_LEASE)
4759 log_info ("choosing lease on requested address.");
4761 lease_reference (&lease
, ip_lease
, MDL
);
4763 host_dereference (&lease
-> host
, MDL
);
4767 /* If we got a lease that matched the client identifier, we may want
4768 to use it, but if we already have a lease we like, we must free
4769 the lease that matched the client identifier. */
4772 log_error("uid lease %s for client %s is duplicate "
4774 piaddr(uid_lease
->ip_addr
),
4775 print_hw_addr(packet
->raw
->htype
,
4777 packet
->raw
->chaddr
),
4778 uid_lease
->subnet
->shared_network
->name
);
4780 if (!packet
-> raw
-> ciaddr
.s_addr
&&
4781 packet
-> packet_type
== DHCPREQUEST
&&
4782 uid_lease
-> binding_state
== FTS_ACTIVE
)
4783 release_lease(uid_lease
, packet
);
4784 #if defined (DEBUG_FIND_LEASE)
4785 log_info ("not choosing uid lease.");
4788 lease_reference (&lease
, uid_lease
, MDL
);
4790 host_dereference (&lease
-> host
, MDL
);
4791 #if defined (DEBUG_FIND_LEASE)
4792 log_info ("choosing uid lease.");
4795 lease_dereference (&uid_lease
, MDL
);
4798 /* The lease that matched the hardware address is treated likewise. */
4801 #if defined (DEBUG_FIND_LEASE)
4802 log_info ("not choosing hardware lease.");
4805 /* We're a little lax here - if the client didn't
4806 send a client identifier and it's a bootp client,
4807 but the lease has a client identifier, we still
4808 let the client have a lease. */
4809 if (!hw_lease
-> uid_len
||
4810 (have_client_identifier
4811 ? (hw_lease
-> uid_len
==
4812 client_identifier
.len
&&
4813 !memcmp (hw_lease
-> uid
,
4814 client_identifier
.data
,
4815 client_identifier
.len
))
4816 : packet
-> packet_type
== 0)) {
4817 lease_reference (&lease
, hw_lease
, MDL
);
4819 host_dereference (&lease
-> host
, MDL
);
4820 #if defined (DEBUG_FIND_LEASE)
4821 log_info ("choosing hardware lease.");
4824 #if defined (DEBUG_FIND_LEASE)
4825 log_info ("not choosing hardware lease: %s.",
4830 lease_dereference (&hw_lease
, MDL
);
4834 * If we found a host_decl but no matching address, try to
4835 * find a host_decl that has no address, and if there is one,
4836 * hang it off the lease so that we can use the supplied
4839 if (lease
&& host
&& !lease
->host
) {
4840 struct host_decl
*p
= NULL
;
4841 struct host_decl
*n
= NULL
;
4843 host_reference(&p
, host
, MDL
);
4845 if (!p
->fixed_addr
) {
4847 * If the lease is currently active, then it
4848 * must be allocated to the present client.
4849 * We store a reference to the host record on
4850 * the lease to save a lookup later (in
4851 * ack_lease()). We mustn't refer to the host
4852 * record on non-active leases because the
4853 * client may be denied later.
4855 * XXX: Not having this reference (such as in
4856 * DHCPDISCOVER/INIT) means ack_lease will have
4857 * to perform this lookup a second time. This
4858 * hopefully isn't a problem as DHCPREQUEST is
4859 * more common than DHCPDISCOVER.
4861 if (lease
->binding_state
== FTS_ACTIVE
)
4862 host_reference(&lease
->host
, p
, MDL
);
4864 host_dereference(&p
, MDL
);
4867 if (p
->n_ipaddr
!= NULL
)
4868 host_reference(&n
, p
->n_ipaddr
, MDL
);
4869 host_dereference(&p
, MDL
);
4871 host_reference(&p
, n
, MDL
);
4872 host_dereference(&n
, MDL
);
4877 /* If we find an abandoned lease, but it's the one the client
4878 requested, we assume that previous bugginess on the part
4879 of the client, or a server database loss, caused the lease to
4880 be abandoned, so we reclaim it and let the client have it. */
4882 (lease
-> binding_state
== FTS_ABANDONED
) &&
4883 lease
== ip_lease
&&
4884 packet
-> packet_type
== DHCPREQUEST
) {
4885 log_error ("Reclaiming REQUESTed abandoned IP address %s.",
4886 piaddr (lease
-> ip_addr
));
4887 } else if (lease
&& (lease
-> binding_state
== FTS_ABANDONED
)) {
4888 /* Otherwise, if it's not the one the client requested, we do not
4889 return it - instead, we claim it's ours, causing a DHCPNAK to be
4890 sent if this lookup is for a DHCPREQUEST, and force the client
4891 to go back through the allocation process. */
4894 lease_dereference (&lease
, MDL
);
4898 if (have_client_identifier
)
4899 data_string_forget (&client_identifier
, MDL
);
4902 lease_dereference (&fixed_lease
, MDL
);
4904 lease_dereference (&hw_lease
, MDL
);
4906 lease_dereference (&uid_lease
, MDL
);
4908 lease_dereference (&ip_lease
, MDL
);
4910 host_dereference (&host
, MDL
);
4913 #if defined (DEBUG_FIND_LEASE)
4914 log_info ("Returning lease: %s.",
4915 piaddr (lease
-> ip_addr
));
4917 lease_reference (lp
, lease
, file
, line
);
4918 lease_dereference (&lease
, MDL
);
4921 #if defined (DEBUG_FIND_LEASE)
4922 log_info ("Not returning a lease.");
4927 /* Search the provided host_decl structure list for an address that's on
4928 the specified shared network. If one is found, mock up and return a
4929 lease structure for it; otherwise return the null pointer. */
4931 int mockup_lease (struct lease
**lp
, struct packet
*packet
,
4932 struct shared_network
*share
, struct host_decl
*hp
)
4934 struct lease
*lease
= (struct lease
*)0;
4935 struct host_decl
*rhp
= (struct host_decl
*)0;
4937 if (lease_allocate (&lease
, MDL
) != ISC_R_SUCCESS
)
4939 if (host_reference (&rhp
, hp
, MDL
) != ISC_R_SUCCESS
) {
4940 lease_dereference (&lease
, MDL
);
4943 if (!find_host_for_network (&lease
-> subnet
,
4944 &rhp
, &lease
-> ip_addr
, share
)) {
4945 lease_dereference (&lease
, MDL
);
4946 host_dereference (&rhp
, MDL
);
4949 host_reference (&lease
-> host
, rhp
, MDL
);
4950 if (rhp
-> client_identifier
.len
> sizeof lease
-> uid_buf
)
4951 lease
-> uid
= dmalloc (rhp
-> client_identifier
.len
, MDL
);
4953 lease
-> uid
= lease
-> uid_buf
;
4954 if (!lease
-> uid
) {
4955 lease_dereference (&lease
, MDL
);
4956 host_dereference (&rhp
, MDL
);
4959 memcpy (lease
-> uid
, rhp
-> client_identifier
.data
,
4960 rhp
-> client_identifier
.len
);
4961 lease
-> uid_len
= rhp
-> client_identifier
.len
;
4962 lease
-> hardware_addr
= rhp
-> interface
;
4963 lease
-> starts
= lease
-> cltt
= lease
-> ends
= MIN_TIME
;
4964 lease
-> flags
= STATIC_LEASE
;
4965 lease
-> binding_state
= FTS_FREE
;
4967 lease_reference (lp
, lease
, MDL
);
4969 lease_dereference (&lease
, MDL
);
4970 host_dereference (&rhp
, MDL
);
4974 /* Look through all the pools in a list starting with the specified pool
4975 for a free lease. We try to find a virgin lease if we can. If we
4976 don't find a virgin lease, we try to find a non-virgin lease that's
4977 free. If we can't find one of those, we try to reclaim an abandoned
4978 lease. If all of these possibilities fail to pan out, we don't return
4981 int allocate_lease (struct lease
**lp
, struct packet
*packet
,
4982 struct pool
*pool
, int *peer_has_leases
)
4984 struct lease
*lease
= NULL
;
4985 struct lease
*candl
= NULL
;
4987 for (; pool
; pool
= pool
-> next
) {
4988 if ((pool
-> prohibit_list
&&
4989 permitted (packet
, pool
-> prohibit_list
)) ||
4990 (pool
-> permit_list
&&
4991 !permitted (packet
, pool
-> permit_list
)))
4994 #if defined (FAILOVER_PROTOCOL)
4995 /* Peer_has_leases just says that we found at least one
4996 free lease. If no free lease is returned, the caller
4997 can deduce that this means the peer is hogging all the
4998 free leases, so we can print a better error message. */
4999 /* XXX Do we need code here to ignore PEER_IS_OWNER and
5000 * XXX just check tstp if we're in, e.g., PARTNER_DOWN?
5001 * XXX Where do we deal with CONFLICT_DETECTED, et al? */
5002 /* XXX This should be handled by the lease binding "state
5003 * XXX machine" - that is, when we get here, if a lease
5004 * XXX could be allocated, it will have the correct
5005 * XXX binding state so that the following code will
5006 * XXX result in its being allocated. */
5007 /* Skip to the most expired lease in the pool that is not
5008 * owned by a failover peer. */
5009 if (pool
->failover_peer
!= NULL
) {
5010 struct lease
*peerl
= NULL
;
5011 if (pool
->failover_peer
->i_am
== primary
) {
5012 candl
= LEASE_GET_FIRST(pool
->free
);
5015 * In normal operation, we never want to touch
5016 * the peer's leases. In partner-down
5017 * operation, we need to be able to pick up
5018 * the peer's leases after STOS+MCLT.
5020 peerl
= LEASE_GET_FIRST(pool
->backup
);
5021 if (peerl
!= NULL
) {
5022 if (((candl
== NULL
) ||
5023 (candl
->ends
> peerl
->ends
)) &&
5024 lease_mine_to_reallocate(peerl
)) {
5027 *peer_has_leases
= 1;
5031 candl
= LEASE_GET_FIRST(pool
->backup
);
5033 peerl
= LEASE_GET_FIRST(pool
->free
);
5034 if (peerl
!= NULL
) {
5035 if (((candl
== NULL
) ||
5036 (candl
->ends
> peerl
->ends
)) &&
5037 lease_mine_to_reallocate(peerl
)) {
5040 *peer_has_leases
= 1;
5045 /* Try abandoned leases as a last resort. */
5046 peerl
= LEASE_GET_FIRST(pool
->abandoned
);
5047 if ((candl
== NULL
) && (peerl
!= NULL
) &&
5048 lease_mine_to_reallocate(peerl
))
5053 if (LEASE_NOT_EMPTY(pool
->free
))
5054 candl
= LEASE_GET_FIRST(pool
->free
);
5056 candl
= LEASE_GET_FIRST(pool
->abandoned
);
5060 * XXX: This may not match with documented expectation.
5061 * It's expected that when we OFFER a lease, we set its
5062 * ends time forward 2 minutes so that it gets sorted to
5063 * the end of its free list (avoiding a similar allocation
5064 * to another client). It is not expected that we issue a
5065 * "no free leases" error when the last lease has been
5066 * offered, but it's not exactly broken either.
5069 (candl
->binding_state
!= FTS_ABANDONED
&&
5070 (candl
->ends
> cur_time
))) {
5080 * There are tiers of lease state preference, listed here in
5081 * reverse order (least to most preferential):
5086 * If the selected lease and candidate are both of the same
5087 * state, select the oldest (longest ago) expiration time
5088 * between the two. If the candidate lease is of a higher
5089 * preferred grade over the selected lease, use it.
5091 if ((lease
-> binding_state
== FTS_ABANDONED
) &&
5092 ((candl
-> binding_state
!= FTS_ABANDONED
) ||
5093 (candl
-> ends
< lease
-> ends
))) {
5096 } else if (candl
-> binding_state
== FTS_ABANDONED
)
5099 if ((lease
-> uid_len
|| lease
-> hardware_addr
.hlen
) &&
5100 ((!candl
-> uid_len
&& !candl
-> hardware_addr
.hlen
) ||
5101 (candl
-> ends
< lease
-> ends
))) {
5104 } else if (candl
-> uid_len
|| candl
-> hardware_addr
.hlen
)
5107 if (candl
-> ends
< lease
-> ends
)
5111 if (lease
!= NULL
) {
5112 if (lease
->binding_state
== FTS_ABANDONED
)
5113 log_error("Reclaiming abandoned lease %s.",
5114 piaddr(lease
->ip_addr
));
5117 * XXX: For reliability, we go ahead and remove the host
5118 * record and try to move on. For correctness, if there
5119 * are any other stale host vectors, we want to find them.
5121 if (lease
->host
!= NULL
) {
5122 log_debug("soft impossible condition (%s:%d): stale "
5123 "host \"%s\" found on lease %s", MDL
,
5125 piaddr(lease
->ip_addr
));
5126 host_dereference(&lease
->host
, MDL
);
5129 lease_reference (lp
, lease
, MDL
);
5136 /* Determine whether or not a permit exists on a particular permit list
5137 that matches the specified packet, returning nonzero if so, zero if
5140 int permitted (packet
, permit_list
)
5141 struct packet
*packet
;
5142 struct permit
*permit_list
;
5147 for (p
= permit_list
; p
; p
= p
-> next
) {
5148 switch (p
-> type
) {
5149 case permit_unknown_clients
:
5150 if (!packet
-> known
)
5154 case permit_known_clients
:
5155 if (packet
-> known
)
5159 case permit_authenticated_clients
:
5160 if (packet
-> authenticated
)
5164 case permit_unauthenticated_clients
:
5165 if (!packet
-> authenticated
)
5169 case permit_all_clients
:
5172 case permit_dynamic_bootp_clients
:
5173 if (!packet
-> options_valid
||
5174 !packet
-> packet_type
)
5179 for (i
= 0; i
< packet
-> class_count
; i
++) {
5180 if (p
-> class == packet
-> classes
[i
])
5182 if (packet
-> classes
[i
] &&
5183 packet
-> classes
[i
] -> superclass
&&
5184 (packet
-> classes
[i
] -> superclass
==
5191 if (cur_time
> p
->after
)
5199 #if defined(DHCPv6) && defined(DHCP4o6)
5200 static int locate_network6 (packet
)
5201 struct packet
*packet
;
5203 const struct packet
*chk_packet
;
5204 const struct in6_addr
*link_addr
, *first_link_addr
;
5206 struct data_string data
;
5207 struct subnet
*subnet
= NULL
;
5208 struct option_cache
*oc
;
5210 /* from locate_network() */
5212 /* See if there's a Relay Agent Link Selection Option, or a
5213 * Subnet Selection Option. The Link-Select and Subnet-Select
5214 * are formatted and used precisely the same, but we must prefer
5215 * the link-select over the subnet-select.
5216 * BTW in DHCPv4 over DHCPv6 no cross version relay was specified
5217 * so it is unlikely to see a link-select.
5219 if ((oc
= lookup_option(&agent_universe
, packet
->options
,
5220 RAI_LINK_SELECT
)) == NULL
)
5221 oc
= lookup_option(&dhcp_universe
, packet
->options
,
5222 DHO_SUBNET_SELECTION
);
5224 /* If there's an option indicating link connection or subnet
5225 * selection, and it's valid, use it to figure out the subnet.
5226 * If it's not valid, fail.
5229 memset(&data
, 0, sizeof data
);
5230 if (!evaluate_option_cache(&data
, packet
, NULL
, NULL
,
5231 packet
->options
, NULL
,
5232 &global_scope
, oc
, MDL
)) {
5235 if (data
.len
== 0) {
5238 if (data
.len
!= 4) {
5239 data_string_forget(&data
, MDL
);
5243 memcpy(ia
.iabuf
, data
.data
, 4);
5244 data_string_forget(&data
, MDL
);
5246 if (find_subnet(&subnet
, ia
, MDL
)) {
5247 shared_network_reference(&packet
->shared_network
,
5248 subnet
->shared_network
, MDL
);
5249 subnet_dereference(&subnet
, MDL
);
5255 /* See if there is a giaddr (still unlikely), if there is one
5256 * use it to figure out the subnet. If it's not valid, fail.
5258 if (packet
->raw
->giaddr
.s_addr
) {
5260 memcpy(ia
.iabuf
, &packet
->raw
->giaddr
, 4);
5262 if (find_subnet(&subnet
, ia
, MDL
)) {
5263 shared_network_reference(&packet
->shared_network
,
5264 subnet
->shared_network
, MDL
);
5265 subnet_dereference(&subnet
, MDL
);
5271 /* from shared_network_from_packet6() */
5273 /* First, find the link address where the packet from the client
5274 * first appeared (if this packet was relayed).
5276 first_link_addr
= NULL
;
5277 chk_packet
= packet
->dhcpv6_container_packet
;
5278 while (chk_packet
!= NULL
) {
5279 link_addr
= &chk_packet
->dhcpv6_link_address
;
5280 if (!IN6_IS_ADDR_UNSPECIFIED(link_addr
) &&
5281 !IN6_IS_ADDR_LINKLOCAL(link_addr
)) {
5282 first_link_addr
= link_addr
;
5285 chk_packet
= chk_packet
->dhcpv6_container_packet
;
5288 /* If there is a relayed link address, find the subnet associated
5289 * with that, and use that to get the appropriate shared_network.
5291 if (first_link_addr
!= NULL
) {
5292 ia
.len
= sizeof(*first_link_addr
);
5293 memcpy(ia
.iabuf
, first_link_addr
, sizeof(*first_link_addr
));
5294 if (find_subnet (&subnet
, ia
, MDL
)) {
5295 shared_network_reference(&packet
->shared_network
,
5296 subnet
->shared_network
, MDL
);
5297 subnet_dereference(&subnet
, MDL
);
5303 /* If there is no link address, we will use the interface
5304 * that this packet came in on to pick the shared_network.
5306 if (packet
->interface
!= NULL
) {
5307 if (packet
->interface
->shared_network
== NULL
)
5309 shared_network_reference(&packet
->shared_network
,
5310 packet
->interface
->shared_network
,
5315 /* We shouldn't be able to get here but if there is no link
5316 * address and no interface we don't know where to get the
5317 * shared_network from, log an error and return an error.
5319 log_error("No interface and no link address "
5320 "can't determine DHCP4o6 shared network");
5325 int locate_network (packet
)
5326 struct packet
*packet
;
5329 struct data_string data
;
5330 struct subnet
*subnet
= (struct subnet
*)0;
5331 struct option_cache
*oc
;
5333 #if defined(DHCPv6) && defined(DHCP4o6)
5334 if (dhcpv4_over_dhcpv6
&& (packet
->dhcp4o6_response
!= NULL
)) {
5335 return (locate_network6 (packet
));
5339 /* See if there's a Relay Agent Link Selection Option, or a
5340 * Subnet Selection Option. The Link-Select and Subnet-Select
5341 * are formatted and used precisely the same, but we must prefer
5342 * the link-select over the subnet-select.
5344 if ((oc
= lookup_option(&agent_universe
, packet
->options
,
5345 RAI_LINK_SELECT
)) == NULL
)
5346 oc
= lookup_option(&dhcp_universe
, packet
->options
,
5347 DHO_SUBNET_SELECTION
);
5349 /* If there's no SSO and no giaddr, then use the shared_network
5350 from the interface, if there is one. If not, fail. */
5351 if (!oc
&& !packet
-> raw
-> giaddr
.s_addr
) {
5352 if (packet
-> interface
-> shared_network
) {
5353 shared_network_reference
5354 (&packet
-> shared_network
,
5355 packet
-> interface
-> shared_network
, MDL
);
5361 /* If there's an option indicating link connection, and it's valid,
5362 * use it to figure out the subnet. If it's not valid, fail.
5365 memset (&data
, 0, sizeof data
);
5366 if (!evaluate_option_cache (&data
, packet
, (struct lease
*)0,
5367 (struct client_state
*)0,
5369 (struct option_state
*)0,
5370 &global_scope
, oc
, MDL
)) {
5373 if (data
.len
== 0) {
5376 if (data
.len
!= 4) {
5377 data_string_forget (&data
, MDL
);
5381 memcpy (ia
.iabuf
, data
.data
, 4);
5382 data_string_forget (&data
, MDL
);
5385 memcpy (ia
.iabuf
, &packet
-> raw
-> giaddr
, 4);
5388 /* If we know the subnet on which the IP address lives, use it. */
5389 if (find_subnet (&subnet
, ia
, MDL
)) {
5390 shared_network_reference (&packet
-> shared_network
,
5391 subnet
-> shared_network
, MDL
);
5392 subnet_dereference (&subnet
, MDL
);
5396 /* Otherwise, fail. */
5401 * Try to figure out the source address to send packets from.
5403 * from is the address structure we use to return any address
5406 * options is the option cache to search. This may include
5407 * options from the incoming packet and configuration information.
5409 * out_options is the outgoing option cache. This cache
5410 * may be the same as options. If out_options isn't NULL
5411 * we may save the server address option into it. We do so
5412 * if out_options is different than options or if the option
5413 * wasn't in options and we needed to find the address elsewhere.
5415 * packet is the state structure for the incoming packet
5417 * When finding the address we first check to see if it is
5418 * in the options list. If it isn't we use the first address
5419 * from the interface.
5421 * While this is slightly more complicated than I'd like it allows
5422 * us to use the same code in several different places. ack,
5423 * inform and lease query use it to find the address and fill
5424 * in the options if we get the address from the interface.
5425 * nack uses it to find the address and copy it to the outgoing
5426 * cache. dhcprequest uses it to find the address for comparison
5427 * and doesn't need to add it to an outgoing list.
5431 get_server_source_address(struct in_addr
*from
,
5432 struct option_state
*options
,
5433 struct option_state
*out_options
,
5434 struct packet
*packet
) {
5435 unsigned option_num
;
5436 struct option_cache
*oc
= NULL
;
5437 struct data_string d
;
5438 struct in_addr
*a
= NULL
;
5439 isc_boolean_t found
= ISC_FALSE
;
5442 memset(&d
, 0, sizeof(d
));
5443 memset(from
, 0, sizeof(*from
));
5445 option_num
= DHO_DHCP_SERVER_IDENTIFIER
;
5446 oc
= lookup_option(&dhcp_universe
, options
, option_num
);
5448 if (evaluate_option_cache(&d
, packet
, NULL
, NULL
,
5449 packet
->options
, options
,
5450 &global_scope
, oc
, MDL
)) {
5451 if (d
.len
== sizeof(*from
)) {
5453 memcpy(from
, d
.data
, sizeof(*from
));
5456 * Arrange to save a copy of the data
5457 * to the outgoing list.
5459 if ((out_options
!= NULL
) &&
5460 (options
!= out_options
)) {
5465 data_string_forget(&d
, MDL
);
5470 if ((found
== ISC_FALSE
) &&
5471 (packet
->interface
->address_count
> 0)) {
5472 *from
= packet
->interface
->addresses
[0];
5474 if (out_options
!= NULL
) {
5475 a
= &packet
->interface
->addresses
[0];
5480 (option_cache_allocate(&oc
, MDL
))) {
5481 if (make_const_data(&oc
->expression
,
5482 (unsigned char *)a
, sizeof(*a
),
5483 0, allocate
, MDL
)) {
5484 option_code_hash_lookup(&oc
->option
,
5485 dhcp_universe
.code_hash
,
5486 &option_num
, 0, MDL
);
5487 save_option(&dhcp_universe
, out_options
, oc
);
5489 option_cache_dereference(&oc
, MDL
);
5496 * \brief Builds option set from statements at the global and network scope
5498 * Set up an option state list based on the global and network scopes.
5499 * These are primarily used by NAK logic to locate dhcp-server-id and
5502 * We don't go through all possible options - in particualr we skip the hosts
5503 * and we don't include the lease to avoid making changes to it. This means
5504 * that using these, we won't get the correct server id if the admin puts them
5505 * on hosts or builds the server id with information from the lease.
5507 * As this is a fallback function (used to handle NAKs or sort out server id
5508 * mismatch in failover) and requires configuration by the admin, it should be
5511 * \param network_options option_state to which options will be added. If it
5512 * refers to NULL, it will be allocated. Caller is responsible to delete it.
5513 * \param packet inbound packet
5514 * \param network_group scope group to use if packet->shared_network is null.
5517 eval_network_statements(struct option_state
**network_options
,
5518 struct packet
*packet
,
5519 struct group
*network_group
) {
5521 if (*network_options
== NULL
) {
5522 option_state_allocate (network_options
, MDL
);
5525 /* Use the packet's shared_network if it has one. If not use
5526 * network_group and if it is null then use global scope. */
5527 if (packet
->shared_network
!= NULL
) {
5529 * If we have a subnet and group start with that else start
5530 * with the shared network group. The first will recurse and
5531 * include the second.
5533 if ((packet
->shared_network
->subnets
!= NULL
) &&
5534 (packet
->shared_network
->subnets
->group
!= NULL
)) {
5535 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5536 packet
->options
, *network_options
,
5538 packet
->shared_network
->subnets
->group
,
5541 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5542 packet
->options
, *network_options
,
5544 packet
->shared_network
->group
,
5548 /* do the pool if there is one */
5549 if (packet
->shared_network
->pools
!= NULL
) {
5550 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5551 packet
->options
, *network_options
,
5553 packet
->shared_network
->pools
->group
,
5554 packet
->shared_network
->group
,
5557 } else if (network_group
!= NULL
) {
5558 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5559 packet
->options
, *network_options
,
5560 &global_scope
, network_group
,
5563 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5564 packet
->options
, *network_options
,
5565 &global_scope
, root_group
,
5571 * Look for the lowest numbered site code number and
5572 * apply a log warning if it is less than 224. Do not
5573 * permit site codes less than 128 (old code never did).
5575 * Note that we could search option codes 224 down to 128
5576 * on the hash table, but the table is (probably) smaller
5577 * than that if it was declared as a standalone table with
5578 * defaults. So we traverse the option code hash.
5581 find_min_site_code(struct universe
*u
)
5583 if (u
->site_code_min
)
5584 return u
->site_code_min
;
5587 * Note that site_code_min has to be global as we can't pass an
5588 * argument through hash_foreach(). The value 224 is taken from
5591 site_code_min
= 224;
5592 option_code_hash_foreach(u
->code_hash
, lowest_site_code
);
5594 if (site_code_min
< 224) {
5595 log_error("WARNING: site-local option codes less than 224 have "
5596 "been deprecated by RFC3942. You have options "
5597 "listed in site local space %s that number as low as "
5598 "%d. Please investigate if these should be declared "
5599 "as regular options rather than site-local options, "
5600 "or migrated up past 224.",
5601 u
->name
, site_code_min
);
5605 * don't even bother logging, this is just silly, and never worked
5606 * on any old version of software.
5608 if (site_code_min
< 128)
5609 site_code_min
= 128;
5612 * Cache the determined minimum site code on the universe structure.
5613 * Note that due to the < 128 check above, a value of zero is
5616 u
->site_code_min
= site_code_min
;
5618 return site_code_min
;
5622 lowest_site_code(const void *key
, unsigned len
, void *object
)
5624 struct option
*option
= object
;
5626 if (option
->code
< site_code_min
)
5627 site_code_min
= option
->code
;
5629 return ISC_R_SUCCESS
;
5633 maybe_return_agent_options(struct packet
*packet
, struct option_state
*options
)
5635 /* If there were agent options in the incoming packet, return
5636 * them. Do not return the agent options if they were stashed
5637 * on the lease. We do not check giaddr to detect the presence of
5638 * a relay, as this excludes "l2" relay agents which have no giaddr
5641 * XXX: If the user configures options for the relay agent information
5642 * (state->options->universes[agent_universe.index] is not NULL),
5643 * we're still required to duplicate other values provided by the
5644 * relay agent. So we need to merge the old values not configured
5645 * by the user into the new state, not just give up.
5647 if (!packet
->agent_options_stashed
&&
5648 (packet
->options
!= NULL
) &&
5649 packet
->options
->universe_count
> agent_universe
.index
&&
5650 packet
->options
->universes
[agent_universe
.index
] != NULL
&&
5651 (options
->universe_count
<= agent_universe
.index
||
5652 options
->universes
[agent_universe
.index
] == NULL
)) {
5653 option_chain_head_reference
5654 ((struct option_chain_head
**)
5655 &(options
->universes
[agent_universe
.index
]),
5656 (struct option_chain_head
*)
5657 packet
->options
->universes
[agent_universe
.index
], MDL
);
5659 if (options
->universe_count
<= agent_universe
.index
)
5660 options
->universe_count
= agent_universe
.index
+ 1;
5665 * \brief Adds hostname option when use-host-decl-names is enabled.
5667 * Constructs a hostname option from the name of the host declaration if
5668 * there is one and no hostname has otherwise been provided and the
5669 * use-host-decl-names flag is set, then adds the new option to the given
5670 * option_state. This funciton is used for both bootp and dhcp.
5672 * \param packet inbound packet received from the client
5673 * \param lease lease associated with the client
5674 * \param options option state to search and update
5676 void use_host_decl_name(struct packet
* packet
,
5677 struct lease
*lease
,
5678 struct option_state
*options
) {
5679 unsigned int ocode
= SV_USE_HOST_DECL_NAMES
;
5680 if ((lease
->host
&& lease
->host
->name
) &&
5681 !lookup_option(&dhcp_universe
, options
, DHO_HOST_NAME
) &&
5682 (evaluate_boolean_option_cache(NULL
, packet
, lease
, NULL
,
5683 packet
->options
, options
,
5685 lookup_option(&server_universe
,
5688 struct option_cache
*oc
= NULL
;
5689 if (option_cache_allocate (&oc
, MDL
)) {
5690 if (make_const_data(&oc
-> expression
,
5691 ((unsigned char*)lease
->host
->name
),
5692 strlen(lease
->host
->name
),
5694 ocode
= DHO_HOST_NAME
;
5695 option_code_hash_lookup(&oc
->option
,
5696 dhcp_universe
.code_hash
,
5698 save_option(&dhcp_universe
, options
, oc
);
5700 option_cache_dereference(&oc
, MDL
);
5706 * \brief Checks and preps for lease resuse based on dhcp-cache-threshold
5708 * If dhcp-cache-threshold is enabled (i.e. greater than zero), this function
5709 * determines if the current lease is young enough to be reused. If the lease
5710 * can be resused the function returns 1, O if not. This function is called
5711 * by ack_lease when responding to both DISCOVERs and REQUESTS.
5713 * The current lease can be reused only if all of the following are true:
5714 * a. dhcp-cache-threshold is > 0
5715 * b. The current lease is active
5716 * c. The lease "age" is less than that allowed by the threshold
5717 * d. DNS updates are not being performed on the new lease.
5718 * e. Lease has not been otherwise disqualified for reuse (Ex: billing class
5719 * or hostname changed)
5720 * f. The host declaration has changed (either a new one was added
5721 * or an older one was found due to something like a change in the uid)
5722 * g. The UID or hardware address have changed.
5724 * Clients may renew leases using full DORA cycles or just RAs. This means
5725 * that reusability must be checked when acking both DISCOVERs and REQUESTs.
5726 * When a lease cannot be reused, ack_lease() calls supersede_lease() which
5727 * updates the lease start time (among other things). If this occurs on the
5728 * DISCOVER, then the lease will virtually always be seen as young enough to
5729 * reuse on the ensuing REQUEST and the lease updates will not get committed
5730 * to the lease file. The lease.cannot_reuse flag is used to handle this
5733 * \param packet inbound packet received from the client
5734 * \param new_lease candidate new lease to associate with the client
5735 * \param lease current lease associated with the client
5736 * \param lease_state lease state to search and update
5737 * \param offer type of DHCP response we're building
5738 * \param[out] same_client pointer to int, that will be set to 1 if
5739 * the two leases refer to the same client, 0 if not. Must NOT be null.
5741 * \return 1 if the lease can be reused.
5744 reuse_lease (struct packet
* packet
,
5745 struct lease
* new_lease
,
5746 struct lease
* lease
,
5747 struct lease_state
*state
,
5752 /* To even consider reuse all of the following must be true:
5753 * 1 - reuse hasn't already disqualified
5754 * 2 - current lease is active
5755 * 3 - DNS info hasn't changed
5756 * 4 - the host declaration hasn't changed
5757 * 5 - the uid hasn't changed
5758 * 6 - the hardware address hasn't changed */
5760 /* Check client equality separately so we can pass the result out. */
5762 (((lease
->host
== new_lease
->host
) &&
5763 (lease
->uid_len
== new_lease
->uid_len
) &&
5764 (memcmp(lease
->uid
, new_lease
->uid
, new_lease
->uid_len
) == 0) &&
5765 (lease
->hardware_addr
.hlen
== new_lease
->hardware_addr
.hlen
) &&
5766 (memcmp(&lease
->hardware_addr
.hbuf
[0],
5767 &new_lease
->hardware_addr
.hbuf
[0],
5768 lease
->hardware_addr
.hlen
) == 0)) ? 1 : 0);
5770 if ((lease
->cannot_reuse
== 0) &&
5771 (lease
->binding_state
== FTS_ACTIVE
) &&
5772 (new_lease
->ddns_cb
== NULL
) && *same_client
) {
5773 int thresh
= DEFAULT_CACHE_THRESHOLD
;
5774 struct option_cache
* oc
= NULL
;
5775 struct data_string d1
;
5777 /* Look up threshold value */
5778 memset(&d1
, 0, sizeof(struct data_string
));
5779 if ((oc
= lookup_option(&server_universe
, state
->options
,
5780 SV_CACHE_THRESHOLD
)) &&
5781 (evaluate_option_cache(&d1
, packet
, new_lease
, NULL
,
5782 packet
->options
, state
->options
,
5783 &new_lease
->scope
, oc
, MDL
))) {
5784 if (d1
.len
== 1 && (d1
.data
[0] < 100))
5785 thresh
= d1
.data
[0];
5787 data_string_forget(&d1
, MDL
);
5790 /* If threshold is enabled, check lease age */
5793 int lease_length
= 0;
5796 /* Calculate limit in seconds */
5797 lease_length
= lease
->ends
- lease
->starts
;
5798 if (lease_length
<= (INT_MAX
/ thresh
))
5799 limit
= lease_length
* thresh
/ 100;
5801 limit
= lease_length
/ 100 * thresh
;
5803 /* Note new_lease->starts is really just cur_time */
5804 lease_age
= new_lease
->starts
- lease
->starts
;
5806 /* Is the lease young enough to reuse? */
5807 if (lease_age
<= limit
) {
5808 /* Restore expiry to its original value */
5809 state
->offered_expiry
= lease
->ends
;
5811 /* Restore bindings. This fixes 37368. */
5812 if (new_lease
->scope
!= NULL
) {
5813 if (lease
->scope
!= NULL
) {
5814 binding_scope_dereference(
5819 binding_scope_reference(&lease
->scope
,
5820 new_lease
->scope
, MDL
);
5823 /* restore client hostname, fixes 42849. */
5824 if (new_lease
->client_hostname
) {
5825 lease
->client_hostname
=
5826 new_lease
->client_hostname
;
5827 new_lease
->client_hostname
= NULL
;
5830 /* We're cleared to reuse it */
5831 log_debug("reuse_lease: lease age %ld (secs)"
5832 " under %d%% threshold, reply with "
5833 "unaltered, existing lease for %s",
5834 lease_age
, thresh
, piaddr(lease
->ip_addr
));
5841 /* If we can't reuse it and this is an offer disqualify reuse for
5842 * ensuing REQUEST, otherwise clear the flag. */
5843 lease
->cannot_reuse
= (!reusable
&& offer
== DHCPOFFER
);
5847 /* \brief Validates a proposed value for use as a lease time
5849 * Convenience function used for catching calculeated lease
5850 * times that overflow 4-byte times used in v4 protocol.
5852 * We use variables of type TIME in lots of places, which on
5853 * 64-bit systems is 8 bytes while on 32-bit OSs it is int32_t,
5854 * so we have all sorts of fun places to mess things up.
5855 * This function checks a calculated lease time for and if it
5856 * is unsuitable for use as a lease time, the given alternate
5857 * value is returned.
5861 * \returen either the calculated value if it is valid, or
5862 * the alternate value supplied
5864 TIME
leaseTimeCheck(TIME calculated
, TIME alternate
) {
5865 if ((sizeof(TIME
) > 4 && calculated
>= INFINITE_TIME
) ||
5866 (calculated
< cur_time
)) {
5870 return (calculated
);