3 DHCP Protocol engine. */
6 * Copyright (c) 2004-2015 by Internet Systems Consortium, Inc. ("ISC")
7 * Copyright (c) 1995-2003 by Internet Software Consortium
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
13 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 * Internet Systems Consortium, Inc.
23 * Redwood City, CA 94063
25 * https://www.isc.org/
34 static void maybe_return_agent_options(struct packet
*packet
,
35 struct option_state
*options
);
36 static int reuse_lease (struct packet
* packet
, struct lease
* new_lease
,
37 struct lease
* lease
, struct lease_state
*state
,
40 int outstanding_pings
;
42 #if defined(DELAYED_ACK)
43 static void delayed_ack_enqueue(struct lease
*);
44 static void delayed_acks_timer(void *);
47 struct leasequeue
*ackqueue_head
, *ackqueue_tail
;
48 static struct leasequeue
*free_ackqueue
;
49 static struct timeval max_fsync
;
52 int max_outstanding_acks
= DEFAULT_DELAYED_ACK
;
53 int max_ack_delay_secs
= DEFAULT_ACK_DELAY_SECS
;
54 int max_ack_delay_usecs
= DEFAULT_ACK_DELAY_USECS
;
55 int min_ack_delay_usecs
= DEFAULT_MIN_ACK_DELAY_USECS
;
58 static char dhcp_message
[256];
59 static int site_code_min
;
61 static int find_min_site_code(struct universe
*);
62 static isc_result_t
lowest_site_code(const void *, unsigned, void *);
64 static const char *dhcp_type_names
[] = {
75 "DHCPLEASEUNASSIGNED",
79 const int dhcp_type_name_max
= ((sizeof dhcp_type_names
) / sizeof (char *));
82 # define send_packet trace_packet_send
86 dhcp (struct packet
*packet
) {
88 struct option_cache
*oc
;
89 struct lease
*lease
= NULL
;
91 struct data_string data
;
93 if (!locate_network(packet
) &&
94 packet
->packet_type
!= DHCPREQUEST
&&
95 packet
->packet_type
!= DHCPINFORM
&&
96 packet
->packet_type
!= DHCPLEASEQUERY
) {
99 errmsg
= "unknown network segment";
102 if (packet
->packet_type
> 0 &&
103 packet
->packet_type
<= dhcp_type_name_max
) {
104 s
= dhcp_type_names
[packet
->packet_type
- 1];
106 /* %Audit% Cannot exceed 28 bytes. %2004.06.17,Safe% */
107 sprintf(typebuf
, "type %d", packet
->packet_type
);
111 log_info("%s from %s via %s: %s", s
,
113 ? print_hw_addr(packet
->raw
->htype
,
116 : "<no identifier>"),
117 packet
->raw
->giaddr
.s_addr
118 ? inet_ntoa(packet
->raw
->giaddr
)
119 : packet
->interface
->name
, errmsg
);
123 /* There is a problem with the relay agent information option,
124 * which is that in order for a normal relay agent to append
125 * this option, the relay agent has to have been involved in
126 * getting the packet from the client to the server. Note
127 * that this is the software entity known as the relay agent,
128 * _not_ the hardware entity known as a router in which the
129 * relay agent may be running, so the fact that a router has
130 * forwarded a packet does not mean that the relay agent in
131 * the router was involved.
133 * So when the client broadcasts (DHCPDISCOVER, or giaddr is set),
134 * we can be sure that there are either agent options in the
135 * packet, or there aren't supposed to be. When the giaddr is not
136 * set, it's still possible that the client is on a directly
137 * attached subnet, and agent options are being appended by an l2
138 * device that has no address, and so sets no giaddr.
140 * But in either case it's possible that the packets we receive
141 * from the client in RENEW state may not include the agent options,
142 * so if they are not in the packet we must "pretend" the last values
143 * we observed were provided.
145 if (packet
->packet_type
== DHCPREQUEST
&&
146 packet
->raw
->ciaddr
.s_addr
&& !packet
->raw
->giaddr
.s_addr
&&
147 (packet
->options
->universe_count
<= agent_universe
.index
||
148 packet
->options
->universes
[agent_universe
.index
] == NULL
))
152 cip
.len
= sizeof packet
-> raw
-> ciaddr
;
153 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
,
154 sizeof packet
-> raw
-> ciaddr
);
155 if (!find_lease_by_ip_addr (&lease
, cip
, MDL
))
158 /* If there are no agent options on the lease, it's not
160 if (!lease
-> agent_options
)
163 /* The client should not be unicasting a renewal if its lease
164 has expired, so make it go through the process of getting
165 its agent options legally. */
166 if (lease
-> ends
< cur_time
)
169 if (lease
-> uid_len
) {
170 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
171 DHO_DHCP_CLIENT_IDENTIFIER
);
175 memset (&data
, 0, sizeof data
);
176 if (!evaluate_option_cache (&data
,
177 packet
, (struct lease
*)0,
178 (struct client_state
*)0,
180 (struct option_state
*)0,
181 &global_scope
, oc
, MDL
))
183 if (lease
-> uid_len
!= data
.len
||
184 memcmp (lease
-> uid
, data
.data
, data
.len
)) {
185 data_string_forget (&data
, MDL
);
188 data_string_forget (&data
, MDL
);
190 if ((lease
-> hardware_addr
.hbuf
[0] !=
191 packet
-> raw
-> htype
) ||
192 (lease
-> hardware_addr
.hlen
- 1 !=
193 packet
-> raw
-> hlen
) ||
194 memcmp (&lease
-> hardware_addr
.hbuf
[1],
195 packet
-> raw
-> chaddr
,
196 packet
-> raw
-> hlen
))
199 /* Okay, so we found a lease that matches the client. */
200 option_chain_head_reference ((struct option_chain_head
**)
201 &(packet
-> options
-> universes
202 [agent_universe
.index
]),
203 lease
-> agent_options
, MDL
);
205 if (packet
->options
->universe_count
<= agent_universe
.index
)
206 packet
->options
->universe_count
=
207 agent_universe
.index
+ 1;
209 packet
->agent_options_stashed
= ISC_TRUE
;
213 /* If a client null terminates options it sends, it probably
214 * expects the server to reciprocate.
216 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
218 if (!oc
-> expression
)
219 ms_nulltp
= oc
->flags
& OPTION_HAD_NULLS
;
222 /* Classify the client. */
223 classify_client (packet
);
225 switch (packet
-> packet_type
) {
227 dhcpdiscover (packet
, ms_nulltp
);
231 dhcprequest (packet
, ms_nulltp
, lease
);
235 dhcprelease (packet
, ms_nulltp
);
239 dhcpdecline (packet
, ms_nulltp
);
243 dhcpinform (packet
, ms_nulltp
);
247 dhcpleasequery(packet
, ms_nulltp
);
253 case DHCPLEASEUNASSIGNED
:
254 case DHCPLEASEUNKNOWN
:
255 case DHCPLEASEACTIVE
:
259 errmsg
= "unknown packet type";
264 lease_dereference (&lease
, MDL
);
267 void dhcpdiscover (packet
, ms_nulltp
)
268 struct packet
*packet
;
271 struct lease
*lease
= (struct lease
*)0;
272 char msgbuf
[1024]; /* XXX */
275 int peer_has_leases
= 0;
276 #if defined (FAILOVER_PROTOCOL)
277 dhcp_failover_state_t
*peer
;
280 find_lease (&lease
, packet
, packet
-> shared_network
,
281 0, &peer_has_leases
, (struct lease
*)0, MDL
);
283 if (lease
&& lease
-> client_hostname
) {
284 if ((strlen (lease
-> client_hostname
) <= 64) &&
285 db_printable((unsigned char *)lease
->client_hostname
))
286 s
= lease
-> client_hostname
;
288 s
= "Hostname Unsuitable for Printing";
292 /* %Audit% This is log output. %2004.06.17,Safe%
293 * If we truncate we hope the user can get a hint from the log.
295 snprintf (msgbuf
, sizeof msgbuf
, "DHCPDISCOVER from %s %s%s%svia %s",
296 (packet
-> raw
-> htype
297 ? print_hw_addr (packet
-> raw
-> htype
,
298 packet
-> raw
-> hlen
,
299 packet
-> raw
-> chaddr
)
301 ? print_hex_1(lease
->uid_len
, lease
->uid
, 60)
302 : "<no identifier>")),
303 s
? "(" : "", s
? s
: "", s
? ") " : "",
304 packet
-> raw
-> giaddr
.s_addr
305 ? inet_ntoa (packet
-> raw
-> giaddr
)
306 : packet
-> interface
-> name
);
308 /* Sourceless packets don't make sense here. */
309 if (!packet
-> shared_network
) {
310 log_info ("Packet from unknown subnet: %s",
311 inet_ntoa (packet
-> raw
-> giaddr
));
315 #if defined (FAILOVER_PROTOCOL)
316 if (lease
&& lease
-> pool
&& lease
-> pool
-> failover_peer
) {
317 peer
= lease
-> pool
-> failover_peer
;
320 * If the lease is ours to (re)allocate, then allocate it.
322 * If the lease is active, it belongs to the client. This
323 * is the right lease, if we are to offer one. We decide
324 * whether or not to offer later on.
326 * If the lease was last active, and we've reached this
327 * point, then it was last active with the same client. We
328 * can safely re-activate the lease with this client.
330 if (lease
->binding_state
== FTS_ACTIVE
||
331 lease
->rewind_binding_state
== FTS_ACTIVE
||
332 lease_mine_to_reallocate(lease
)) {
333 ; /* This space intentionally left blank. */
335 /* Otherwise, we can't let the client have this lease. */
337 #if defined (DEBUG_FIND_LEASE)
338 log_debug ("discarding %s - %s",
339 piaddr (lease
-> ip_addr
),
340 binding_state_print (lease
-> binding_state
));
342 lease_dereference (&lease
, MDL
);
347 /* If we didn't find a lease, try to allocate one... */
349 if (!allocate_lease (&lease
, packet
,
350 packet
-> shared_network
-> pools
,
353 log_error ("%s: peer holds all free leases",
356 log_error ("%s: network %s: no free leases",
358 packet
-> shared_network
-> name
);
363 #if defined (FAILOVER_PROTOCOL)
364 if (lease
&& lease
-> pool
&& lease
-> pool
-> failover_peer
) {
365 peer
= lease
-> pool
-> failover_peer
;
366 if (peer
-> service_state
== not_responding
||
367 peer
-> service_state
== service_startup
) {
368 log_info ("%s: not responding%s",
369 msgbuf
, peer
-> nrr
);
373 peer
= (dhcp_failover_state_t
*)0;
375 /* Do load balancing if configured. */
376 if (peer
&& (peer
-> service_state
== cooperating
) &&
377 !load_balance_mine (packet
, peer
)) {
378 if (peer_has_leases
) {
379 log_debug ("%s: load balance to peer %s",
380 msgbuf
, peer
-> name
);
383 log_debug ("%s: cancel load balance to peer %s - %s",
384 msgbuf
, peer
-> name
, "no free leases");
389 /* If it's an expired lease, get rid of any bindings. */
390 if (lease
-> ends
< cur_time
&& lease
-> scope
)
391 binding_scope_dereference (&lease
-> scope
, MDL
);
393 /* Set the lease to really expire in 2 minutes, unless it has
394 not yet expired, in which case leave its expiry time alone. */
395 when
= cur_time
+ 120;
396 if (when
< lease
-> ends
)
397 when
= lease
-> ends
;
399 ack_lease (packet
, lease
, DHCPOFFER
, when
, msgbuf
, ms_nulltp
,
400 (struct host_decl
*)0);
403 lease_dereference (&lease
, MDL
);
406 void dhcprequest (packet
, ms_nulltp
, ip_lease
)
407 struct packet
*packet
;
409 struct lease
*ip_lease
;
414 struct subnet
*subnet
;
416 struct option_cache
*oc
;
417 struct data_string data
;
418 char msgbuf
[1024]; /* XXX */
421 #if defined (FAILOVER_PROTOCOL)
422 dhcp_failover_state_t
*peer
;
424 int have_requested_addr
= 0;
426 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
427 DHO_DHCP_REQUESTED_ADDRESS
);
428 memset (&data
, 0, sizeof data
);
430 evaluate_option_cache (&data
, packet
, (struct lease
*)0,
431 (struct client_state
*)0,
432 packet
-> options
, (struct option_state
*)0,
433 &global_scope
, oc
, MDL
)) {
435 memcpy (cip
.iabuf
, data
.data
, 4);
436 data_string_forget (&data
, MDL
);
437 have_requested_addr
= 1;
439 oc
= (struct option_cache
*)0;
441 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
.s_addr
, 4);
444 /* Find the lease that matches the address requested by the
447 subnet
= (struct subnet
*)0;
448 lease
= (struct lease
*)0;
449 if (find_subnet (&subnet
, cip
, MDL
))
450 find_lease (&lease
, packet
,
451 subnet
-> shared_network
, &ours
, 0, ip_lease
, MDL
);
453 if (lease
&& lease
-> client_hostname
) {
454 if ((strlen (lease
-> client_hostname
) <= 64) &&
455 db_printable((unsigned char *)lease
->client_hostname
))
456 s
= lease
-> client_hostname
;
458 s
= "Hostname Unsuitable for Printing";
462 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
463 DHO_DHCP_SERVER_IDENTIFIER
);
464 memset (&data
, 0, sizeof data
);
466 evaluate_option_cache (&data
, packet
, (struct lease
*)0,
467 (struct client_state
*)0,
468 packet
-> options
, (struct option_state
*)0,
469 &global_scope
, oc
, MDL
)) {
471 memcpy (sip
.iabuf
, data
.data
, 4);
472 data_string_forget (&data
, MDL
);
473 /* piaddr() should not return more than a 15 byte string.
476 sprintf (smbuf
, " (%s)", piaddr (sip
));
482 /* %Audit% This is log output. %2004.06.17,Safe%
483 * If we truncate we hope the user can get a hint from the log.
485 snprintf (msgbuf
, sizeof msgbuf
,
486 "DHCPREQUEST for %s%s from %s %s%s%svia %s",
488 (packet
-> raw
-> htype
489 ? print_hw_addr (packet
-> raw
-> htype
,
490 packet
-> raw
-> hlen
,
491 packet
-> raw
-> chaddr
)
493 ? print_hex_1(lease
->uid_len
, lease
->uid
, 60)
494 : "<no identifier>")),
495 s
? "(" : "", s
? s
: "", s
? ") " : "",
496 packet
-> raw
-> giaddr
.s_addr
497 ? inet_ntoa (packet
-> raw
-> giaddr
)
498 : packet
-> interface
-> name
);
500 #if defined (FAILOVER_PROTOCOL)
501 if (lease
&& lease
-> pool
&& lease
-> pool
-> failover_peer
) {
502 peer
= lease
-> pool
-> failover_peer
;
503 if (peer
-> service_state
== not_responding
||
504 peer
-> service_state
== service_startup
) {
505 log_info ("%s: not responding%s",
506 msgbuf
, peer
-> nrr
);
510 /* "load balance to peer" - is not done at all for request.
512 * If it's RENEWING, we are the only server to hear it, so
513 * we have to serve it. If it's REBINDING, it's out of
514 * communication with the other server, so there's no point
515 * in waiting to serve it. However, if the lease we're
516 * offering is not a free lease, then we may be the only
517 * server that can offer it, so we can't load balance if
518 * the lease isn't in the free or backup state. If it is
519 * in the free or backup state, then that state is what
520 * mandates one server or the other should perform the
521 * allocation, not the LBA...we know the peer cannot
522 * allocate a request for an address in our free state.
524 * So our only compass is lease_mine_to_reallocate(). This
525 * effects both load balancing, and a sanity-check that we
526 * are not going to try to allocate a lease that isn't ours.
528 if ((lease
-> binding_state
== FTS_FREE
||
529 lease
-> binding_state
== FTS_BACKUP
) &&
530 !lease_mine_to_reallocate (lease
)) {
531 log_debug ("%s: lease owned by peer", msgbuf
);
536 * If the lease is in a transitional state, we can't
537 * renew it unless we can rewind it to a non-transitional
538 * state (active, free, or backup). lease_mine_to_reallocate()
539 * checks for free/backup, so we only need to check for active.
541 if ((lease
->binding_state
== FTS_RELEASED
||
542 lease
->binding_state
== FTS_EXPIRED
) &&
543 lease
->rewind_binding_state
!= FTS_ACTIVE
&&
544 !lease_mine_to_reallocate(lease
)) {
545 log_debug("%s: lease in transition state %s", msgbuf
,
546 (lease
->binding_state
== FTS_RELEASED
)
547 ? "released" : "expired");
551 /* It's actually very unlikely that we'll ever get here,
552 but if we do, tell the client to stop using the lease,
553 because the administrator reset it. */
554 if (lease
-> binding_state
== FTS_RESET
&&
555 !lease_mine_to_reallocate (lease
)) {
556 log_debug ("%s: lease reset by administrator", msgbuf
);
557 nak_lease (packet
, &cip
, lease
->subnet
->group
);
561 /* If server-id-check is enabled, verify that the client's
562 * server source address (sip from incoming packet) is ours.
563 * To avoid problems with confused clients we do some sanity
564 * checks to verify sip's length and that it isn't all zeros.
565 * We then get the server id we would likely use for this
566 * packet and compare them. If they don't match it we assume
567 * we didn't send the offer and so we don't process the
569 if ((server_id_check
== 1) && (sip
.len
== 4) &&
570 (memcmp(sip
.iabuf
, "\0\0\0\0", sip
.len
) != 0)) {
572 struct option_state
*eval_options
= NULL
;
574 eval_network_statements(&eval_options
, packet
, NULL
);
575 get_server_source_address(&from
, eval_options
,
577 option_state_dereference (&eval_options
, MDL
);
578 if (memcmp(sip
.iabuf
, &from
, sip
.len
) != 0) {
579 log_debug("%s: not our server id", msgbuf
);
584 /* At this point it's possible that we will get a broadcast
585 DHCPREQUEST for a lease that we didn't offer, because
586 both we and the peer are in a position to offer it.
587 In that case, we probably shouldn't answer. In order
588 to not answer, we would have to compare the server
589 identifier sent by the client with the list of possible
590 server identifiers we can send, and if the client's
591 identifier isn't on the list, drop the DHCPREQUEST.
592 We aren't currently doing that for two reasons - first,
593 it's not clear that all clients do the right thing
594 with respect to sending the client identifier, which
595 could mean that we might simply not respond to a client
596 that is depending on us to respond. Secondly, we allow
597 the user to specify the server identifier to send, and
598 we don't enforce that the server identifier should be
599 one of our IP addresses. This is probably not a big
600 deal, but it's theoretically an issue.
602 The reason we care about this is that if both servers
603 send a DHCPACK to the DHCPREQUEST, they are then going
604 to send dueling BNDUPD messages, which could cause
605 trouble. I think it causes no harm, but it seems
608 peer
= (dhcp_failover_state_t
*)0;
611 /* If a client on a given network REQUESTs a lease on an
612 address on a different network, NAK it. If the Requested
613 Address option was used, the protocol says that it must
614 have been broadcast, so we can trust the source network
617 If ciaddr was specified and Requested Address was not, then
618 we really only know for sure what network a packet came from
619 if it came through a BOOTP gateway - if it came through an
620 IP router, we'll just have to assume that it's cool.
622 If we don't think we know where the packet came from, it
623 came through a gateway from an unknown network, so it's not
624 from a RENEWING client. If we recognize the network it
625 *thinks* it's on, we can NAK it even though we don't
626 recognize the network it's *actually* on; otherwise we just
629 We don't currently try to take advantage of access to the
630 raw packet, because it's not available on all platforms.
631 So a packet that was unicast to us through a router from a
632 RENEWING client is going to look exactly like a packet that
633 was broadcast to us from an INIT-REBOOT client.
635 Since we can't tell the difference between these two kinds
636 of packets, if the packet appears to have come in off the
637 local wire, we have to treat it as if it's a RENEWING
638 client. This means that we can't NAK a RENEWING client on
639 the local wire that has a bogus address. The good news is
640 that we won't ACK it either, so it should revert to INIT
641 state and send us a DHCPDISCOVER, which we *can* work with.
643 Because we can't detect that a RENEWING client is on the
644 wrong wire, it's going to sit there trying to renew until
645 it gets to the REBIND state, when we *can* NAK it because
646 the packet will get to us through a BOOTP gateway. We
647 shouldn't actually see DHCPREQUEST packets from RENEWING
648 clients on the wrong wire anyway, since their idea of their
649 local router will be wrong. In any case, the protocol
650 doesn't really allow us to NAK a DHCPREQUEST from a
651 RENEWING client, so we can punt on this issue. */
653 if (!packet
-> shared_network
||
654 (packet
-> raw
-> ciaddr
.s_addr
&&
655 packet
-> raw
-> giaddr
.s_addr
) ||
656 (have_requested_addr
&& !packet
-> raw
-> ciaddr
.s_addr
)) {
658 /* If we don't know where it came from but we do know
659 where it claims to have come from, it didn't come
661 if (!packet
-> shared_network
) {
662 if (subnet
&& subnet
-> group
-> authoritative
) {
663 log_info ("%s: wrong network.", msgbuf
);
664 nak_lease (packet
, &cip
, NULL
);
667 /* Otherwise, ignore it. */
668 log_info ("%s: ignored (%s).", msgbuf
,
670 ? "not authoritative" : "unknown subnet"));
674 /* If we do know where it came from and it asked for an
675 address that is not on that shared network, nak it. */
677 subnet_dereference (&subnet
, MDL
);
678 if (!find_grouped_subnet (&subnet
, packet
-> shared_network
,
680 if (packet
-> shared_network
-> group
-> authoritative
)
682 log_info ("%s: wrong network.", msgbuf
);
683 nak_lease (packet
, &cip
, NULL
);
686 log_info ("%s: ignored (not authoritative).", msgbuf
);
691 /* If the address the client asked for is ours, but it wasn't
692 available for the client, NAK it. */
693 if (!lease
&& ours
) {
694 log_info ("%s: lease %s unavailable.", msgbuf
, piaddr (cip
));
695 nak_lease (packet
, &cip
, (subnet
? subnet
->group
: NULL
));
699 /* Otherwise, send the lease to the client if we found one. */
701 ack_lease (packet
, lease
, DHCPACK
, 0, msgbuf
, ms_nulltp
,
702 (struct host_decl
*)0);
704 log_info ("%s: unknown lease %s.", msgbuf
, piaddr (cip
));
708 subnet_dereference (&subnet
, MDL
);
710 lease_dereference (&lease
, MDL
);
714 void dhcprelease (packet
, ms_nulltp
)
715 struct packet
*packet
;
718 struct lease
*lease
= (struct lease
*)0, *next
= (struct lease
*)0;
720 struct option_cache
*oc
;
721 struct data_string data
;
723 char msgbuf
[1024], cstr
[16]; /* XXX */
726 /* DHCPRELEASE must not specify address in requested-address
727 option, but old protocol specs weren't explicit about this,
729 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
730 DHO_DHCP_REQUESTED_ADDRESS
))) {
731 log_info ("DHCPRELEASE from %s specified requested-address.",
732 print_hw_addr (packet
-> raw
-> htype
,
733 packet
-> raw
-> hlen
,
734 packet
-> raw
-> chaddr
));
737 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
738 DHO_DHCP_CLIENT_IDENTIFIER
);
739 memset (&data
, 0, sizeof data
);
741 evaluate_option_cache (&data
, packet
, (struct lease
*)0,
742 (struct client_state
*)0,
743 packet
-> options
, (struct option_state
*)0,
744 &global_scope
, oc
, MDL
)) {
745 find_lease_by_uid (&lease
, data
.data
, data
.len
, MDL
);
746 data_string_forget (&data
, MDL
);
748 /* See if we can find a lease that matches the IP address
749 the client is claiming. */
752 lease_reference (&next
, lease
-> n_uid
, MDL
);
753 if (!memcmp (&packet
-> raw
-> ciaddr
,
754 lease
-> ip_addr
.iabuf
, 4)) {
757 lease_dereference (&lease
, MDL
);
759 lease_reference (&lease
, next
, MDL
);
760 lease_dereference (&next
, MDL
);
764 lease_dereference (&next
, MDL
);
767 /* The client is supposed to pass a valid client-identifier,
768 but the spec on this has changed historically, so try the
769 IP address in ciaddr if the client-identifier fails. */
772 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
, 4);
773 find_lease_by_ip_addr (&lease
, cip
, MDL
);
777 /* If the hardware address doesn't match, don't do the release. */
779 (lease
-> hardware_addr
.hlen
!= packet
-> raw
-> hlen
+ 1 ||
780 lease
-> hardware_addr
.hbuf
[0] != packet
-> raw
-> htype
||
781 memcmp (&lease
-> hardware_addr
.hbuf
[1],
782 packet
-> raw
-> chaddr
, packet
-> raw
-> hlen
)))
783 lease_dereference (&lease
, MDL
);
785 if (lease
&& lease
-> client_hostname
) {
786 if ((strlen (lease
-> client_hostname
) <= 64) &&
787 db_printable((unsigned char *)lease
->client_hostname
))
788 s
= lease
-> client_hostname
;
790 s
= "Hostname Unsuitable for Printing";
794 /* %Audit% Cannot exceed 16 bytes. %2004.06.17,Safe%
795 * We copy this out to stack because we actually want to log two
796 * inet_ntoa()'s in this message.
798 strncpy(cstr
, inet_ntoa (packet
-> raw
-> ciaddr
), 15);
801 /* %Audit% This is log output. %2004.06.17,Safe%
802 * If we truncate we hope the user can get a hint from the log.
804 snprintf (msgbuf
, sizeof msgbuf
,
805 "DHCPRELEASE of %s from %s %s%s%svia %s (%sfound)",
807 (packet
-> raw
-> htype
808 ? print_hw_addr (packet
-> raw
-> htype
,
809 packet
-> raw
-> hlen
,
810 packet
-> raw
-> chaddr
)
812 ? print_hex_1(lease
->uid_len
, lease
->uid
, 60)
813 : "<no identifier>")),
814 s
? "(" : "", s
? s
: "", s
? ") " : "",
815 packet
-> raw
-> giaddr
.s_addr
816 ? inet_ntoa (packet
-> raw
-> giaddr
)
817 : packet
-> interface
-> name
,
818 lease
? "" : "not ");
820 #if defined (FAILOVER_PROTOCOL)
821 if (lease
&& lease
-> pool
&& lease
-> pool
-> failover_peer
) {
822 dhcp_failover_state_t
*peer
= lease
-> pool
-> failover_peer
;
823 if (peer
-> service_state
== not_responding
||
824 peer
-> service_state
== service_startup
) {
825 log_info ("%s: ignored%s",
826 peer
-> name
, peer
-> nrr
);
830 /* DHCPRELEASE messages are unicast, so if the client
831 sent the DHCPRELEASE to us, it's not going to send it
832 to the peer. Not sure why this would happen, and
833 if it does happen I think we still have to change the
834 lease state, so that's what we're doing.
835 XXX See what it says in the draft about this. */
839 /* If we found a lease, release it. */
840 if (lease
&& lease
-> ends
> cur_time
) {
841 release_lease (lease
, packet
);
843 log_info ("%s", msgbuf
);
844 #if defined(FAILOVER_PROTOCOL)
848 lease_dereference (&lease
, MDL
);
851 void dhcpdecline (packet
, ms_nulltp
)
852 struct packet
*packet
;
855 struct lease
*lease
= (struct lease
*)0;
856 struct option_state
*options
= (struct option_state
*)0;
861 char msgbuf
[1024]; /* XXX */
863 struct option_cache
*oc
;
864 struct data_string data
;
866 /* DHCPDECLINE must specify address. */
867 if (!(oc
= lookup_option (&dhcp_universe
, packet
-> options
,
868 DHO_DHCP_REQUESTED_ADDRESS
)))
870 memset (&data
, 0, sizeof data
);
871 if (!evaluate_option_cache (&data
, packet
, (struct lease
*)0,
872 (struct client_state
*)0,
874 (struct option_state
*)0,
875 &global_scope
, oc
, MDL
))
879 memcpy (cip
.iabuf
, data
.data
, 4);
880 data_string_forget (&data
, MDL
);
881 find_lease_by_ip_addr (&lease
, cip
, MDL
);
883 if (lease
&& lease
-> client_hostname
) {
884 if ((strlen (lease
-> client_hostname
) <= 64) &&
885 db_printable((unsigned char *)lease
->client_hostname
))
886 s
= lease
-> client_hostname
;
888 s
= "Hostname Unsuitable for Printing";
892 /* %Audit% This is log output. %2004.06.17,Safe%
893 * If we truncate we hope the user can get a hint from the log.
895 snprintf (msgbuf
, sizeof msgbuf
,
896 "DHCPDECLINE of %s from %s %s%s%svia %s",
898 (packet
-> raw
-> htype
899 ? print_hw_addr (packet
-> raw
-> htype
,
900 packet
-> raw
-> hlen
,
901 packet
-> raw
-> chaddr
)
903 ? print_hex_1(lease
->uid_len
, lease
->uid
, 60)
904 : "<no identifier>")),
905 s
? "(" : "", s
? s
: "", s
? ") " : "",
906 packet
-> raw
-> giaddr
.s_addr
907 ? inet_ntoa (packet
-> raw
-> giaddr
)
908 : packet
-> interface
-> name
);
910 option_state_allocate (&options
, MDL
);
912 /* Execute statements in scope starting with the subnet scope. */
914 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
915 packet
->options
, options
,
917 lease
->subnet
->group
,
920 /* Execute statements in the class scopes. */
921 for (i
= packet
-> class_count
; i
> 0; i
--) {
922 execute_statements_in_scope
923 (NULL
, packet
, NULL
, NULL
, packet
->options
, options
,
924 &global_scope
, packet
->classes
[i
- 1]->group
,
925 lease
? lease
->subnet
->group
: NULL
, NULL
);
928 /* Drop the request if dhcpdeclines are being ignored. */
929 oc
= lookup_option (&server_universe
, options
, SV_DECLINES
);
931 evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
932 (struct client_state
*)0,
933 packet
-> options
, options
,
934 &lease
-> scope
, oc
, MDL
)) {
935 /* If we found a lease, mark it as unusable and complain. */
937 #if defined (FAILOVER_PROTOCOL)
938 if (lease
-> pool
&& lease
-> pool
-> failover_peer
) {
939 dhcp_failover_state_t
*peer
=
940 lease
-> pool
-> failover_peer
;
941 if (peer
-> service_state
== not_responding
||
942 peer
-> service_state
== service_startup
) {
944 log_info ("%s: ignored%s",
945 peer
-> name
, peer
-> nrr
);
949 /* DHCPDECLINE messages are broadcast, so we can safely
950 ignore the DHCPDECLINE if the peer has the lease.
951 XXX Of course, at this point that information has been
956 abandon_lease (lease
, "declined.");
957 status
= "abandoned";
959 status
= "not found";
965 log_info ("%s: %s", msgbuf
, status
);
967 #if defined(FAILOVER_PROTOCOL)
971 option_state_dereference (&options
, MDL
);
973 lease_dereference (&lease
, MDL
);
976 void dhcpinform (packet
, ms_nulltp
)
977 struct packet
*packet
;
980 char msgbuf
[1024], *addr_type
;
981 struct data_string d1
, prl
, fixed_addr
;
982 struct option_cache
*oc
;
983 struct option_state
*options
= NULL
;
984 struct dhcp_packet raw
;
985 struct packet outgoing
;
986 unsigned char dhcpack
= DHCPACK
;
987 struct subnet
*subnet
= NULL
;
988 struct iaddr cip
, gip
, sip
;
991 struct sockaddr_in to
;
993 isc_boolean_t zeroed_ciaddr
;
994 struct interface_info
*interface
;
995 int result
, h_m_client_ip
= 0;
996 struct host_decl
*host
= NULL
, *hp
= NULL
, *h
;
997 #if defined (DEBUG_INFORM_HOST)
998 int h_w_fixed_addr
= 0;
1001 /* The client should set ciaddr to its IP address, but apparently
1002 it's common for clients not to do this, so we'll use their IP
1003 source address if they didn't set ciaddr. */
1004 if (!packet
->raw
->ciaddr
.s_addr
) {
1005 zeroed_ciaddr
= ISC_TRUE
;
1007 memcpy(cip
.iabuf
, &packet
->client_addr
.iabuf
, 4);
1008 addr_type
= "source";
1010 zeroed_ciaddr
= ISC_FALSE
;
1012 memcpy(cip
.iabuf
, &packet
->raw
->ciaddr
, 4);
1013 addr_type
= "client";
1016 memcpy(sip
.iabuf
, cip
.iabuf
, 4);
1018 if (packet
->raw
->giaddr
.s_addr
) {
1020 memcpy(gip
.iabuf
, &packet
->raw
->giaddr
, 4);
1021 if (zeroed_ciaddr
== ISC_TRUE
) {
1022 addr_type
= "relay";
1023 memcpy(sip
.iabuf
, gip
.iabuf
, 4);
1028 /* %Audit% This is log output. %2004.06.17,Safe%
1029 * If we truncate we hope the user can get a hint from the log.
1031 snprintf(msgbuf
, sizeof(msgbuf
), "DHCPINFORM from %s via %s",
1033 packet
->raw
->giaddr
.s_addr
?
1034 inet_ntoa(packet
->raw
->giaddr
) :
1035 packet
->interface
->name
);
1037 /* If the IP source address is zero, don't respond. */
1038 if (!memcmp(cip
.iabuf
, "\0\0\0", 4)) {
1039 log_info("%s: ignored (null source address).", msgbuf
);
1043 /* Find the subnet that the client is on.
1044 * CC: Do the link selection / subnet selection
1047 option_state_allocate(&options
, MDL
);
1049 if ((oc
= lookup_option(&agent_universe
, packet
->options
,
1050 RAI_LINK_SELECT
)) == NULL
)
1051 oc
= lookup_option(&dhcp_universe
, packet
->options
,
1052 DHO_SUBNET_SELECTION
);
1054 memset(&d1
, 0, sizeof d1
);
1055 if (oc
&& evaluate_option_cache(&d1
, packet
, NULL
, NULL
,
1056 packet
->options
, NULL
,
1057 &global_scope
, oc
, MDL
)) {
1058 struct option_cache
*noc
= NULL
;
1061 log_info("%s: ignored (invalid subnet selection option).", msgbuf
);
1062 option_state_dereference(&options
, MDL
);
1066 memcpy(sip
.iabuf
, d1
.data
, 4);
1067 data_string_forget(&d1
, MDL
);
1069 /* Make a copy of the data. */
1070 if (option_cache_allocate(&noc
, MDL
)) {
1072 data_string_copy(&noc
->data
, &oc
->data
, MDL
);
1074 expression_reference(&noc
->expression
,
1075 oc
->expression
, MDL
);
1077 option_reference(&(noc
->option
), oc
->option
,
1080 save_option(&dhcp_universe
, options
, noc
);
1081 option_cache_dereference(&noc
, MDL
);
1083 if ((zeroed_ciaddr
== ISC_TRUE
) && (gip
.len
!= 0))
1084 addr_type
= "relay link select";
1086 addr_type
= "selected";
1089 find_subnet(&subnet
, sip
, MDL
);
1091 if (subnet
== NULL
) {
1092 log_info("%s: unknown subnet for %s address %s",
1093 msgbuf
, addr_type
, piaddr(sip
));
1094 option_state_dereference(&options
, MDL
);
1098 /* We don't respond to DHCPINFORM packets if we're not authoritative.
1099 It would be nice if a per-host value could override this, but
1100 there's overhead involved in checking this, so let's see how people
1102 if (!subnet
->group
->authoritative
) {
1104 log_info("%s: not authoritative for subnet %s",
1105 msgbuf
, piaddr (subnet
-> net
));
1107 log_info("If this DHCP server is authoritative for%s",
1109 log_info("please write an `authoritative;' directi%s",
1110 "ve either in the");
1111 log_info("subnet declaration or in some scope that%s",
1113 log_info("subnet declaration - for example, write %s",
1115 log_info("of the dhcpd.conf file.");
1119 subnet_dereference(&subnet
, MDL
);
1120 option_state_dereference(&options
, MDL
);
1124 memset(&outgoing
, 0, sizeof outgoing
);
1125 memset(&raw
, 0, sizeof raw
);
1126 outgoing
.raw
= &raw
;
1128 maybe_return_agent_options(packet
, options
);
1130 /* Execute statements in scope starting with the subnet scope. */
1131 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
1132 packet
->options
, options
,
1133 &global_scope
, subnet
->group
,
1136 /* Execute statements in the class scopes. */
1137 for (i
= packet
->class_count
; i
> 0; i
--) {
1138 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
1139 packet
->options
, options
,
1141 packet
->classes
[i
- 1]->group
,
1147 * Process host declarations during DHCPINFORM,
1148 * Try to find a matching host declaration by cli ID or HW addr.
1150 * Look through the host decls for one that matches the
1151 * client identifer or the hardware address. The preference
1153 * client id with matching ip address
1154 * hardware address with matching ip address
1155 * client id without a ip fixed address
1156 * hardware address without a fixed ip address
1157 * If found, set host to use its option definitions.
1159 oc
= lookup_option(&dhcp_universe
, packet
->options
,
1160 DHO_DHCP_CLIENT_IDENTIFIER
);
1161 memset(&d1
, 0, sizeof(d1
));
1163 evaluate_option_cache(&d1
, packet
, NULL
, NULL
,
1164 packet
->options
, NULL
,
1165 &global_scope
, oc
, MDL
)) {
1166 find_hosts_by_uid(&hp
, d1
.data
, d1
.len
, MDL
);
1167 data_string_forget(&d1
, MDL
);
1169 #if defined (DEBUG_INFORM_HOST)
1171 log_debug ("dhcpinform: found host by ID "
1172 "-- checking fixed-address match");
1174 /* check if we have one with fixed-address
1175 * matching the client ip first */
1176 for (h
= hp
; !h_m_client_ip
&& h
; h
= h
->n_ipaddr
) {
1180 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
1181 if (!evaluate_option_cache (&fixed_addr
, NULL
,
1182 NULL
, NULL
, NULL
, NULL
,
1184 h
->fixed_addr
, MDL
))
1187 #if defined (DEBUG_INFORM_HOST)
1191 (i
+ cip
.len
) <= fixed_addr
.len
;
1193 if (memcmp(fixed_addr
.data
+ i
,
1194 cip
.iabuf
, cip
.len
) == 0) {
1195 #if defined (DEBUG_INFORM_HOST)
1196 log_debug ("dhcpinform: found "
1197 "host with matching "
1198 "fixed-address by ID");
1200 host_reference(&host
, h
, MDL
);
1205 data_string_forget(&fixed_addr
, MDL
);
1208 /* fallback to a host without fixed-address */
1209 for (h
= hp
; !host
&& h
; h
= h
->n_ipaddr
) {
1213 #if defined (DEBUG_INFORM_HOST)
1214 log_debug ("dhcpinform: found host "
1215 "without fixed-address by ID");
1217 host_reference(&host
, h
, MDL
);
1221 host_dereference (&hp
, MDL
);
1223 if (!host
|| !h_m_client_ip
) {
1224 find_hosts_by_haddr(&hp
, packet
->raw
->htype
,
1225 packet
->raw
->chaddr
,
1226 packet
->raw
->hlen
, MDL
);
1228 #if defined (DEBUG_INFORM_HOST)
1230 log_debug ("dhcpinform: found host by HW "
1231 "-- checking fixed-address match");
1234 /* check if we have one with fixed-address
1235 * matching the client ip first */
1236 for (h
= hp
; !h_m_client_ip
&& h
; h
= h
->n_ipaddr
) {
1240 memset (&fixed_addr
, 0, sizeof(fixed_addr
));
1241 if (!evaluate_option_cache (&fixed_addr
, NULL
,
1242 NULL
, NULL
, NULL
, NULL
,
1244 h
->fixed_addr
, MDL
))
1247 #if defined (DEBUG_INFORM_HOST)
1251 (i
+ cip
.len
) <= fixed_addr
.len
;
1253 if (memcmp(fixed_addr
.data
+ i
,
1254 cip
.iabuf
, cip
.len
) == 0) {
1255 #if defined (DEBUG_INFORM_HOST)
1256 log_debug ("dhcpinform: found "
1257 "host with matching "
1258 "fixed-address by HW");
1261 * Hmm.. we've found one
1262 * without IP by ID and now
1263 * (better) one with IP by HW.
1266 host_dereference(&host
, MDL
);
1267 host_reference(&host
, h
, MDL
);
1272 data_string_forget(&fixed_addr
, MDL
);
1274 /* fallback to a host without fixed-address */
1275 for (h
= hp
; !host
&& h
; h
= h
->n_ipaddr
) {
1279 #if defined (DEBUG_INFORM_HOST)
1280 log_debug ("dhcpinform: found host without "
1281 "fixed-address by HW");
1283 host_reference (&host
, h
, MDL
);
1288 host_dereference (&hp
, MDL
);
1291 #if defined (DEBUG_INFORM_HOST)
1292 /* Hmm..: what when there is a host with a fixed-address,
1293 * that matches by hw or id, but the fixed-addresses
1294 * didn't match client ip?
1296 if (h_w_fixed_addr
&& !h_m_client_ip
) {
1297 log_info ("dhcpinform: matching host with "
1298 "fixed-address different than "
1299 "client IP detected?!");
1303 /* If we have a host_decl structure, run the options
1304 * associated with its group. Whether the host decl
1305 * struct is old or not. */
1307 #if defined (DEBUG_INFORM_HOST)
1308 log_info ("dhcpinform: applying host (group) options");
1310 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
1311 packet
->options
, options
,
1312 &global_scope
, host
->group
,
1315 host_dereference (&host
, MDL
);
1318 /* CC: end of host entry processing.... */
1320 /* Figure out the filename. */
1321 memset (&d1
, 0, sizeof d1
);
1322 oc
= lookup_option (&server_universe
, options
, SV_FILENAME
);
1324 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1325 (struct client_state
*)0,
1326 packet
-> options
, (struct option_state
*)0,
1327 &global_scope
, oc
, MDL
)) {
1329 if (i
>= sizeof(raw
.file
)) {
1330 log_info("file name longer than packet field "
1331 "truncated - field: %lu name: %d %.*s",
1332 (unsigned long)sizeof(raw
.file
), i
,
1334 i
= sizeof(raw
.file
);
1337 memcpy (raw
.file
, d1
.data
, i
);
1338 data_string_forget (&d1
, MDL
);
1341 /* Choose a server name as above. */
1342 oc
= lookup_option (&server_universe
, options
, SV_SERVER_NAME
);
1344 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1345 (struct client_state
*)0,
1346 packet
-> options
, (struct option_state
*)0,
1347 &global_scope
, oc
, MDL
)) {
1349 if (i
>= sizeof(raw
.sname
)) {
1350 log_info("server name longer than packet field "
1351 "truncated - field: %lu name: %d %.*s",
1352 (unsigned long)sizeof(raw
.sname
), i
,
1354 i
= sizeof(raw
.sname
);
1357 memcpy (raw
.sname
, d1
.data
, i
);
1358 data_string_forget (&d1
, MDL
);
1361 /* Set a flag if this client is a lame Microsoft client that NUL
1362 terminates string options and expects us to do likewise. */
1364 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
1366 if (!oc
->expression
)
1367 nulltp
= oc
->flags
& OPTION_HAD_NULLS
;
1370 /* Put in DHCP-specific options. */
1371 i
= DHO_DHCP_MESSAGE_TYPE
;
1372 oc
= (struct option_cache
*)0;
1373 if (option_cache_allocate (&oc
, MDL
)) {
1374 if (make_const_data (&oc
-> expression
,
1375 &dhcpack
, 1, 0, 0, MDL
)) {
1376 option_code_hash_lookup(&oc
->option
,
1377 dhcp_universe
.code_hash
,
1379 save_option (&dhcp_universe
, options
, oc
);
1381 option_cache_dereference (&oc
, MDL
);
1384 get_server_source_address(&from
, options
, options
, packet
);
1386 /* Use the subnet mask from the subnet declaration if no other
1387 mask has been provided. */
1388 i
= DHO_SUBNET_MASK
;
1389 if (subnet
&& !lookup_option (&dhcp_universe
, options
, i
)) {
1390 oc
= (struct option_cache
*)0;
1391 if (option_cache_allocate (&oc
, MDL
)) {
1392 if (make_const_data (&oc
-> expression
,
1393 subnet
-> netmask
.iabuf
,
1394 subnet
-> netmask
.len
,
1396 option_code_hash_lookup(&oc
->option
,
1397 dhcp_universe
.code_hash
,
1399 save_option (&dhcp_universe
, options
, oc
);
1401 option_cache_dereference (&oc
, MDL
);
1405 /* If a site option space has been specified, use that for
1406 site option codes. */
1407 i
= SV_SITE_OPTION_SPACE
;
1408 if ((oc
= lookup_option (&server_universe
, options
, i
)) &&
1409 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1410 (struct client_state
*)0,
1411 packet
-> options
, options
,
1412 &global_scope
, oc
, MDL
)) {
1413 struct universe
*u
= (struct universe
*)0;
1415 if (!universe_hash_lookup (&u
, universe_hash
,
1416 (const char *)d1
.data
, d1
.len
,
1418 log_error ("unknown option space %s.", d1
.data
);
1419 option_state_dereference (&options
, MDL
);
1421 subnet_dereference (&subnet
, MDL
);
1425 options
-> site_universe
= u
-> index
;
1426 options
->site_code_min
= find_min_site_code(u
);
1427 data_string_forget (&d1
, MDL
);
1429 options
-> site_universe
= dhcp_universe
.index
;
1430 options
-> site_code_min
= 0; /* Trust me, it works. */
1433 memset (&prl
, 0, sizeof prl
);
1435 /* Use the parameter list from the scope if there is one. */
1436 oc
= lookup_option (&dhcp_universe
, options
,
1437 DHO_DHCP_PARAMETER_REQUEST_LIST
);
1439 /* Otherwise, if the client has provided a list of options
1440 that it wishes returned, use it to prioritize. Otherwise,
1441 prioritize based on the default priority list. */
1444 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
1445 DHO_DHCP_PARAMETER_REQUEST_LIST
);
1448 evaluate_option_cache (&prl
, packet
, (struct lease
*)0,
1449 (struct client_state
*)0,
1450 packet
-> options
, options
,
1451 &global_scope
, oc
, MDL
);
1454 dump_packet (packet
);
1455 dump_raw ((unsigned char *)packet
-> raw
, packet
-> packet_length
);
1458 log_info ("%s", msgbuf
);
1460 /* Figure out the address of the boot file server. */
1462 lookup_option (&server_universe
, options
, SV_NEXT_SERVER
))) {
1463 if (evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1464 (struct client_state
*)0,
1465 packet
-> options
, options
,
1466 &global_scope
, oc
, MDL
)) {
1467 /* If there was more than one answer,
1469 if (d1
.len
>= 4 && d1
.data
)
1470 memcpy (&raw
.siaddr
, d1
.data
, 4);
1471 data_string_forget (&d1
, MDL
);
1476 * Remove any time options, per section 3.4 RFC 2131
1478 delete_option(&dhcp_universe
, options
, DHO_DHCP_LEASE_TIME
);
1479 delete_option(&dhcp_universe
, options
, DHO_DHCP_RENEWAL_TIME
);
1480 delete_option(&dhcp_universe
, options
, DHO_DHCP_REBINDING_TIME
);
1482 /* Set up the option buffer... */
1483 outgoing
.packet_length
=
1484 cons_options (packet
, outgoing
.raw
, (struct lease
*)0,
1485 (struct client_state
*)0,
1486 0, packet
-> options
, options
, &global_scope
,
1488 prl
.len
? &prl
: (struct data_string
*)0,
1490 option_state_dereference (&options
, MDL
);
1491 data_string_forget (&prl
, MDL
);
1493 /* Make sure that the packet is at least as big as a BOOTP packet. */
1494 if (outgoing
.packet_length
< BOOTP_MIN_LEN
)
1495 outgoing
.packet_length
= BOOTP_MIN_LEN
;
1497 raw
.giaddr
= packet
-> raw
-> giaddr
;
1498 raw
.ciaddr
= packet
-> raw
-> ciaddr
;
1499 memcpy (raw
.chaddr
, packet
-> raw
-> chaddr
, sizeof raw
.chaddr
);
1500 raw
.hlen
= packet
-> raw
-> hlen
;
1501 raw
.htype
= packet
-> raw
-> htype
;
1503 raw
.xid
= packet
-> raw
-> xid
;
1504 raw
.secs
= packet
-> raw
-> secs
;
1505 raw
.flags
= packet
-> raw
-> flags
;
1506 raw
.hops
= packet
-> raw
-> hops
;
1510 dump_packet (&outgoing
);
1511 dump_raw ((unsigned char *)&raw
, outgoing
.packet_length
);
1514 /* Set up the common stuff... */
1515 to
.sin_family
= AF_INET
;
1517 to
.sin_len
= sizeof to
;
1519 memset (to
.sin_zero
, 0, sizeof to
.sin_zero
);
1521 /* RFC2131 states the server SHOULD unicast to ciaddr.
1522 * There are two wrinkles - relays, and when ciaddr is zero.
1523 * There's actually no mention of relays at all in rfc2131 in
1524 * regard to DHCPINFORM, except to say we might get packets from
1525 * clients via them. Note: relays unicast to clients to the
1526 * "yiaddr" address, which servers are forbidden to set when
1527 * answering an inform.
1529 * The solution: If ciaddr is zero, and giaddr is set, go via the
1530 * relay with the broadcast flag set to help the relay (with no
1531 * yiaddr and very likely no chaddr, it will have no idea where to
1534 * If the ciaddr is zero and giaddr is not set, go via the source
1535 * IP address (but you are permitted to barf on their shoes).
1537 * If ciaddr is not zero, send the packet there always.
1539 if (!raw
.ciaddr
.s_addr
&& gip
.len
) {
1540 memcpy(&to
.sin_addr
, gip
.iabuf
, 4);
1541 to
.sin_port
= local_port
;
1542 raw
.flags
|= htons(BOOTP_BROADCAST
);
1545 memcpy(&to
.sin_addr
, cip
.iabuf
, 4);
1546 to
.sin_port
= remote_port
;
1549 /* Report what we're sending. */
1550 snprintf(msgbuf
, sizeof msgbuf
, "DHCPACK to %s (%s) via", piaddr(cip
),
1551 (packet
->raw
->htype
&& packet
->raw
->hlen
) ?
1552 print_hw_addr(packet
->raw
->htype
, packet
->raw
->hlen
,
1553 packet
->raw
->chaddr
) :
1554 "<no client hardware address>");
1555 log_info("%s %s", msgbuf
, gip
.len
? piaddr(gip
) :
1556 packet
->interface
->name
);
1559 interface
= (fallback_interface
? fallback_interface
1560 : packet
-> interface
);
1561 result
= send_packet(interface
, &outgoing
, &raw
,
1562 outgoing
.packet_length
, from
, &to
, NULL
);
1564 log_error ("%s:%d: Failed to send %d byte long packet over %s "
1565 "interface.", MDL
, outgoing
.packet_length
,
1571 subnet_dereference (&subnet
, MDL
);
1575 * \brief Constructs and sends a DHCP Nak
1577 * In order to populate options such as dhcp-server-id and
1578 * dhcp-client-identifier, the function creates a temporary option cache
1579 * and evaluates options based on the packet's shared-network or the
1580 * network_group in its absence, as well as the packet->clasess (if any).
1582 * \param packet inbound packet received from the client
1583 * \param cip address requested by the client
1584 * \param network_group optional scope for use in setting up options
1586 void nak_lease (packet
, cip
, network_group
)
1587 struct packet
*packet
;
1589 struct group
*network_group
; /* scope to use for options */
1591 struct sockaddr_in to
;
1592 struct in_addr from
;
1594 struct dhcp_packet raw
;
1595 unsigned char nak
= DHCPNAK
;
1596 struct packet outgoing
;
1598 struct option_state
*options
= (struct option_state
*)0;
1599 struct option_cache
*oc
= (struct option_cache
*)0;
1600 struct option_state
*eval_options
= NULL
;
1602 option_state_allocate (&options
, MDL
);
1603 memset (&outgoing
, 0, sizeof outgoing
);
1604 memset (&raw
, 0, sizeof raw
);
1605 outgoing
.raw
= &raw
;
1607 /* Set DHCP_MESSAGE_TYPE to DHCPNAK */
1608 if (!option_cache_allocate (&oc
, MDL
)) {
1609 log_error ("No memory for DHCPNAK message type.");
1610 option_state_dereference (&options
, MDL
);
1613 if (!make_const_data (&oc
-> expression
, &nak
, sizeof nak
,
1615 log_error ("No memory for expr_const expression.");
1616 option_cache_dereference (&oc
, MDL
);
1617 option_state_dereference (&options
, MDL
);
1620 i
= DHO_DHCP_MESSAGE_TYPE
;
1621 option_code_hash_lookup(&oc
->option
, dhcp_universe
.code_hash
,
1623 save_option (&dhcp_universe
, options
, oc
);
1624 option_cache_dereference (&oc
, MDL
);
1626 /* Set DHCP_MESSAGE to whatever the message is */
1627 if (!option_cache_allocate (&oc
, MDL
)) {
1628 log_error ("No memory for DHCPNAK message type.");
1629 option_state_dereference (&options
, MDL
);
1632 if (!make_const_data (&oc
-> expression
,
1633 (unsigned char *)dhcp_message
,
1634 strlen (dhcp_message
), 1, 0, MDL
)) {
1635 log_error ("No memory for expr_const expression.");
1636 option_cache_dereference (&oc
, MDL
);
1637 option_state_dereference (&options
, MDL
);
1640 i
= DHO_DHCP_MESSAGE
;
1641 option_code_hash_lookup(&oc
->option
, dhcp_universe
.code_hash
,
1643 save_option (&dhcp_universe
, options
, oc
);
1644 option_cache_dereference (&oc
, MDL
);
1646 /* Setup the options at the global and subnet scopes. These
1647 * may be used to locate sever id option if enabled as well
1648 * for echo-client-id further on. (This allocates eval_options). */
1649 eval_network_statements(&eval_options
, packet
, network_group
);
1651 #if defined(SERVER_ID_FOR_NAK)
1652 /* Pass in the evaluated options so they can be searched for
1653 * server-id, otherwise source address comes from the interface
1655 get_server_source_address(&from
, eval_options
, options
, packet
);
1657 /* Get server source address from the interface address */
1658 get_server_source_address(&from
, NULL
, options
, packet
);
1659 #endif /* if defined(SERVER_ID_FOR_NAK) */
1661 /* If there were agent options in the incoming packet, return
1662 * them. We do not check giaddr to detect the presence of a
1663 * relay, as this excludes "l2" relay agents which have no
1666 if (packet
->options
->universe_count
> agent_universe
.index
&&
1667 packet
->options
->universes
[agent_universe
.index
]) {
1668 option_chain_head_reference
1669 ((struct option_chain_head
**)
1670 &(options
-> universes
[agent_universe
.index
]),
1671 (struct option_chain_head
*)
1672 packet
-> options
-> universes
[agent_universe
.index
],
1676 /* echo-client-id can specified at the class level so add class-scoped
1677 * options into eval_options. */
1678 for (i
= packet
->class_count
; i
> 0; i
--) {
1679 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
1680 packet
->options
, eval_options
,
1682 packet
->classes
[i
- 1]->group
,
1686 /* Echo client id if we received and it's enabled */
1687 echo_client_id(packet
, NULL
, eval_options
, options
);
1688 option_state_dereference (&eval_options
, MDL
);
1690 /* Do not use the client's requested parameter list. */
1691 delete_option (&dhcp_universe
, packet
-> options
,
1692 DHO_DHCP_PARAMETER_REQUEST_LIST
);
1694 /* Set up the option buffer... */
1695 outgoing
.packet_length
=
1696 cons_options (packet
, outgoing
.raw
, (struct lease
*)0,
1697 (struct client_state
*)0,
1698 0, packet
-> options
, options
, &global_scope
,
1699 0, 0, 0, (struct data_string
*)0, (char *)0);
1700 option_state_dereference (&options
, MDL
);
1702 /* memset (&raw.ciaddr, 0, sizeof raw.ciaddr);*/
1703 raw
.giaddr
= packet
-> raw
-> giaddr
;
1704 memcpy (raw
.chaddr
, packet
-> raw
-> chaddr
, sizeof raw
.chaddr
);
1705 raw
.hlen
= packet
-> raw
-> hlen
;
1706 raw
.htype
= packet
-> raw
-> htype
;
1708 raw
.xid
= packet
-> raw
-> xid
;
1709 raw
.secs
= packet
-> raw
-> secs
;
1710 raw
.flags
= packet
-> raw
-> flags
| htons (BOOTP_BROADCAST
);
1711 raw
.hops
= packet
-> raw
-> hops
;
1714 /* Report what we're sending... */
1715 log_info ("DHCPNAK on %s to %s via %s",
1717 print_hw_addr (packet
-> raw
-> htype
,
1718 packet
-> raw
-> hlen
,
1719 packet
-> raw
-> chaddr
),
1720 packet
-> raw
-> giaddr
.s_addr
1721 ? inet_ntoa (packet
-> raw
-> giaddr
)
1722 : packet
-> interface
-> name
);
1725 dump_packet (packet
);
1726 dump_raw ((unsigned char *)packet
-> raw
, packet
-> packet_length
);
1727 dump_packet (&outgoing
);
1728 dump_raw ((unsigned char *)&raw
, outgoing
.packet_length
);
1731 /* Set up the common stuff... */
1732 to
.sin_family
= AF_INET
;
1734 to
.sin_len
= sizeof to
;
1736 memset (to
.sin_zero
, 0, sizeof to
.sin_zero
);
1738 /* Make sure that the packet is at least as big as a BOOTP packet. */
1739 if (outgoing
.packet_length
< BOOTP_MIN_LEN
)
1740 outgoing
.packet_length
= BOOTP_MIN_LEN
;
1742 /* If this was gatewayed, send it back to the gateway.
1743 Otherwise, broadcast it on the local network. */
1744 if (raw
.giaddr
.s_addr
) {
1745 to
.sin_addr
= raw
.giaddr
;
1746 if (raw
.giaddr
.s_addr
!= htonl (INADDR_LOOPBACK
))
1747 to
.sin_port
= local_port
;
1749 to
.sin_port
= remote_port
; /* for testing. */
1751 if (fallback_interface
) {
1752 result
= send_packet(fallback_interface
, packet
, &raw
,
1753 outgoing
.packet_length
, from
, &to
,
1756 log_error ("%s:%d: Failed to send %d byte long "
1757 "packet over %s interface.", MDL
,
1758 outgoing
.packet_length
,
1759 fallback_interface
->name
);
1765 to
.sin_addr
= limited_broadcast
;
1766 to
.sin_port
= remote_port
;
1770 result
= send_packet(packet
->interface
, packet
, &raw
,
1771 outgoing
.packet_length
, from
, &to
, NULL
);
1773 log_error ("%s:%d: Failed to send %d byte long packet over %s "
1774 "interface.", MDL
, outgoing
.packet_length
,
1775 packet
->interface
->name
);
1781 * \brief Adds a dhcp-client-id option to a set of options
1782 * Given a set of input options, it searches for echo-client-id. If it is
1783 * defined and enabled, the given packet is searched for dhcp-client-id. If
1784 * the option is found it is replicated into the given set of output options.
1785 * This allows us to provide compliance with RFC 6842. It is called when we ack
1786 * or nak a lease. In the latter case we may or may not have created the
1787 * requisite scope to lookup echo-client-id.
1789 * Note the flag packet.sv_echo_client_id is set to reflect the configuration
1790 * option. This bypases inaccessiblity of server_universe in cons_options()
1791 * which must amend the PRL (when not empty) if echoing is enabled.
1793 * \param packet inbound packet received from the client
1794 * \param lease lease associated with this client (if one)
1795 * \param in_options options in which to search for echo-client-id
1796 * \param out_options options to which to save the client-id
1798 void echo_client_id(packet
, lease
, in_options
, out_options
)
1799 struct packet
*packet
;
1800 struct lease
*lease
;
1801 struct option_state
*in_options
;
1802 struct option_state
*out_options
;
1804 struct option_cache
*oc
;
1807 /* Check if echo-client-id is enabled */
1808 oc
= lookup_option(&server_universe
, in_options
, SV_ECHO_CLIENT_ID
);
1809 if (oc
&& evaluate_boolean_option_cache(&ignorep
, packet
, lease
,
1810 NULL
, packet
->options
,
1812 (lease
? &lease
->scope
: NULL
),
1814 struct data_string client_id
;
1815 unsigned int opcode
= DHO_DHCP_CLIENT_IDENTIFIER
;
1817 /* Save knowledge that echo is enabled to the packet */
1818 packet
->sv_echo_client_id
= ISC_TRUE
;
1820 /* Now see if inbound packet contains client-id */
1821 oc
= lookup_option(&dhcp_universe
, packet
->options
, opcode
);
1822 memset(&client_id
, 0, sizeof client_id
);
1823 if (oc
&& evaluate_option_cache(&client_id
,
1825 packet
->options
, NULL
,
1826 (lease
? &lease
->scope
: NULL
),
1828 /* Packet contained client-id, add it to out_options. */
1830 if (option_cache_allocate(&oc
, MDL
)) {
1831 if (make_const_data(&oc
->expression
,
1835 option_code_hash_lookup(&oc
->option
,
1840 save_option(&dhcp_universe
,
1843 option_cache_dereference(&oc
, MDL
);
1849 void check_pool_threshold (packet
, lease
, state
)
1850 struct packet
*packet
;
1851 struct lease
*lease
;
1852 struct lease_state
*state
;
1856 struct pool
*pool
= lease
->pool
;
1857 int used
, count
, high_threshold
, poolhigh
= 0, poollow
= 0;
1858 char *shared_name
= "no name";
1863 /* get a pointer to the name if we have one */
1864 if ((pool
->shared_network
!= NULL
) &&
1865 (pool
->shared_network
->name
!= NULL
)) {
1866 shared_name
= pool
->shared_network
->name
;
1869 count
= pool
->lease_count
;
1870 used
= count
- (pool
->free_leases
+ pool
->backup_leases
);
1872 /* The logged flag indicates if we have already crossed the high
1873 * threshold and emitted a log message. If it is set we check to
1874 * see if we have re-crossed the low threshold and need to reset
1875 * things. When we cross the high threshold we determine what
1876 * the low threshold is and save it into the low_threshold value.
1877 * When we cross that threshold we reset the logged flag and
1878 * the low_threshold to 0 which allows the high threshold message
1879 * to be emitted once again.
1880 * if we haven't recrossed the boundry we don't need to do anything.
1882 if (pool
->logged
!=0) {
1883 if (used
<= pool
->low_threshold
) {
1884 pool
->low_threshold
= 0;
1886 log_error("Pool threshold reset - shared subnet: %s; "
1887 "address: %s; low threshold %d/%d.",
1888 shared_name
, piaddr(lease
->ip_addr
),
1894 /* find the high threshold */
1895 if (get_option_int(&poolhigh
, &server_universe
, packet
, lease
, NULL
,
1896 packet
->options
, state
->options
, state
->options
,
1897 &lease
->scope
, SV_LOG_THRESHOLD_HIGH
, MDL
) == 0) {
1898 /* no threshold bail out */
1902 /* We do have a threshold for this pool, see if its valid */
1903 if ((poolhigh
<= 0) || (poolhigh
> 100)) {
1908 /* we have a valid value, have we exceeded it */
1909 high_threshold
= FIND_PERCENT(count
, poolhigh
);
1910 if (used
< high_threshold
) {
1911 /* nope, no more to do */
1915 /* we've exceeded it, output a message */
1916 log_error("Pool threshold exceeded - shared subnet: %s; "
1917 "address: %s; high threshold %d%% %d/%d.",
1918 shared_name
, piaddr(lease
->ip_addr
),
1919 poolhigh
, used
, count
);
1921 /* handle the low threshold now, if we don't
1922 * have a valid one we default to 0. */
1923 if ((get_option_int(&poollow
, &server_universe
, packet
, lease
, NULL
,
1924 packet
->options
, state
->options
, state
->options
,
1925 &lease
->scope
, SV_LOG_THRESHOLD_LOW
, MDL
) == 0) ||
1931 * If the low theshold is higher than the high threshold we continue to log
1932 * If it isn't then we set the flag saying we already logged and determine
1933 * what the reset threshold is.
1935 if (poollow
< poolhigh
) {
1937 pool
->low_threshold
= FIND_PERCENT(count
, poollow
);
1941 void ack_lease (packet
, lease
, offer
, when
, msg
, ms_nulltp
, hp
)
1942 struct packet
*packet
;
1943 struct lease
*lease
;
1948 struct host_decl
*hp
;
1951 struct lease_state
*state
;
1953 struct host_decl
*host
= (struct host_decl
*)0;
1955 TIME offered_lease_time
;
1956 struct data_string d1
;
1957 TIME min_lease_time
;
1958 TIME max_lease_time
;
1959 TIME default_lease_time
;
1960 struct option_cache
*oc
;
1961 isc_result_t result
;
1964 struct in_addr from
;
1965 TIME remaining_time
;
1967 #if defined(DELAYED_ACK)
1968 /* By default we don't do the enqueue */
1969 isc_boolean_t enqueue
= ISC_FALSE
;
1971 int use_old_lease
= 0;
1978 /* If we're already acking this lease, don't do it again. */
1982 /* Save original cltt for comparison later. */
1983 lease_cltt
= lease
->cltt
;
1985 /* If the lease carries a host record, remember it. */
1987 host_reference (&host
, hp
, MDL
);
1988 else if (lease
-> host
)
1989 host_reference (&host
, lease
-> host
, MDL
);
1991 /* Allocate a lease state structure... */
1992 state
= new_lease_state (MDL
);
1994 log_fatal ("unable to allocate lease state!");
1995 state
-> got_requested_address
= packet
-> got_requested_address
;
1996 shared_network_reference (&state
-> shared_network
,
1997 packet
-> interface
-> shared_network
, MDL
);
1999 /* See if we got a server identifier option. */
2000 if (lookup_option (&dhcp_universe
,
2001 packet
-> options
, DHO_DHCP_SERVER_IDENTIFIER
))
2002 state
-> got_server_identifier
= 1;
2004 maybe_return_agent_options(packet
, state
->options
);
2006 /* If we are offering a lease that is still currently valid, preserve
2007 the events. We need to do this because if the client does not
2008 REQUEST our offer, it will expire in 2 minutes, overriding the
2009 expire time in the currently in force lease. We want the expire
2010 events to be executed at that point. */
2011 if (lease
->ends
<= cur_time
&& offer
!= DHCPOFFER
) {
2012 /* Get rid of any old expiry or release statements - by
2013 executing the statements below, we will be inserting new
2014 ones if there are any to insert. */
2015 if (lease
->on_star
.on_expiry
)
2016 executable_statement_dereference
2017 (&lease
->on_star
.on_expiry
, MDL
);
2018 if (lease
->on_star
.on_commit
)
2019 executable_statement_dereference
2020 (&lease
->on_star
.on_commit
, MDL
);
2021 if (lease
->on_star
.on_release
)
2022 executable_statement_dereference
2023 (&lease
->on_star
.on_release
, MDL
);
2026 /* Execute statements in scope starting with the subnet scope. */
2027 execute_statements_in_scope (NULL
, packet
, lease
,
2028 NULL
, packet
->options
,
2029 state
->options
, &lease
->scope
,
2030 lease
->subnet
->group
, NULL
, NULL
);
2032 /* If the lease is from a pool, run the pool scope. */
2034 (execute_statements_in_scope(NULL
, packet
, lease
, NULL
,
2035 packet
->options
, state
->options
,
2036 &lease
->scope
, lease
->pool
->group
,
2038 shared_network
->group
,
2041 /* Execute statements from class scopes. */
2042 for (i
= packet
-> class_count
; i
> 0; i
--) {
2043 execute_statements_in_scope(NULL
, packet
, lease
, NULL
,
2044 packet
->options
, state
->options
,
2046 packet
->classes
[i
- 1]->group
,
2047 (lease
->pool
? lease
->pool
->group
2048 : lease
->subnet
->group
),
2052 /* See if the client is only supposed to have one lease at a time,
2053 and if so, find its other leases and release them. We can only
2054 do this on DHCPREQUEST. It's a little weird to do this before
2055 looking at permissions, because the client might not actually
2056 _get_ a lease after we've done the permission check, but the
2057 assumption for this option is that the client has exactly one
2058 network interface, and will only ever remember one lease. So
2059 if it sends a DHCPREQUEST, and doesn't get the lease, it's already
2060 forgotten about its old lease, so we can too. */
2061 if (packet
-> packet_type
== DHCPREQUEST
&&
2062 (oc
= lookup_option (&server_universe
, state
-> options
,
2063 SV_ONE_LEASE_PER_CLIENT
)) &&
2064 evaluate_boolean_option_cache (&ignorep
,
2066 (struct client_state
*)0,
2068 state
-> options
, &lease
-> scope
,
2071 if (lease
-> uid_len
) {
2073 seek
= (struct lease
*)0;
2074 find_lease_by_uid (&seek
, lease
-> uid
,
2075 lease
-> uid_len
, MDL
);
2078 if (seek
== lease
&& !seek
-> n_uid
) {
2079 lease_dereference (&seek
, MDL
);
2082 next
= (struct lease
*)0;
2084 /* Don't release expired leases, and don't
2085 release the lease we're going to assign. */
2086 next
= (struct lease
*)0;
2089 lease_reference (&next
, seek
-> n_uid
, MDL
);
2090 if (seek
!= lease
&&
2091 seek
-> binding_state
!= FTS_RELEASED
&&
2092 seek
-> binding_state
!= FTS_EXPIRED
&&
2093 seek
-> binding_state
!= FTS_RESET
&&
2094 seek
-> binding_state
!= FTS_FREE
&&
2095 seek
-> binding_state
!= FTS_BACKUP
)
2097 lease_dereference (&seek
, MDL
);
2099 lease_reference (&seek
, next
, MDL
);
2100 lease_dereference (&next
, MDL
);
2104 lease_dereference (&next
, MDL
);
2106 release_lease (seek
, packet
);
2107 lease_dereference (&seek
, MDL
);
2112 if (!lease
-> uid_len
||
2114 !host
-> client_identifier
.len
&&
2115 (oc
= lookup_option (&server_universe
, state
-> options
,
2117 !evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
2118 (struct client_state
*)0,
2124 seek
= (struct lease
*)0;
2125 find_lease_by_hw_addr
2126 (&seek
, lease
-> hardware_addr
.hbuf
,
2127 lease
-> hardware_addr
.hlen
, MDL
);
2130 if (seek
== lease
&& !seek
-> n_hw
) {
2131 lease_dereference (&seek
, MDL
);
2134 next
= (struct lease
*)0;
2137 lease_reference (&next
, seek
-> n_hw
, MDL
);
2138 if (seek
!= lease
&&
2139 seek
-> binding_state
!= FTS_RELEASED
&&
2140 seek
-> binding_state
!= FTS_EXPIRED
&&
2141 seek
-> binding_state
!= FTS_RESET
&&
2142 seek
-> binding_state
!= FTS_FREE
&&
2143 seek
-> binding_state
!= FTS_BACKUP
)
2145 lease_dereference (&seek
, MDL
);
2147 lease_reference (&seek
, next
, MDL
);
2148 lease_dereference (&next
, MDL
);
2152 lease_dereference (&next
, MDL
);
2154 release_lease (seek
, packet
);
2155 lease_dereference (&seek
, MDL
);
2163 /* Make sure this packet satisfies the configured minimum
2164 number of seconds. */
2165 memset (&d1
, 0, sizeof d1
);
2166 if (offer
== DHCPOFFER
&&
2167 (oc
= lookup_option (&server_universe
, state
-> options
,
2169 if (evaluate_option_cache (&d1
, packet
, lease
,
2170 (struct client_state
*)0,
2171 packet
-> options
, state
-> options
,
2172 &lease
-> scope
, oc
, MDL
)) {
2174 ntohs (packet
-> raw
-> secs
) < d1
.data
[0]) {
2175 log_info("%s: configured min-secs value (%d) "
2176 "is greater than secs field (%d). "
2177 "message dropped.", msg
, d1
.data
[0],
2178 ntohs(packet
->raw
->secs
));
2179 data_string_forget (&d1
, MDL
);
2180 free_lease_state (state
, MDL
);
2182 host_dereference (&host
, MDL
);
2185 data_string_forget (&d1
, MDL
);
2189 /* Try to find a matching host declaration for this lease.
2192 struct host_decl
*hp
= (struct host_decl
*)0;
2193 struct host_decl
*h
;
2195 /* Try to find a host_decl that matches the client
2196 identifier or hardware address on the packet, and
2197 has no fixed IP address. If there is one, hang
2198 it off the lease so that its option definitions
2200 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
2201 DHO_DHCP_CLIENT_IDENTIFIER
);
2203 evaluate_option_cache (&d1
, packet
, lease
,
2204 (struct client_state
*)0,
2205 packet
-> options
, state
-> options
,
2206 &lease
-> scope
, oc
, MDL
)) {
2207 find_hosts_by_uid (&hp
, d1
.data
, d1
.len
, MDL
);
2208 data_string_forget (&d1
, MDL
);
2209 for (h
= hp
; h
; h
= h
-> n_ipaddr
) {
2210 if (!h
-> fixed_addr
)
2214 host_reference (&host
, h
, MDL
);
2216 host_dereference(&hp
, MDL
);
2219 find_hosts_by_haddr (&hp
,
2220 packet
-> raw
-> htype
,
2221 packet
-> raw
-> chaddr
,
2222 packet
-> raw
-> hlen
,
2224 for (h
= hp
; h
; h
= h
-> n_ipaddr
) {
2225 if (!h
-> fixed_addr
)
2229 host_reference (&host
, h
, MDL
);
2231 host_dereference(&hp
, MDL
);
2234 find_hosts_by_option(&hp
, packet
,
2235 packet
->options
, MDL
);
2236 for (h
= hp
; h
; h
= h
-> n_ipaddr
) {
2237 if (!h
-> fixed_addr
)
2241 host_reference (&host
, h
, MDL
);
2243 host_dereference(&hp
, MDL
);
2247 /* If we have a host_decl structure, run the options associated
2248 with its group. Whether the host decl struct is old or not. */
2250 execute_statements_in_scope (NULL
, packet
, lease
, NULL
,
2251 packet
->options
, state
->options
,
2252 &lease
->scope
, host
->group
,
2254 ? lease
->pool
->group
2255 : lease
->subnet
->group
),
2258 /* Drop the request if it's not allowed for this client. By
2259 default, unknown clients are allowed. */
2261 (oc
= lookup_option (&server_universe
, state
-> options
,
2262 SV_BOOT_UNKNOWN_CLIENTS
)) &&
2263 !evaluate_boolean_option_cache (&ignorep
,
2265 (struct client_state
*)0,
2268 &lease
-> scope
, oc
, MDL
)) {
2270 log_info ("%s: unknown client", msg
);
2271 free_lease_state (state
, MDL
);
2273 host_dereference (&host
, MDL
);
2277 /* Drop the request if it's not allowed for this client. */
2279 (oc
= lookup_option (&server_universe
, state
-> options
,
2281 !evaluate_boolean_option_cache (&ignorep
,
2283 (struct client_state
*)0,
2286 &lease
-> scope
, oc
, MDL
)) {
2288 log_info ("%s: bootp disallowed", msg
);
2289 free_lease_state (state
, MDL
);
2291 host_dereference (&host
, MDL
);
2295 /* Drop the request if booting is specifically denied. */
2296 oc
= lookup_option (&server_universe
, state
-> options
,
2299 !evaluate_boolean_option_cache (&ignorep
,
2301 (struct client_state
*)0,
2304 &lease
-> scope
, oc
, MDL
)) {
2306 log_info ("%s: booting disallowed", msg
);
2307 free_lease_state (state
, MDL
);
2309 host_dereference (&host
, MDL
);
2313 /* If we are configured to do per-class billing, do it. */
2314 if (have_billing_classes
&& !(lease
-> flags
& STATIC_LEASE
)) {
2315 /* See if the lease is currently being billed to a
2316 class, and if so, whether or not it can continue to
2317 be billed to that class. */
2318 if (lease
-> billing_class
) {
2319 for (i
= 0; i
< packet
-> class_count
; i
++)
2320 if (packet
-> classes
[i
] ==
2321 lease
-> billing_class
)
2323 if (i
== packet
-> class_count
) {
2324 unbill_class(lease
);
2325 /* Active lease billing change negates reuse */
2326 if (lease
->binding_state
== FTS_ACTIVE
) {
2327 lease
->cannot_reuse
= 1;
2332 /* If we don't have an active billing, see if we need
2333 one, and if we do, try to do so. */
2334 if (lease
->billing_class
== NULL
) {
2338 for (i
= 0; i
< packet
->class_count
; i
++) {
2339 struct class *billclass
, *subclass
;
2341 billclass
= packet
->classes
[i
];
2342 if (billclass
->lease_limit
) {
2344 if (bill_class(lease
, billclass
))
2347 subclass
= billclass
->superclass
;
2348 if (subclass
== NULL
)
2349 cname
= subclass
->name
;
2351 cname
= billclass
->name
;
2354 if (bill
!= 0 && i
== packet
->class_count
) {
2355 log_info("%s: no available billing: lease "
2356 "limit reached in all matching "
2357 "classes (last: '%s')", msg
, cname
);
2358 free_lease_state(state
, MDL
);
2360 host_dereference(&host
, MDL
);
2365 * If this is an offer, undo the billing. We go
2366 * through all the steps above to bill a class so
2367 * we can hit the 'no available billing' mark and
2368 * abort without offering. But it just doesn't make
2369 * sense to permanently bill a class for a non-active
2370 * lease. This means on REQUEST, we will bill this
2371 * lease again (if there is a REQUEST).
2373 if (offer
== DHCPOFFER
&&
2374 lease
->billing_class
!= NULL
&&
2375 lease
->binding_state
!= FTS_ACTIVE
)
2376 unbill_class(lease
);
2378 /* Lease billing change negates reuse */
2379 if (lease
->billing_class
!= NULL
) {
2380 lease
->cannot_reuse
= 1;
2385 /* Figure out the filename. */
2386 oc
= lookup_option (&server_universe
, state
-> options
, SV_FILENAME
);
2388 evaluate_option_cache (&state
-> filename
, packet
, lease
,
2389 (struct client_state
*)0,
2390 packet
-> options
, state
-> options
,
2391 &lease
-> scope
, oc
, MDL
);
2393 /* Choose a server name as above. */
2394 oc
= lookup_option (&server_universe
, state
-> options
,
2397 evaluate_option_cache (&state
-> server_name
, packet
, lease
,
2398 (struct client_state
*)0,
2399 packet
-> options
, state
-> options
,
2400 &lease
-> scope
, oc
, MDL
);
2402 /* At this point, we have a lease that we can offer the client.
2403 Now we construct a lease structure that contains what we want,
2404 and call supersede_lease to do the right thing with it. */
2405 lt
= (struct lease
*)0;
2406 result
= lease_allocate (<
, MDL
);
2407 if (result
!= ISC_R_SUCCESS
) {
2408 log_info ("%s: can't allocate temporary lease structure: %s",
2409 msg
, isc_result_totext (result
));
2410 free_lease_state (state
, MDL
);
2412 host_dereference (&host
, MDL
);
2416 /* Use the ip address of the lease that we finally found in
2418 lt
-> ip_addr
= lease
-> ip_addr
;
2421 lt
-> starts
= cur_time
;
2423 /* Figure out how long a lease to assign. If this is a
2424 dynamic BOOTP lease, its duration must be infinite. */
2426 lt
->flags
&= ~BOOTP_LEASE
;
2428 default_lease_time
= DEFAULT_DEFAULT_LEASE_TIME
;
2429 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2430 SV_DEFAULT_LEASE_TIME
))) {
2431 if (evaluate_option_cache (&d1
, packet
, lease
,
2432 (struct client_state
*)0,
2435 &lease
-> scope
, oc
, MDL
)) {
2436 if (d1
.len
== sizeof (u_int32_t
))
2437 default_lease_time
=
2439 data_string_forget (&d1
, MDL
);
2443 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
2444 DHO_DHCP_LEASE_TIME
)))
2445 s1
= evaluate_option_cache (&d1
, packet
, lease
,
2446 (struct client_state
*)0,
2449 &lease
-> scope
, oc
, MDL
);
2453 if (s1
&& (d1
.len
== 4)) {
2454 u_int32_t ones
= 0xffffffff;
2456 /* One potential use of reserved leases is to allow
2457 * clients to signal reservation of their lease. They
2458 * can kinda sorta do this, if you squint hard enough,
2459 * by supplying an 'infinite' requested-lease-time
2460 * option. This is generally bad practice...you want
2461 * clients to return to the server on at least some
2462 * period (days, months, years) to get up-to-date
2465 * 1) A client requests 0xffffffff lease-time.
2466 * 2) The server reserves the lease, and assigns a
2467 * <= max_lease_time lease-time to the client, which
2468 * we presume is much smaller than 0xffffffff.
2469 * 3) The client ultimately fails to renew its lease
2470 * (all clients go offline at some point).
2471 * 4) The server retains the reservation, although
2472 * the lease expires and passes through those states
2473 * as normal, it's placed in the 'reserved' queue,
2474 * and is under no circumstances allocated to any
2477 * Whether the client knows its reserving its lease or
2478 * not, this can be a handy tool for a sysadmin.
2480 if ((memcmp(d1
.data
, &ones
, 4) == 0) &&
2481 (oc
= lookup_option(&server_universe
,
2483 SV_RESERVE_INFINITE
)) &&
2484 evaluate_boolean_option_cache(&ignorep
, packet
,
2485 lease
, NULL
, packet
->options
,
2486 state
->options
, &lease
->scope
,
2488 lt
->flags
|= RESERVED_LEASE
;
2490 log_info("Infinite-leasetime "
2491 "reservation made on %s.",
2492 piaddr(lt
->ip_addr
));
2495 lease_time
= getULong (d1
.data
);
2497 lease_time
= default_lease_time
;
2500 data_string_forget(&d1
, MDL
);
2502 /* See if there's a maximum lease time. */
2503 max_lease_time
= DEFAULT_MAX_LEASE_TIME
;
2504 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2505 SV_MAX_LEASE_TIME
))) {
2506 if (evaluate_option_cache (&d1
, packet
, lease
,
2507 (struct client_state
*)0,
2510 &lease
-> scope
, oc
, MDL
)) {
2511 if (d1
.len
== sizeof (u_int32_t
))
2514 data_string_forget (&d1
, MDL
);
2518 /* Enforce the maximum lease length. */
2519 if (lease_time
< 0 /* XXX */
2520 || lease_time
> max_lease_time
)
2521 lease_time
= max_lease_time
;
2523 min_lease_time
= DEFAULT_MIN_LEASE_TIME
;
2524 if (min_lease_time
> max_lease_time
)
2525 min_lease_time
= max_lease_time
;
2527 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2528 SV_MIN_LEASE_TIME
))) {
2529 if (evaluate_option_cache (&d1
, packet
, lease
,
2530 (struct client_state
*)0,
2533 &lease
-> scope
, oc
, MDL
)) {
2534 if (d1
.len
== sizeof (u_int32_t
))
2535 min_lease_time
= getULong (d1
.data
);
2536 data_string_forget (&d1
, MDL
);
2540 /* CC: If there are less than
2541 adaptive-lease-time-threshold % free leases,
2542 hand out only short term leases */
2544 memset(&d1
, 0, sizeof(d1
));
2546 (oc
= lookup_option(&server_universe
, state
->options
,
2547 SV_ADAPTIVE_LEASE_TIME_THRESHOLD
)) &&
2548 evaluate_option_cache(&d1
, packet
, lease
, NULL
,
2549 packet
->options
, state
->options
,
2550 &lease
->scope
, oc
, MDL
)) {
2551 if (d1
.len
== 1 && d1
.data
[0] > 0 &&
2554 int poolfilled
, total
, count
;
2557 adaptive_time
= min_lease_time
;
2559 adaptive_time
= DEFAULT_MIN_LEASE_TIME
;
2561 /* Allow the client to keep its lease. */
2562 if (lease
->ends
- cur_time
> adaptive_time
)
2563 adaptive_time
= lease
->ends
- cur_time
;
2565 count
= lease
->pool
->lease_count
;
2566 total
= count
- (lease
->pool
->free_leases
+
2567 lease
->pool
->backup_leases
);
2569 poolfilled
= (total
> (INT_MAX
/ 100)) ?
2570 total
/ (count
/ 100) :
2571 (total
* 100) / count
;
2573 log_debug("Adap-lease: Total: %d, Free: %d, "
2574 "Ends: %d, Adaptive: %d, Fill: %d, "
2576 lease
->pool
->lease_count
,
2577 lease
->pool
->free_leases
,
2578 (int)(lease
->ends
- cur_time
),
2579 (int)adaptive_time
, poolfilled
,
2582 if (poolfilled
>= d1
.data
[0] &&
2583 lease_time
> adaptive_time
) {
2584 log_info("Pool over threshold, time "
2585 "for %s reduced from %d to "
2586 "%d.", piaddr(lease
->ip_addr
),
2588 (int)adaptive_time
);
2590 lease_time
= adaptive_time
;
2593 data_string_forget(&d1
, MDL
);
2598 * If this is an ack check to see if we have used enough of
2599 * the pool to want to log a message
2601 if (offer
== DHCPACK
)
2602 check_pool_threshold(packet
, lease
, state
);
2604 /* a client requests an address which is not yet active*/
2605 if (lease
->pool
&& lease
->pool
->valid_from
&&
2606 cur_time
< lease
->pool
->valid_from
) {
2607 /* NAK leases before pool activation date */
2609 memcpy (cip
.iabuf
, <
->ip_addr
.iabuf
, 4);
2610 nak_lease(packet
, &cip
, lease
->subnet
->group
);
2611 free_lease_state (state
, MDL
);
2612 lease_dereference (<
, MDL
);
2614 host_dereference (&host
, MDL
);
2620 a) NAK current lease if past the expiration date
2621 b) extend lease only up to the expiration date, but not
2622 below min-lease-time
2623 Setting min-lease-time is essential for this to work!
2624 The value of min-lease-time determines the length
2625 of the transition window:
2626 A client renewing a second before the deadline will
2627 get a min-lease-time lease. Since the current ip might not
2628 be routable after the deadline, the client will
2629 be offline until it DISCOVERS again. Otherwise it will
2630 receive a NAK at T/2.
2631 A min-lease-time of 6 seconds effectively switches over
2632 all clients in this pool very quickly.
2635 if (lease
->pool
&& lease
->pool
->valid_until
) {
2636 if (cur_time
>= lease
->pool
->valid_until
) {
2637 /* NAK leases after pool expiration date */
2639 memcpy (cip
.iabuf
, <
->ip_addr
.iabuf
, 4);
2640 nak_lease(packet
, &cip
, lease
->subnet
->group
);
2641 free_lease_state (state
, MDL
);
2642 lease_dereference (<
, MDL
);
2644 host_dereference (&host
, MDL
);
2647 remaining_time
= lease
->pool
->valid_until
- cur_time
;
2648 if (lease_time
> remaining_time
)
2649 lease_time
= remaining_time
;
2652 if (lease_time
< min_lease_time
) {
2654 lease_time
= min_lease_time
;
2656 lease_time
= default_lease_time
;
2660 #if defined (FAILOVER_PROTOCOL)
2661 /* Okay, we know the lease duration. Now check the
2662 failover state, if any. */
2663 if (lease
-> pool
&& lease
-> pool
-> failover_peer
) {
2664 TIME new_lease_time
= lease_time
;
2665 dhcp_failover_state_t
*peer
=
2666 lease
-> pool
-> failover_peer
;
2668 /* Copy previous lease failover ack-state. */
2669 lt
->tsfp
= lease
->tsfp
;
2670 lt
->atsfp
= lease
->atsfp
;
2672 /* cltt set below */
2674 /* Lease times less than MCLT are not a concern. */
2675 if (lease_time
> peer
->mclt
) {
2676 /* Each server can only offer a lease time
2677 * that is either equal to MCLT (at least),
2678 * or up to TSFP+MCLT. Only if the desired
2679 * lease time falls within TSFP+MCLT, can
2680 * the server allow it.
2682 if (lt
->tsfp
<= cur_time
)
2683 new_lease_time
= peer
->mclt
;
2684 else if ((cur_time
+ lease_time
) >
2685 (lt
->tsfp
+ peer
->mclt
))
2686 new_lease_time
= (lt
->tsfp
- cur_time
)
2690 /* Update potential expiry. Allow for the desired
2691 * lease time plus one half the actual (whether
2692 * modified downward or not) lease time, which is
2693 * actually an estimate of when the client will
2694 * renew. This way, the client will be able to get
2695 * the desired lease time upon renewal.
2697 if (offer
== DHCPACK
) {
2698 lt
->tstp
= cur_time
+ lease_time
+
2699 (new_lease_time
/ 2);
2701 /* If we reduced the potential expiry time,
2702 * make sure we don't offer an old-expiry-time
2703 * lease for this lease before the change is
2706 if (lt
->tstp
< lt
->tsfp
)
2707 lt
->tsfp
= lt
->tstp
;
2709 lt
->tstp
= lease
->tstp
;
2711 /* Use failover-modified lease time. */
2712 lease_time
= new_lease_time
;
2714 #endif /* FAILOVER_PROTOCOL */
2716 /* If the lease duration causes the time value to wrap,
2717 use the maximum expiry time. */
2718 if (cur_time
+ lease_time
< cur_time
)
2719 state
-> offered_expiry
= MAX_TIME
- 1;
2721 state
-> offered_expiry
= cur_time
+ lease_time
;
2725 lt
-> ends
= state
-> offered_expiry
;
2727 /* Don't make lease active until we actually get a
2729 if (offer
== DHCPACK
)
2730 lt
-> next_binding_state
= FTS_ACTIVE
;
2732 lt
-> next_binding_state
= lease
-> binding_state
;
2734 lt
->flags
|= BOOTP_LEASE
;
2736 lease_time
= MAX_TIME
- cur_time
;
2738 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2739 SV_BOOTP_LEASE_LENGTH
))) {
2740 if (evaluate_option_cache (&d1
, packet
, lease
,
2741 (struct client_state
*)0,
2744 &lease
-> scope
, oc
, MDL
)) {
2745 if (d1
.len
== sizeof (u_int32_t
))
2746 lease_time
= getULong (d1
.data
);
2747 data_string_forget (&d1
, MDL
);
2751 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2752 SV_BOOTP_LEASE_CUTOFF
))) {
2753 if (evaluate_option_cache (&d1
, packet
, lease
,
2754 (struct client_state
*)0,
2757 &lease
-> scope
, oc
, MDL
)) {
2758 if (d1
.len
== sizeof (u_int32_t
))
2759 lease_time
= (getULong (d1
.data
) -
2761 data_string_forget (&d1
, MDL
);
2765 lt
-> ends
= state
-> offered_expiry
= cur_time
+ lease_time
;
2766 lt
-> next_binding_state
= FTS_ACTIVE
;
2769 /* Update Client Last Transaction Time. */
2770 lt
->cltt
= cur_time
;
2772 /* See if we want to record the uid for this client */
2773 oc
= lookup_option(&server_universe
, state
->options
,
2774 SV_IGNORE_CLIENT_UIDS
);
2776 !evaluate_boolean_option_cache(&ignorep
, packet
, lease
, NULL
,
2777 packet
->options
, state
->options
,
2778 &lease
->scope
, oc
, MDL
)) {
2780 /* Record the uid, if given... */
2781 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
2782 DHO_DHCP_CLIENT_IDENTIFIER
);
2784 evaluate_option_cache(&d1
, packet
, lease
, NULL
,
2785 packet
->options
, state
->options
,
2786 &lease
->scope
, oc
, MDL
)) {
2787 if (d1
.len
<= sizeof(lt
->uid_buf
)) {
2788 memcpy(lt
->uid_buf
, d1
.data
, d1
.len
);
2789 lt
->uid
= lt
->uid_buf
;
2790 lt
->uid_max
= sizeof(lt
->uid_buf
);
2791 lt
->uid_len
= d1
.len
;
2793 unsigned char *tuid
;
2794 lt
->uid_max
= d1
.len
;
2795 lt
->uid_len
= d1
.len
;
2796 tuid
= (unsigned char *)dmalloc(lt
->uid_max
,
2800 log_fatal ("no memory for large uid.");
2801 memcpy(tuid
, d1
.data
, lt
->uid_len
);
2804 data_string_forget (&d1
, MDL
);
2809 host_reference (<
-> host
, host
, MDL
);
2810 host_dereference (&host
, MDL
);
2812 if (lease
-> subnet
)
2813 subnet_reference (<
-> subnet
, lease
-> subnet
, MDL
);
2814 if (lease
-> billing_class
)
2815 class_reference (<
-> billing_class
,
2816 lease
-> billing_class
, MDL
);
2818 /* Set a flag if this client is a broken client that NUL
2819 terminates string options and expects us to do likewise. */
2821 lease
-> flags
|= MS_NULL_TERMINATION
;
2823 lease
-> flags
&= ~MS_NULL_TERMINATION
;
2825 /* Save any bindings. */
2826 if (lease
-> scope
) {
2827 binding_scope_reference (<
-> scope
, lease
-> scope
, MDL
);
2828 binding_scope_dereference (&lease
-> scope
, MDL
);
2830 if (lease
-> agent_options
)
2831 option_chain_head_reference (<
-> agent_options
,
2832 lease
-> agent_options
, MDL
);
2834 /* Save the vendor-class-identifier for DHCPLEASEQUERY. */
2835 oc
= lookup_option(&dhcp_universe
, packet
->options
,
2836 DHO_VENDOR_CLASS_IDENTIFIER
);
2838 evaluate_option_cache(&d1
, packet
, NULL
, NULL
, packet
->options
,
2839 NULL
, <
->scope
, oc
, MDL
)) {
2841 bind_ds_value(<
->scope
, "vendor-class-identifier",
2845 data_string_forget(&d1
, MDL
);
2848 /* If we got relay agent information options from the packet, then
2849 * cache them for renewal in case the relay agent can't supply them
2850 * when the client unicasts. The options may be from an addressed
2851 * "l3" relay, or from an unaddressed "l2" relay which does not set
2854 if (!packet
->agent_options_stashed
&&
2855 (packet
->options
!= NULL
) &&
2856 packet
->options
->universe_count
> agent_universe
.index
&&
2857 packet
->options
->universes
[agent_universe
.index
] != NULL
) {
2858 oc
= lookup_option (&server_universe
, state
-> options
,
2859 SV_STASH_AGENT_OPTIONS
);
2861 evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
2862 (struct client_state
*)0,
2865 &lease
-> scope
, oc
, MDL
)) {
2866 if (lt
-> agent_options
)
2867 option_chain_head_dereference (<
-> agent_options
, MDL
);
2868 option_chain_head_reference
2869 (<
-> agent_options
,
2870 (struct option_chain_head
*)
2871 packet
-> options
-> universes
[agent_universe
.index
],
2876 /* Replace the old lease hostname with the new one, if it's changed. */
2877 oc
= lookup_option (&dhcp_universe
, packet
-> options
, DHO_HOST_NAME
);
2879 s1
= evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
2880 (struct client_state
*)0,
2882 (struct option_state
*)0,
2883 &global_scope
, oc
, MDL
);
2888 lease
-> client_hostname
&&
2889 strlen (lease
-> client_hostname
) == d1
.len
&&
2890 !memcmp (lease
-> client_hostname
, d1
.data
, d1
.len
)) {
2891 /* Hasn't changed. */
2892 data_string_forget (&d1
, MDL
);
2893 lt
-> client_hostname
= lease
-> client_hostname
;
2894 lease
-> client_hostname
= (char *)0;
2895 } else if (oc
&& s1
) {
2896 lt
-> client_hostname
= dmalloc (d1
.len
+ 1, MDL
);
2897 if (!lt
-> client_hostname
)
2898 log_error ("no memory for client hostname.");
2900 memcpy (lt
-> client_hostname
, d1
.data
, d1
.len
);
2901 lt
-> client_hostname
[d1
.len
] = 0;
2903 data_string_forget (&d1
, MDL
);
2906 /* Record the hardware address, if given... */
2907 lt
-> hardware_addr
.hlen
= packet
-> raw
-> hlen
+ 1;
2908 lt
-> hardware_addr
.hbuf
[0] = packet
-> raw
-> htype
;
2909 memcpy (<
-> hardware_addr
.hbuf
[1], packet
-> raw
-> chaddr
,
2910 sizeof packet
-> raw
-> chaddr
);
2912 lt
-> flags
= lease
-> flags
& ~PERSISTENT_FLAGS
;
2914 /* If there are statements to execute when the lease is
2915 committed, execute them. */
2916 if (lease
->on_star
.on_commit
&& (!offer
|| offer
== DHCPACK
)) {
2917 execute_statements (NULL
, packet
, lt
, NULL
, packet
->options
,
2918 state
->options
, <
->scope
,
2919 lease
->on_star
.on_commit
, NULL
);
2920 if (lease
->on_star
.on_commit
)
2921 executable_statement_dereference
2922 (&lease
->on_star
.on_commit
, MDL
);
2926 /* Perform DDNS updates, if configured to. */
2927 if ((!offer
|| offer
== DHCPACK
) &&
2928 (!(oc
= lookup_option (&server_universe
, state
-> options
,
2929 SV_DDNS_UPDATES
)) ||
2930 evaluate_boolean_option_cache (&ignorep
, packet
, lt
,
2931 (struct client_state
*)0,
2934 <
-> scope
, oc
, MDL
))) {
2935 ddns_updates(packet
, lt
, lease
, NULL
, NULL
, state
->options
);
2937 #endif /* NSUPDATE */
2939 /* Don't call supersede_lease on a mocked-up lease. */
2940 if (lease
-> flags
& STATIC_LEASE
) {
2941 /* Copy the hardware address into the static lease
2943 lease
-> hardware_addr
.hlen
= packet
-> raw
-> hlen
+ 1;
2944 lease
-> hardware_addr
.hbuf
[0] = packet
-> raw
-> htype
;
2945 memcpy (&lease
-> hardware_addr
.hbuf
[1],
2946 packet
-> raw
-> chaddr
,
2947 sizeof packet
-> raw
-> chaddr
); /* XXX */
2949 int commit
= (!offer
|| (offer
== DHCPACK
));
2951 /* If dhcp-cache-threshold is enabled, see if "lease" can
2953 use_old_lease
= reuse_lease(packet
, lt
, lease
, state
, offer
);
2954 if (use_old_lease
== 1) {
2958 #if !defined(DELAYED_ACK)
2959 /* Install the new information on 'lt' onto the lease at
2960 * 'lease'. If this is a DHCPOFFER, it is a 'soft' promise,
2961 * if it is a DHCPACK, it is a 'hard' binding, so it needs
2962 * to be recorded and propogated immediately. If the update
2963 * fails, don't ACK it (or BOOTREPLY) either; we may give
2964 * the same lease to another client later, and that would be
2967 if ((use_old_lease
== 0) &&
2968 !supersede_lease(lease
, lt
, commit
,
2969 offer
== DHCPACK
, offer
== DHCPACK
, 0)) {
2970 #else /* defined(DELAYED_ACK) */
2972 * If there already isn't a need for a lease commit, and we
2973 * can just answer right away, set a flag to indicate this.
2978 /* Install the new information on 'lt' onto the lease at
2979 * 'lease'. We will not 'commit' this information to disk
2980 * yet (fsync()), we will 'propogate' the information if
2981 * this is BOOTP or a DHCPACK, but we will not 'pimmediate'ly
2982 * transmit failover binding updates (this is delayed until
2983 * after the fsync()). If the update fails, don't ACK it (or
2984 * BOOTREPLY either); we may give the same lease out to a
2985 * different client, and that would be a conflict.
2987 if ((use_old_lease
== 0) &&
2988 !supersede_lease(lease
, lt
, 0,
2989 !offer
|| offer
== DHCPACK
, 0, 0)) {
2991 log_info ("%s: database update failed", msg
);
2992 free_lease_state (state
, MDL
);
2993 lease_dereference (<
, MDL
);
2997 lease_dereference (<
, MDL
);
2999 /* Remember the interface on which the packet arrived. */
3000 state
-> ip
= packet
-> interface
;
3002 /* Remember the giaddr, xid, secs, flags and hops. */
3003 state
-> giaddr
= packet
-> raw
-> giaddr
;
3004 state
-> ciaddr
= packet
-> raw
-> ciaddr
;
3005 state
-> xid
= packet
-> raw
-> xid
;
3006 state
-> secs
= packet
-> raw
-> secs
;
3007 state
-> bootp_flags
= packet
-> raw
-> flags
;
3008 state
-> hops
= packet
-> raw
-> hops
;
3009 state
-> offer
= offer
;
3011 /* If we're always supposed to broadcast to this client, set
3012 the broadcast bit in the bootp flags field. */
3013 if ((oc
= lookup_option (&server_universe
, state
-> options
,
3014 SV_ALWAYS_BROADCAST
)) &&
3015 evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
3016 (struct client_state
*)0,
3017 packet
-> options
, state
-> options
,
3018 &lease
-> scope
, oc
, MDL
))
3019 state
-> bootp_flags
|= htons (BOOTP_BROADCAST
);
3021 /* Get the Maximum Message Size option from the packet, if one
3023 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
3024 DHO_DHCP_MAX_MESSAGE_SIZE
);
3026 evaluate_option_cache (&d1
, packet
, lease
,
3027 (struct client_state
*)0,
3028 packet
-> options
, state
-> options
,
3029 &lease
-> scope
, oc
, MDL
)) {
3030 if (d1
.len
== sizeof (u_int16_t
))
3031 state
-> max_message_size
= getUShort (d1
.data
);
3032 data_string_forget (&d1
, MDL
);
3034 oc
= lookup_option (&dhcp_universe
, state
-> options
,
3035 DHO_DHCP_MAX_MESSAGE_SIZE
);
3037 evaluate_option_cache (&d1
, packet
, lease
,
3038 (struct client_state
*)0,
3039 packet
-> options
, state
-> options
,
3040 &lease
-> scope
, oc
, MDL
)) {
3041 if (d1
.len
== sizeof (u_int16_t
))
3042 state
-> max_message_size
=
3043 getUShort (d1
.data
);
3044 data_string_forget (&d1
, MDL
);
3048 /* Get the Subnet Selection option from the packet, if one
3050 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
3051 DHO_SUBNET_SELECTION
))) {
3053 /* Make a copy of the data. */
3054 struct option_cache
*noc
= (struct option_cache
*)0;
3055 if (option_cache_allocate (&noc
, MDL
)) {
3057 data_string_copy (&noc
-> data
,
3059 if (oc
-> expression
)
3060 expression_reference (&noc
-> expression
,
3061 oc
-> expression
, MDL
);
3063 option_reference(&(noc
->option
), oc
->option
,
3066 save_option (&dhcp_universe
, state
-> options
, noc
);
3067 option_cache_dereference (&noc
, MDL
);
3071 /* Now, if appropriate, put in DHCP-specific options that
3073 if (state
-> offer
) {
3074 i
= DHO_DHCP_MESSAGE_TYPE
;
3075 oc
= (struct option_cache
*)0;
3076 if (option_cache_allocate (&oc
, MDL
)) {
3077 if (make_const_data (&oc
-> expression
,
3078 &state
-> offer
, 1, 0, 0, MDL
)) {
3079 option_code_hash_lookup(&oc
->option
,
3080 dhcp_universe
.code_hash
,
3082 save_option (&dhcp_universe
,
3083 state
-> options
, oc
);
3085 option_cache_dereference (&oc
, MDL
);
3088 get_server_source_address(&from
, state
->options
,
3089 state
->options
, packet
);
3090 memcpy(state
->from
.iabuf
, &from
, sizeof(from
));
3091 state
->from
.len
= sizeof(from
);
3093 offered_lease_time
=
3094 state
-> offered_expiry
- cur_time
;
3096 putULong(state
->expiry
, (u_int32_t
)offered_lease_time
);
3097 i
= DHO_DHCP_LEASE_TIME
;
3098 oc
= (struct option_cache
*)0;
3099 if (option_cache_allocate (&oc
, MDL
)) {
3100 if (make_const_data(&oc
->expression
, state
->expiry
,
3102 option_code_hash_lookup(&oc
->option
,
3103 dhcp_universe
.code_hash
,
3105 save_option (&dhcp_universe
,
3106 state
-> options
, oc
);
3108 option_cache_dereference (&oc
, MDL
);
3112 * Validate any configured renew or rebinding times against
3113 * the determined lease time. Do rebinding first so that
3114 * the renew time can be validated against the rebind time.
3116 if ((oc
= lookup_option(&dhcp_universe
, state
->options
,
3117 DHO_DHCP_REBINDING_TIME
)) != NULL
&&
3118 evaluate_option_cache(&d1
, packet
, lease
, NULL
,
3119 packet
->options
, state
->options
,
3120 &lease
->scope
, oc
, MDL
)) {
3121 TIME rebind_time
= getULong(d1
.data
);
3123 /* Drop the configured (invalid) rebinding time. */
3124 if (rebind_time
>= offered_lease_time
)
3125 delete_option(&dhcp_universe
, state
->options
,
3126 DHO_DHCP_REBINDING_TIME
);
3127 else /* XXX: variable is reused. */
3128 offered_lease_time
= rebind_time
;
3130 data_string_forget(&d1
, MDL
);
3133 if ((oc
= lookup_option(&dhcp_universe
, state
->options
,
3134 DHO_DHCP_RENEWAL_TIME
)) != NULL
&&
3135 evaluate_option_cache(&d1
, packet
, lease
, NULL
,
3136 packet
->options
, state
->options
,
3137 &lease
->scope
, oc
, MDL
)) {
3138 if (getULong(d1
.data
) >= offered_lease_time
)
3139 delete_option(&dhcp_universe
, state
->options
,
3140 DHO_DHCP_RENEWAL_TIME
);
3142 data_string_forget(&d1
, MDL
);
3145 /* XXXSK: should we use get_server_source_address() here? */
3146 if (state
-> ip
-> address_count
) {
3148 sizeof state
-> ip
-> addresses
[0];
3149 memcpy (state
-> from
.iabuf
,
3150 &state
-> ip
-> addresses
[0],
3155 /* Figure out the address of the boot file server. */
3156 memset (&state
-> siaddr
, 0, sizeof state
-> siaddr
);
3158 lookup_option (&server_universe
,
3159 state
-> options
, SV_NEXT_SERVER
))) {
3160 if (evaluate_option_cache (&d1
, packet
, lease
,
3161 (struct client_state
*)0,
3162 packet
-> options
, state
-> options
,
3163 &lease
-> scope
, oc
, MDL
)) {
3164 /* If there was more than one answer,
3166 if (d1
.len
>= 4 && d1
.data
)
3167 memcpy (&state
-> siaddr
, d1
.data
, 4);
3168 data_string_forget (&d1
, MDL
);
3172 /* Use the subnet mask from the subnet declaration if no other
3173 mask has been provided. */
3174 i
= DHO_SUBNET_MASK
;
3175 if (!lookup_option (&dhcp_universe
, state
-> options
, i
)) {
3176 oc
= (struct option_cache
*)0;
3177 if (option_cache_allocate (&oc
, MDL
)) {
3178 if (make_const_data (&oc
-> expression
,
3179 lease
-> subnet
-> netmask
.iabuf
,
3180 lease
-> subnet
-> netmask
.len
,
3182 option_code_hash_lookup(&oc
->option
,
3183 dhcp_universe
.code_hash
,
3185 save_option (&dhcp_universe
,
3186 state
-> options
, oc
);
3188 option_cache_dereference (&oc
, MDL
);
3192 /* Use the name of the host declaration if there is one
3193 and no hostname has otherwise been provided, and if the
3194 use-host-decl-name flag is set. */
3195 use_host_decl_name(packet
, lease
, state
->options
);
3197 /* Send client_id back if we received it and echo-client-id is on. */
3198 echo_client_id(packet
, lease
, state
->options
, state
->options
);
3200 /* If we don't have a hostname yet, and we've been asked to do
3201 a reverse lookup to find the hostname, do it. */
3203 j
= SV_GET_LEASE_HOSTNAMES
;
3204 if (!lookup_option(&dhcp_universe
, state
->options
, i
) &&
3205 evaluate_boolean_option_cache
3206 (&ignorep
, packet
, lease
, NULL
,
3207 packet
->options
, state
->options
, &lease
->scope
,
3208 lookup_option (&server_universe
, state
->options
, j
), MDL
)) {
3212 memcpy (&ia
, lease
-> ip_addr
.iabuf
, 4);
3214 h
= gethostbyaddr ((char *)&ia
, sizeof ia
, AF_INET
);
3216 log_error ("No hostname for %s", inet_ntoa (ia
));
3218 oc
= (struct option_cache
*)0;
3219 if (option_cache_allocate (&oc
, MDL
)) {
3220 if (make_const_data (&oc
-> expression
,
3223 strlen (h
-> h_name
) + 1,
3225 option_code_hash_lookup(&oc
->option
,
3226 dhcp_universe
.code_hash
,
3228 save_option (&dhcp_universe
,
3229 state
-> options
, oc
);
3231 option_cache_dereference (&oc
, MDL
);
3236 /* If so directed, use the leased IP address as the router address.
3237 This supposedly makes Win95 machines ARP for all IP addresses,
3238 so if the local router does proxy arp, you win. */
3240 if (evaluate_boolean_option_cache
3241 (&ignorep
, packet
, lease
, (struct client_state
*)0,
3242 packet
-> options
, state
-> options
, &lease
-> scope
,
3243 lookup_option (&server_universe
, state
-> options
,
3244 SV_USE_LEASE_ADDR_FOR_DEFAULT_ROUTE
), MDL
)) {
3246 oc
= lookup_option (&dhcp_universe
, state
-> options
, i
);
3248 oc
= (struct option_cache
*)0;
3249 if (option_cache_allocate (&oc
, MDL
)) {
3250 if (make_const_data (&oc
-> expression
,
3251 lease
-> ip_addr
.iabuf
,
3252 lease
-> ip_addr
.len
,
3254 option_code_hash_lookup(&oc
->option
,
3255 dhcp_universe
.code_hash
,
3257 save_option (&dhcp_universe
,
3258 state
-> options
, oc
);
3260 option_cache_dereference (&oc
, MDL
);
3265 /* If a site option space has been specified, use that for
3266 site option codes. */
3267 i
= SV_SITE_OPTION_SPACE
;
3268 if ((oc
= lookup_option (&server_universe
, state
-> options
, i
)) &&
3269 evaluate_option_cache (&d1
, packet
, lease
,
3270 (struct client_state
*)0,
3271 packet
-> options
, state
-> options
,
3272 &lease
-> scope
, oc
, MDL
)) {
3273 struct universe
*u
= (struct universe
*)0;
3275 if (!universe_hash_lookup (&u
, universe_hash
,
3276 (const char *)d1
.data
, d1
.len
,
3278 log_error ("unknown option space %s.", d1
.data
);
3282 state
-> options
-> site_universe
= u
-> index
;
3283 state
->options
->site_code_min
= find_min_site_code(u
);
3284 data_string_forget (&d1
, MDL
);
3286 state
-> options
-> site_code_min
= 0;
3287 state
-> options
-> site_universe
= dhcp_universe
.index
;
3290 /* If the client has provided a list of options that it wishes
3291 returned, use it to prioritize. If there's a parameter
3292 request list in scope, use that in preference. Otherwise
3293 use the default priority list. */
3295 oc
= lookup_option (&dhcp_universe
, state
-> options
,
3296 DHO_DHCP_PARAMETER_REQUEST_LIST
);
3299 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
3300 DHO_DHCP_PARAMETER_REQUEST_LIST
);
3302 evaluate_option_cache (&state
-> parameter_request_list
,
3303 packet
, lease
, (struct client_state
*)0,
3304 packet
-> options
, state
-> options
,
3305 &lease
-> scope
, oc
, MDL
);
3308 dump_packet (packet
);
3309 dump_raw ((unsigned char *)packet
-> raw
, packet
-> packet_length
);
3312 lease
-> state
= state
;
3314 log_info ("%s", msg
);
3316 /* Hang the packet off the lease state. */
3317 packet_reference (&lease
-> state
-> packet
, packet
, MDL
);
3319 /* If this is a DHCPOFFER, ping the lease address before actually
3320 sending the offer. */
3321 if (offer
== DHCPOFFER
&& !(lease
-> flags
& STATIC_LEASE
) &&
3322 ((cur_time
- lease_cltt
) > 60) &&
3323 (!(oc
= lookup_option (&server_universe
, state
-> options
,
3325 evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
3326 (struct client_state
*)0,
3329 &lease
-> scope
, oc
, MDL
))) {
3330 icmp_echorequest (&lease
-> ip_addr
);
3332 /* Determine whether to use configured or default ping timeout.
3334 if ((oc
= lookup_option (&server_universe
, state
-> options
,
3335 SV_PING_TIMEOUT
)) &&
3336 evaluate_option_cache (&d1
, packet
, lease
, NULL
,
3339 &lease
-> scope
, oc
, MDL
)) {
3340 if (d1
.len
== sizeof (u_int32_t
))
3341 ping_timeout
= getULong (d1
.data
);
3343 ping_timeout
= DEFAULT_PING_TIMEOUT
;
3345 data_string_forget (&d1
, MDL
);
3347 ping_timeout
= DEFAULT_PING_TIMEOUT
;
3350 log_debug ("Ping timeout: %ld", (long)ping_timeout
);
3354 * Set a timeout for 'ping-timeout' seconds from NOW, including
3355 * current microseconds. As ping-timeout defaults to 1, the
3356 * exclusion of current microseconds causes a value somewhere
3357 * /between/ zero and one.
3359 tv
.tv_sec
= cur_tv
.tv_sec
+ ping_timeout
;
3360 tv
.tv_usec
= cur_tv
.tv_usec
;
3361 add_timeout (&tv
, lease_ping_timeout
, lease
,
3362 (tvref_t
)lease_reference
,
3363 (tvunref_t
)lease_dereference
);
3364 ++outstanding_pings
;
3366 lease
->cltt
= cur_time
;
3367 #if defined(DELAYED_ACK)
3369 delayed_ack_enqueue(lease
);
3376 #if defined(DELAYED_ACK)
3379 * CC: queue single ACK:
3380 * - write the lease (but do not fsync it yet)
3381 * - add to double linked list
3382 * - commit if more than xx ACKs pending
3383 * - if necessary set the max timer and bump the next timer
3384 * but only up to the max timer value.
3388 delayed_ack_enqueue(struct lease
*lease
)
3390 struct leasequeue
*q
;
3392 if (!write_lease(lease
))
3394 if (free_ackqueue
) {
3396 free_ackqueue
= q
->next
;
3398 q
= ((struct leasequeue
*)
3399 dmalloc(sizeof(struct leasequeue
), MDL
));
3401 log_fatal("delayed_ack_enqueue: no memory!");
3403 memset(q
, 0, sizeof *q
);
3404 /* prepend to ackqueue*/
3405 lease_reference(&q
->lease
, lease
, MDL
);
3406 q
->next
= ackqueue_head
;
3414 if (outstanding_acks
> max_outstanding_acks
) {
3415 /* Cancel any pending timeout and call handler directly */
3416 cancel_timeout(delayed_acks_timer
, NULL
);
3417 delayed_acks_timer(NULL
);
3419 struct timeval next_fsync
;
3421 if (max_fsync
.tv_sec
== 0 && max_fsync
.tv_usec
== 0) {
3422 /* set the maximum time we'll wait */
3423 max_fsync
.tv_sec
= cur_tv
.tv_sec
+ max_ack_delay_secs
;
3424 max_fsync
.tv_usec
= cur_tv
.tv_usec
+
3425 max_ack_delay_usecs
;
3427 if (max_fsync
.tv_usec
>= 1000000) {
3429 max_fsync
.tv_usec
-= 1000000;
3433 /* Set the timeout */
3434 next_fsync
.tv_sec
= cur_tv
.tv_sec
;
3435 next_fsync
.tv_usec
= cur_tv
.tv_usec
+ min_ack_delay_usecs
;
3436 if (next_fsync
.tv_usec
>= 1000000) {
3437 next_fsync
.tv_sec
++;
3438 next_fsync
.tv_usec
-= 1000000;
3440 /* but not more than the max */
3441 if ((next_fsync
.tv_sec
> max_fsync
.tv_sec
) ||
3442 ((next_fsync
.tv_sec
== max_fsync
.tv_sec
) &&
3443 (next_fsync
.tv_usec
> max_fsync
.tv_usec
))) {
3444 next_fsync
.tv_sec
= max_fsync
.tv_sec
;
3445 next_fsync
.tv_usec
= max_fsync
.tv_usec
;
3448 add_timeout(&next_fsync
, delayed_acks_timer
, NULL
,
3449 (tvref_t
) NULL
, (tvunref_t
) NULL
);
3453 /* Processes any delayed acks:
3454 * Commits the leases and then for each delayed ack:
3455 * - Update the failover peer if we're in failover
3456 * - Send the REPLY to the client
3459 delayed_acks_timer(void *foo
)
3461 struct leasequeue
*ack
, *p
;
3463 /* Reset max fsync */
3464 memset(&max_fsync
, 0, sizeof(max_fsync
));
3466 if (!outstanding_acks
) {
3467 /* Nothing to do, so punt, shouldn't happen? */
3471 /* Commit the leases first */
3474 /* Now process the delayed ACKs
3475 - update failover peer
3476 - send out the ACK packets
3477 - move the queue slots to the free list
3480 /* process from bottom to retain packet order */
3481 for (ack
= ackqueue_tail
; ack
; ack
= p
) {
3484 #if defined(FAILOVER_PROTOCOL)
3485 /* If we're in failover we need to send any deferred
3486 * bind updates as well as the replies */
3487 if (ack
->lease
->pool
) {
3488 dhcp_failover_state_t
*fpeer
;
3490 fpeer
= ack
->lease
->pool
->failover_peer
;
3491 if (fpeer
&& fpeer
->link_to_peer
) {
3492 dhcp_failover_send_updates(fpeer
);
3497 /* dhcp_reply() requires that the reply state still be valid */
3498 if (ack
->lease
->state
== NULL
)
3499 log_error("delayed ack for %s has gone stale",
3500 piaddr(ack
->lease
->ip_addr
));
3502 dhcp_reply(ack
->lease
);
3505 lease_dereference(&ack
->lease
, MDL
);
3506 ack
->next
= free_ackqueue
;
3507 free_ackqueue
= ack
;
3510 ackqueue_head
= NULL
;
3511 ackqueue_tail
= NULL
;
3512 outstanding_acks
= 0;
3515 #if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
3517 relinquish_ackqueue(void)
3519 struct leasequeue
*q
, *n
;
3521 for (q
= ackqueue_head
; q
; q
= n
) {
3525 for (q
= free_ackqueue
; q
; q
= n
) {
3532 #endif /* defined(DELAYED_ACK) */
3534 void dhcp_reply (lease
)
3535 struct lease
*lease
;
3538 unsigned packet_length
;
3539 struct dhcp_packet raw
;
3540 struct sockaddr_in to
;
3541 struct in_addr from
;
3542 struct hardware hto
;
3544 struct lease_state
*state
= lease
-> state
;
3545 int nulltp
, bootpp
, unicastp
= 1;
3546 struct data_string d1
;
3550 log_fatal ("dhcp_reply was supplied lease with no state!");
3552 /* Compose a response for the client... */
3553 memset (&raw
, 0, sizeof raw
);
3554 memset (&d1
, 0, sizeof d1
);
3556 /* Copy in the filename if given; otherwise, flag the filename
3557 buffer as available for options. */
3558 if (state
-> filename
.len
&& state
-> filename
.data
) {
3560 state
-> filename
.data
,
3561 state
-> filename
.len
> sizeof raw
.file
3562 ? sizeof raw
.file
: state
-> filename
.len
);
3563 if (sizeof raw
.file
> state
-> filename
.len
)
3564 memset (&raw
.file
[state
-> filename
.len
], 0,
3565 (sizeof raw
.file
) - state
-> filename
.len
);
3567 log_info("file name longer than packet field "
3568 "truncated - field: %lu name: %d %.*s",
3569 (unsigned long)sizeof(raw
.file
),
3570 state
->filename
.len
, (int)state
->filename
.len
,
3571 state
->filename
.data
);
3575 /* Copy in the server name if given; otherwise, flag the
3576 server_name buffer as available for options. */
3577 if (state
-> server_name
.len
&& state
-> server_name
.data
) {
3579 state
-> server_name
.data
,
3580 state
-> server_name
.len
> sizeof raw
.sname
3581 ? sizeof raw
.sname
: state
-> server_name
.len
);
3582 if (sizeof raw
.sname
> state
-> server_name
.len
)
3583 memset (&raw
.sname
[state
-> server_name
.len
], 0,
3584 (sizeof raw
.sname
) - state
-> server_name
.len
);
3586 log_info("server name longer than packet field "
3587 "truncated - field: %lu name: %d %.*s",
3588 (unsigned long)sizeof(raw
.sname
),
3589 state
->server_name
.len
,
3590 (int)state
->server_name
.len
,
3591 state
->server_name
.data
);
3593 bufs
|= 2; /* XXX */
3596 &lease
-> hardware_addr
.hbuf
[1], sizeof raw
.chaddr
);
3597 raw
.hlen
= lease
-> hardware_addr
.hlen
- 1;
3598 raw
.htype
= lease
-> hardware_addr
.hbuf
[0];
3600 /* See if this is a Microsoft client that NUL-terminates its
3601 strings and expects us to do likewise... */
3602 if (lease
-> flags
& MS_NULL_TERMINATION
)
3607 /* See if this is a bootp client... */
3613 /* Insert such options as will fit into the buffer. */
3614 packet_length
= cons_options (state
-> packet
, &raw
, lease
,
3615 (struct client_state
*)0,
3616 state
-> max_message_size
,
3617 state
-> packet
-> options
,
3618 state
-> options
, &global_scope
,
3619 bufs
, nulltp
, bootpp
,
3620 &state
-> parameter_request_list
,
3623 memcpy (&raw
.ciaddr
, &state
-> ciaddr
, sizeof raw
.ciaddr
);
3624 memcpy (&raw
.yiaddr
, lease
-> ip_addr
.iabuf
, 4);
3625 raw
.siaddr
= state
-> siaddr
;
3626 raw
.giaddr
= state
-> giaddr
;
3628 raw
.xid
= state
-> xid
;
3629 raw
.secs
= state
-> secs
;
3630 raw
.flags
= state
-> bootp_flags
;
3631 raw
.hops
= state
-> hops
;
3634 if (lease
-> client_hostname
) {
3635 if ((strlen (lease
-> client_hostname
) <= 64) &&
3636 db_printable((unsigned char *)lease
->client_hostname
))
3637 s
= lease
-> client_hostname
;
3639 s
= "Hostname Unsuitable for Printing";
3643 /* Say what we're doing... */
3644 log_info ("%s on %s to %s %s%s%svia %s",
3646 ? (state
-> offer
== DHCPACK
? "DHCPACK" : "DHCPOFFER")
3648 piaddr (lease
-> ip_addr
),
3649 (lease
-> hardware_addr
.hlen
3650 ? print_hw_addr (lease
-> hardware_addr
.hbuf
[0],
3651 lease
-> hardware_addr
.hlen
- 1,
3652 &lease
-> hardware_addr
.hbuf
[1])
3653 : print_hex_1(lease
->uid_len
, lease
->uid
, 60)),
3654 s
? "(" : "", s
? s
: "", s
? ") " : "",
3655 (state
-> giaddr
.s_addr
3656 ? inet_ntoa (state
-> giaddr
)
3657 : state
-> ip
-> name
));
3659 /* Set up the hardware address... */
3660 hto
.hlen
= lease
-> hardware_addr
.hlen
;
3661 memcpy (hto
.hbuf
, lease
-> hardware_addr
.hbuf
, hto
.hlen
);
3663 to
.sin_family
= AF_INET
;
3665 to
.sin_len
= sizeof to
;
3667 memset (to
.sin_zero
, 0, sizeof to
.sin_zero
);
3670 dump_raw ((unsigned char *)&raw
, packet_length
);
3673 /* Make sure outgoing packets are at least as big
3674 as a BOOTP packet. */
3675 if (packet_length
< BOOTP_MIN_LEN
)
3676 packet_length
= BOOTP_MIN_LEN
;
3678 /* If this was gatewayed, send it back to the gateway... */
3679 if (raw
.giaddr
.s_addr
) {
3680 to
.sin_addr
= raw
.giaddr
;
3681 if (raw
.giaddr
.s_addr
!= htonl (INADDR_LOOPBACK
))
3682 to
.sin_port
= local_port
;
3684 to
.sin_port
= remote_port
; /* For debugging. */
3686 if (fallback_interface
) {
3687 result
= send_packet(fallback_interface
, NULL
, &raw
,
3688 packet_length
, raw
.siaddr
, &to
,
3691 log_error ("%s:%d: Failed to send %d byte long "
3692 "packet over %s interface.", MDL
,
3694 fallback_interface
->name
);
3698 free_lease_state (state
, MDL
);
3699 lease
-> state
= (struct lease_state
*)0;
3703 /* If the client is RENEWING, unicast to the client using the
3704 regular IP stack. Some clients, particularly those that
3705 follow RFC1541, are buggy, and send both ciaddr and server
3706 identifier. We deal with this situation by assuming that
3707 if we got both dhcp-server-identifier and ciaddr, and
3708 giaddr was not set, then the client is on the local
3709 network, and we can therefore unicast or broadcast to it
3710 successfully. A client in REQUESTING state on another
3711 network that's making this mistake will have set giaddr,
3712 and will therefore get a relayed response from the above
3714 } else if (raw
.ciaddr
.s_addr
&&
3715 !((state
-> got_server_identifier
||
3716 (raw
.flags
& htons (BOOTP_BROADCAST
))) &&
3717 /* XXX This won't work if giaddr isn't zero, but it is: */
3718 (state
-> shared_network
==
3719 lease
-> subnet
-> shared_network
)) &&
3720 state
-> offer
== DHCPACK
) {
3721 to
.sin_addr
= raw
.ciaddr
;
3722 to
.sin_port
= remote_port
;
3724 if (fallback_interface
) {
3725 result
= send_packet(fallback_interface
, NULL
, &raw
,
3726 packet_length
, raw
.siaddr
, &to
,
3729 log_error("%s:%d: Failed to send %d byte long"
3730 " packet over %s interface.", MDL
,
3732 fallback_interface
->name
);
3735 free_lease_state (state
, MDL
);
3736 lease
-> state
= (struct lease_state
*)0;
3740 /* If it comes from a client that already knows its address
3741 and is not requesting a broadcast response, and we can
3742 unicast to a client without using the ARP protocol, sent it
3743 directly to that client. */
3744 } else if (!(raw
.flags
& htons (BOOTP_BROADCAST
)) &&
3745 can_unicast_without_arp (state
-> ip
)) {
3746 to
.sin_addr
= raw
.yiaddr
;
3747 to
.sin_port
= remote_port
;
3749 /* Otherwise, broadcast it on the local network. */
3751 to
.sin_addr
= limited_broadcast
;
3752 to
.sin_port
= remote_port
;
3753 if (!(lease
-> flags
& UNICAST_BROADCAST_HACK
))
3757 memcpy (&from
, state
-> from
.iabuf
, sizeof from
);
3759 result
= send_packet(state
->ip
, NULL
, &raw
, packet_length
,
3760 from
, &to
, unicastp
? &hto
: NULL
);
3762 log_error ("%s:%d: Failed to send %d byte long "
3763 "packet over %s interface.", MDL
,
3764 packet_length
, state
->ip
->name
);
3768 /* Free all of the entries in the option_state structure
3769 now that we're done with them. */
3771 free_lease_state (state
, MDL
);
3772 lease
-> state
= (struct lease_state
*)0;
3775 int find_lease (struct lease
**lp
,
3776 struct packet
*packet
, struct shared_network
*share
, int *ours
,
3777 int *peer_has_leases
, struct lease
*ip_lease_in
,
3778 const char *file
, int line
)
3780 struct lease
*uid_lease
= (struct lease
*)0;
3781 struct lease
*ip_lease
= (struct lease
*)0;
3782 struct lease
*hw_lease
= (struct lease
*)0;
3783 struct lease
*lease
= (struct lease
*)0;
3785 struct host_decl
*hp
= (struct host_decl
*)0;
3786 struct host_decl
*host
= (struct host_decl
*)0;
3787 struct lease
*fixed_lease
= (struct lease
*)0;
3788 struct lease
*next
= (struct lease
*)0;
3789 struct option_cache
*oc
;
3790 struct data_string d1
;
3791 int have_client_identifier
= 0;
3792 struct data_string client_identifier
;
3795 #if defined(FAILOVER_PROTOCOL)
3796 /* Quick check to see if the peer has leases. */
3797 if (peer_has_leases
) {
3800 for (pool
= share
->pools
; pool
; pool
= pool
->next
) {
3801 dhcp_failover_state_t
*peer
= pool
->failover_peer
;
3804 ((peer
->i_am
== primary
&& pool
->backup_leases
) ||
3805 (peer
->i_am
== secondary
&& pool
->free_leases
))) {
3806 *peer_has_leases
= 1;
3811 #endif /* FAILOVER_PROTOCOL */
3813 if (packet
-> raw
-> ciaddr
.s_addr
) {
3815 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
, 4);
3817 /* Look up the requested address. */
3818 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
3819 DHO_DHCP_REQUESTED_ADDRESS
);
3820 memset (&d1
, 0, sizeof d1
);
3822 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
3823 (struct client_state
*)0,
3825 (struct option_state
*)0,
3826 &global_scope
, oc
, MDL
)) {
3827 packet
-> got_requested_address
= 1;
3829 memcpy (cip
.iabuf
, d1
.data
, cip
.len
);
3830 data_string_forget (&d1
, MDL
);
3835 /* Try to find a host or lease that's been assigned to the
3836 specified unique client identifier. */
3837 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
3838 DHO_DHCP_CLIENT_IDENTIFIER
);
3839 memset (&client_identifier
, 0, sizeof client_identifier
);
3841 evaluate_option_cache (&client_identifier
,
3842 packet
, (struct lease
*)0,
3843 (struct client_state
*)0,
3844 packet
-> options
, (struct option_state
*)0,
3845 &global_scope
, oc
, MDL
)) {
3846 /* Remember this for later. */
3847 have_client_identifier
= 1;
3849 /* First, try to find a fixed host entry for the specified
3850 client identifier... */
3851 if (find_hosts_by_uid (&hp
, client_identifier
.data
,
3852 client_identifier
.len
, MDL
)) {
3853 /* Remember if we know of this client. */
3854 packet
-> known
= 1;
3855 mockup_lease (&fixed_lease
, packet
, share
, hp
);
3858 #if defined (DEBUG_FIND_LEASE)
3860 log_info ("Found host for client identifier: %s.",
3861 piaddr (fixed_lease
-> ip_addr
));
3865 if (!fixed_lease
) /* Save the host if we found one. */
3866 host_reference (&host
, hp
, MDL
);
3867 host_dereference (&hp
, MDL
);
3870 find_lease_by_uid (&uid_lease
, client_identifier
.data
,
3871 client_identifier
.len
, MDL
);
3874 /* If we didn't find a fixed lease using the uid, try doing
3875 it with the hardware address... */
3876 if (!fixed_lease
&& !host
) {
3877 if (find_hosts_by_haddr (&hp
, packet
-> raw
-> htype
,
3878 packet
-> raw
-> chaddr
,
3879 packet
-> raw
-> hlen
, MDL
)) {
3880 /* Remember if we know of this client. */
3881 packet
-> known
= 1;
3883 host_dereference (&host
, MDL
);
3884 host_reference (&host
, hp
, MDL
);
3885 host_dereference (&hp
, MDL
);
3886 mockup_lease (&fixed_lease
, packet
, share
, host
);
3887 #if defined (DEBUG_FIND_LEASE)
3889 log_info ("Found host for link address: %s.",
3890 piaddr (fixed_lease
-> ip_addr
));
3896 /* Finally, if we haven't found anything yet try again with the
3897 * host-identifier option ... */
3898 if (!fixed_lease
&& !host
) {
3899 if (find_hosts_by_option(&hp
, packet
,
3900 packet
->options
, MDL
) == 1) {
3903 host_dereference(&host
, MDL
);
3904 host_reference(&host
, hp
, MDL
);
3905 host_dereference(&hp
, MDL
);
3906 mockup_lease (&fixed_lease
, packet
, share
, host
);
3907 #if defined (DEBUG_FIND_LEASE)
3909 log_info ("Found host via host-identifier");
3915 /* If fixed_lease is present but does not match the requested
3916 IP address, and this is a DHCPREQUEST, then we can't return
3917 any other lease, so we might as well return now. */
3918 if (packet
-> packet_type
== DHCPREQUEST
&& fixed_lease
&&
3919 (fixed_lease
-> ip_addr
.len
!= cip
.len
||
3920 memcmp (fixed_lease
-> ip_addr
.iabuf
,
3921 cip
.iabuf
, cip
.len
))) {
3924 strcpy (dhcp_message
, "requested address is incorrect");
3925 #if defined (DEBUG_FIND_LEASE)
3926 log_info ("Client's fixed-address %s doesn't match %s%s",
3927 piaddr (fixed_lease
-> ip_addr
), "request ",
3928 print_dotted_quads (cip
.len
, cip
.iabuf
));
3934 * If we found leases matching the client identifier, loop through
3935 * the n_uid pointer looking for one that's actually valid. We
3936 * can't do this until we get here because we depend on
3937 * packet -> known, which may be set by either the uid host
3938 * lookup or the haddr host lookup.
3940 * Note that the n_uid lease chain is sorted in order of
3941 * preference, so the first one is the best one.
3944 #if defined (DEBUG_FIND_LEASE)
3945 log_info ("trying next lease matching client id: %s",
3946 piaddr (uid_lease
-> ip_addr
));
3949 #if defined (FAILOVER_PROTOCOL)
3951 * When we lookup a lease by uid, we know the client identifier
3952 * matches the lease's record. If it is active, or was last
3953 * active with the same client, we can trivially extend it.
3954 * If is not or was not active, we can allocate it to this
3955 * client if it matches the usual free/backup criteria (which
3956 * is contained in lease_mine_to_reallocate()).
3958 if (uid_lease
->binding_state
!= FTS_ACTIVE
&&
3959 uid_lease
->rewind_binding_state
!= FTS_ACTIVE
&&
3960 !lease_mine_to_reallocate(uid_lease
)) {
3961 #if defined (DEBUG_FIND_LEASE)
3962 log_info("not active or not mine to allocate: %s",
3963 piaddr(uid_lease
->ip_addr
));
3969 if (uid_lease
-> subnet
-> shared_network
!= share
) {
3970 #if defined (DEBUG_FIND_LEASE)
3971 log_info ("wrong network segment: %s",
3972 piaddr (uid_lease
-> ip_addr
));
3977 if ((uid_lease
-> pool
-> prohibit_list
&&
3978 permitted (packet
, uid_lease
-> pool
-> prohibit_list
)) ||
3979 (uid_lease
-> pool
-> permit_list
&&
3980 !permitted (packet
, uid_lease
-> pool
-> permit_list
))) {
3981 #if defined (DEBUG_FIND_LEASE)
3982 log_info ("not permitted: %s",
3983 piaddr (uid_lease
-> ip_addr
));
3986 if (uid_lease
-> n_uid
)
3987 lease_reference (&next
,
3988 uid_lease
-> n_uid
, MDL
);
3989 if (!packet
-> raw
-> ciaddr
.s_addr
)
3990 release_lease (uid_lease
, packet
);
3991 lease_dereference (&uid_lease
, MDL
);
3993 lease_reference (&uid_lease
, next
, MDL
);
3994 lease_dereference (&next
, MDL
);
4000 #if defined (DEBUG_FIND_LEASE)
4002 log_info ("Found lease for client id: %s.",
4003 piaddr (uid_lease
-> ip_addr
));
4006 /* Find a lease whose hardware address matches, whose client
4007 * identifier matches (or equally doesn't have one), that's
4008 * permitted, and that's on the correct subnet.
4010 * Note that the n_hw chain is sorted in order of preference, so
4011 * the first one found is the best one.
4013 h
.hlen
= packet
-> raw
-> hlen
+ 1;
4014 h
.hbuf
[0] = packet
-> raw
-> htype
;
4015 memcpy (&h
.hbuf
[1], packet
-> raw
-> chaddr
, packet
-> raw
-> hlen
);
4016 find_lease_by_hw_addr (&hw_lease
, h
.hbuf
, h
.hlen
, MDL
);
4018 #if defined (DEBUG_FIND_LEASE)
4019 log_info ("trying next lease matching hw addr: %s",
4020 piaddr (hw_lease
-> ip_addr
));
4022 #if defined (FAILOVER_PROTOCOL)
4024 * When we lookup a lease by chaddr, we know the MAC address
4025 * matches the lease record (we will check if the lease has a
4026 * client-id the client does not next). If the lease is
4027 * currently active or was last active with this client, we can
4028 * trivially extend it. Otherwise, there are a set of rules
4029 * that govern if we can reallocate this lease to any client
4030 * ("lease_mine_to_reallocate()") including this one.
4032 if (hw_lease
->binding_state
!= FTS_ACTIVE
&&
4033 hw_lease
->rewind_binding_state
!= FTS_ACTIVE
&&
4034 !lease_mine_to_reallocate(hw_lease
)) {
4035 #if defined (DEBUG_FIND_LEASE)
4036 log_info("not active or not mine to allocate: %s",
4037 piaddr(hw_lease
->ip_addr
));
4044 * This conditional skips "potentially active" leases (leases
4045 * we think are expired may be extended by the peer, etc) that
4046 * may be assigned to a differently /client-identified/ client
4047 * with the same MAC address.
4049 if (hw_lease
-> binding_state
!= FTS_FREE
&&
4050 hw_lease
-> binding_state
!= FTS_BACKUP
&&
4052 (!have_client_identifier
||
4053 hw_lease
-> uid_len
!= client_identifier
.len
||
4054 memcmp (hw_lease
-> uid
, client_identifier
.data
,
4055 hw_lease
-> uid_len
))) {
4056 #if defined (DEBUG_FIND_LEASE)
4057 log_info ("wrong client identifier: %s",
4058 piaddr (hw_lease
-> ip_addr
));
4062 if (hw_lease
-> subnet
-> shared_network
!= share
) {
4063 #if defined (DEBUG_FIND_LEASE)
4064 log_info ("wrong network segment: %s",
4065 piaddr (hw_lease
-> ip_addr
));
4069 if ((hw_lease
-> pool
-> prohibit_list
&&
4070 permitted (packet
, hw_lease
-> pool
-> prohibit_list
)) ||
4071 (hw_lease
-> pool
-> permit_list
&&
4072 !permitted (packet
, hw_lease
-> pool
-> permit_list
))) {
4073 #if defined (DEBUG_FIND_LEASE)
4074 log_info ("not permitted: %s",
4075 piaddr (hw_lease
-> ip_addr
));
4077 if (!packet
-> raw
-> ciaddr
.s_addr
)
4078 release_lease (hw_lease
, packet
);
4080 if (hw_lease
-> n_hw
)
4081 lease_reference (&next
, hw_lease
-> n_hw
, MDL
);
4082 lease_dereference (&hw_lease
, MDL
);
4084 lease_reference (&hw_lease
, next
, MDL
);
4085 lease_dereference (&next
, MDL
);
4091 #if defined (DEBUG_FIND_LEASE)
4093 log_info ("Found lease for hardware address: %s.",
4094 piaddr (hw_lease
-> ip_addr
));
4097 /* Try to find a lease that's been allocated to the client's
4100 lease_reference (&ip_lease
, ip_lease_in
, MDL
);
4102 find_lease_by_ip_addr (&ip_lease
, cip
, MDL
);
4104 #if defined (DEBUG_FIND_LEASE)
4106 log_info ("Found lease for requested address: %s.",
4107 piaddr (ip_lease
-> ip_addr
));
4110 /* If ip_lease is valid at this point, set ours to one, so that
4111 even if we choose a different lease, we know that the address
4112 the client was requesting was ours, and thus we can NAK it. */
4113 if (ip_lease
&& ours
)
4116 /* If the requested IP address isn't on the network the packet
4117 came from, don't use it. Allow abandoned leases to be matched
4118 here - if the client is requesting it, there's a decent chance
4119 that it's because the lease database got trashed and a client
4120 that thought it had this lease answered an ARP or PING, causing the
4121 lease to be abandoned. If so, this request probably came from
4123 if (ip_lease
&& (ip_lease
-> subnet
-> shared_network
!= share
)) {
4126 #if defined (DEBUG_FIND_LEASE)
4127 log_info ("...but it was on the wrong shared network.");
4129 strcpy (dhcp_message
, "requested address on bad subnet");
4130 lease_dereference (&ip_lease
, MDL
);
4134 * If the requested address is in use (or potentially in use) by
4135 * a different client, it can't be granted.
4137 * This first conditional only detects if the lease is currently
4138 * identified to a different client (client-id and/or chaddr
4139 * mismatch). In this case we may not want to give the client the
4140 * lease, if doing so may potentially be an addressing conflict.
4144 (!have_client_identifier
||
4145 ip_lease
-> uid_len
!= client_identifier
.len
||
4146 memcmp (ip_lease
-> uid
, client_identifier
.data
,
4147 ip_lease
-> uid_len
)) :
4148 (ip_lease
-> hardware_addr
.hbuf
[0] != packet
-> raw
-> htype
||
4149 ip_lease
-> hardware_addr
.hlen
!= packet
-> raw
-> hlen
+ 1 ||
4150 memcmp (&ip_lease
-> hardware_addr
.hbuf
[1],
4151 packet
-> raw
-> chaddr
,
4152 (unsigned)(ip_lease
-> hardware_addr
.hlen
- 1))))) {
4154 * A lease is unavailable for allocation to a new client if
4155 * it is not in the FREE or BACKUP state. There may be
4156 * leases that are in the expired state with a rewinding
4157 * state that is free or backup, but these will be processed
4158 * into the free or backup states by expiration processes, so
4159 * checking for them here is superfluous.
4161 if (ip_lease
-> binding_state
!= FTS_FREE
&&
4162 ip_lease
-> binding_state
!= FTS_BACKUP
) {
4163 #if defined (DEBUG_FIND_LEASE)
4164 log_info ("rejecting lease for requested address.");
4166 /* If we're rejecting it because the peer has
4167 it, don't set "ours", because we shouldn't NAK. */
4168 if (ours
&& ip_lease
-> binding_state
!= FTS_ACTIVE
)
4170 lease_dereference (&ip_lease
, MDL
);
4175 * If we got an ip_lease and a uid_lease or hw_lease, and ip_lease
4176 * is/was not active, and is not ours to reallocate, forget about it.
4178 if (ip_lease
&& (uid_lease
|| hw_lease
) &&
4179 ip_lease
->binding_state
!= FTS_ACTIVE
&&
4180 ip_lease
->rewind_binding_state
!= FTS_ACTIVE
&&
4181 #if defined(FAILOVER_PROTOCOL)
4182 !lease_mine_to_reallocate(ip_lease
) &&
4184 packet
->packet_type
== DHCPDISCOVER
) {
4185 #if defined (DEBUG_FIND_LEASE)
4186 log_info("ip lease not active or not ours to offer.");
4188 lease_dereference(&ip_lease
, MDL
);
4191 /* If for some reason the client has more than one lease
4192 on the subnet that matches its uid, pick the one that
4193 it asked for and (if we can) free the other. */
4194 if (ip_lease
&& ip_lease
->binding_state
== FTS_ACTIVE
&&
4195 ip_lease
->uid
&& ip_lease
!= uid_lease
) {
4196 if (have_client_identifier
&&
4197 (ip_lease
-> uid_len
== client_identifier
.len
) &&
4198 !memcmp (client_identifier
.data
,
4199 ip_lease
-> uid
, ip_lease
-> uid_len
)) {
4201 if (uid_lease
->binding_state
== FTS_ACTIVE
) {
4202 log_error ("client %s has duplicate%s on %s",
4204 (packet
-> raw
-> htype
,
4205 packet
-> raw
-> hlen
,
4206 packet
-> raw
-> chaddr
)),
4208 (ip_lease
-> subnet
->
4209 shared_network
-> name
));
4211 /* If the client is REQUESTing the lease,
4212 it shouldn't still be using the old
4213 one, so we can free it for allocation. */
4215 uid_lease
->binding_state
== FTS_ACTIVE
&&
4216 !packet
-> raw
-> ciaddr
.s_addr
&&
4218 uid_lease
-> subnet
-> shared_network
) &&
4219 packet
-> packet_type
== DHCPREQUEST
)
4220 release_lease (uid_lease
, packet
);
4222 lease_dereference (&uid_lease
, MDL
);
4223 lease_reference (&uid_lease
, ip_lease
, MDL
);
4227 /* If we get to here and fixed_lease is not null, that means
4228 that there are both a dynamic lease and a fixed-address
4229 declaration for the same IP address. */
4230 if (packet
-> packet_type
== DHCPREQUEST
&& fixed_lease
) {
4231 lease_dereference (&fixed_lease
, MDL
);
4233 log_error ("Dynamic and static leases present for %s.",
4235 log_error ("Remove host declaration %s or remove %s",
4236 (fixed_lease
&& fixed_lease
-> host
4237 ? (fixed_lease
-> host
-> name
4238 ? fixed_lease
-> host
-> name
4242 log_error ("from the dynamic address pool for %s",
4243 ip_lease
-> subnet
-> shared_network
-> name
4246 lease_dereference (&ip_lease
, MDL
);
4247 strcpy (dhcp_message
,
4248 "database conflict - call for help!");
4251 if (ip_lease
&& ip_lease
!= uid_lease
) {
4252 #if defined (DEBUG_FIND_LEASE)
4253 log_info ("requested address not available.");
4255 lease_dereference (&ip_lease
, MDL
);
4259 /* If we get to here with both fixed_lease and ip_lease not
4260 null, then we have a configuration file bug. */
4261 if (packet
-> packet_type
== DHCPREQUEST
&& fixed_lease
&& ip_lease
)
4264 /* Toss extra pointers to the same lease... */
4265 if (hw_lease
&& hw_lease
== uid_lease
) {
4266 #if defined (DEBUG_FIND_LEASE)
4267 log_info ("hardware lease and uid lease are identical.");
4269 lease_dereference (&hw_lease
, MDL
);
4271 if (ip_lease
&& ip_lease
== hw_lease
) {
4272 lease_dereference (&hw_lease
, MDL
);
4273 #if defined (DEBUG_FIND_LEASE)
4274 log_info ("hardware lease and ip lease are identical.");
4277 if (ip_lease
&& ip_lease
== uid_lease
) {
4278 lease_dereference (&uid_lease
, MDL
);
4279 #if defined (DEBUG_FIND_LEASE)
4280 log_info ("uid lease and ip lease are identical.");
4284 /* Make sure the client is permitted to use the requested lease. */
4286 ((ip_lease
-> pool
-> prohibit_list
&&
4287 permitted (packet
, ip_lease
-> pool
-> prohibit_list
)) ||
4288 (ip_lease
-> pool
-> permit_list
&&
4289 !permitted (packet
, ip_lease
-> pool
-> permit_list
)))) {
4290 if (!packet
->raw
->ciaddr
.s_addr
&&
4291 (ip_lease
->binding_state
== FTS_ACTIVE
))
4292 release_lease (ip_lease
, packet
);
4294 lease_dereference (&ip_lease
, MDL
);
4298 ((uid_lease
-> pool
-> prohibit_list
&&
4299 permitted (packet
, uid_lease
-> pool
-> prohibit_list
)) ||
4300 (uid_lease
-> pool
-> permit_list
&&
4301 !permitted (packet
, uid_lease
-> pool
-> permit_list
)))) {
4302 if (!packet
-> raw
-> ciaddr
.s_addr
)
4303 release_lease (uid_lease
, packet
);
4304 lease_dereference (&uid_lease
, MDL
);
4308 ((hw_lease
-> pool
-> prohibit_list
&&
4309 permitted (packet
, hw_lease
-> pool
-> prohibit_list
)) ||
4310 (hw_lease
-> pool
-> permit_list
&&
4311 !permitted (packet
, hw_lease
-> pool
-> permit_list
)))) {
4312 if (!packet
-> raw
-> ciaddr
.s_addr
)
4313 release_lease (hw_lease
, packet
);
4314 lease_dereference (&hw_lease
, MDL
);
4317 /* If we've already eliminated the lease, it wasn't there to
4318 begin with. If we have come up with a matching lease,
4319 set the message to bad network in case we have to throw it out. */
4321 strcpy (dhcp_message
, "requested address not available");
4324 /* If this is a DHCPREQUEST, make sure the lease we're going to return
4325 matches the requested IP address. If it doesn't, don't return a
4327 if (packet
-> packet_type
== DHCPREQUEST
&&
4328 !ip_lease
&& !fixed_lease
) {
4329 #if defined (DEBUG_FIND_LEASE)
4330 log_info ("no applicable lease found for DHCPREQUEST.");
4335 /* At this point, if fixed_lease is nonzero, we can assign it to
4338 lease_reference (&lease
, fixed_lease
, MDL
);
4339 lease_dereference (&fixed_lease
, MDL
);
4340 #if defined (DEBUG_FIND_LEASE)
4341 log_info ("choosing fixed address.");
4345 /* If we got a lease that matched the ip address and don't have
4346 a better offer, use that; otherwise, release it. */
4349 if (!packet
-> raw
-> ciaddr
.s_addr
)
4350 release_lease (ip_lease
, packet
);
4351 #if defined (DEBUG_FIND_LEASE)
4352 log_info ("not choosing requested address (!).");
4355 #if defined (DEBUG_FIND_LEASE)
4356 log_info ("choosing lease on requested address.");
4358 lease_reference (&lease
, ip_lease
, MDL
);
4360 host_dereference (&lease
-> host
, MDL
);
4362 lease_dereference (&ip_lease
, MDL
);
4365 /* If we got a lease that matched the client identifier, we may want
4366 to use it, but if we already have a lease we like, we must free
4367 the lease that matched the client identifier. */
4370 log_error("uid lease %s for client %s is duplicate "
4372 piaddr(uid_lease
->ip_addr
),
4373 print_hw_addr(packet
->raw
->htype
,
4375 packet
->raw
->chaddr
),
4376 uid_lease
->subnet
->shared_network
->name
);
4378 if (!packet
-> raw
-> ciaddr
.s_addr
&&
4379 packet
-> packet_type
== DHCPREQUEST
&&
4380 uid_lease
-> binding_state
== FTS_ACTIVE
)
4381 release_lease(uid_lease
, packet
);
4382 #if defined (DEBUG_FIND_LEASE)
4383 log_info ("not choosing uid lease.");
4386 lease_reference (&lease
, uid_lease
, MDL
);
4388 host_dereference (&lease
-> host
, MDL
);
4389 #if defined (DEBUG_FIND_LEASE)
4390 log_info ("choosing uid lease.");
4393 lease_dereference (&uid_lease
, MDL
);
4396 /* The lease that matched the hardware address is treated likewise. */
4399 #if defined (DEBUG_FIND_LEASE)
4400 log_info ("not choosing hardware lease.");
4403 /* We're a little lax here - if the client didn't
4404 send a client identifier and it's a bootp client,
4405 but the lease has a client identifier, we still
4406 let the client have a lease. */
4407 if (!hw_lease
-> uid_len
||
4408 (have_client_identifier
4409 ? (hw_lease
-> uid_len
==
4410 client_identifier
.len
&&
4411 !memcmp (hw_lease
-> uid
,
4412 client_identifier
.data
,
4413 client_identifier
.len
))
4414 : packet
-> packet_type
== 0)) {
4415 lease_reference (&lease
, hw_lease
, MDL
);
4417 host_dereference (&lease
-> host
, MDL
);
4418 #if defined (DEBUG_FIND_LEASE)
4419 log_info ("choosing hardware lease.");
4422 #if defined (DEBUG_FIND_LEASE)
4423 log_info ("not choosing hardware lease: %s.",
4428 lease_dereference (&hw_lease
, MDL
);
4432 * If we found a host_decl but no matching address, try to
4433 * find a host_decl that has no address, and if there is one,
4434 * hang it off the lease so that we can use the supplied
4437 if (lease
&& host
&& !lease
->host
) {
4438 struct host_decl
*p
= NULL
;
4439 struct host_decl
*n
= NULL
;
4441 host_reference(&p
, host
, MDL
);
4443 if (!p
->fixed_addr
) {
4445 * If the lease is currently active, then it
4446 * must be allocated to the present client.
4447 * We store a reference to the host record on
4448 * the lease to save a lookup later (in
4449 * ack_lease()). We mustn't refer to the host
4450 * record on non-active leases because the
4451 * client may be denied later.
4453 * XXX: Not having this reference (such as in
4454 * DHCPDISCOVER/INIT) means ack_lease will have
4455 * to perform this lookup a second time. This
4456 * hopefully isn't a problem as DHCPREQUEST is
4457 * more common than DHCPDISCOVER.
4459 if (lease
->binding_state
== FTS_ACTIVE
)
4460 host_reference(&lease
->host
, p
, MDL
);
4462 host_dereference(&p
, MDL
);
4465 if (p
->n_ipaddr
!= NULL
)
4466 host_reference(&n
, p
->n_ipaddr
, MDL
);
4467 host_dereference(&p
, MDL
);
4469 host_reference(&p
, n
, MDL
);
4470 host_dereference(&n
, MDL
);
4475 /* If we find an abandoned lease, but it's the one the client
4476 requested, we assume that previous bugginess on the part
4477 of the client, or a server database loss, caused the lease to
4478 be abandoned, so we reclaim it and let the client have it. */
4480 (lease
-> binding_state
== FTS_ABANDONED
) &&
4481 lease
== ip_lease
&&
4482 packet
-> packet_type
== DHCPREQUEST
) {
4483 log_error ("Reclaiming REQUESTed abandoned IP address %s.",
4484 piaddr (lease
-> ip_addr
));
4485 } else if (lease
&& (lease
-> binding_state
== FTS_ABANDONED
)) {
4486 /* Otherwise, if it's not the one the client requested, we do not
4487 return it - instead, we claim it's ours, causing a DHCPNAK to be
4488 sent if this lookup is for a DHCPREQUEST, and force the client
4489 to go back through the allocation process. */
4492 lease_dereference (&lease
, MDL
);
4496 if (have_client_identifier
)
4497 data_string_forget (&client_identifier
, MDL
);
4500 lease_dereference (&fixed_lease
, MDL
);
4502 lease_dereference (&hw_lease
, MDL
);
4504 lease_dereference (&uid_lease
, MDL
);
4506 lease_dereference (&ip_lease
, MDL
);
4508 host_dereference (&host
, MDL
);
4511 #if defined (DEBUG_FIND_LEASE)
4512 log_info ("Returning lease: %s.",
4513 piaddr (lease
-> ip_addr
));
4515 lease_reference (lp
, lease
, file
, line
);
4516 lease_dereference (&lease
, MDL
);
4519 #if defined (DEBUG_FIND_LEASE)
4520 log_info ("Not returning a lease.");
4525 /* Search the provided host_decl structure list for an address that's on
4526 the specified shared network. If one is found, mock up and return a
4527 lease structure for it; otherwise return the null pointer. */
4529 int mockup_lease (struct lease
**lp
, struct packet
*packet
,
4530 struct shared_network
*share
, struct host_decl
*hp
)
4532 struct lease
*lease
= (struct lease
*)0;
4533 struct host_decl
*rhp
= (struct host_decl
*)0;
4535 if (lease_allocate (&lease
, MDL
) != ISC_R_SUCCESS
)
4537 if (host_reference (&rhp
, hp
, MDL
) != ISC_R_SUCCESS
) {
4538 lease_dereference (&lease
, MDL
);
4541 if (!find_host_for_network (&lease
-> subnet
,
4542 &rhp
, &lease
-> ip_addr
, share
)) {
4543 lease_dereference (&lease
, MDL
);
4544 host_dereference (&rhp
, MDL
);
4547 host_reference (&lease
-> host
, rhp
, MDL
);
4548 if (rhp
-> client_identifier
.len
> sizeof lease
-> uid_buf
)
4549 lease
-> uid
= dmalloc (rhp
-> client_identifier
.len
, MDL
);
4551 lease
-> uid
= lease
-> uid_buf
;
4552 if (!lease
-> uid
) {
4553 lease_dereference (&lease
, MDL
);
4554 host_dereference (&rhp
, MDL
);
4557 memcpy (lease
-> uid
, rhp
-> client_identifier
.data
,
4558 rhp
-> client_identifier
.len
);
4559 lease
-> uid_len
= rhp
-> client_identifier
.len
;
4560 lease
-> hardware_addr
= rhp
-> interface
;
4561 lease
-> starts
= lease
-> cltt
= lease
-> ends
= MIN_TIME
;
4562 lease
-> flags
= STATIC_LEASE
;
4563 lease
-> binding_state
= FTS_FREE
;
4565 lease_reference (lp
, lease
, MDL
);
4567 lease_dereference (&lease
, MDL
);
4568 host_dereference (&rhp
, MDL
);
4572 /* Look through all the pools in a list starting with the specified pool
4573 for a free lease. We try to find a virgin lease if we can. If we
4574 don't find a virgin lease, we try to find a non-virgin lease that's
4575 free. If we can't find one of those, we try to reclaim an abandoned
4576 lease. If all of these possibilities fail to pan out, we don't return
4579 int allocate_lease (struct lease
**lp
, struct packet
*packet
,
4580 struct pool
*pool
, int *peer_has_leases
)
4582 struct lease
*lease
= NULL
;
4583 struct lease
*candl
= NULL
;
4585 for (; pool
; pool
= pool
-> next
) {
4586 if ((pool
-> prohibit_list
&&
4587 permitted (packet
, pool
-> prohibit_list
)) ||
4588 (pool
-> permit_list
&&
4589 !permitted (packet
, pool
-> permit_list
)))
4592 #if defined (FAILOVER_PROTOCOL)
4593 /* Peer_has_leases just says that we found at least one
4594 free lease. If no free lease is returned, the caller
4595 can deduce that this means the peer is hogging all the
4596 free leases, so we can print a better error message. */
4597 /* XXX Do we need code here to ignore PEER_IS_OWNER and
4598 * XXX just check tstp if we're in, e.g., PARTNER_DOWN?
4599 * XXX Where do we deal with CONFLICT_DETECTED, et al? */
4600 /* XXX This should be handled by the lease binding "state
4601 * XXX machine" - that is, when we get here, if a lease
4602 * XXX could be allocated, it will have the correct
4603 * XXX binding state so that the following code will
4604 * XXX result in its being allocated. */
4605 /* Skip to the most expired lease in the pool that is not
4606 * owned by a failover peer. */
4607 if (pool
->failover_peer
!= NULL
) {
4608 struct lease
*peerl
= NULL
;
4609 if (pool
->failover_peer
->i_am
== primary
) {
4610 candl
= LEASE_GET_FIRST(pool
->free
);
4613 * In normal operation, we never want to touch
4614 * the peer's leases. In partner-down
4615 * operation, we need to be able to pick up
4616 * the peer's leases after STOS+MCLT.
4618 peerl
= LEASE_GET_FIRST(pool
->backup
);
4619 if (peerl
!= NULL
) {
4620 if (((candl
== NULL
) ||
4621 (candl
->ends
> peerl
->ends
)) &&
4622 lease_mine_to_reallocate(peerl
)) {
4625 *peer_has_leases
= 1;
4629 candl
= LEASE_GET_FIRST(pool
->backup
);
4631 peerl
= LEASE_GET_FIRST(pool
->free
);
4632 if (peerl
!= NULL
) {
4633 if (((candl
== NULL
) ||
4634 (candl
->ends
> peerl
->ends
)) &&
4635 lease_mine_to_reallocate(peerl
)) {
4638 *peer_has_leases
= 1;
4643 /* Try abandoned leases as a last resort. */
4644 peerl
= LEASE_GET_FIRST(pool
->abandoned
);
4645 if ((candl
== NULL
) && (peerl
!= NULL
) &&
4646 lease_mine_to_reallocate(peerl
))
4651 if (LEASE_NOT_EMPTY(pool
->free
))
4652 candl
= LEASE_GET_FIRST(pool
->free
);
4654 candl
= LEASE_GET_FIRST(pool
->abandoned
);
4658 * XXX: This may not match with documented expectation.
4659 * It's expected that when we OFFER a lease, we set its
4660 * ends time forward 2 minutes so that it gets sorted to
4661 * the end of its free list (avoiding a similar allocation
4662 * to another client). It is not expected that we issue a
4663 * "no free leases" error when the last lease has been
4664 * offered, but it's not exactly broken either.
4666 if (!candl
|| (candl
-> ends
> cur_time
))
4675 * There are tiers of lease state preference, listed here in
4676 * reverse order (least to most preferential):
4681 * If the selected lease and candidate are both of the same
4682 * state, select the oldest (longest ago) expiration time
4683 * between the two. If the candidate lease is of a higher
4684 * preferred grade over the selected lease, use it.
4686 if ((lease
-> binding_state
== FTS_ABANDONED
) &&
4687 ((candl
-> binding_state
!= FTS_ABANDONED
) ||
4688 (candl
-> ends
< lease
-> ends
))) {
4691 } else if (candl
-> binding_state
== FTS_ABANDONED
)
4694 if ((lease
-> uid_len
|| lease
-> hardware_addr
.hlen
) &&
4695 ((!candl
-> uid_len
&& !candl
-> hardware_addr
.hlen
) ||
4696 (candl
-> ends
< lease
-> ends
))) {
4699 } else if (candl
-> uid_len
|| candl
-> hardware_addr
.hlen
)
4702 if (candl
-> ends
< lease
-> ends
)
4706 if (lease
!= NULL
) {
4707 if (lease
->binding_state
== FTS_ABANDONED
)
4708 log_error("Reclaiming abandoned lease %s.",
4709 piaddr(lease
->ip_addr
));
4712 * XXX: For reliability, we go ahead and remove the host
4713 * record and try to move on. For correctness, if there
4714 * are any other stale host vectors, we want to find them.
4716 if (lease
->host
!= NULL
) {
4717 log_debug("soft impossible condition (%s:%d): stale "
4718 "host \"%s\" found on lease %s", MDL
,
4720 piaddr(lease
->ip_addr
));
4721 host_dereference(&lease
->host
, MDL
);
4724 lease_reference (lp
, lease
, MDL
);
4731 /* Determine whether or not a permit exists on a particular permit list
4732 that matches the specified packet, returning nonzero if so, zero if
4735 int permitted (packet
, permit_list
)
4736 struct packet
*packet
;
4737 struct permit
*permit_list
;
4742 for (p
= permit_list
; p
; p
= p
-> next
) {
4743 switch (p
-> type
) {
4744 case permit_unknown_clients
:
4745 if (!packet
-> known
)
4749 case permit_known_clients
:
4750 if (packet
-> known
)
4754 case permit_authenticated_clients
:
4755 if (packet
-> authenticated
)
4759 case permit_unauthenticated_clients
:
4760 if (!packet
-> authenticated
)
4764 case permit_all_clients
:
4767 case permit_dynamic_bootp_clients
:
4768 if (!packet
-> options_valid
||
4769 !packet
-> packet_type
)
4774 for (i
= 0; i
< packet
-> class_count
; i
++) {
4775 if (p
-> class == packet
-> classes
[i
])
4777 if (packet
-> classes
[i
] &&
4778 packet
-> classes
[i
] -> superclass
&&
4779 (packet
-> classes
[i
] -> superclass
==
4786 if (cur_time
> p
->after
)
4794 int locate_network (packet
)
4795 struct packet
*packet
;
4798 struct data_string data
;
4799 struct subnet
*subnet
= (struct subnet
*)0;
4800 struct option_cache
*oc
;
4802 /* See if there's a Relay Agent Link Selection Option, or a
4803 * Subnet Selection Option. The Link-Select and Subnet-Select
4804 * are formatted and used precisely the same, but we must prefer
4805 * the link-select over the subnet-select.
4807 if ((oc
= lookup_option(&agent_universe
, packet
->options
,
4808 RAI_LINK_SELECT
)) == NULL
)
4809 oc
= lookup_option(&dhcp_universe
, packet
->options
,
4810 DHO_SUBNET_SELECTION
);
4812 /* If there's no SSO and no giaddr, then use the shared_network
4813 from the interface, if there is one. If not, fail. */
4814 if (!oc
&& !packet
-> raw
-> giaddr
.s_addr
) {
4815 if (packet
-> interface
-> shared_network
) {
4816 shared_network_reference
4817 (&packet
-> shared_network
,
4818 packet
-> interface
-> shared_network
, MDL
);
4824 /* If there's an option indicating link connection, and it's valid,
4825 * use it to figure out the subnet. If it's not valid, fail.
4828 memset (&data
, 0, sizeof data
);
4829 if (!evaluate_option_cache (&data
, packet
, (struct lease
*)0,
4830 (struct client_state
*)0,
4832 (struct option_state
*)0,
4833 &global_scope
, oc
, MDL
)) {
4836 if (data
.len
!= 4) {
4840 memcpy (ia
.iabuf
, data
.data
, 4);
4841 data_string_forget (&data
, MDL
);
4844 memcpy (ia
.iabuf
, &packet
-> raw
-> giaddr
, 4);
4847 /* If we know the subnet on which the IP address lives, use it. */
4848 if (find_subnet (&subnet
, ia
, MDL
)) {
4849 shared_network_reference (&packet
-> shared_network
,
4850 subnet
-> shared_network
, MDL
);
4851 subnet_dereference (&subnet
, MDL
);
4855 /* Otherwise, fail. */
4860 * Try to figure out the source address to send packets from.
4862 * from is the address structure we use to return any address
4865 * options is the option cache to search. This may include
4866 * options from the incoming packet and configuration information.
4868 * out_options is the outgoing option cache. This cache
4869 * may be the same as options. If out_options isn't NULL
4870 * we may save the server address option into it. We do so
4871 * if out_options is different than options or if the option
4872 * wasn't in options and we needed to find the address elsewhere.
4874 * packet is the state structure for the incoming packet
4876 * When finding the address we first check to see if it is
4877 * in the options list. If it isn't we use the first address
4878 * from the interface.
4880 * While this is slightly more complicated than I'd like it allows
4881 * us to use the same code in several different places. ack,
4882 * inform and lease query use it to find the address and fill
4883 * in the options if we get the address from the interface.
4884 * nack uses it to find the address and copy it to the outgoing
4885 * cache. dhcprequest uses it to find the address for comparison
4886 * and doesn't need to add it to an outgoing list.
4890 get_server_source_address(struct in_addr
*from
,
4891 struct option_state
*options
,
4892 struct option_state
*out_options
,
4893 struct packet
*packet
) {
4894 unsigned option_num
;
4895 struct option_cache
*oc
= NULL
;
4896 struct data_string d
;
4897 struct in_addr
*a
= NULL
;
4898 isc_boolean_t found
= ISC_FALSE
;
4901 memset(&d
, 0, sizeof(d
));
4902 memset(from
, 0, sizeof(*from
));
4904 option_num
= DHO_DHCP_SERVER_IDENTIFIER
;
4905 oc
= lookup_option(&dhcp_universe
, options
, option_num
);
4907 if (evaluate_option_cache(&d
, packet
, NULL
, NULL
,
4908 packet
->options
, options
,
4909 &global_scope
, oc
, MDL
)) {
4910 if (d
.len
== sizeof(*from
)) {
4912 memcpy(from
, d
.data
, sizeof(*from
));
4915 * Arrange to save a copy of the data
4916 * to the outgoing list.
4918 if ((out_options
!= NULL
) &&
4919 (options
!= out_options
)) {
4924 data_string_forget(&d
, MDL
);
4929 if ((found
== ISC_FALSE
) &&
4930 (packet
->interface
->address_count
> 0)) {
4931 *from
= packet
->interface
->addresses
[0];
4933 if (out_options
!= NULL
) {
4934 a
= &packet
->interface
->addresses
[0];
4939 (option_cache_allocate(&oc
, MDL
))) {
4940 if (make_const_data(&oc
->expression
,
4941 (unsigned char *)a
, sizeof(*a
),
4942 0, allocate
, MDL
)) {
4943 option_code_hash_lookup(&oc
->option
,
4944 dhcp_universe
.code_hash
,
4945 &option_num
, 0, MDL
);
4946 save_option(&dhcp_universe
, out_options
, oc
);
4948 option_cache_dereference(&oc
, MDL
);
4955 * \brief Builds option set from statements at the global and network scope
4957 * Set up an option state list based on the global and network scopes.
4958 * These are primarily used by NAK logic to locate dhcp-server-id and
4961 * We don't go through all possible options - in particualr we skip the hosts
4962 * and we don't include the lease to avoid making changes to it. This means
4963 * that using these, we won't get the correct server id if the admin puts them
4964 * on hosts or builds the server id with information from the lease.
4966 * As this is a fallback function (used to handle NAKs or sort out server id
4967 * mismatch in failover) and requires configuration by the admin, it should be
4970 * \param network_options option_state to which options will be added. If it
4971 * refers to NULL, it will be allocated. Caller is responsible to delete it.
4972 * \param packet inbound packet
4973 * \param network_group scope group to use if packet->shared_network is null.
4976 eval_network_statements(struct option_state
**network_options
,
4977 struct packet
*packet
,
4978 struct group
*network_group
) {
4980 if (*network_options
== NULL
) {
4981 option_state_allocate (network_options
, MDL
);
4984 /* Use the packet's shared_network if it has one. If not use
4985 * network_group and if it is null then use global scope. */
4986 if (packet
->shared_network
!= NULL
) {
4988 * If we have a subnet and group start with that else start
4989 * with the shared network group. The first will recurse and
4990 * include the second.
4992 if ((packet
->shared_network
->subnets
!= NULL
) &&
4993 (packet
->shared_network
->subnets
->group
!= NULL
)) {
4994 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
4995 packet
->options
, *network_options
,
4997 packet
->shared_network
->subnets
->group
,
5000 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5001 packet
->options
, *network_options
,
5003 packet
->shared_network
->group
,
5007 /* do the pool if there is one */
5008 if (packet
->shared_network
->pools
!= NULL
) {
5009 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5010 packet
->options
, *network_options
,
5012 packet
->shared_network
->pools
->group
,
5013 packet
->shared_network
->group
,
5016 } else if (network_group
!= NULL
) {
5017 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5018 packet
->options
, *network_options
,
5019 &global_scope
, network_group
,
5022 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5023 packet
->options
, *network_options
,
5024 &global_scope
, root_group
,
5030 * Look for the lowest numbered site code number and
5031 * apply a log warning if it is less than 224. Do not
5032 * permit site codes less than 128 (old code never did).
5034 * Note that we could search option codes 224 down to 128
5035 * on the hash table, but the table is (probably) smaller
5036 * than that if it was declared as a standalone table with
5037 * defaults. So we traverse the option code hash.
5040 find_min_site_code(struct universe
*u
)
5042 if (u
->site_code_min
)
5043 return u
->site_code_min
;
5046 * Note that site_code_min has to be global as we can't pass an
5047 * argument through hash_foreach(). The value 224 is taken from
5050 site_code_min
= 224;
5051 option_code_hash_foreach(u
->code_hash
, lowest_site_code
);
5053 if (site_code_min
< 224) {
5054 log_error("WARNING: site-local option codes less than 224 have "
5055 "been deprecated by RFC3942. You have options "
5056 "listed in site local space %s that number as low as "
5057 "%d. Please investigate if these should be declared "
5058 "as regular options rather than site-local options, "
5059 "or migrated up past 224.",
5060 u
->name
, site_code_min
);
5064 * don't even bother logging, this is just silly, and never worked
5065 * on any old version of software.
5067 if (site_code_min
< 128)
5068 site_code_min
= 128;
5071 * Cache the determined minimum site code on the universe structure.
5072 * Note that due to the < 128 check above, a value of zero is
5075 u
->site_code_min
= site_code_min
;
5077 return site_code_min
;
5081 lowest_site_code(const void *key
, unsigned len
, void *object
)
5083 struct option
*option
= object
;
5085 if (option
->code
< site_code_min
)
5086 site_code_min
= option
->code
;
5088 return ISC_R_SUCCESS
;
5092 maybe_return_agent_options(struct packet
*packet
, struct option_state
*options
)
5094 /* If there were agent options in the incoming packet, return
5095 * them. Do not return the agent options if they were stashed
5096 * on the lease. We do not check giaddr to detect the presence of
5097 * a relay, as this excludes "l2" relay agents which have no giaddr
5100 * XXX: If the user configures options for the relay agent information
5101 * (state->options->universes[agent_universe.index] is not NULL),
5102 * we're still required to duplicate other values provided by the
5103 * relay agent. So we need to merge the old values not configured
5104 * by the user into the new state, not just give up.
5106 if (!packet
->agent_options_stashed
&&
5107 (packet
->options
!= NULL
) &&
5108 packet
->options
->universe_count
> agent_universe
.index
&&
5109 packet
->options
->universes
[agent_universe
.index
] != NULL
&&
5110 (options
->universe_count
<= agent_universe
.index
||
5111 options
->universes
[agent_universe
.index
] == NULL
)) {
5112 option_chain_head_reference
5113 ((struct option_chain_head
**)
5114 &(options
->universes
[agent_universe
.index
]),
5115 (struct option_chain_head
*)
5116 packet
->options
->universes
[agent_universe
.index
], MDL
);
5118 if (options
->universe_count
<= agent_universe
.index
)
5119 options
->universe_count
= agent_universe
.index
+ 1;
5124 * \brief Adds hostname option when use-host-decl-names is enabled.
5126 * Constructs a hostname option from the name of the host declaration if
5127 * there is one and no hostname has otherwise been provided and the
5128 * use-host-decl-names flag is set, then adds the new option to the given
5129 * option_state. This funciton is used for both bootp and dhcp.
5131 * \param packet inbound packet received from the client
5132 * \param lease lease associated with the client
5133 * \param options option state to search and update
5135 void use_host_decl_name(struct packet
* packet
,
5136 struct lease
*lease
,
5137 struct option_state
*options
) {
5138 unsigned int ocode
= SV_USE_HOST_DECL_NAMES
;
5139 if ((lease
->host
&& lease
->host
->name
) &&
5140 !lookup_option(&dhcp_universe
, options
, DHO_HOST_NAME
) &&
5141 (evaluate_boolean_option_cache(NULL
, packet
, lease
, NULL
,
5142 packet
->options
, options
,
5144 lookup_option(&server_universe
,
5147 struct option_cache
*oc
= NULL
;
5148 if (option_cache_allocate (&oc
, MDL
)) {
5149 if (make_const_data(&oc
-> expression
,
5150 ((unsigned char*)lease
->host
->name
),
5151 strlen(lease
->host
->name
),
5153 ocode
= DHO_HOST_NAME
;
5154 option_code_hash_lookup(&oc
->option
,
5155 dhcp_universe
.code_hash
,
5157 save_option(&dhcp_universe
, options
, oc
);
5159 option_cache_dereference(&oc
, MDL
);
5165 * \brief Checks and preps for lease resuse based on dhcp-cache-threshold
5167 * If dhcp-cache-threshold is enabled (i.e. greater than zero), this function
5168 * determines if the current lease is young enough to be reused. If the lease
5169 * can be resused the function returns 1, O if not. This function is called
5170 * by ack_lease when responding to both DISCOVERs and REQUESTS.
5172 * The current lease can be reused only if all of the following are true:
5173 * a. dhcp-cache-threshold is > 0
5174 * b. The current lease is active
5175 * c. The lease "age" is less than that allowed by the threshold
5176 * d. DNS updates are not being performed on the new lease.
5177 * e. Lease has not been otherwise disqualified for reuse (Ex: billing class
5180 * Clients may renew leases using full DORA cycles or just RAs. This means
5181 * that reusability must be checked when acking both DISCOVERs and REQUESTs.
5182 * When a lease cannot be reused, ack_lease() calls supersede_lease() which
5183 * updates the lease start time (among other things). If this occurs on the
5184 * DISCOVER, then the lease will virtually always be seen as young enough to
5185 * reuse on the ensuing REQUEST and the lease updates will not get committed
5186 * to the lease file. The lease.cannot_reuse flag is used to handle this
5189 * \param packet inbound packet received from the client
5190 * \param new_lease candidate new lease to associate with the client
5191 * \param lease current lease associated with the client
5192 * \param options option state to search and update
5195 reuse_lease (struct packet
* packet
,
5196 struct lease
* new_lease
,
5197 struct lease
* lease
,
5198 struct lease_state
*state
,
5202 /* To even consider reuse all of the following must be true:
5203 * 1 - reuse hasn't already disqualified
5204 * 2 - current lease is active
5205 * 3 - DNS info hasn't changed */
5206 if ((lease
->cannot_reuse
== 0) &&
5207 (lease
->binding_state
== FTS_ACTIVE
) &&
5208 (new_lease
->ddns_cb
== NULL
)) {
5209 int thresh
= DEFAULT_CACHE_THRESHOLD
;
5210 struct option_cache
* oc
= NULL
;
5211 struct data_string d1
;
5213 /* Look up threshold value */
5214 memset(&d1
, 0, sizeof(struct data_string
));
5215 if ((oc
= lookup_option(&server_universe
, state
->options
,
5216 SV_CACHE_THRESHOLD
)) &&
5217 (evaluate_option_cache(&d1
, packet
, new_lease
, NULL
,
5218 packet
->options
, state
->options
,
5219 &new_lease
->scope
, oc
, MDL
))) {
5220 if (d1
.len
== 1 && (d1
.data
[0] < 100))
5221 thresh
= d1
.data
[0];
5223 data_string_forget(&d1
, MDL
);
5226 /* If threshold is enabled, check lease age */
5229 int lease_length
= 0;
5232 /* Calculate limit in seconds */
5233 lease_length
= lease
->ends
- lease
->starts
;
5234 if (lease_length
<= (INT_MAX
/ thresh
))
5235 limit
= lease_length
* thresh
/ 100;
5237 limit
= lease_length
/ 100 * thresh
;
5239 /* Note new_lease->starts is really just cur_time */
5240 lease_age
= new_lease
->starts
- lease
->starts
;
5242 /* Is the lease is young enough to reuse? */
5243 if (lease_age
<= limit
) {
5244 /* Restore expiry to its original value */
5245 state
->offered_expiry
= lease
->ends
;
5247 /* Restore bindings. This fixes 37368. */
5248 if (new_lease
->scope
!= NULL
) {
5249 if (lease
->scope
!= NULL
) {
5250 binding_scope_dereference(
5255 binding_scope_reference(&lease
->scope
,
5256 new_lease
->scope
, MDL
);
5259 /* We're cleared to reuse it */
5260 log_debug("reuse_lease: lease age %ld (secs)"
5261 " under %d%% threshold, reply with "
5262 "unaltered, existing lease for %s",
5263 lease_age
, thresh
, piaddr(lease
->ip_addr
));
5270 /* If we can't reuse it and this is an offer disqualify reuse for
5271 * ensuing REQUEST, otherwise clear the flag. */
5272 lease
->cannot_reuse
= (!reusable
&& offer
== DHCPOFFER
);