3 DHCP Protocol engine. */
6 * Copyright (c) 2004-2014 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 commit_leases_ackout(void *foo
);
35 static void maybe_return_agent_options(struct packet
*packet
,
36 struct option_state
*options
);
38 int outstanding_pings
;
40 struct leasequeue
*ackqueue_head
, *ackqueue_tail
;
41 static struct leasequeue
*free_ackqueue
;
42 static struct timeval max_fsync
;
45 int max_outstanding_acks
= DEFAULT_DELAYED_ACK
;
46 int max_ack_delay_secs
= DEFAULT_ACK_DELAY_SECS
;
47 int max_ack_delay_usecs
= DEFAULT_ACK_DELAY_USECS
;
48 int min_ack_delay_usecs
= DEFAULT_MIN_ACK_DELAY_USECS
;
50 static char dhcp_message
[256];
51 static int site_code_min
;
53 static int find_min_site_code(struct universe
*);
54 static isc_result_t
lowest_site_code(const void *, unsigned, void *);
56 static const char *dhcp_type_names
[] = {
67 "DHCPLEASEUNASSIGNED",
71 const int dhcp_type_name_max
= ((sizeof dhcp_type_names
) / sizeof (char *));
74 # define send_packet trace_packet_send
78 dhcp (struct packet
*packet
) {
80 struct option_cache
*oc
;
81 struct lease
*lease
= NULL
;
83 struct data_string data
;
85 if (!locate_network(packet
) &&
86 packet
->packet_type
!= DHCPREQUEST
&&
87 packet
->packet_type
!= DHCPINFORM
&&
88 packet
->packet_type
!= DHCPLEASEQUERY
) {
91 errmsg
= "unknown network segment";
94 if (packet
->packet_type
> 0 &&
95 packet
->packet_type
<= dhcp_type_name_max
) {
96 s
= dhcp_type_names
[packet
->packet_type
- 1];
98 /* %Audit% Cannot exceed 28 bytes. %2004.06.17,Safe% */
99 sprintf(typebuf
, "type %d", packet
->packet_type
);
103 log_info("%s from %s via %s: %s", s
,
105 ? print_hw_addr(packet
->raw
->htype
,
108 : "<no identifier>"),
109 packet
->raw
->giaddr
.s_addr
110 ? inet_ntoa(packet
->raw
->giaddr
)
111 : packet
->interface
->name
, errmsg
);
115 /* There is a problem with the relay agent information option,
116 * which is that in order for a normal relay agent to append
117 * this option, the relay agent has to have been involved in
118 * getting the packet from the client to the server. Note
119 * that this is the software entity known as the relay agent,
120 * _not_ the hardware entity known as a router in which the
121 * relay agent may be running, so the fact that a router has
122 * forwarded a packet does not mean that the relay agent in
123 * the router was involved.
125 * So when the client broadcasts (DHCPDISCOVER, or giaddr is set),
126 * we can be sure that there are either agent options in the
127 * packet, or there aren't supposed to be. When the giaddr is not
128 * set, it's still possible that the client is on a directly
129 * attached subnet, and agent options are being appended by an l2
130 * device that has no address, and so sets no giaddr.
132 * But in either case it's possible that the packets we receive
133 * from the client in RENEW state may not include the agent options,
134 * so if they are not in the packet we must "pretend" the last values
135 * we observed were provided.
137 if (packet
->packet_type
== DHCPREQUEST
&&
138 packet
->raw
->ciaddr
.s_addr
&& !packet
->raw
->giaddr
.s_addr
&&
139 (packet
->options
->universe_count
<= agent_universe
.index
||
140 packet
->options
->universes
[agent_universe
.index
] == NULL
))
144 cip
.len
= sizeof packet
-> raw
-> ciaddr
;
145 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
,
146 sizeof packet
-> raw
-> ciaddr
);
147 if (!find_lease_by_ip_addr (&lease
, cip
, MDL
))
150 /* If there are no agent options on the lease, it's not
152 if (!lease
-> agent_options
)
155 /* The client should not be unicasting a renewal if its lease
156 has expired, so make it go through the process of getting
157 its agent options legally. */
158 if (lease
-> ends
< cur_time
)
161 if (lease
-> uid_len
) {
162 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
163 DHO_DHCP_CLIENT_IDENTIFIER
);
167 memset (&data
, 0, sizeof data
);
168 if (!evaluate_option_cache (&data
,
169 packet
, (struct lease
*)0,
170 (struct client_state
*)0,
172 (struct option_state
*)0,
173 &global_scope
, oc
, MDL
))
175 if (lease
-> uid_len
!= data
.len
||
176 memcmp (lease
-> uid
, data
.data
, data
.len
)) {
177 data_string_forget (&data
, MDL
);
180 data_string_forget (&data
, MDL
);
182 if ((lease
-> hardware_addr
.hbuf
[0] !=
183 packet
-> raw
-> htype
) ||
184 (lease
-> hardware_addr
.hlen
- 1 !=
185 packet
-> raw
-> hlen
) ||
186 memcmp (&lease
-> hardware_addr
.hbuf
[1],
187 packet
-> raw
-> chaddr
,
188 packet
-> raw
-> hlen
))
191 /* Okay, so we found a lease that matches the client. */
192 option_chain_head_reference ((struct option_chain_head
**)
193 &(packet
-> options
-> universes
194 [agent_universe
.index
]),
195 lease
-> agent_options
, MDL
);
197 if (packet
->options
->universe_count
<= agent_universe
.index
)
198 packet
->options
->universe_count
=
199 agent_universe
.index
+ 1;
201 packet
->agent_options_stashed
= ISC_TRUE
;
205 /* If a client null terminates options it sends, it probably
206 * expects the server to reciprocate.
208 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
210 if (!oc
-> expression
)
211 ms_nulltp
= oc
->flags
& OPTION_HAD_NULLS
;
214 /* Classify the client. */
215 classify_client (packet
);
217 switch (packet
-> packet_type
) {
219 dhcpdiscover (packet
, ms_nulltp
);
223 dhcprequest (packet
, ms_nulltp
, lease
);
227 dhcprelease (packet
, ms_nulltp
);
231 dhcpdecline (packet
, ms_nulltp
);
235 dhcpinform (packet
, ms_nulltp
);
239 dhcpleasequery(packet
, ms_nulltp
);
245 case DHCPLEASEUNASSIGNED
:
246 case DHCPLEASEUNKNOWN
:
247 case DHCPLEASEACTIVE
:
251 errmsg
= "unknown packet type";
256 lease_dereference (&lease
, MDL
);
259 void dhcpdiscover (packet
, ms_nulltp
)
260 struct packet
*packet
;
263 struct lease
*lease
= (struct lease
*)0;
264 char msgbuf
[1024]; /* XXX */
267 int peer_has_leases
= 0;
268 #if defined (FAILOVER_PROTOCOL)
269 dhcp_failover_state_t
*peer
;
272 find_lease (&lease
, packet
, packet
-> shared_network
,
273 0, &peer_has_leases
, (struct lease
*)0, MDL
);
275 if (lease
&& lease
-> client_hostname
) {
276 if ((strlen (lease
-> client_hostname
) <= 64) &&
277 db_printable((unsigned char *)lease
->client_hostname
))
278 s
= lease
-> client_hostname
;
280 s
= "Hostname Unsuitable for Printing";
284 /* %Audit% This is log output. %2004.06.17,Safe%
285 * If we truncate we hope the user can get a hint from the log.
287 snprintf (msgbuf
, sizeof msgbuf
, "DHCPDISCOVER from %s %s%s%svia %s",
288 (packet
-> raw
-> htype
289 ? print_hw_addr (packet
-> raw
-> htype
,
290 packet
-> raw
-> hlen
,
291 packet
-> raw
-> chaddr
)
293 ? print_hex_1(lease
->uid_len
, lease
->uid
, 60)
294 : "<no identifier>")),
295 s
? "(" : "", s
? s
: "", s
? ") " : "",
296 packet
-> raw
-> giaddr
.s_addr
297 ? inet_ntoa (packet
-> raw
-> giaddr
)
298 : packet
-> interface
-> name
);
300 /* Sourceless packets don't make sense here. */
301 if (!packet
-> shared_network
) {
302 log_info ("Packet from unknown subnet: %s",
303 inet_ntoa (packet
-> raw
-> giaddr
));
307 #if defined (FAILOVER_PROTOCOL)
308 if (lease
&& lease
-> pool
&& lease
-> pool
-> failover_peer
) {
309 peer
= lease
-> pool
-> failover_peer
;
312 * If the lease is ours to (re)allocate, then allocate it.
314 * If the lease is active, it belongs to the client. This
315 * is the right lease, if we are to offer one. We decide
316 * whether or not to offer later on.
318 * If the lease was last active, and we've reached this
319 * point, then it was last active with the same client. We
320 * can safely re-activate the lease with this client.
322 if (lease
->binding_state
== FTS_ACTIVE
||
323 lease
->rewind_binding_state
== FTS_ACTIVE
||
324 lease_mine_to_reallocate(lease
)) {
325 ; /* This space intentionally left blank. */
327 /* Otherwise, we can't let the client have this lease. */
329 #if defined (DEBUG_FIND_LEASE)
330 log_debug ("discarding %s - %s",
331 piaddr (lease
-> ip_addr
),
332 binding_state_print (lease
-> binding_state
));
334 lease_dereference (&lease
, MDL
);
339 /* If we didn't find a lease, try to allocate one... */
341 if (!allocate_lease (&lease
, packet
,
342 packet
-> shared_network
-> pools
,
345 log_error ("%s: peer holds all free leases",
348 log_error ("%s: network %s: no free leases",
350 packet
-> shared_network
-> name
);
355 #if defined (FAILOVER_PROTOCOL)
356 if (lease
&& lease
-> pool
&& lease
-> pool
-> failover_peer
) {
357 peer
= lease
-> pool
-> failover_peer
;
358 if (peer
-> service_state
== not_responding
||
359 peer
-> service_state
== service_startup
) {
360 log_info ("%s: not responding%s",
361 msgbuf
, peer
-> nrr
);
365 peer
= (dhcp_failover_state_t
*)0;
367 /* Do load balancing if configured. */
368 if (peer
&& (peer
-> service_state
== cooperating
) &&
369 !load_balance_mine (packet
, peer
)) {
370 if (peer_has_leases
) {
371 log_debug ("%s: load balance to peer %s",
372 msgbuf
, peer
-> name
);
375 log_debug ("%s: cancel load balance to peer %s - %s",
376 msgbuf
, peer
-> name
, "no free leases");
381 /* If it's an expired lease, get rid of any bindings. */
382 if (lease
-> ends
< cur_time
&& lease
-> scope
)
383 binding_scope_dereference (&lease
-> scope
, MDL
);
385 /* Set the lease to really expire in 2 minutes, unless it has
386 not yet expired, in which case leave its expiry time alone. */
387 when
= cur_time
+ 120;
388 if (when
< lease
-> ends
)
389 when
= lease
-> ends
;
391 ack_lease (packet
, lease
, DHCPOFFER
, when
, msgbuf
, ms_nulltp
,
392 (struct host_decl
*)0);
395 lease_dereference (&lease
, MDL
);
398 void dhcprequest (packet
, ms_nulltp
, ip_lease
)
399 struct packet
*packet
;
401 struct lease
*ip_lease
;
406 struct subnet
*subnet
;
408 struct option_cache
*oc
;
409 struct data_string data
;
410 char msgbuf
[1024]; /* XXX */
413 #if defined (FAILOVER_PROTOCOL)
414 dhcp_failover_state_t
*peer
;
416 int have_requested_addr
= 0;
418 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
419 DHO_DHCP_REQUESTED_ADDRESS
);
420 memset (&data
, 0, sizeof data
);
422 evaluate_option_cache (&data
, packet
, (struct lease
*)0,
423 (struct client_state
*)0,
424 packet
-> options
, (struct option_state
*)0,
425 &global_scope
, oc
, MDL
)) {
427 memcpy (cip
.iabuf
, data
.data
, 4);
428 data_string_forget (&data
, MDL
);
429 have_requested_addr
= 1;
431 oc
= (struct option_cache
*)0;
433 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
.s_addr
, 4);
436 /* Find the lease that matches the address requested by the
439 subnet
= (struct subnet
*)0;
440 lease
= (struct lease
*)0;
441 if (find_subnet (&subnet
, cip
, MDL
))
442 find_lease (&lease
, packet
,
443 subnet
-> shared_network
, &ours
, 0, ip_lease
, MDL
);
445 if (lease
&& lease
-> client_hostname
) {
446 if ((strlen (lease
-> client_hostname
) <= 64) &&
447 db_printable((unsigned char *)lease
->client_hostname
))
448 s
= lease
-> client_hostname
;
450 s
= "Hostname Unsuitable for Printing";
454 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
455 DHO_DHCP_SERVER_IDENTIFIER
);
456 memset (&data
, 0, sizeof data
);
458 evaluate_option_cache (&data
, packet
, (struct lease
*)0,
459 (struct client_state
*)0,
460 packet
-> options
, (struct option_state
*)0,
461 &global_scope
, oc
, MDL
)) {
463 memcpy (sip
.iabuf
, data
.data
, 4);
464 data_string_forget (&data
, MDL
);
465 /* piaddr() should not return more than a 15 byte string.
468 sprintf (smbuf
, " (%s)", piaddr (sip
));
474 /* %Audit% This is log output. %2004.06.17,Safe%
475 * If we truncate we hope the user can get a hint from the log.
477 snprintf (msgbuf
, sizeof msgbuf
,
478 "DHCPREQUEST for %s%s from %s %s%s%svia %s",
480 (packet
-> raw
-> htype
481 ? print_hw_addr (packet
-> raw
-> htype
,
482 packet
-> raw
-> hlen
,
483 packet
-> raw
-> chaddr
)
485 ? print_hex_1(lease
->uid_len
, lease
->uid
, 60)
486 : "<no identifier>")),
487 s
? "(" : "", s
? s
: "", s
? ") " : "",
488 packet
-> raw
-> giaddr
.s_addr
489 ? inet_ntoa (packet
-> raw
-> giaddr
)
490 : packet
-> interface
-> name
);
492 #if defined (FAILOVER_PROTOCOL)
493 if (lease
&& lease
-> pool
&& lease
-> pool
-> failover_peer
) {
494 peer
= lease
-> pool
-> failover_peer
;
495 if (peer
-> service_state
== not_responding
||
496 peer
-> service_state
== service_startup
) {
497 log_info ("%s: not responding%s",
498 msgbuf
, peer
-> nrr
);
502 /* "load balance to peer" - is not done at all for request.
504 * If it's RENEWING, we are the only server to hear it, so
505 * we have to serve it. If it's REBINDING, it's out of
506 * communication with the other server, so there's no point
507 * in waiting to serve it. However, if the lease we're
508 * offering is not a free lease, then we may be the only
509 * server that can offer it, so we can't load balance if
510 * the lease isn't in the free or backup state. If it is
511 * in the free or backup state, then that state is what
512 * mandates one server or the other should perform the
513 * allocation, not the LBA...we know the peer cannot
514 * allocate a request for an address in our free state.
516 * So our only compass is lease_mine_to_reallocate(). This
517 * effects both load balancing, and a sanity-check that we
518 * are not going to try to allocate a lease that isn't ours.
520 if ((lease
-> binding_state
== FTS_FREE
||
521 lease
-> binding_state
== FTS_BACKUP
) &&
522 !lease_mine_to_reallocate (lease
)) {
523 log_debug ("%s: lease owned by peer", msgbuf
);
528 * If the lease is in a transitional state, we can't
529 * renew it unless we can rewind it to a non-transitional
530 * state (active, free, or backup). lease_mine_to_reallocate()
531 * checks for free/backup, so we only need to check for active.
533 if ((lease
->binding_state
== FTS_RELEASED
||
534 lease
->binding_state
== FTS_EXPIRED
) &&
535 lease
->rewind_binding_state
!= FTS_ACTIVE
&&
536 !lease_mine_to_reallocate(lease
)) {
537 log_debug("%s: lease in transition state %s", msgbuf
,
538 (lease
->binding_state
== FTS_RELEASED
)
539 ? "released" : "expired");
543 /* It's actually very unlikely that we'll ever get here,
544 but if we do, tell the client to stop using the lease,
545 because the administrator reset it. */
546 if (lease
-> binding_state
== FTS_RESET
&&
547 !lease_mine_to_reallocate (lease
)) {
548 log_debug ("%s: lease reset by administrator", msgbuf
);
549 nak_lease (packet
, &cip
, lease
->subnet
->group
);
553 #if defined(SERVER_ID_CHECK)
554 /* Do a quick check on the server source address to see if
555 it is ours. sip is the incoming servrer id. To avoid
556 problems with confused clients we do some sanity checks
557 to verify sip's length and that it isn't all zeros.
558 We then get the server id we would likely use for this
559 packet and compare them. If they don't match it we assume
560 we didn't send the offer and so we don't process the request.
563 if ((sip
.len
== 4) &&
564 (memcmp(sip
.iabuf
, "\0\0\0\0", sip
.len
) != 0)) {
566 struct option_state
*eval_options
= NULL
;
568 eval_network_statements(&eval_options
, packet
, NULL
);
569 get_server_source_address(&from
, eval_options
, NULL
,
571 option_state_dereference (&eval_options
, MDL
);
572 if (memcmp(sip
.iabuf
, &from
, sip
.len
) != 0) {
573 log_debug("%s: not our server id", msgbuf
);
577 #endif /* if defined(SERVER_ID_CHECK) */
579 /* At this point it's possible that we will get a broadcast
580 DHCPREQUEST for a lease that we didn't offer, because
581 both we and the peer are in a position to offer it.
582 In that case, we probably shouldn't answer. In order
583 to not answer, we would have to compare the server
584 identifier sent by the client with the list of possible
585 server identifiers we can send, and if the client's
586 identifier isn't on the list, drop the DHCPREQUEST.
587 We aren't currently doing that for two reasons - first,
588 it's not clear that all clients do the right thing
589 with respect to sending the client identifier, which
590 could mean that we might simply not respond to a client
591 that is depending on us to respond. Secondly, we allow
592 the user to specify the server identifier to send, and
593 we don't enforce that the server identifier should be
594 one of our IP addresses. This is probably not a big
595 deal, but it's theoretically an issue.
597 The reason we care about this is that if both servers
598 send a DHCPACK to the DHCPREQUEST, they are then going
599 to send dueling BNDUPD messages, which could cause
600 trouble. I think it causes no harm, but it seems
603 peer
= (dhcp_failover_state_t
*)0;
606 /* If a client on a given network REQUESTs a lease on an
607 address on a different network, NAK it. If the Requested
608 Address option was used, the protocol says that it must
609 have been broadcast, so we can trust the source network
612 If ciaddr was specified and Requested Address was not, then
613 we really only know for sure what network a packet came from
614 if it came through a BOOTP gateway - if it came through an
615 IP router, we'll just have to assume that it's cool.
617 If we don't think we know where the packet came from, it
618 came through a gateway from an unknown network, so it's not
619 from a RENEWING client. If we recognize the network it
620 *thinks* it's on, we can NAK it even though we don't
621 recognize the network it's *actually* on; otherwise we just
624 We don't currently try to take advantage of access to the
625 raw packet, because it's not available on all platforms.
626 So a packet that was unicast to us through a router from a
627 RENEWING client is going to look exactly like a packet that
628 was broadcast to us from an INIT-REBOOT client.
630 Since we can't tell the difference between these two kinds
631 of packets, if the packet appears to have come in off the
632 local wire, we have to treat it as if it's a RENEWING
633 client. This means that we can't NAK a RENEWING client on
634 the local wire that has a bogus address. The good news is
635 that we won't ACK it either, so it should revert to INIT
636 state and send us a DHCPDISCOVER, which we *can* work with.
638 Because we can't detect that a RENEWING client is on the
639 wrong wire, it's going to sit there trying to renew until
640 it gets to the REBIND state, when we *can* NAK it because
641 the packet will get to us through a BOOTP gateway. We
642 shouldn't actually see DHCPREQUEST packets from RENEWING
643 clients on the wrong wire anyway, since their idea of their
644 local router will be wrong. In any case, the protocol
645 doesn't really allow us to NAK a DHCPREQUEST from a
646 RENEWING client, so we can punt on this issue. */
648 if (!packet
-> shared_network
||
649 (packet
-> raw
-> ciaddr
.s_addr
&&
650 packet
-> raw
-> giaddr
.s_addr
) ||
651 (have_requested_addr
&& !packet
-> raw
-> ciaddr
.s_addr
)) {
653 /* If we don't know where it came from but we do know
654 where it claims to have come from, it didn't come
656 if (!packet
-> shared_network
) {
657 if (subnet
&& subnet
-> group
-> authoritative
) {
658 log_info ("%s: wrong network.", msgbuf
);
659 nak_lease (packet
, &cip
, NULL
);
662 /* Otherwise, ignore it. */
663 log_info ("%s: ignored (%s).", msgbuf
,
665 ? "not authoritative" : "unknown subnet"));
669 /* If we do know where it came from and it asked for an
670 address that is not on that shared network, nak it. */
672 subnet_dereference (&subnet
, MDL
);
673 if (!find_grouped_subnet (&subnet
, packet
-> shared_network
,
675 if (packet
-> shared_network
-> group
-> authoritative
)
677 log_info ("%s: wrong network.", msgbuf
);
678 nak_lease (packet
, &cip
, NULL
);
681 log_info ("%s: ignored (not authoritative).", msgbuf
);
686 /* If the address the client asked for is ours, but it wasn't
687 available for the client, NAK it. */
688 if (!lease
&& ours
) {
689 log_info ("%s: lease %s unavailable.", msgbuf
, piaddr (cip
));
690 nak_lease (packet
, &cip
, (subnet
? subnet
->group
: NULL
));
694 /* Otherwise, send the lease to the client if we found one. */
696 ack_lease (packet
, lease
, DHCPACK
, 0, msgbuf
, ms_nulltp
,
697 (struct host_decl
*)0);
699 log_info ("%s: unknown lease %s.", msgbuf
, piaddr (cip
));
703 subnet_dereference (&subnet
, MDL
);
705 lease_dereference (&lease
, MDL
);
709 void dhcprelease (packet
, ms_nulltp
)
710 struct packet
*packet
;
713 struct lease
*lease
= (struct lease
*)0, *next
= (struct lease
*)0;
715 struct option_cache
*oc
;
716 struct data_string data
;
718 char msgbuf
[1024], cstr
[16]; /* XXX */
721 /* DHCPRELEASE must not specify address in requested-address
722 option, but old protocol specs weren't explicit about this,
724 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
725 DHO_DHCP_REQUESTED_ADDRESS
))) {
726 log_info ("DHCPRELEASE from %s specified requested-address.",
727 print_hw_addr (packet
-> raw
-> htype
,
728 packet
-> raw
-> hlen
,
729 packet
-> raw
-> chaddr
));
732 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
733 DHO_DHCP_CLIENT_IDENTIFIER
);
734 memset (&data
, 0, sizeof data
);
736 evaluate_option_cache (&data
, packet
, (struct lease
*)0,
737 (struct client_state
*)0,
738 packet
-> options
, (struct option_state
*)0,
739 &global_scope
, oc
, MDL
)) {
740 find_lease_by_uid (&lease
, data
.data
, data
.len
, MDL
);
741 data_string_forget (&data
, MDL
);
743 /* See if we can find a lease that matches the IP address
744 the client is claiming. */
747 lease_reference (&next
, lease
-> n_uid
, MDL
);
748 if (!memcmp (&packet
-> raw
-> ciaddr
,
749 lease
-> ip_addr
.iabuf
, 4)) {
752 lease_dereference (&lease
, MDL
);
754 lease_reference (&lease
, next
, MDL
);
755 lease_dereference (&next
, MDL
);
759 lease_dereference (&next
, MDL
);
762 /* The client is supposed to pass a valid client-identifier,
763 but the spec on this has changed historically, so try the
764 IP address in ciaddr if the client-identifier fails. */
767 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
, 4);
768 find_lease_by_ip_addr (&lease
, cip
, MDL
);
772 /* If the hardware address doesn't match, don't do the release. */
774 (lease
-> hardware_addr
.hlen
!= packet
-> raw
-> hlen
+ 1 ||
775 lease
-> hardware_addr
.hbuf
[0] != packet
-> raw
-> htype
||
776 memcmp (&lease
-> hardware_addr
.hbuf
[1],
777 packet
-> raw
-> chaddr
, packet
-> raw
-> hlen
)))
778 lease_dereference (&lease
, MDL
);
780 if (lease
&& lease
-> client_hostname
) {
781 if ((strlen (lease
-> client_hostname
) <= 64) &&
782 db_printable((unsigned char *)lease
->client_hostname
))
783 s
= lease
-> client_hostname
;
785 s
= "Hostname Unsuitable for Printing";
789 /* %Audit% Cannot exceed 16 bytes. %2004.06.17,Safe%
790 * We copy this out to stack because we actually want to log two
791 * inet_ntoa()'s in this message.
793 strncpy(cstr
, inet_ntoa (packet
-> raw
-> ciaddr
), 15);
796 /* %Audit% This is log output. %2004.06.17,Safe%
797 * If we truncate we hope the user can get a hint from the log.
799 snprintf (msgbuf
, sizeof msgbuf
,
800 "DHCPRELEASE of %s from %s %s%s%svia %s (%sfound)",
802 (packet
-> raw
-> htype
803 ? print_hw_addr (packet
-> raw
-> htype
,
804 packet
-> raw
-> hlen
,
805 packet
-> raw
-> chaddr
)
807 ? print_hex_1(lease
->uid_len
, lease
->uid
, 60)
808 : "<no identifier>")),
809 s
? "(" : "", s
? s
: "", s
? ") " : "",
810 packet
-> raw
-> giaddr
.s_addr
811 ? inet_ntoa (packet
-> raw
-> giaddr
)
812 : packet
-> interface
-> name
,
813 lease
? "" : "not ");
815 #if defined (FAILOVER_PROTOCOL)
816 if (lease
&& lease
-> pool
&& lease
-> pool
-> failover_peer
) {
817 dhcp_failover_state_t
*peer
= lease
-> pool
-> failover_peer
;
818 if (peer
-> service_state
== not_responding
||
819 peer
-> service_state
== service_startup
) {
820 log_info ("%s: ignored%s",
821 peer
-> name
, peer
-> nrr
);
825 /* DHCPRELEASE messages are unicast, so if the client
826 sent the DHCPRELEASE to us, it's not going to send it
827 to the peer. Not sure why this would happen, and
828 if it does happen I think we still have to change the
829 lease state, so that's what we're doing.
830 XXX See what it says in the draft about this. */
834 /* If we found a lease, release it. */
835 if (lease
&& lease
-> ends
> cur_time
) {
836 release_lease (lease
, packet
);
838 log_info ("%s", msgbuf
);
839 #if defined(FAILOVER_PROTOCOL)
843 lease_dereference (&lease
, MDL
);
846 void dhcpdecline (packet
, ms_nulltp
)
847 struct packet
*packet
;
850 struct lease
*lease
= (struct lease
*)0;
851 struct option_state
*options
= (struct option_state
*)0;
856 char msgbuf
[1024]; /* XXX */
858 struct option_cache
*oc
;
859 struct data_string data
;
861 /* DHCPDECLINE must specify address. */
862 if (!(oc
= lookup_option (&dhcp_universe
, packet
-> options
,
863 DHO_DHCP_REQUESTED_ADDRESS
)))
865 memset (&data
, 0, sizeof data
);
866 if (!evaluate_option_cache (&data
, packet
, (struct lease
*)0,
867 (struct client_state
*)0,
869 (struct option_state
*)0,
870 &global_scope
, oc
, MDL
))
874 memcpy (cip
.iabuf
, data
.data
, 4);
875 data_string_forget (&data
, MDL
);
876 find_lease_by_ip_addr (&lease
, cip
, MDL
);
878 if (lease
&& lease
-> client_hostname
) {
879 if ((strlen (lease
-> client_hostname
) <= 64) &&
880 db_printable((unsigned char *)lease
->client_hostname
))
881 s
= lease
-> client_hostname
;
883 s
= "Hostname Unsuitable for Printing";
887 /* %Audit% This is log output. %2004.06.17,Safe%
888 * If we truncate we hope the user can get a hint from the log.
890 snprintf (msgbuf
, sizeof msgbuf
,
891 "DHCPDECLINE of %s from %s %s%s%svia %s",
893 (packet
-> raw
-> htype
894 ? print_hw_addr (packet
-> raw
-> htype
,
895 packet
-> raw
-> hlen
,
896 packet
-> raw
-> chaddr
)
898 ? print_hex_1(lease
->uid_len
, lease
->uid
, 60)
899 : "<no identifier>")),
900 s
? "(" : "", s
? s
: "", s
? ") " : "",
901 packet
-> raw
-> giaddr
.s_addr
902 ? inet_ntoa (packet
-> raw
-> giaddr
)
903 : packet
-> interface
-> name
);
905 option_state_allocate (&options
, MDL
);
907 /* Execute statements in scope starting with the subnet scope. */
909 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
910 packet
->options
, options
,
912 lease
->subnet
->group
,
915 /* Execute statements in the class scopes. */
916 for (i
= packet
-> class_count
; i
> 0; i
--) {
917 execute_statements_in_scope
918 (NULL
, packet
, NULL
, NULL
, packet
->options
, options
,
919 &global_scope
, packet
->classes
[i
- 1]->group
,
920 lease
? lease
->subnet
->group
: NULL
, NULL
);
923 /* Drop the request if dhcpdeclines are being ignored. */
924 oc
= lookup_option (&server_universe
, options
, SV_DECLINES
);
926 evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
927 (struct client_state
*)0,
928 packet
-> options
, options
,
929 &lease
-> scope
, oc
, MDL
)) {
930 /* If we found a lease, mark it as unusable and complain. */
932 #if defined (FAILOVER_PROTOCOL)
933 if (lease
-> pool
&& lease
-> pool
-> failover_peer
) {
934 dhcp_failover_state_t
*peer
=
935 lease
-> pool
-> failover_peer
;
936 if (peer
-> service_state
== not_responding
||
937 peer
-> service_state
== service_startup
) {
939 log_info ("%s: ignored%s",
940 peer
-> name
, peer
-> nrr
);
944 /* DHCPDECLINE messages are broadcast, so we can safely
945 ignore the DHCPDECLINE if the peer has the lease.
946 XXX Of course, at this point that information has been
951 abandon_lease (lease
, "declined.");
952 status
= "abandoned";
954 status
= "not found";
960 log_info ("%s: %s", msgbuf
, status
);
962 #if defined(FAILOVER_PROTOCOL)
966 option_state_dereference (&options
, MDL
);
968 lease_dereference (&lease
, MDL
);
971 void dhcpinform (packet
, ms_nulltp
)
972 struct packet
*packet
;
975 char msgbuf
[1024], *addr_type
;
976 struct data_string d1
, prl
, fixed_addr
;
977 struct option_cache
*oc
;
978 struct option_state
*options
= NULL
;
979 struct dhcp_packet raw
;
980 struct packet outgoing
;
981 unsigned char dhcpack
= DHCPACK
;
982 struct subnet
*subnet
= NULL
;
983 struct iaddr cip
, gip
, sip
;
986 struct sockaddr_in to
;
988 isc_boolean_t zeroed_ciaddr
;
989 struct interface_info
*interface
;
990 int result
, h_m_client_ip
= 0;
991 struct host_decl
*host
= NULL
, *hp
= NULL
, *h
;
992 #if defined (DEBUG_INFORM_HOST)
993 int h_w_fixed_addr
= 0;
996 /* The client should set ciaddr to its IP address, but apparently
997 it's common for clients not to do this, so we'll use their IP
998 source address if they didn't set ciaddr. */
999 if (!packet
->raw
->ciaddr
.s_addr
) {
1000 zeroed_ciaddr
= ISC_TRUE
;
1002 memcpy(cip
.iabuf
, &packet
->client_addr
.iabuf
, 4);
1003 addr_type
= "source";
1005 zeroed_ciaddr
= ISC_FALSE
;
1007 memcpy(cip
.iabuf
, &packet
->raw
->ciaddr
, 4);
1008 addr_type
= "client";
1011 memcpy(sip
.iabuf
, cip
.iabuf
, 4);
1013 if (packet
->raw
->giaddr
.s_addr
) {
1015 memcpy(gip
.iabuf
, &packet
->raw
->giaddr
, 4);
1016 if (zeroed_ciaddr
== ISC_TRUE
) {
1017 addr_type
= "relay";
1018 memcpy(sip
.iabuf
, gip
.iabuf
, 4);
1023 /* %Audit% This is log output. %2004.06.17,Safe%
1024 * If we truncate we hope the user can get a hint from the log.
1026 snprintf(msgbuf
, sizeof(msgbuf
), "DHCPINFORM from %s via %s",
1028 packet
->raw
->giaddr
.s_addr
?
1029 inet_ntoa(packet
->raw
->giaddr
) :
1030 packet
->interface
->name
);
1032 /* If the IP source address is zero, don't respond. */
1033 if (!memcmp(cip
.iabuf
, "\0\0\0", 4)) {
1034 log_info("%s: ignored (null source address).", msgbuf
);
1038 /* Find the subnet that the client is on.
1039 * CC: Do the link selection / subnet selection
1042 option_state_allocate(&options
, MDL
);
1044 if ((oc
= lookup_option(&agent_universe
, packet
->options
,
1045 RAI_LINK_SELECT
)) == NULL
)
1046 oc
= lookup_option(&dhcp_universe
, packet
->options
,
1047 DHO_SUBNET_SELECTION
);
1049 memset(&d1
, 0, sizeof d1
);
1050 if (oc
&& evaluate_option_cache(&d1
, packet
, NULL
, NULL
,
1051 packet
->options
, NULL
,
1052 &global_scope
, oc
, MDL
)) {
1053 struct option_cache
*noc
= NULL
;
1056 log_info("%s: ignored (invalid subnet selection option).", msgbuf
);
1057 option_state_dereference(&options
, MDL
);
1061 memcpy(sip
.iabuf
, d1
.data
, 4);
1062 data_string_forget(&d1
, MDL
);
1064 /* Make a copy of the data. */
1065 if (option_cache_allocate(&noc
, MDL
)) {
1067 data_string_copy(&noc
->data
, &oc
->data
, MDL
);
1069 expression_reference(&noc
->expression
,
1070 oc
->expression
, MDL
);
1072 option_reference(&(noc
->option
), oc
->option
,
1075 save_option(&dhcp_universe
, options
, noc
);
1076 option_cache_dereference(&noc
, MDL
);
1078 if ((zeroed_ciaddr
== ISC_TRUE
) && (gip
.len
!= 0))
1079 addr_type
= "relay link select";
1081 addr_type
= "selected";
1084 find_subnet(&subnet
, sip
, MDL
);
1086 if (subnet
== NULL
) {
1087 log_info("%s: unknown subnet for %s address %s",
1088 msgbuf
, addr_type
, piaddr(sip
));
1089 option_state_dereference(&options
, MDL
);
1093 /* We don't respond to DHCPINFORM packets if we're not authoritative.
1094 It would be nice if a per-host value could override this, but
1095 there's overhead involved in checking this, so let's see how people
1097 if (!subnet
->group
->authoritative
) {
1099 log_info("%s: not authoritative for subnet %s",
1100 msgbuf
, piaddr (subnet
-> net
));
1102 log_info("If this DHCP server is authoritative for%s",
1104 log_info("please write an `authoritative;' directi%s",
1105 "ve either in the");
1106 log_info("subnet declaration or in some scope that%s",
1108 log_info("subnet declaration - for example, write %s",
1110 log_info("of the dhcpd.conf file.");
1114 subnet_dereference(&subnet
, MDL
);
1115 option_state_dereference(&options
, MDL
);
1119 memset(&outgoing
, 0, sizeof outgoing
);
1120 memset(&raw
, 0, sizeof raw
);
1121 outgoing
.raw
= &raw
;
1123 maybe_return_agent_options(packet
, options
);
1125 /* Execute statements in scope starting with the subnet scope. */
1126 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
1127 packet
->options
, options
,
1128 &global_scope
, subnet
->group
,
1131 /* Execute statements in the class scopes. */
1132 for (i
= packet
->class_count
; i
> 0; i
--) {
1133 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
1134 packet
->options
, options
,
1136 packet
->classes
[i
- 1]->group
,
1142 * Process host declarations during DHCPINFORM,
1143 * Try to find a matching host declaration by cli ID or HW addr.
1145 * Look through the host decls for one that matches the
1146 * client identifer or the hardware address. The preference
1148 * client id with matching ip address
1149 * hardware address with matching ip address
1150 * client id without a ip fixed address
1151 * hardware address without a fixed ip address
1152 * If found, set host to use its option definitions.
1154 oc
= lookup_option(&dhcp_universe
, packet
->options
,
1155 DHO_DHCP_CLIENT_IDENTIFIER
);
1156 memset(&d1
, 0, sizeof(d1
));
1158 evaluate_option_cache(&d1
, packet
, NULL
, NULL
,
1159 packet
->options
, NULL
,
1160 &global_scope
, oc
, MDL
)) {
1161 find_hosts_by_uid(&hp
, d1
.data
, d1
.len
, MDL
);
1162 data_string_forget(&d1
, MDL
);
1164 #if defined (DEBUG_INFORM_HOST)
1166 log_debug ("dhcpinform: found host by ID "
1167 "-- checking fixed-address match");
1169 /* check if we have one with fixed-address
1170 * matching the client ip first */
1171 for (h
= hp
; !h_m_client_ip
&& h
; h
= h
->n_ipaddr
) {
1175 memset(&fixed_addr
, 0, sizeof(fixed_addr
));
1176 if (!evaluate_option_cache (&fixed_addr
, NULL
,
1177 NULL
, NULL
, NULL
, NULL
,
1179 h
->fixed_addr
, MDL
))
1182 #if defined (DEBUG_INFORM_HOST)
1186 (i
+ cip
.len
) <= fixed_addr
.len
;
1188 if (memcmp(fixed_addr
.data
+ i
,
1189 cip
.iabuf
, cip
.len
) == 0) {
1190 #if defined (DEBUG_INFORM_HOST)
1191 log_debug ("dhcpinform: found "
1192 "host with matching "
1193 "fixed-address by ID");
1195 host_reference(&host
, h
, MDL
);
1200 data_string_forget(&fixed_addr
, MDL
);
1203 /* fallback to a host without fixed-address */
1204 for (h
= hp
; !host
&& h
; h
= h
->n_ipaddr
) {
1208 #if defined (DEBUG_INFORM_HOST)
1209 log_debug ("dhcpinform: found host "
1210 "without fixed-address by ID");
1212 host_reference(&host
, h
, MDL
);
1216 host_dereference (&hp
, MDL
);
1218 if (!host
|| !h_m_client_ip
) {
1219 find_hosts_by_haddr(&hp
, packet
->raw
->htype
,
1220 packet
->raw
->chaddr
,
1221 packet
->raw
->hlen
, MDL
);
1223 #if defined (DEBUG_INFORM_HOST)
1225 log_debug ("dhcpinform: found host by HW "
1226 "-- checking fixed-address match");
1229 /* check if we have one with fixed-address
1230 * matching the client ip first */
1231 for (h
= hp
; !h_m_client_ip
&& h
; h
= h
->n_ipaddr
) {
1235 memset (&fixed_addr
, 0, sizeof(fixed_addr
));
1236 if (!evaluate_option_cache (&fixed_addr
, NULL
,
1237 NULL
, NULL
, NULL
, NULL
,
1239 h
->fixed_addr
, MDL
))
1242 #if defined (DEBUG_INFORM_HOST)
1246 (i
+ cip
.len
) <= fixed_addr
.len
;
1248 if (memcmp(fixed_addr
.data
+ i
,
1249 cip
.iabuf
, cip
.len
) == 0) {
1250 #if defined (DEBUG_INFORM_HOST)
1251 log_debug ("dhcpinform: found "
1252 "host with matching "
1253 "fixed-address by HW");
1256 * Hmm.. we've found one
1257 * without IP by ID and now
1258 * (better) one with IP by HW.
1261 host_dereference(&host
, MDL
);
1262 host_reference(&host
, h
, MDL
);
1267 data_string_forget(&fixed_addr
, MDL
);
1269 /* fallback to a host without fixed-address */
1270 for (h
= hp
; !host
&& h
; h
= h
->n_ipaddr
) {
1274 #if defined (DEBUG_INFORM_HOST)
1275 log_debug ("dhcpinform: found host without "
1276 "fixed-address by HW");
1278 host_reference (&host
, h
, MDL
);
1283 host_dereference (&hp
, MDL
);
1286 #if defined (DEBUG_INFORM_HOST)
1287 /* Hmm..: what when there is a host with a fixed-address,
1288 * that matches by hw or id, but the fixed-addresses
1289 * didn't match client ip?
1291 if (h_w_fixed_addr
&& !h_m_client_ip
) {
1292 log_info ("dhcpinform: matching host with "
1293 "fixed-address different than "
1294 "client IP detected?!");
1298 /* If we have a host_decl structure, run the options
1299 * associated with its group. Whether the host decl
1300 * struct is old or not. */
1302 #if defined (DEBUG_INFORM_HOST)
1303 log_info ("dhcpinform: applying host (group) options");
1305 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
1306 packet
->options
, options
,
1307 &global_scope
, host
->group
,
1309 host
->group
->next
: NULL
,
1311 host_dereference (&host
, MDL
);
1314 /* CC: end of host entry processing.... */
1316 /* Figure out the filename. */
1317 memset (&d1
, 0, sizeof d1
);
1318 oc
= lookup_option (&server_universe
, options
, SV_FILENAME
);
1320 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1321 (struct client_state
*)0,
1322 packet
-> options
, (struct option_state
*)0,
1323 &global_scope
, oc
, MDL
)) {
1325 if (i
>= sizeof(raw
.file
)) {
1326 log_info("file name longer than packet field "
1327 "truncated - field: %lu name: %d %.*s",
1328 (unsigned long)sizeof(raw
.file
), i
,
1330 i
= sizeof(raw
.file
);
1333 memcpy (raw
.file
, d1
.data
, i
);
1334 data_string_forget (&d1
, MDL
);
1337 /* Choose a server name as above. */
1338 oc
= lookup_option (&server_universe
, options
, SV_SERVER_NAME
);
1340 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1341 (struct client_state
*)0,
1342 packet
-> options
, (struct option_state
*)0,
1343 &global_scope
, oc
, MDL
)) {
1345 if (i
>= sizeof(raw
.sname
)) {
1346 log_info("server name longer than packet field "
1347 "truncated - field: %lu name: %d %.*s",
1348 (unsigned long)sizeof(raw
.sname
), i
,
1350 i
= sizeof(raw
.sname
);
1353 memcpy (raw
.sname
, d1
.data
, i
);
1354 data_string_forget (&d1
, MDL
);
1357 /* Set a flag if this client is a lame Microsoft client that NUL
1358 terminates string options and expects us to do likewise. */
1360 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
1362 if (!oc
->expression
)
1363 nulltp
= oc
->flags
& OPTION_HAD_NULLS
;
1366 /* Put in DHCP-specific options. */
1367 i
= DHO_DHCP_MESSAGE_TYPE
;
1368 oc
= (struct option_cache
*)0;
1369 if (option_cache_allocate (&oc
, MDL
)) {
1370 if (make_const_data (&oc
-> expression
,
1371 &dhcpack
, 1, 0, 0, MDL
)) {
1372 option_code_hash_lookup(&oc
->option
,
1373 dhcp_universe
.code_hash
,
1375 save_option (&dhcp_universe
, options
, oc
);
1377 option_cache_dereference (&oc
, MDL
);
1380 get_server_source_address(&from
, options
, options
, packet
);
1382 /* Use the subnet mask from the subnet declaration if no other
1383 mask has been provided. */
1384 i
= DHO_SUBNET_MASK
;
1385 if (subnet
&& !lookup_option (&dhcp_universe
, options
, i
)) {
1386 oc
= (struct option_cache
*)0;
1387 if (option_cache_allocate (&oc
, MDL
)) {
1388 if (make_const_data (&oc
-> expression
,
1389 subnet
-> netmask
.iabuf
,
1390 subnet
-> netmask
.len
,
1392 option_code_hash_lookup(&oc
->option
,
1393 dhcp_universe
.code_hash
,
1395 save_option (&dhcp_universe
, options
, oc
);
1397 option_cache_dereference (&oc
, MDL
);
1401 /* If a site option space has been specified, use that for
1402 site option codes. */
1403 i
= SV_SITE_OPTION_SPACE
;
1404 if ((oc
= lookup_option (&server_universe
, options
, i
)) &&
1405 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1406 (struct client_state
*)0,
1407 packet
-> options
, options
,
1408 &global_scope
, oc
, MDL
)) {
1409 struct universe
*u
= (struct universe
*)0;
1411 if (!universe_hash_lookup (&u
, universe_hash
,
1412 (const char *)d1
.data
, d1
.len
,
1414 log_error ("unknown option space %s.", d1
.data
);
1415 option_state_dereference (&options
, MDL
);
1417 subnet_dereference (&subnet
, MDL
);
1421 options
-> site_universe
= u
-> index
;
1422 options
->site_code_min
= find_min_site_code(u
);
1423 data_string_forget (&d1
, MDL
);
1425 options
-> site_universe
= dhcp_universe
.index
;
1426 options
-> site_code_min
= 0; /* Trust me, it works. */
1429 memset (&prl
, 0, sizeof prl
);
1431 /* Use the parameter list from the scope if there is one. */
1432 oc
= lookup_option (&dhcp_universe
, options
,
1433 DHO_DHCP_PARAMETER_REQUEST_LIST
);
1435 /* Otherwise, if the client has provided a list of options
1436 that it wishes returned, use it to prioritize. Otherwise,
1437 prioritize based on the default priority list. */
1440 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
1441 DHO_DHCP_PARAMETER_REQUEST_LIST
);
1444 evaluate_option_cache (&prl
, packet
, (struct lease
*)0,
1445 (struct client_state
*)0,
1446 packet
-> options
, options
,
1447 &global_scope
, oc
, MDL
);
1450 dump_packet (packet
);
1451 dump_raw ((unsigned char *)packet
-> raw
, packet
-> packet_length
);
1454 log_info ("%s", msgbuf
);
1456 /* Figure out the address of the boot file server. */
1458 lookup_option (&server_universe
, options
, SV_NEXT_SERVER
))) {
1459 if (evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1460 (struct client_state
*)0,
1461 packet
-> options
, options
,
1462 &global_scope
, oc
, MDL
)) {
1463 /* If there was more than one answer,
1465 if (d1
.len
>= 4 && d1
.data
)
1466 memcpy (&raw
.siaddr
, d1
.data
, 4);
1467 data_string_forget (&d1
, MDL
);
1472 * Remove any time options, per section 3.4 RFC 2131
1474 delete_option(&dhcp_universe
, options
, DHO_DHCP_LEASE_TIME
);
1475 delete_option(&dhcp_universe
, options
, DHO_DHCP_RENEWAL_TIME
);
1476 delete_option(&dhcp_universe
, options
, DHO_DHCP_REBINDING_TIME
);
1478 /* Set up the option buffer... */
1479 outgoing
.packet_length
=
1480 cons_options (packet
, outgoing
.raw
, (struct lease
*)0,
1481 (struct client_state
*)0,
1482 0, packet
-> options
, options
, &global_scope
,
1484 prl
.len
? &prl
: (struct data_string
*)0,
1486 option_state_dereference (&options
, MDL
);
1487 data_string_forget (&prl
, MDL
);
1489 /* Make sure that the packet is at least as big as a BOOTP packet. */
1490 if (outgoing
.packet_length
< BOOTP_MIN_LEN
)
1491 outgoing
.packet_length
= BOOTP_MIN_LEN
;
1493 raw
.giaddr
= packet
-> raw
-> giaddr
;
1494 raw
.ciaddr
= packet
-> raw
-> ciaddr
;
1495 memcpy (raw
.chaddr
, packet
-> raw
-> chaddr
, sizeof raw
.chaddr
);
1496 raw
.hlen
= packet
-> raw
-> hlen
;
1497 raw
.htype
= packet
-> raw
-> htype
;
1499 raw
.xid
= packet
-> raw
-> xid
;
1500 raw
.secs
= packet
-> raw
-> secs
;
1501 raw
.flags
= packet
-> raw
-> flags
;
1502 raw
.hops
= packet
-> raw
-> hops
;
1506 dump_packet (&outgoing
);
1507 dump_raw ((unsigned char *)&raw
, outgoing
.packet_length
);
1510 /* Set up the common stuff... */
1511 to
.sin_family
= AF_INET
;
1513 to
.sin_len
= sizeof to
;
1515 memset (to
.sin_zero
, 0, sizeof to
.sin_zero
);
1517 /* RFC2131 states the server SHOULD unciast to ciaddr.
1518 * There are two wrinkles - relays, and when ciaddr is zero.
1519 * There's actually no mention of relays at all in rfc2131 in
1520 * regard to DHCPINFORM, except to say we might get packets from
1521 * clients via them. Note: relays unicast to clients to the
1522 * "yiaddr" address, which servers are forbidden to set when
1523 * answering an inform.
1525 * The solution: If ciaddr is zero, and giaddr is set, go via the
1526 * relay with the broadcast flag set to help the relay (with no
1527 * yiaddr and very likely no chaddr, it will have no idea where to
1530 * If the ciaddr is zero and giaddr is not set, go via the source
1531 * IP address (but you are permitted to barf on their shoes).
1533 * If ciaddr is not zero, send the packet there always.
1535 if (!raw
.ciaddr
.s_addr
&& gip
.len
) {
1536 memcpy(&to
.sin_addr
, gip
.iabuf
, 4);
1537 to
.sin_port
= local_port
;
1538 raw
.flags
|= htons(BOOTP_BROADCAST
);
1541 memcpy(&to
.sin_addr
, cip
.iabuf
, 4);
1542 to
.sin_port
= remote_port
;
1545 /* Report what we're sending. */
1546 snprintf(msgbuf
, sizeof msgbuf
, "DHCPACK to %s (%s) via", piaddr(cip
),
1547 (packet
->raw
->htype
&& packet
->raw
->hlen
) ?
1548 print_hw_addr(packet
->raw
->htype
, packet
->raw
->hlen
,
1549 packet
->raw
->chaddr
) :
1550 "<no client hardware address>");
1551 log_info("%s %s", msgbuf
, gip
.len
? piaddr(gip
) :
1552 packet
->interface
->name
);
1555 interface
= (fallback_interface
? fallback_interface
1556 : packet
-> interface
);
1557 result
= send_packet(interface
, &outgoing
, &raw
,
1558 outgoing
.packet_length
, from
, &to
, NULL
);
1560 log_error ("%s:%d: Failed to send %d byte long packet over %s "
1561 "interface.", MDL
, outgoing
.packet_length
,
1567 subnet_dereference (&subnet
, MDL
);
1571 * \brief Constructs and sends a DHCP Nak
1573 * In order to populate options such as dhcp-server-id and
1574 * dhcp-client-identifier, the function creates a temporary option cache
1575 * and evaluates options based on the packet's shared-network or the
1576 * network_group in its absence, as well as the packet->clasess (if any).
1578 * \param packet inbound packet received from the client
1579 * \param cip address requested by the client
1580 * \param network_group optional scope for use in setting up options
1582 void nak_lease (packet
, cip
, network_group
)
1583 struct packet
*packet
;
1585 struct group
*network_group
; /* scope to use for options */
1587 struct sockaddr_in to
;
1588 struct in_addr from
;
1590 struct dhcp_packet raw
;
1591 unsigned char nak
= DHCPNAK
;
1592 struct packet outgoing
;
1594 struct option_state
*options
= (struct option_state
*)0;
1595 struct option_cache
*oc
= (struct option_cache
*)0;
1596 struct option_state
*eval_options
= NULL
;
1598 option_state_allocate (&options
, MDL
);
1599 memset (&outgoing
, 0, sizeof outgoing
);
1600 memset (&raw
, 0, sizeof raw
);
1601 outgoing
.raw
= &raw
;
1603 /* Set DHCP_MESSAGE_TYPE to DHCPNAK */
1604 if (!option_cache_allocate (&oc
, MDL
)) {
1605 log_error ("No memory for DHCPNAK message type.");
1606 option_state_dereference (&options
, MDL
);
1609 if (!make_const_data (&oc
-> expression
, &nak
, sizeof nak
,
1611 log_error ("No memory for expr_const expression.");
1612 option_cache_dereference (&oc
, MDL
);
1613 option_state_dereference (&options
, MDL
);
1616 i
= DHO_DHCP_MESSAGE_TYPE
;
1617 option_code_hash_lookup(&oc
->option
, dhcp_universe
.code_hash
,
1619 save_option (&dhcp_universe
, options
, oc
);
1620 option_cache_dereference (&oc
, MDL
);
1622 /* Set DHCP_MESSAGE to whatever the message is */
1623 if (!option_cache_allocate (&oc
, MDL
)) {
1624 log_error ("No memory for DHCPNAK message type.");
1625 option_state_dereference (&options
, MDL
);
1628 if (!make_const_data (&oc
-> expression
,
1629 (unsigned char *)dhcp_message
,
1630 strlen (dhcp_message
), 1, 0, MDL
)) {
1631 log_error ("No memory for expr_const expression.");
1632 option_cache_dereference (&oc
, MDL
);
1633 option_state_dereference (&options
, MDL
);
1636 i
= DHO_DHCP_MESSAGE
;
1637 option_code_hash_lookup(&oc
->option
, dhcp_universe
.code_hash
,
1639 save_option (&dhcp_universe
, options
, oc
);
1640 option_cache_dereference (&oc
, MDL
);
1642 /* Setup the options at the global and subnet scopes. These
1643 * may be used to locate sever id option if enabled as well
1644 * for echo-client-id further on. (This allocates eval_options). */
1645 eval_network_statements(&eval_options
, packet
, network_group
);
1647 #if defined(SERVER_ID_FOR_NAK)
1648 /* Pass in the evaluated options so they can be searched for
1649 * server-id, otherwise source address comes from the interface
1651 get_server_source_address(&from
, eval_options
, options
, packet
);
1653 /* Get server source address from the interface address */
1654 get_server_source_address(&from
, NULL
, options
, packet
);
1655 #endif /* if defined(SERVER_ID_FOR_NAK) */
1657 /* If there were agent options in the incoming packet, return
1658 * them. We do not check giaddr to detect the presence of a
1659 * relay, as this excludes "l2" relay agents which have no
1662 if (packet
->options
->universe_count
> agent_universe
.index
&&
1663 packet
->options
->universes
[agent_universe
.index
]) {
1664 option_chain_head_reference
1665 ((struct option_chain_head
**)
1666 &(options
-> universes
[agent_universe
.index
]),
1667 (struct option_chain_head
*)
1668 packet
-> options
-> universes
[agent_universe
.index
],
1672 /* echo-client-id can specified at the class level so add class-scoped
1673 * options into eval_options. */
1674 for (i
= packet
->class_count
; i
> 0; i
--) {
1675 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
1676 packet
->options
, eval_options
,
1678 packet
->classes
[i
- 1]->group
,
1682 /* Echo client id if we received and it's enabled */
1683 echo_client_id(packet
, NULL
, eval_options
, options
);
1684 option_state_dereference (&eval_options
, MDL
);
1686 /* Do not use the client's requested parameter list. */
1687 delete_option (&dhcp_universe
, packet
-> options
,
1688 DHO_DHCP_PARAMETER_REQUEST_LIST
);
1690 /* Set up the option buffer... */
1691 outgoing
.packet_length
=
1692 cons_options (packet
, outgoing
.raw
, (struct lease
*)0,
1693 (struct client_state
*)0,
1694 0, packet
-> options
, options
, &global_scope
,
1695 0, 0, 0, (struct data_string
*)0, (char *)0);
1696 option_state_dereference (&options
, MDL
);
1698 /* memset (&raw.ciaddr, 0, sizeof raw.ciaddr);*/
1699 if (packet
->interface
->address_count
)
1700 raw
.siaddr
= packet
->interface
->addresses
[0];
1701 raw
.giaddr
= packet
-> raw
-> giaddr
;
1702 memcpy (raw
.chaddr
, packet
-> raw
-> chaddr
, sizeof raw
.chaddr
);
1703 raw
.hlen
= packet
-> raw
-> hlen
;
1704 raw
.htype
= packet
-> raw
-> htype
;
1706 raw
.xid
= packet
-> raw
-> xid
;
1707 raw
.secs
= packet
-> raw
-> secs
;
1708 raw
.flags
= packet
-> raw
-> flags
| htons (BOOTP_BROADCAST
);
1709 raw
.hops
= packet
-> raw
-> hops
;
1712 /* Report what we're sending... */
1713 log_info ("DHCPNAK on %s to %s via %s",
1715 print_hw_addr (packet
-> raw
-> htype
,
1716 packet
-> raw
-> hlen
,
1717 packet
-> raw
-> chaddr
),
1718 packet
-> raw
-> giaddr
.s_addr
1719 ? inet_ntoa (packet
-> raw
-> giaddr
)
1720 : packet
-> interface
-> name
);
1723 dump_packet (packet
);
1724 dump_raw ((unsigned char *)packet
-> raw
, packet
-> packet_length
);
1725 dump_packet (&outgoing
);
1726 dump_raw ((unsigned char *)&raw
, outgoing
.packet_length
);
1729 /* Set up the common stuff... */
1730 to
.sin_family
= AF_INET
;
1732 to
.sin_len
= sizeof to
;
1734 memset (to
.sin_zero
, 0, sizeof to
.sin_zero
);
1736 /* Make sure that the packet is at least as big as a BOOTP packet. */
1737 if (outgoing
.packet_length
< BOOTP_MIN_LEN
)
1738 outgoing
.packet_length
= BOOTP_MIN_LEN
;
1740 /* If this was gatewayed, send it back to the gateway.
1741 Otherwise, broadcast it on the local network. */
1742 if (raw
.giaddr
.s_addr
) {
1743 to
.sin_addr
= raw
.giaddr
;
1744 if (raw
.giaddr
.s_addr
!= htonl (INADDR_LOOPBACK
))
1745 to
.sin_port
= local_port
;
1747 to
.sin_port
= remote_port
; /* for testing. */
1749 if (fallback_interface
) {
1750 result
= send_packet(fallback_interface
, packet
, &raw
,
1751 outgoing
.packet_length
, from
, &to
,
1754 log_error ("%s:%d: Failed to send %d byte long "
1755 "packet over %s interface.", MDL
,
1756 outgoing
.packet_length
,
1757 fallback_interface
->name
);
1763 to
.sin_addr
= limited_broadcast
;
1764 to
.sin_port
= remote_port
;
1768 result
= send_packet(packet
->interface
, packet
, &raw
,
1769 outgoing
.packet_length
, from
, &to
, NULL
);
1771 log_error ("%s:%d: Failed to send %d byte long packet over %s "
1772 "interface.", MDL
, outgoing
.packet_length
,
1773 packet
->interface
->name
);
1779 * \brief Adds a dhcp-client-id option to a set of options
1780 * Given a set of input options, it searches for echo-client-id. If it is
1781 * defined and enabled, the given packet is searched for dhcp-client-id. If
1782 * the option is found it is replicated into the given set of output options.
1783 * This allows us to provide compliance with RFC 6842. It is called when we ack
1784 * or nak a lease. In the latter case we may or may not have created the
1785 * requisite scope to lookup echo-client-id.
1787 * Note the flag packet.sv_echo_client_id is set to reflect the configuration
1788 * option. This bypases inaccessiblity of server_universe in cons_options()
1789 * which must amend the PRL (when not empty) if echoing is enabled.
1791 * \param packet inbound packet received from the client
1792 * \param lease lease associated with this client (if one)
1793 * \param in_options options in which to search for echo-client-id
1794 * \param out_options options to which to save the client-id
1796 void echo_client_id(packet
, lease
, in_options
, out_options
)
1797 struct packet
*packet
;
1798 struct lease
*lease
;
1799 struct option_state
*in_options
;
1800 struct option_state
*out_options
;
1802 struct option_cache
*oc
;
1805 /* Check if echo-client-id is enabled */
1806 oc
= lookup_option(&server_universe
, in_options
, SV_ECHO_CLIENT_ID
);
1807 if (oc
&& evaluate_boolean_option_cache(&ignorep
, packet
, lease
,
1808 NULL
, packet
->options
,
1810 (lease
? &lease
->scope
: NULL
),
1812 struct data_string client_id
;
1813 unsigned int opcode
= DHO_DHCP_CLIENT_IDENTIFIER
;
1815 /* Save knowledge that echo is enabled to the packet */
1816 packet
->sv_echo_client_id
= ISC_TRUE
;
1818 /* Now see if inbound packet contains client-id */
1819 oc
= lookup_option(&dhcp_universe
, packet
->options
, opcode
);
1820 memset(&client_id
, 0, sizeof client_id
);
1821 if (oc
&& evaluate_option_cache(&client_id
,
1823 packet
->options
, NULL
,
1824 (lease
? &lease
->scope
: NULL
),
1826 /* Packet contained client-id, add it to out_options. */
1828 if (option_cache_allocate(&oc
, MDL
)) {
1829 if (make_const_data(&oc
->expression
,
1833 option_code_hash_lookup(&oc
->option
,
1838 save_option(&dhcp_universe
,
1841 option_cache_dereference(&oc
, MDL
);
1847 void check_pool_threshold (packet
, lease
, state
)
1848 struct packet
*packet
;
1849 struct lease
*lease
;
1850 struct lease_state
*state
;
1854 struct pool
*pool
= lease
->pool
;
1855 int used
, count
, high_threshold
, poolhigh
= 0, poollow
= 0;
1856 char *shared_name
= "no name";
1861 /* get a pointer to the name if we have one */
1862 if ((pool
->shared_network
!= NULL
) &&
1863 (pool
->shared_network
->name
!= NULL
)) {
1864 shared_name
= pool
->shared_network
->name
;
1867 count
= pool
->lease_count
;
1868 used
= count
- (pool
->free_leases
+ pool
->backup_leases
);
1870 /* The logged flag indicates if we have already crossed the high
1871 * threshold and emitted a log message. If it is set we check to
1872 * see if we have re-crossed the low threshold and need to reset
1873 * things. When we cross the high threshold we determine what
1874 * the low threshold is and save it into the low_threshold value.
1875 * When we cross that threshold we reset the logged flag and
1876 * the low_threshold to 0 which allows the high threshold message
1877 * to be emitted once again.
1878 * if we haven't recrossed the boundry we don't need to do anything.
1880 if (pool
->logged
!=0) {
1881 if (used
<= pool
->low_threshold
) {
1882 pool
->low_threshold
= 0;
1884 log_error("Pool threshold reset - shared subnet: %s; "
1885 "address: %s; low threshold %d/%d.",
1886 shared_name
, piaddr(lease
->ip_addr
),
1892 /* find the high threshold */
1893 if (get_option_int(&poolhigh
, &server_universe
, packet
, lease
, NULL
,
1894 packet
->options
, state
->options
, state
->options
,
1895 &lease
->scope
, SV_LOG_THRESHOLD_HIGH
, MDL
) == 0) {
1896 /* no threshold bail out */
1900 /* We do have a threshold for this pool, see if its valid */
1901 if ((poolhigh
<= 0) || (poolhigh
> 100)) {
1906 /* we have a valid value, have we exceeded it */
1907 high_threshold
= FIND_PERCENT(count
, poolhigh
);
1908 if (used
< high_threshold
) {
1909 /* nope, no more to do */
1913 /* we've exceeded it, output a message */
1914 log_error("Pool threshold exceeded - shared subnet: %s; "
1915 "address: %s; high threshold %d%% %d/%d.",
1916 shared_name
, piaddr(lease
->ip_addr
),
1917 poolhigh
, used
, count
);
1919 /* handle the low threshold now, if we don't
1920 * have a valid one we default to 0. */
1921 if ((get_option_int(&poollow
, &server_universe
, packet
, lease
, NULL
,
1922 packet
->options
, state
->options
, state
->options
,
1923 &lease
->scope
, SV_LOG_THRESHOLD_LOW
, MDL
) == 0) ||
1929 * If the low theshold is higher than the high threshold we continue to log
1930 * If it isn't then we set the flag saying we already logged and determine
1931 * what the reset threshold is.
1933 if (poollow
< poolhigh
) {
1935 pool
->low_threshold
= FIND_PERCENT(count
, poollow
);
1939 void ack_lease (packet
, lease
, offer
, when
, msg
, ms_nulltp
, hp
)
1940 struct packet
*packet
;
1941 struct lease
*lease
;
1946 struct host_decl
*hp
;
1949 struct lease_state
*state
;
1951 struct host_decl
*host
= (struct host_decl
*)0;
1953 TIME offered_lease_time
;
1954 struct data_string d1
;
1955 TIME min_lease_time
;
1956 TIME max_lease_time
;
1957 TIME default_lease_time
;
1958 struct option_cache
*oc
;
1959 isc_result_t result
;
1962 struct in_addr from
;
1963 TIME remaining_time
;
1965 #if defined(DELAYED_ACK)
1966 /* By default we don't do the enqueue */
1967 isc_boolean_t enqueue
= ISC_FALSE
;
1969 int use_old_lease
= 0;
1976 /* If we're already acking this lease, don't do it again. */
1980 /* Save original cltt for comparison later. */
1981 lease_cltt
= lease
->cltt
;
1983 /* If the lease carries a host record, remember it. */
1985 host_reference (&host
, hp
, MDL
);
1986 else if (lease
-> host
)
1987 host_reference (&host
, lease
-> host
, MDL
);
1989 /* Allocate a lease state structure... */
1990 state
= new_lease_state (MDL
);
1992 log_fatal ("unable to allocate lease state!");
1993 state
-> got_requested_address
= packet
-> got_requested_address
;
1994 shared_network_reference (&state
-> shared_network
,
1995 packet
-> interface
-> shared_network
, MDL
);
1997 /* See if we got a server identifier option. */
1998 if (lookup_option (&dhcp_universe
,
1999 packet
-> options
, DHO_DHCP_SERVER_IDENTIFIER
))
2000 state
-> got_server_identifier
= 1;
2002 maybe_return_agent_options(packet
, state
->options
);
2004 /* If we are offering a lease that is still currently valid, preserve
2005 the events. We need to do this because if the client does not
2006 REQUEST our offer, it will expire in 2 minutes, overriding the
2007 expire time in the currently in force lease. We want the expire
2008 events to be executed at that point. */
2009 if (lease
->ends
<= cur_time
&& offer
!= DHCPOFFER
) {
2010 /* Get rid of any old expiry or release statements - by
2011 executing the statements below, we will be inserting new
2012 ones if there are any to insert. */
2013 if (lease
->on_star
.on_expiry
)
2014 executable_statement_dereference
2015 (&lease
->on_star
.on_expiry
, MDL
);
2016 if (lease
->on_star
.on_commit
)
2017 executable_statement_dereference
2018 (&lease
->on_star
.on_commit
, MDL
);
2019 if (lease
->on_star
.on_release
)
2020 executable_statement_dereference
2021 (&lease
->on_star
.on_release
, MDL
);
2024 /* Execute statements in scope starting with the subnet scope. */
2025 execute_statements_in_scope (NULL
, packet
, lease
,
2026 NULL
, packet
->options
,
2027 state
->options
, &lease
->scope
,
2028 lease
->subnet
->group
, NULL
, NULL
);
2030 /* If the lease is from a pool, run the pool scope. */
2032 (execute_statements_in_scope(NULL
, packet
, lease
, NULL
,
2033 packet
->options
, state
->options
,
2034 &lease
->scope
, lease
->pool
->group
,
2036 shared_network
->group
,
2039 /* Execute statements from class scopes. */
2040 for (i
= packet
-> class_count
; i
> 0; i
--) {
2041 execute_statements_in_scope(NULL
, packet
, lease
, NULL
,
2042 packet
->options
, state
->options
,
2044 packet
->classes
[i
- 1]->group
,
2045 (lease
->pool
? lease
->pool
->group
2046 : lease
->subnet
->group
),
2050 /* See if the client is only supposed to have one lease at a time,
2051 and if so, find its other leases and release them. We can only
2052 do this on DHCPREQUEST. It's a little weird to do this before
2053 looking at permissions, because the client might not actually
2054 _get_ a lease after we've done the permission check, but the
2055 assumption for this option is that the client has exactly one
2056 network interface, and will only ever remember one lease. So
2057 if it sends a DHCPREQUEST, and doesn't get the lease, it's already
2058 forgotten about its old lease, so we can too. */
2059 if (packet
-> packet_type
== DHCPREQUEST
&&
2060 (oc
= lookup_option (&server_universe
, state
-> options
,
2061 SV_ONE_LEASE_PER_CLIENT
)) &&
2062 evaluate_boolean_option_cache (&ignorep
,
2064 (struct client_state
*)0,
2066 state
-> options
, &lease
-> scope
,
2069 if (lease
-> uid_len
) {
2071 seek
= (struct lease
*)0;
2072 find_lease_by_uid (&seek
, lease
-> uid
,
2073 lease
-> uid_len
, MDL
);
2076 if (seek
== lease
&& !seek
-> n_uid
) {
2077 lease_dereference (&seek
, MDL
);
2080 next
= (struct lease
*)0;
2082 /* Don't release expired leases, and don't
2083 release the lease we're going to assign. */
2084 next
= (struct lease
*)0;
2087 lease_reference (&next
, seek
-> n_uid
, MDL
);
2088 if (seek
!= lease
&&
2089 seek
-> binding_state
!= FTS_RELEASED
&&
2090 seek
-> binding_state
!= FTS_EXPIRED
&&
2091 seek
-> binding_state
!= FTS_RESET
&&
2092 seek
-> binding_state
!= FTS_FREE
&&
2093 seek
-> binding_state
!= FTS_BACKUP
)
2095 lease_dereference (&seek
, MDL
);
2097 lease_reference (&seek
, next
, MDL
);
2098 lease_dereference (&next
, MDL
);
2102 lease_dereference (&next
, MDL
);
2104 release_lease (seek
, packet
);
2105 lease_dereference (&seek
, MDL
);
2110 if (!lease
-> uid_len
||
2112 !host
-> client_identifier
.len
&&
2113 (oc
= lookup_option (&server_universe
, state
-> options
,
2115 !evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
2116 (struct client_state
*)0,
2122 seek
= (struct lease
*)0;
2123 find_lease_by_hw_addr
2124 (&seek
, lease
-> hardware_addr
.hbuf
,
2125 lease
-> hardware_addr
.hlen
, MDL
);
2128 if (seek
== lease
&& !seek
-> n_hw
) {
2129 lease_dereference (&seek
, MDL
);
2132 next
= (struct lease
*)0;
2135 lease_reference (&next
, seek
-> n_hw
, MDL
);
2136 if (seek
!= lease
&&
2137 seek
-> binding_state
!= FTS_RELEASED
&&
2138 seek
-> binding_state
!= FTS_EXPIRED
&&
2139 seek
-> binding_state
!= FTS_RESET
&&
2140 seek
-> binding_state
!= FTS_FREE
&&
2141 seek
-> binding_state
!= FTS_BACKUP
)
2143 lease_dereference (&seek
, MDL
);
2145 lease_reference (&seek
, next
, MDL
);
2146 lease_dereference (&next
, MDL
);
2150 lease_dereference (&next
, MDL
);
2152 release_lease (seek
, packet
);
2153 lease_dereference (&seek
, MDL
);
2161 /* Make sure this packet satisfies the configured minimum
2162 number of seconds. */
2163 memset (&d1
, 0, sizeof d1
);
2164 if (offer
== DHCPOFFER
&&
2165 (oc
= lookup_option (&server_universe
, state
-> options
,
2167 if (evaluate_option_cache (&d1
, packet
, lease
,
2168 (struct client_state
*)0,
2169 packet
-> options
, state
-> options
,
2170 &lease
-> scope
, oc
, MDL
)) {
2172 ntohs (packet
-> raw
-> secs
) < d1
.data
[0]) {
2173 log_info("%s: configured min-secs value (%d) "
2174 "is greater than secs field (%d). "
2175 "message dropped.", msg
, d1
.data
[0],
2176 ntohs(packet
->raw
->secs
));
2177 data_string_forget (&d1
, MDL
);
2178 free_lease_state (state
, MDL
);
2180 host_dereference (&host
, MDL
);
2183 data_string_forget (&d1
, MDL
);
2187 /* Try to find a matching host declaration for this lease.
2190 struct host_decl
*hp
= (struct host_decl
*)0;
2191 struct host_decl
*h
;
2193 /* Try to find a host_decl that matches the client
2194 identifier or hardware address on the packet, and
2195 has no fixed IP address. If there is one, hang
2196 it off the lease so that its option definitions
2198 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
2199 DHO_DHCP_CLIENT_IDENTIFIER
);
2201 evaluate_option_cache (&d1
, packet
, lease
,
2202 (struct client_state
*)0,
2203 packet
-> options
, state
-> options
,
2204 &lease
-> scope
, oc
, MDL
)) {
2205 find_hosts_by_uid (&hp
, d1
.data
, d1
.len
, MDL
);
2206 data_string_forget (&d1
, MDL
);
2207 for (h
= hp
; h
; h
= h
-> n_ipaddr
) {
2208 if (!h
-> fixed_addr
)
2212 host_reference (&host
, h
, MDL
);
2214 host_dereference(&hp
, MDL
);
2217 find_hosts_by_haddr (&hp
,
2218 packet
-> raw
-> htype
,
2219 packet
-> raw
-> chaddr
,
2220 packet
-> raw
-> hlen
,
2222 for (h
= hp
; h
; h
= h
-> n_ipaddr
) {
2223 if (!h
-> fixed_addr
)
2227 host_reference (&host
, h
, MDL
);
2229 host_dereference(&hp
, MDL
);
2232 find_hosts_by_option(&hp
, packet
,
2233 packet
->options
, MDL
);
2234 for (h
= hp
; h
; h
= h
-> n_ipaddr
) {
2235 if (!h
-> fixed_addr
)
2239 host_reference (&host
, h
, MDL
);
2241 host_dereference(&hp
, MDL
);
2245 /* If we have a host_decl structure, run the options associated
2246 with its group. Whether the host decl struct is old or not. */
2248 execute_statements_in_scope (NULL
, packet
, lease
, NULL
,
2249 packet
->options
, state
->options
,
2250 &lease
->scope
, host
->group
,
2252 ? lease
->pool
->group
2253 : lease
->subnet
->group
),
2256 /* Drop the request if it's not allowed for this client. By
2257 default, unknown clients are allowed. */
2259 (oc
= lookup_option (&server_universe
, state
-> options
,
2260 SV_BOOT_UNKNOWN_CLIENTS
)) &&
2261 !evaluate_boolean_option_cache (&ignorep
,
2263 (struct client_state
*)0,
2266 &lease
-> scope
, oc
, MDL
)) {
2268 log_info ("%s: unknown client", msg
);
2269 free_lease_state (state
, MDL
);
2271 host_dereference (&host
, MDL
);
2275 /* Drop the request if it's not allowed for this client. */
2277 (oc
= lookup_option (&server_universe
, state
-> options
,
2279 !evaluate_boolean_option_cache (&ignorep
,
2281 (struct client_state
*)0,
2284 &lease
-> scope
, oc
, MDL
)) {
2286 log_info ("%s: bootp disallowed", msg
);
2287 free_lease_state (state
, MDL
);
2289 host_dereference (&host
, MDL
);
2293 /* Drop the request if booting is specifically denied. */
2294 oc
= lookup_option (&server_universe
, state
-> options
,
2297 !evaluate_boolean_option_cache (&ignorep
,
2299 (struct client_state
*)0,
2302 &lease
-> scope
, oc
, MDL
)) {
2304 log_info ("%s: booting disallowed", msg
);
2305 free_lease_state (state
, MDL
);
2307 host_dereference (&host
, MDL
);
2311 /* If we are configured to do per-class billing, do it. */
2312 if (have_billing_classes
&& !(lease
-> flags
& STATIC_LEASE
)) {
2313 /* See if the lease is currently being billed to a
2314 class, and if so, whether or not it can continue to
2315 be billed to that class. */
2316 if (lease
-> billing_class
) {
2317 for (i
= 0; i
< packet
-> class_count
; i
++)
2318 if (packet
-> classes
[i
] ==
2319 lease
-> billing_class
)
2321 if (i
== packet
-> class_count
)
2322 unbill_class (lease
, lease
-> billing_class
);
2325 /* If we don't have an active billing, see if we need
2326 one, and if we do, try to do so. */
2327 if (lease
->billing_class
== NULL
) {
2331 for (i
= 0; i
< packet
->class_count
; i
++) {
2332 struct class *billclass
, *subclass
;
2334 billclass
= packet
->classes
[i
];
2335 if (billclass
->lease_limit
) {
2337 if (bill_class(lease
, billclass
))
2340 subclass
= billclass
->superclass
;
2341 if (subclass
== NULL
)
2342 cname
= subclass
->name
;
2344 cname
= billclass
->name
;
2347 if (bill
!= 0 && i
== packet
->class_count
) {
2348 log_info("%s: no available billing: lease "
2349 "limit reached in all matching "
2350 "classes (last: '%s')", msg
, cname
);
2351 free_lease_state(state
, MDL
);
2353 host_dereference(&host
, MDL
);
2358 * If this is an offer, undo the billing. We go
2359 * through all the steps above to bill a class so
2360 * we can hit the 'no available billing' mark and
2361 * abort without offering. But it just doesn't make
2362 * sense to permanently bill a class for a non-active
2363 * lease. This means on REQUEST, we will bill this
2364 * lease again (if there is a REQUEST).
2366 if (offer
== DHCPOFFER
&&
2367 lease
->billing_class
!= NULL
&&
2368 lease
->binding_state
!= FTS_ACTIVE
)
2369 unbill_class(lease
, lease
->billing_class
);
2373 /* Figure out the filename. */
2374 oc
= lookup_option (&server_universe
, state
-> options
, SV_FILENAME
);
2376 evaluate_option_cache (&state
-> filename
, packet
, lease
,
2377 (struct client_state
*)0,
2378 packet
-> options
, state
-> options
,
2379 &lease
-> scope
, oc
, MDL
);
2381 /* Choose a server name as above. */
2382 oc
= lookup_option (&server_universe
, state
-> options
,
2385 evaluate_option_cache (&state
-> server_name
, packet
, lease
,
2386 (struct client_state
*)0,
2387 packet
-> options
, state
-> options
,
2388 &lease
-> scope
, oc
, MDL
);
2390 /* At this point, we have a lease that we can offer the client.
2391 Now we construct a lease structure that contains what we want,
2392 and call supersede_lease to do the right thing with it. */
2393 lt
= (struct lease
*)0;
2394 result
= lease_allocate (<
, MDL
);
2395 if (result
!= ISC_R_SUCCESS
) {
2396 log_info ("%s: can't allocate temporary lease structure: %s",
2397 msg
, isc_result_totext (result
));
2398 free_lease_state (state
, MDL
);
2400 host_dereference (&host
, MDL
);
2404 /* Use the ip address of the lease that we finally found in
2406 lt
-> ip_addr
= lease
-> ip_addr
;
2409 lt
-> starts
= cur_time
;
2411 /* Figure out how long a lease to assign. If this is a
2412 dynamic BOOTP lease, its duration must be infinite. */
2414 lt
->flags
&= ~BOOTP_LEASE
;
2416 default_lease_time
= DEFAULT_DEFAULT_LEASE_TIME
;
2417 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2418 SV_DEFAULT_LEASE_TIME
))) {
2419 if (evaluate_option_cache (&d1
, packet
, lease
,
2420 (struct client_state
*)0,
2423 &lease
-> scope
, oc
, MDL
)) {
2424 if (d1
.len
== sizeof (u_int32_t
))
2425 default_lease_time
=
2427 data_string_forget (&d1
, MDL
);
2431 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
2432 DHO_DHCP_LEASE_TIME
)))
2433 s1
= evaluate_option_cache (&d1
, packet
, lease
,
2434 (struct client_state
*)0,
2437 &lease
-> scope
, oc
, MDL
);
2441 if (s1
&& (d1
.len
== 4)) {
2442 u_int32_t ones
= 0xffffffff;
2444 /* One potential use of reserved leases is to allow
2445 * clients to signal reservation of their lease. They
2446 * can kinda sorta do this, if you squint hard enough,
2447 * by supplying an 'infinite' requested-lease-time
2448 * option. This is generally bad practice...you want
2449 * clients to return to the server on at least some
2450 * period (days, months, years) to get up-to-date
2453 * 1) A client requests 0xffffffff lease-time.
2454 * 2) The server reserves the lease, and assigns a
2455 * <= max_lease_time lease-time to the client, which
2456 * we presume is much smaller than 0xffffffff.
2457 * 3) The client ultimately fails to renew its lease
2458 * (all clients go offline at some point).
2459 * 4) The server retains the reservation, although
2460 * the lease expires and passes through those states
2461 * as normal, it's placed in the 'reserved' queue,
2462 * and is under no circumstances allocated to any
2465 * Whether the client knows its reserving its lease or
2466 * not, this can be a handy tool for a sysadmin.
2468 if ((memcmp(d1
.data
, &ones
, 4) == 0) &&
2469 (oc
= lookup_option(&server_universe
,
2471 SV_RESERVE_INFINITE
)) &&
2472 evaluate_boolean_option_cache(&ignorep
, packet
,
2473 lease
, NULL
, packet
->options
,
2474 state
->options
, &lease
->scope
,
2476 lt
->flags
|= RESERVED_LEASE
;
2478 log_info("Infinite-leasetime "
2479 "reservation made on %s.",
2480 piaddr(lt
->ip_addr
));
2483 lease_time
= getULong (d1
.data
);
2485 lease_time
= default_lease_time
;
2488 data_string_forget(&d1
, MDL
);
2490 /* See if there's a maximum lease time. */
2491 max_lease_time
= DEFAULT_MAX_LEASE_TIME
;
2492 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2493 SV_MAX_LEASE_TIME
))) {
2494 if (evaluate_option_cache (&d1
, packet
, lease
,
2495 (struct client_state
*)0,
2498 &lease
-> scope
, oc
, MDL
)) {
2499 if (d1
.len
== sizeof (u_int32_t
))
2502 data_string_forget (&d1
, MDL
);
2506 /* Enforce the maximum lease length. */
2507 if (lease_time
< 0 /* XXX */
2508 || lease_time
> max_lease_time
)
2509 lease_time
= max_lease_time
;
2511 min_lease_time
= DEFAULT_MIN_LEASE_TIME
;
2512 if (min_lease_time
> max_lease_time
)
2513 min_lease_time
= max_lease_time
;
2515 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2516 SV_MIN_LEASE_TIME
))) {
2517 if (evaluate_option_cache (&d1
, packet
, lease
,
2518 (struct client_state
*)0,
2521 &lease
-> scope
, oc
, MDL
)) {
2522 if (d1
.len
== sizeof (u_int32_t
))
2523 min_lease_time
= getULong (d1
.data
);
2524 data_string_forget (&d1
, MDL
);
2528 /* CC: If there are less than
2529 adaptive-lease-time-threshold % free leases,
2530 hand out only short term leases */
2532 memset(&d1
, 0, sizeof(d1
));
2534 (oc
= lookup_option(&server_universe
, state
->options
,
2535 SV_ADAPTIVE_LEASE_TIME_THRESHOLD
)) &&
2536 evaluate_option_cache(&d1
, packet
, lease
, NULL
,
2537 packet
->options
, state
->options
,
2538 &lease
->scope
, oc
, MDL
)) {
2539 if (d1
.len
== 1 && d1
.data
[0] > 0 &&
2542 int poolfilled
, total
, count
;
2545 adaptive_time
= min_lease_time
;
2547 adaptive_time
= DEFAULT_MIN_LEASE_TIME
;
2549 /* Allow the client to keep its lease. */
2550 if (lease
->ends
- cur_time
> adaptive_time
)
2551 adaptive_time
= lease
->ends
- cur_time
;
2553 count
= lease
->pool
->lease_count
;
2554 total
= count
- (lease
->pool
->free_leases
+
2555 lease
->pool
->backup_leases
);
2557 poolfilled
= (total
> (INT_MAX
/ 100)) ?
2558 total
/ (count
/ 100) :
2559 (total
* 100) / count
;
2561 log_debug("Adap-lease: Total: %d, Free: %d, "
2562 "Ends: %d, Adaptive: %d, Fill: %d, "
2564 lease
->pool
->lease_count
,
2565 lease
->pool
->free_leases
,
2566 (int)(lease
->ends
- cur_time
),
2567 (int)adaptive_time
, poolfilled
,
2570 if (poolfilled
>= d1
.data
[0] &&
2571 lease_time
> adaptive_time
) {
2572 log_info("Pool over threshold, time "
2573 "for %s reduced from %d to "
2574 "%d.", piaddr(lease
->ip_addr
),
2576 (int)adaptive_time
);
2578 lease_time
= adaptive_time
;
2581 data_string_forget(&d1
, MDL
);
2586 * If this is an ack check to see if we have used enough of
2587 * the pool to want to log a message
2589 if (offer
== DHCPACK
)
2590 check_pool_threshold(packet
, lease
, state
);
2592 /* a client requests an address which is not yet active*/
2593 if (lease
->pool
&& lease
->pool
->valid_from
&&
2594 cur_time
< lease
->pool
->valid_from
) {
2595 /* NAK leases before pool activation date */
2597 memcpy (cip
.iabuf
, <
->ip_addr
.iabuf
, 4);
2598 nak_lease(packet
, &cip
, lease
->subnet
->group
);
2599 free_lease_state (state
, MDL
);
2600 lease_dereference (<
, MDL
);
2602 host_dereference (&host
, MDL
);
2608 a) NAK current lease if past the expiration date
2609 b) extend lease only up to the expiration date, but not
2610 below min-lease-time
2611 Setting min-lease-time is essential for this to work!
2612 The value of min-lease-time determines the length
2613 of the transition window:
2614 A client renewing a second before the deadline will
2615 get a min-lease-time lease. Since the current ip might not
2616 be routable after the deadline, the client will
2617 be offline until it DISCOVERS again. Otherwise it will
2618 receive a NAK at T/2.
2619 A min-lease-time of 6 seconds effectively switches over
2620 all clients in this pool very quickly.
2623 if (lease
->pool
&& lease
->pool
->valid_until
) {
2624 if (cur_time
>= lease
->pool
->valid_until
) {
2625 /* NAK leases after pool expiration date */
2627 memcpy (cip
.iabuf
, <
->ip_addr
.iabuf
, 4);
2628 nak_lease(packet
, &cip
, lease
->subnet
->group
);
2629 free_lease_state (state
, MDL
);
2630 lease_dereference (<
, MDL
);
2632 host_dereference (&host
, MDL
);
2635 remaining_time
= lease
->pool
->valid_until
- cur_time
;
2636 if (lease_time
> remaining_time
)
2637 lease_time
= remaining_time
;
2640 if (lease_time
< min_lease_time
) {
2642 lease_time
= min_lease_time
;
2644 lease_time
= default_lease_time
;
2648 #if defined (FAILOVER_PROTOCOL)
2649 /* Okay, we know the lease duration. Now check the
2650 failover state, if any. */
2651 if (lease
-> pool
&& lease
-> pool
-> failover_peer
) {
2652 TIME new_lease_time
= lease_time
;
2653 dhcp_failover_state_t
*peer
=
2654 lease
-> pool
-> failover_peer
;
2656 /* Copy previous lease failover ack-state. */
2657 lt
->tsfp
= lease
->tsfp
;
2658 lt
->atsfp
= lease
->atsfp
;
2660 /* cltt set below */
2662 /* Lease times less than MCLT are not a concern. */
2663 if (lease_time
> peer
->mclt
) {
2664 /* Each server can only offer a lease time
2665 * that is either equal to MCLT (at least),
2666 * or up to TSFP+MCLT. Only if the desired
2667 * lease time falls within TSFP+MCLT, can
2668 * the server allow it.
2670 if (lt
->tsfp
<= cur_time
)
2671 new_lease_time
= peer
->mclt
;
2672 else if ((cur_time
+ lease_time
) >
2673 (lt
->tsfp
+ peer
->mclt
))
2674 new_lease_time
= (lt
->tsfp
- cur_time
)
2678 /* Update potential expiry. Allow for the desired
2679 * lease time plus one half the actual (whether
2680 * modified downward or not) lease time, which is
2681 * actually an estimate of when the client will
2682 * renew. This way, the client will be able to get
2683 * the desired lease time upon renewal.
2685 if (offer
== DHCPACK
) {
2686 lt
->tstp
= cur_time
+ lease_time
+
2687 (new_lease_time
/ 2);
2689 /* If we reduced the potential expiry time,
2690 * make sure we don't offer an old-expiry-time
2691 * lease for this lease before the change is
2694 if (lt
->tstp
< lt
->tsfp
)
2695 lt
->tsfp
= lt
->tstp
;
2697 lt
->tstp
= lease
->tstp
;
2699 /* Use failover-modified lease time. */
2700 lease_time
= new_lease_time
;
2702 #endif /* FAILOVER_PROTOCOL */
2704 /* If the lease duration causes the time value to wrap,
2705 use the maximum expiry time. */
2706 if (cur_time
+ lease_time
< cur_time
)
2707 state
-> offered_expiry
= MAX_TIME
- 1;
2709 state
-> offered_expiry
= cur_time
+ lease_time
;
2713 lt
-> ends
= state
-> offered_expiry
;
2715 /* Don't make lease active until we actually get a
2717 if (offer
== DHCPACK
)
2718 lt
-> next_binding_state
= FTS_ACTIVE
;
2720 lt
-> next_binding_state
= lease
-> binding_state
;
2722 lt
->flags
|= BOOTP_LEASE
;
2724 lease_time
= MAX_TIME
- cur_time
;
2726 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2727 SV_BOOTP_LEASE_LENGTH
))) {
2728 if (evaluate_option_cache (&d1
, packet
, lease
,
2729 (struct client_state
*)0,
2732 &lease
-> scope
, oc
, MDL
)) {
2733 if (d1
.len
== sizeof (u_int32_t
))
2734 lease_time
= getULong (d1
.data
);
2735 data_string_forget (&d1
, MDL
);
2739 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2740 SV_BOOTP_LEASE_CUTOFF
))) {
2741 if (evaluate_option_cache (&d1
, packet
, lease
,
2742 (struct client_state
*)0,
2745 &lease
-> scope
, oc
, MDL
)) {
2746 if (d1
.len
== sizeof (u_int32_t
))
2747 lease_time
= (getULong (d1
.data
) -
2749 data_string_forget (&d1
, MDL
);
2753 lt
-> ends
= state
-> offered_expiry
= cur_time
+ lease_time
;
2754 lt
-> next_binding_state
= FTS_ACTIVE
;
2757 /* Update Client Last Transaction Time. */
2758 lt
->cltt
= cur_time
;
2760 /* See if we want to record the uid for this client */
2761 oc
= lookup_option(&server_universe
, state
->options
,
2762 SV_IGNORE_CLIENT_UIDS
);
2764 !evaluate_boolean_option_cache(&ignorep
, packet
, lease
, NULL
,
2765 packet
->options
, state
->options
,
2766 &lease
->scope
, oc
, MDL
)) {
2768 /* Record the uid, if given... */
2769 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
2770 DHO_DHCP_CLIENT_IDENTIFIER
);
2772 evaluate_option_cache(&d1
, packet
, lease
, NULL
,
2773 packet
->options
, state
->options
,
2774 &lease
->scope
, oc
, MDL
)) {
2775 if (d1
.len
<= sizeof(lt
->uid_buf
)) {
2776 memcpy(lt
->uid_buf
, d1
.data
, d1
.len
);
2777 lt
->uid
= lt
->uid_buf
;
2778 lt
->uid_max
= sizeof(lt
->uid_buf
);
2779 lt
->uid_len
= d1
.len
;
2781 unsigned char *tuid
;
2782 lt
->uid_max
= d1
.len
;
2783 lt
->uid_len
= d1
.len
;
2784 tuid
= (unsigned char *)dmalloc(lt
->uid_max
,
2788 log_fatal ("no memory for large uid.");
2789 memcpy(tuid
, d1
.data
, lt
->uid_len
);
2792 data_string_forget (&d1
, MDL
);
2797 host_reference (<
-> host
, host
, MDL
);
2798 host_dereference (&host
, MDL
);
2800 if (lease
-> subnet
)
2801 subnet_reference (<
-> subnet
, lease
-> subnet
, MDL
);
2802 if (lease
-> billing_class
)
2803 class_reference (<
-> billing_class
,
2804 lease
-> billing_class
, MDL
);
2806 /* Set a flag if this client is a broken client that NUL
2807 terminates string options and expects us to do likewise. */
2809 lease
-> flags
|= MS_NULL_TERMINATION
;
2811 lease
-> flags
&= ~MS_NULL_TERMINATION
;
2813 /* Save any bindings. */
2814 if (lease
-> scope
) {
2815 binding_scope_reference (<
-> scope
, lease
-> scope
, MDL
);
2816 binding_scope_dereference (&lease
-> scope
, MDL
);
2818 if (lease
-> agent_options
)
2819 option_chain_head_reference (<
-> agent_options
,
2820 lease
-> agent_options
, MDL
);
2822 /* Save the vendor-class-identifier for DHCPLEASEQUERY. */
2823 oc
= lookup_option(&dhcp_universe
, packet
->options
,
2824 DHO_VENDOR_CLASS_IDENTIFIER
);
2826 evaluate_option_cache(&d1
, packet
, NULL
, NULL
, packet
->options
,
2827 NULL
, &lease
->scope
, oc
, MDL
)) {
2829 bind_ds_value(&lease
->scope
, "vendor-class-identifier",
2833 data_string_forget(&d1
, MDL
);
2836 /* If we got relay agent information options from the packet, then
2837 * cache them for renewal in case the relay agent can't supply them
2838 * when the client unicasts. The options may be from an addressed
2839 * "l3" relay, or from an unaddressed "l2" relay which does not set
2842 if (!packet
->agent_options_stashed
&&
2843 (packet
->options
!= NULL
) &&
2844 packet
->options
->universe_count
> agent_universe
.index
&&
2845 packet
->options
->universes
[agent_universe
.index
] != NULL
) {
2846 oc
= lookup_option (&server_universe
, state
-> options
,
2847 SV_STASH_AGENT_OPTIONS
);
2849 evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
2850 (struct client_state
*)0,
2853 &lease
-> scope
, oc
, MDL
)) {
2854 if (lt
-> agent_options
)
2855 option_chain_head_dereference (<
-> agent_options
, MDL
);
2856 option_chain_head_reference
2857 (<
-> agent_options
,
2858 (struct option_chain_head
*)
2859 packet
-> options
-> universes
[agent_universe
.index
],
2864 /* Replace the old lease hostname with the new one, if it's changed. */
2865 oc
= lookup_option (&dhcp_universe
, packet
-> options
, DHO_HOST_NAME
);
2867 s1
= evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
2868 (struct client_state
*)0,
2870 (struct option_state
*)0,
2871 &global_scope
, oc
, MDL
);
2876 lease
-> client_hostname
&&
2877 strlen (lease
-> client_hostname
) == d1
.len
&&
2878 !memcmp (lease
-> client_hostname
, d1
.data
, d1
.len
)) {
2879 /* Hasn't changed. */
2880 data_string_forget (&d1
, MDL
);
2881 lt
-> client_hostname
= lease
-> client_hostname
;
2882 lease
-> client_hostname
= (char *)0;
2883 } else if (oc
&& s1
) {
2884 lt
-> client_hostname
= dmalloc (d1
.len
+ 1, MDL
);
2885 if (!lt
-> client_hostname
)
2886 log_error ("no memory for client hostname.");
2888 memcpy (lt
-> client_hostname
, d1
.data
, d1
.len
);
2889 lt
-> client_hostname
[d1
.len
] = 0;
2891 data_string_forget (&d1
, MDL
);
2894 /* Record the hardware address, if given... */
2895 lt
-> hardware_addr
.hlen
= packet
-> raw
-> hlen
+ 1;
2896 lt
-> hardware_addr
.hbuf
[0] = packet
-> raw
-> htype
;
2897 memcpy (<
-> hardware_addr
.hbuf
[1], packet
-> raw
-> chaddr
,
2898 sizeof packet
-> raw
-> chaddr
);
2900 lt
-> flags
= lease
-> flags
& ~PERSISTENT_FLAGS
;
2902 /* If there are statements to execute when the lease is
2903 committed, execute them. */
2904 if (lease
->on_star
.on_commit
&& (!offer
|| offer
== DHCPACK
)) {
2905 execute_statements (NULL
, packet
, lt
, NULL
, packet
->options
,
2906 state
->options
, <
->scope
,
2907 lease
->on_star
.on_commit
, NULL
);
2908 if (lease
->on_star
.on_commit
)
2909 executable_statement_dereference
2910 (&lease
->on_star
.on_commit
, MDL
);
2914 /* Perform DDNS updates, if configured to. */
2915 if ((!offer
|| offer
== DHCPACK
) &&
2916 (!(oc
= lookup_option (&server_universe
, state
-> options
,
2917 SV_DDNS_UPDATES
)) ||
2918 evaluate_boolean_option_cache (&ignorep
, packet
, lt
,
2919 (struct client_state
*)0,
2922 <
-> scope
, oc
, MDL
))) {
2923 ddns_updates(packet
, lt
, lease
, NULL
, NULL
, state
->options
);
2925 #endif /* NSUPDATE */
2927 /* Don't call supersede_lease on a mocked-up lease. */
2928 if (lease
-> flags
& STATIC_LEASE
) {
2929 /* Copy the hardware address into the static lease
2931 lease
-> hardware_addr
.hlen
= packet
-> raw
-> hlen
+ 1;
2932 lease
-> hardware_addr
.hbuf
[0] = packet
-> raw
-> htype
;
2933 memcpy (&lease
-> hardware_addr
.hbuf
[1],
2934 packet
-> raw
-> chaddr
,
2935 sizeof packet
-> raw
-> chaddr
); /* XXX */
2937 int commit
= (!offer
|| (offer
== DHCPACK
));
2938 int thresh
= DEFAULT_CACHE_THRESHOLD
;
2941 * Check if the lease was issued recently, if so replay the
2942 * current lease and do not require a database sync event.
2943 * Recently is defined as being issued less than a given
2944 * percentage of the lease previously. The percentage can be
2945 * chosen either from a default value or via configuration.
2948 if ((oc
= lookup_option(&server_universe
, state
->options
,
2949 SV_CACHE_THRESHOLD
)) &&
2950 evaluate_option_cache(&d1
, packet
, lt
, NULL
,
2951 packet
->options
, state
->options
,
2952 <
->scope
, oc
, MDL
)) {
2953 if (d1
.len
== 1 && (d1
.data
[0] < 100))
2954 thresh
= d1
.data
[0];
2956 data_string_forget(&d1
, MDL
);
2960 * We check on ddns_cb to see if the ddns code has
2961 * updated the lt structure. We could probably simply
2962 * copy the ddns_cb pointer in that case but lets be
2963 * simple and safe and update the entire lease.
2965 if ((lt
->ddns_cb
== NULL
) &&
2966 (thresh
> 0) && (offer
== DHCPACK
) &&
2967 (lease
->binding_state
== FTS_ACTIVE
)) {
2969 int prev_lease
= lease
->ends
- lease
->starts
;
2971 /* it is better to avoid division by 0 */
2972 if (prev_lease
<= (INT_MAX
/ thresh
))
2973 limit
= prev_lease
* thresh
/ 100;
2975 limit
= prev_lease
/ 100 * thresh
;
2977 if ((lt
->starts
- lease
->starts
) <= limit
) {
2978 lt
->starts
= lease
->starts
;
2979 state
->offered_expiry
= lt
->ends
= lease
->ends
;
2985 #if !defined(DELAYED_ACK)
2986 /* Install the new information on 'lt' onto the lease at
2987 * 'lease'. If this is a DHCPOFFER, it is a 'soft' promise,
2988 * if it is a DHCPACK, it is a 'hard' binding, so it needs
2989 * to be recorded and propogated immediately. If the update
2990 * fails, don't ACK it (or BOOTREPLY) either; we may give
2991 * the same lease to another client later, and that would be
2994 if ((use_old_lease
== 0) &&
2995 !supersede_lease(lease
, lt
, commit
,
2996 offer
== DHCPACK
, offer
== DHCPACK
)) {
2997 #else /* defined(DELAYED_ACK) */
2999 * If there already isn't a need for a lease commit, and we
3000 * can just answer right away, set a flag to indicate this.
3005 /* Install the new information on 'lt' onto the lease at
3006 * 'lease'. We will not 'commit' this information to disk
3007 * yet (fsync()), we will 'propogate' the information if
3008 * this is BOOTP or a DHCPACK, but we will not 'pimmediate'ly
3009 * transmit failover binding updates (this is delayed until
3010 * after the fsync()). If the update fails, don't ACK it (or
3011 * BOOTREPLY either); we may give the same lease out to a
3012 * different client, and that would be a conflict.
3014 if ((use_old_lease
== 0) &&
3015 !supersede_lease(lease
, lt
, 0,
3016 !offer
|| offer
== DHCPACK
, 0)) {
3018 log_info ("%s: database update failed", msg
);
3019 free_lease_state (state
, MDL
);
3020 lease_dereference (<
, MDL
);
3024 lease_dereference (<
, MDL
);
3026 /* Remember the interface on which the packet arrived. */
3027 state
-> ip
= packet
-> interface
;
3029 /* Remember the giaddr, xid, secs, flags and hops. */
3030 state
-> giaddr
= packet
-> raw
-> giaddr
;
3031 state
-> ciaddr
= packet
-> raw
-> ciaddr
;
3032 state
-> xid
= packet
-> raw
-> xid
;
3033 state
-> secs
= packet
-> raw
-> secs
;
3034 state
-> bootp_flags
= packet
-> raw
-> flags
;
3035 state
-> hops
= packet
-> raw
-> hops
;
3036 state
-> offer
= offer
;
3038 /* If we're always supposed to broadcast to this client, set
3039 the broadcast bit in the bootp flags field. */
3040 if ((oc
= lookup_option (&server_universe
, state
-> options
,
3041 SV_ALWAYS_BROADCAST
)) &&
3042 evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
3043 (struct client_state
*)0,
3044 packet
-> options
, state
-> options
,
3045 &lease
-> scope
, oc
, MDL
))
3046 state
-> bootp_flags
|= htons (BOOTP_BROADCAST
);
3048 /* Get the Maximum Message Size option from the packet, if one
3050 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
3051 DHO_DHCP_MAX_MESSAGE_SIZE
);
3053 evaluate_option_cache (&d1
, packet
, lease
,
3054 (struct client_state
*)0,
3055 packet
-> options
, state
-> options
,
3056 &lease
-> scope
, oc
, MDL
)) {
3057 if (d1
.len
== sizeof (u_int16_t
))
3058 state
-> max_message_size
= getUShort (d1
.data
);
3059 data_string_forget (&d1
, MDL
);
3061 oc
= lookup_option (&dhcp_universe
, state
-> options
,
3062 DHO_DHCP_MAX_MESSAGE_SIZE
);
3064 evaluate_option_cache (&d1
, packet
, lease
,
3065 (struct client_state
*)0,
3066 packet
-> options
, state
-> options
,
3067 &lease
-> scope
, oc
, MDL
)) {
3068 if (d1
.len
== sizeof (u_int16_t
))
3069 state
-> max_message_size
=
3070 getUShort (d1
.data
);
3071 data_string_forget (&d1
, MDL
);
3075 /* Get the Subnet Selection option from the packet, if one
3077 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
3078 DHO_SUBNET_SELECTION
))) {
3080 /* Make a copy of the data. */
3081 struct option_cache
*noc
= (struct option_cache
*)0;
3082 if (option_cache_allocate (&noc
, MDL
)) {
3084 data_string_copy (&noc
-> data
,
3086 if (oc
-> expression
)
3087 expression_reference (&noc
-> expression
,
3088 oc
-> expression
, MDL
);
3090 option_reference(&(noc
->option
), oc
->option
,
3093 save_option (&dhcp_universe
, state
-> options
, noc
);
3094 option_cache_dereference (&noc
, MDL
);
3098 /* Now, if appropriate, put in DHCP-specific options that
3100 if (state
-> offer
) {
3101 i
= DHO_DHCP_MESSAGE_TYPE
;
3102 oc
= (struct option_cache
*)0;
3103 if (option_cache_allocate (&oc
, MDL
)) {
3104 if (make_const_data (&oc
-> expression
,
3105 &state
-> offer
, 1, 0, 0, MDL
)) {
3106 option_code_hash_lookup(&oc
->option
,
3107 dhcp_universe
.code_hash
,
3109 save_option (&dhcp_universe
,
3110 state
-> options
, oc
);
3112 option_cache_dereference (&oc
, MDL
);
3115 get_server_source_address(&from
, state
->options
,
3116 state
->options
, packet
);
3117 memcpy(state
->from
.iabuf
, &from
, sizeof(from
));
3118 state
->from
.len
= sizeof(from
);
3120 offered_lease_time
=
3121 state
-> offered_expiry
- cur_time
;
3123 putULong(state
->expiry
, (u_int32_t
)offered_lease_time
);
3124 i
= DHO_DHCP_LEASE_TIME
;
3125 oc
= (struct option_cache
*)0;
3126 if (option_cache_allocate (&oc
, MDL
)) {
3127 if (make_const_data(&oc
->expression
, state
->expiry
,
3129 option_code_hash_lookup(&oc
->option
,
3130 dhcp_universe
.code_hash
,
3132 save_option (&dhcp_universe
,
3133 state
-> options
, oc
);
3135 option_cache_dereference (&oc
, MDL
);
3139 * Validate any configured renew or rebinding times against
3140 * the determined lease time. Do rebinding first so that
3141 * the renew time can be validated against the rebind time.
3143 if ((oc
= lookup_option(&dhcp_universe
, state
->options
,
3144 DHO_DHCP_REBINDING_TIME
)) != NULL
&&
3145 evaluate_option_cache(&d1
, packet
, lease
, NULL
,
3146 packet
->options
, state
->options
,
3147 &lease
->scope
, oc
, MDL
)) {
3148 TIME rebind_time
= getULong(d1
.data
);
3150 /* Drop the configured (invalid) rebinding time. */
3151 if (rebind_time
>= offered_lease_time
)
3152 delete_option(&dhcp_universe
, state
->options
,
3153 DHO_DHCP_REBINDING_TIME
);
3154 else /* XXX: variable is reused. */
3155 offered_lease_time
= rebind_time
;
3157 data_string_forget(&d1
, MDL
);
3160 if ((oc
= lookup_option(&dhcp_universe
, state
->options
,
3161 DHO_DHCP_RENEWAL_TIME
)) != NULL
&&
3162 evaluate_option_cache(&d1
, packet
, lease
, NULL
,
3163 packet
->options
, state
->options
,
3164 &lease
->scope
, oc
, MDL
)) {
3165 if (getULong(d1
.data
) >= offered_lease_time
)
3166 delete_option(&dhcp_universe
, state
->options
,
3167 DHO_DHCP_RENEWAL_TIME
);
3169 data_string_forget(&d1
, MDL
);
3172 /* XXXSK: should we use get_server_source_address() here? */
3173 if (state
-> ip
-> address_count
) {
3175 sizeof state
-> ip
-> addresses
[0];
3176 memcpy (state
-> from
.iabuf
,
3177 &state
-> ip
-> addresses
[0],
3182 /* Figure out the address of the boot file server. */
3183 memset (&state
-> siaddr
, 0, sizeof state
-> siaddr
);
3185 lookup_option (&server_universe
,
3186 state
-> options
, SV_NEXT_SERVER
))) {
3187 if (evaluate_option_cache (&d1
, packet
, lease
,
3188 (struct client_state
*)0,
3189 packet
-> options
, state
-> options
,
3190 &lease
-> scope
, oc
, MDL
)) {
3191 /* If there was more than one answer,
3193 if (d1
.len
>= 4 && d1
.data
)
3194 memcpy (&state
-> siaddr
, d1
.data
, 4);
3195 data_string_forget (&d1
, MDL
);
3199 /* Use the subnet mask from the subnet declaration if no other
3200 mask has been provided. */
3201 i
= DHO_SUBNET_MASK
;
3202 if (!lookup_option (&dhcp_universe
, state
-> options
, i
)) {
3203 oc
= (struct option_cache
*)0;
3204 if (option_cache_allocate (&oc
, MDL
)) {
3205 if (make_const_data (&oc
-> expression
,
3206 lease
-> subnet
-> netmask
.iabuf
,
3207 lease
-> subnet
-> netmask
.len
,
3209 option_code_hash_lookup(&oc
->option
,
3210 dhcp_universe
.code_hash
,
3212 save_option (&dhcp_universe
,
3213 state
-> options
, oc
);
3215 option_cache_dereference (&oc
, MDL
);
3219 /* Use the name of the host declaration if there is one
3220 and no hostname has otherwise been provided, and if the
3221 use-host-decl-name flag is set. */
3222 use_host_decl_name(packet
, lease
, state
->options
);
3224 /* Send client_id back if we received it and echo-client-id is on. */
3225 echo_client_id(packet
, lease
, state
->options
, state
->options
);
3227 /* If we don't have a hostname yet, and we've been asked to do
3228 a reverse lookup to find the hostname, do it. */
3230 j
= SV_GET_LEASE_HOSTNAMES
;
3231 if (!lookup_option(&dhcp_universe
, state
->options
, i
) &&
3232 evaluate_boolean_option_cache
3233 (&ignorep
, packet
, lease
, NULL
,
3234 packet
->options
, state
->options
, &lease
->scope
,
3235 lookup_option (&server_universe
, state
->options
, j
), MDL
)) {
3239 memcpy (&ia
, lease
-> ip_addr
.iabuf
, 4);
3241 h
= gethostbyaddr ((char *)&ia
, sizeof ia
, AF_INET
);
3243 log_error ("No hostname for %s", inet_ntoa (ia
));
3245 oc
= (struct option_cache
*)0;
3246 if (option_cache_allocate (&oc
, MDL
)) {
3247 if (make_const_data (&oc
-> expression
,
3250 strlen (h
-> h_name
) + 1,
3252 option_code_hash_lookup(&oc
->option
,
3253 dhcp_universe
.code_hash
,
3255 save_option (&dhcp_universe
,
3256 state
-> options
, oc
);
3258 option_cache_dereference (&oc
, MDL
);
3263 /* If so directed, use the leased IP address as the router address.
3264 This supposedly makes Win95 machines ARP for all IP addresses,
3265 so if the local router does proxy arp, you win. */
3267 if (evaluate_boolean_option_cache
3268 (&ignorep
, packet
, lease
, (struct client_state
*)0,
3269 packet
-> options
, state
-> options
, &lease
-> scope
,
3270 lookup_option (&server_universe
, state
-> options
,
3271 SV_USE_LEASE_ADDR_FOR_DEFAULT_ROUTE
), MDL
)) {
3273 oc
= lookup_option (&dhcp_universe
, state
-> options
, i
);
3275 oc
= (struct option_cache
*)0;
3276 if (option_cache_allocate (&oc
, MDL
)) {
3277 if (make_const_data (&oc
-> expression
,
3278 lease
-> ip_addr
.iabuf
,
3279 lease
-> ip_addr
.len
,
3281 option_code_hash_lookup(&oc
->option
,
3282 dhcp_universe
.code_hash
,
3284 save_option (&dhcp_universe
,
3285 state
-> options
, oc
);
3287 option_cache_dereference (&oc
, MDL
);
3292 /* If a site option space has been specified, use that for
3293 site option codes. */
3294 i
= SV_SITE_OPTION_SPACE
;
3295 if ((oc
= lookup_option (&server_universe
, state
-> options
, i
)) &&
3296 evaluate_option_cache (&d1
, packet
, lease
,
3297 (struct client_state
*)0,
3298 packet
-> options
, state
-> options
,
3299 &lease
-> scope
, oc
, MDL
)) {
3300 struct universe
*u
= (struct universe
*)0;
3302 if (!universe_hash_lookup (&u
, universe_hash
,
3303 (const char *)d1
.data
, d1
.len
,
3305 log_error ("unknown option space %s.", d1
.data
);
3309 state
-> options
-> site_universe
= u
-> index
;
3310 state
->options
->site_code_min
= find_min_site_code(u
);
3311 data_string_forget (&d1
, MDL
);
3313 state
-> options
-> site_code_min
= 0;
3314 state
-> options
-> site_universe
= dhcp_universe
.index
;
3317 /* If the client has provided a list of options that it wishes
3318 returned, use it to prioritize. If there's a parameter
3319 request list in scope, use that in preference. Otherwise
3320 use the default priority list. */
3322 oc
= lookup_option (&dhcp_universe
, state
-> options
,
3323 DHO_DHCP_PARAMETER_REQUEST_LIST
);
3326 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
3327 DHO_DHCP_PARAMETER_REQUEST_LIST
);
3329 evaluate_option_cache (&state
-> parameter_request_list
,
3330 packet
, lease
, (struct client_state
*)0,
3331 packet
-> options
, state
-> options
,
3332 &lease
-> scope
, oc
, MDL
);
3335 dump_packet (packet
);
3336 dump_raw ((unsigned char *)packet
-> raw
, packet
-> packet_length
);
3339 lease
-> state
= state
;
3341 log_info ("%s", msg
);
3343 /* Hang the packet off the lease state. */
3344 packet_reference (&lease
-> state
-> packet
, packet
, MDL
);
3346 /* If this is a DHCPOFFER, ping the lease address before actually
3347 sending the offer. */
3348 if (offer
== DHCPOFFER
&& !(lease
-> flags
& STATIC_LEASE
) &&
3349 ((cur_time
- lease_cltt
) > 60) &&
3350 (!(oc
= lookup_option (&server_universe
, state
-> options
,
3352 evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
3353 (struct client_state
*)0,
3356 &lease
-> scope
, oc
, MDL
))) {
3357 icmp_echorequest (&lease
-> ip_addr
);
3359 /* Determine whether to use configured or default ping timeout.
3361 if ((oc
= lookup_option (&server_universe
, state
-> options
,
3362 SV_PING_TIMEOUT
)) &&
3363 evaluate_option_cache (&d1
, packet
, lease
, NULL
,
3366 &lease
-> scope
, oc
, MDL
)) {
3367 if (d1
.len
== sizeof (u_int32_t
))
3368 ping_timeout
= getULong (d1
.data
);
3370 ping_timeout
= DEFAULT_PING_TIMEOUT
;
3372 data_string_forget (&d1
, MDL
);
3374 ping_timeout
= DEFAULT_PING_TIMEOUT
;
3377 log_debug ("Ping timeout: %ld", (long)ping_timeout
);
3381 * Set a timeout for 'ping-timeout' seconds from NOW, including
3382 * current microseconds. As ping-timeout defaults to 1, the
3383 * exclusion of current microseconds causes a value somewhere
3384 * /between/ zero and one.
3386 tv
.tv_sec
= cur_tv
.tv_sec
+ ping_timeout
;
3387 tv
.tv_usec
= cur_tv
.tv_usec
;
3388 add_timeout (&tv
, lease_ping_timeout
, lease
,
3389 (tvref_t
)lease_reference
,
3390 (tvunref_t
)lease_dereference
);
3391 ++outstanding_pings
;
3393 lease
->cltt
= cur_time
;
3394 #if defined(DELAYED_ACK)
3396 delayed_ack_enqueue(lease
);
3404 * CC: queue single ACK:
3405 * - write the lease (but do not fsync it yet)
3406 * - add to double linked list
3407 * - commit if more than xx ACKs pending
3408 * - if necessary set the max timer and bump the next timer
3409 * but only up to the max timer value.
3413 delayed_ack_enqueue(struct lease
*lease
)
3415 struct leasequeue
*q
;
3417 if (!write_lease(lease
))
3419 if (free_ackqueue
) {
3421 free_ackqueue
= q
->next
;
3423 q
= ((struct leasequeue
*)
3424 dmalloc(sizeof(struct leasequeue
), MDL
));
3426 log_fatal("delayed_ack_enqueue: no memory!");
3428 memset(q
, 0, sizeof *q
);
3429 /* prepend to ackqueue*/
3430 lease_reference(&q
->lease
, lease
, MDL
);
3431 q
->next
= ackqueue_head
;
3439 if (outstanding_acks
> max_outstanding_acks
) {
3442 /* Reset max_fsync and cancel any pending timeout. */
3443 memset(&max_fsync
, 0, sizeof(max_fsync
));
3444 cancel_timeout(commit_leases_ackout
, NULL
);
3446 struct timeval next_fsync
;
3448 if (max_fsync
.tv_sec
== 0 && max_fsync
.tv_usec
== 0) {
3449 /* set the maximum time we'll wait */
3450 max_fsync
.tv_sec
= cur_tv
.tv_sec
+ max_ack_delay_secs
;
3451 max_fsync
.tv_usec
= cur_tv
.tv_usec
+
3452 max_ack_delay_usecs
;
3454 if (max_fsync
.tv_usec
>= 1000000) {
3456 max_fsync
.tv_usec
-= 1000000;
3460 /* Set the timeout */
3461 next_fsync
.tv_sec
= cur_tv
.tv_sec
;
3462 next_fsync
.tv_usec
= cur_tv
.tv_usec
+ min_ack_delay_usecs
;
3463 if (next_fsync
.tv_usec
>= 1000000) {
3464 next_fsync
.tv_sec
++;
3465 next_fsync
.tv_usec
-= 1000000;
3467 /* but not more than the max */
3468 if ((next_fsync
.tv_sec
> max_fsync
.tv_sec
) ||
3469 ((next_fsync
.tv_sec
== max_fsync
.tv_sec
) &&
3470 (next_fsync
.tv_usec
> max_fsync
.tv_usec
))) {
3471 next_fsync
.tv_sec
= max_fsync
.tv_sec
;
3472 next_fsync
.tv_usec
= max_fsync
.tv_usec
;
3475 add_timeout(&next_fsync
, commit_leases_ackout
, NULL
,
3476 (tvref_t
) NULL
, (tvunref_t
) NULL
);
3481 commit_leases_ackout(void *foo
)
3483 if (outstanding_acks
) {
3486 memset(&max_fsync
, 0, sizeof(max_fsync
));
3490 /* CC: process the delayed ACK responses:
3491 - send out the ACK packets
3492 - move the queue slots to the free list
3495 flush_ackqueue(void *foo
)
3497 struct leasequeue
*ack
, *p
;
3498 /* process from bottom to retain packet order */
3499 for (ack
= ackqueue_tail
; ack
; ack
= p
) {
3502 /* dhcp_reply() requires that the reply state still be valid */
3503 if (ack
->lease
->state
== NULL
)
3504 log_error("delayed ack for %s has gone stale",
3505 piaddr(ack
->lease
->ip_addr
));
3507 dhcp_reply(ack
->lease
);
3509 lease_dereference(&ack
->lease
, MDL
);
3510 ack
->next
= free_ackqueue
;
3511 free_ackqueue
= ack
;
3513 ackqueue_head
= NULL
;
3514 ackqueue_tail
= NULL
;
3515 outstanding_acks
= 0;
3518 #if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
3520 relinquish_ackqueue(void)
3522 struct leasequeue
*q
, *n
;
3524 for (q
= ackqueue_head
; q
; q
= n
) {
3528 for (q
= free_ackqueue
; q
; q
= n
) {
3535 void dhcp_reply (lease
)
3536 struct lease
*lease
;
3539 unsigned packet_length
;
3540 struct dhcp_packet raw
;
3541 struct sockaddr_in to
;
3542 struct in_addr from
;
3543 struct hardware hto
;
3545 struct lease_state
*state
= lease
-> state
;
3546 int nulltp
, bootpp
, unicastp
= 1;
3547 struct data_string d1
;
3551 log_fatal ("dhcp_reply was supplied lease with no state!");
3553 /* Compose a response for the client... */
3554 memset (&raw
, 0, sizeof raw
);
3555 memset (&d1
, 0, sizeof d1
);
3557 /* Copy in the filename if given; otherwise, flag the filename
3558 buffer as available for options. */
3559 if (state
-> filename
.len
&& state
-> filename
.data
) {
3561 state
-> filename
.data
,
3562 state
-> filename
.len
> sizeof raw
.file
3563 ? sizeof raw
.file
: state
-> filename
.len
);
3564 if (sizeof raw
.file
> state
-> filename
.len
)
3565 memset (&raw
.file
[state
-> filename
.len
], 0,
3566 (sizeof raw
.file
) - state
-> filename
.len
);
3568 log_info("file name longer than packet field "
3569 "truncated - field: %lu name: %d %.*s",
3570 (unsigned long)sizeof(raw
.file
),
3571 state
->filename
.len
, (int)state
->filename
.len
,
3572 state
->filename
.data
);
3576 /* Copy in the server name if given; otherwise, flag the
3577 server_name buffer as available for options. */
3578 if (state
-> server_name
.len
&& state
-> server_name
.data
) {
3580 state
-> server_name
.data
,
3581 state
-> server_name
.len
> sizeof raw
.sname
3582 ? sizeof raw
.sname
: state
-> server_name
.len
);
3583 if (sizeof raw
.sname
> state
-> server_name
.len
)
3584 memset (&raw
.sname
[state
-> server_name
.len
], 0,
3585 (sizeof raw
.sname
) - state
-> server_name
.len
);
3587 log_info("server name longer than packet field "
3588 "truncated - field: %lu name: %d %.*s",
3589 (unsigned long)sizeof(raw
.sname
),
3590 state
->server_name
.len
,
3591 (int)state
->server_name
.len
,
3592 state
->server_name
.data
);
3594 bufs
|= 2; /* XXX */
3597 &lease
-> hardware_addr
.hbuf
[1], sizeof raw
.chaddr
);
3598 raw
.hlen
= lease
-> hardware_addr
.hlen
- 1;
3599 raw
.htype
= lease
-> hardware_addr
.hbuf
[0];
3601 /* See if this is a Microsoft client that NUL-terminates its
3602 strings and expects us to do likewise... */
3603 if (lease
-> flags
& MS_NULL_TERMINATION
)
3608 /* See if this is a bootp client... */
3614 /* Insert such options as will fit into the buffer. */
3615 packet_length
= cons_options (state
-> packet
, &raw
, lease
,
3616 (struct client_state
*)0,
3617 state
-> max_message_size
,
3618 state
-> packet
-> options
,
3619 state
-> options
, &global_scope
,
3620 bufs
, nulltp
, bootpp
,
3621 &state
-> parameter_request_list
,
3624 memcpy (&raw
.ciaddr
, &state
-> ciaddr
, sizeof raw
.ciaddr
);
3625 memcpy (&raw
.yiaddr
, lease
-> ip_addr
.iabuf
, 4);
3626 raw
.siaddr
= state
-> siaddr
;
3627 raw
.giaddr
= state
-> giaddr
;
3629 raw
.xid
= state
-> xid
;
3630 raw
.secs
= state
-> secs
;
3631 raw
.flags
= state
-> bootp_flags
;
3632 raw
.hops
= state
-> hops
;
3635 if (lease
-> client_hostname
) {
3636 if ((strlen (lease
-> client_hostname
) <= 64) &&
3637 db_printable((unsigned char *)lease
->client_hostname
))
3638 s
= lease
-> client_hostname
;
3640 s
= "Hostname Unsuitable for Printing";
3644 /* Say what we're doing... */
3645 log_info ("%s on %s to %s %s%s%svia %s",
3647 ? (state
-> offer
== DHCPACK
? "DHCPACK" : "DHCPOFFER")
3649 piaddr (lease
-> ip_addr
),
3650 (lease
-> hardware_addr
.hlen
3651 ? print_hw_addr (lease
-> hardware_addr
.hbuf
[0],
3652 lease
-> hardware_addr
.hlen
- 1,
3653 &lease
-> hardware_addr
.hbuf
[1])
3654 : print_hex_1(lease
->uid_len
, lease
->uid
, 60)),
3655 s
? "(" : "", s
? s
: "", s
? ") " : "",
3656 (state
-> giaddr
.s_addr
3657 ? inet_ntoa (state
-> giaddr
)
3658 : state
-> ip
-> name
));
3660 /* Set up the hardware address... */
3661 hto
.hlen
= lease
-> hardware_addr
.hlen
;
3662 memcpy (hto
.hbuf
, lease
-> hardware_addr
.hbuf
, hto
.hlen
);
3664 to
.sin_family
= AF_INET
;
3666 to
.sin_len
= sizeof to
;
3668 memset (to
.sin_zero
, 0, sizeof to
.sin_zero
);
3671 dump_raw ((unsigned char *)&raw
, packet_length
);
3674 /* Make sure outgoing packets are at least as big
3675 as a BOOTP packet. */
3676 if (packet_length
< BOOTP_MIN_LEN
)
3677 packet_length
= BOOTP_MIN_LEN
;
3679 /* If this was gatewayed, send it back to the gateway... */
3680 if (raw
.giaddr
.s_addr
) {
3681 to
.sin_addr
= raw
.giaddr
;
3682 if (raw
.giaddr
.s_addr
!= htonl (INADDR_LOOPBACK
))
3683 to
.sin_port
= local_port
;
3685 to
.sin_port
= remote_port
; /* For debugging. */
3687 if (fallback_interface
) {
3688 result
= send_packet(fallback_interface
, NULL
, &raw
,
3689 packet_length
, raw
.siaddr
, &to
,
3692 log_error ("%s:%d: Failed to send %d byte long "
3693 "packet over %s interface.", MDL
,
3695 fallback_interface
->name
);
3699 free_lease_state (state
, MDL
);
3700 lease
-> state
= (struct lease_state
*)0;
3704 /* If the client is RENEWING, unicast to the client using the
3705 regular IP stack. Some clients, particularly those that
3706 follow RFC1541, are buggy, and send both ciaddr and server
3707 identifier. We deal with this situation by assuming that
3708 if we got both dhcp-server-identifier and ciaddr, and
3709 giaddr was not set, then the client is on the local
3710 network, and we can therefore unicast or broadcast to it
3711 successfully. A client in REQUESTING state on another
3712 network that's making this mistake will have set giaddr,
3713 and will therefore get a relayed response from the above
3715 } else if (raw
.ciaddr
.s_addr
&&
3716 !((state
-> got_server_identifier
||
3717 (raw
.flags
& htons (BOOTP_BROADCAST
))) &&
3718 /* XXX This won't work if giaddr isn't zero, but it is: */
3719 (state
-> shared_network
==
3720 lease
-> subnet
-> shared_network
)) &&
3721 state
-> offer
== DHCPACK
) {
3722 to
.sin_addr
= raw
.ciaddr
;
3723 to
.sin_port
= remote_port
;
3725 if (fallback_interface
) {
3726 result
= send_packet(fallback_interface
, NULL
, &raw
,
3727 packet_length
, raw
.siaddr
, &to
,
3730 log_error("%s:%d: Failed to send %d byte long"
3731 " packet over %s interface.", MDL
,
3733 fallback_interface
->name
);
3736 free_lease_state (state
, MDL
);
3737 lease
-> state
= (struct lease_state
*)0;
3741 /* If it comes from a client that already knows its address
3742 and is not requesting a broadcast response, and we can
3743 unicast to a client without using the ARP protocol, sent it
3744 directly to that client. */
3745 } else if (!(raw
.flags
& htons (BOOTP_BROADCAST
)) &&
3746 can_unicast_without_arp (state
-> ip
)) {
3747 to
.sin_addr
= raw
.yiaddr
;
3748 to
.sin_port
= remote_port
;
3750 /* Otherwise, broadcast it on the local network. */
3752 to
.sin_addr
= limited_broadcast
;
3753 to
.sin_port
= remote_port
;
3754 if (!(lease
-> flags
& UNICAST_BROADCAST_HACK
))
3758 memcpy (&from
, state
-> from
.iabuf
, sizeof from
);
3760 result
= send_packet(state
->ip
, NULL
, &raw
, packet_length
,
3761 from
, &to
, unicastp
? &hto
: NULL
);
3763 log_error ("%s:%d: Failed to send %d byte long "
3764 "packet over %s interface.", MDL
,
3765 packet_length
, state
->ip
->name
);
3769 /* Free all of the entries in the option_state structure
3770 now that we're done with them. */
3772 free_lease_state (state
, MDL
);
3773 lease
-> state
= (struct lease_state
*)0;
3776 int find_lease (struct lease
**lp
,
3777 struct packet
*packet
, struct shared_network
*share
, int *ours
,
3778 int *peer_has_leases
, struct lease
*ip_lease_in
,
3779 const char *file
, int line
)
3781 struct lease
*uid_lease
= (struct lease
*)0;
3782 struct lease
*ip_lease
= (struct lease
*)0;
3783 struct lease
*hw_lease
= (struct lease
*)0;
3784 struct lease
*lease
= (struct lease
*)0;
3786 struct host_decl
*hp
= (struct host_decl
*)0;
3787 struct host_decl
*host
= (struct host_decl
*)0;
3788 struct lease
*fixed_lease
= (struct lease
*)0;
3789 struct lease
*next
= (struct lease
*)0;
3790 struct option_cache
*oc
;
3791 struct data_string d1
;
3792 int have_client_identifier
= 0;
3793 struct data_string client_identifier
;
3796 #if defined(FAILOVER_PROTOCOL)
3797 /* Quick check to see if the peer has leases. */
3798 if (peer_has_leases
) {
3801 for (pool
= share
->pools
; pool
; pool
= pool
->next
) {
3802 dhcp_failover_state_t
*peer
= pool
->failover_peer
;
3805 ((peer
->i_am
== primary
&& pool
->backup_leases
) ||
3806 (peer
->i_am
== secondary
&& pool
->free_leases
))) {
3807 *peer_has_leases
= 1;
3812 #endif /* FAILOVER_PROTOCOL */
3814 if (packet
-> raw
-> ciaddr
.s_addr
) {
3816 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
, 4);
3818 /* Look up the requested address. */
3819 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
3820 DHO_DHCP_REQUESTED_ADDRESS
);
3821 memset (&d1
, 0, sizeof d1
);
3823 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
3824 (struct client_state
*)0,
3826 (struct option_state
*)0,
3827 &global_scope
, oc
, MDL
)) {
3828 packet
-> got_requested_address
= 1;
3830 memcpy (cip
.iabuf
, d1
.data
, cip
.len
);
3831 data_string_forget (&d1
, MDL
);
3836 /* Try to find a host or lease that's been assigned to the
3837 specified unique client identifier. */
3838 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
3839 DHO_DHCP_CLIENT_IDENTIFIER
);
3840 memset (&client_identifier
, 0, sizeof client_identifier
);
3842 evaluate_option_cache (&client_identifier
,
3843 packet
, (struct lease
*)0,
3844 (struct client_state
*)0,
3845 packet
-> options
, (struct option_state
*)0,
3846 &global_scope
, oc
, MDL
)) {
3847 /* Remember this for later. */
3848 have_client_identifier
= 1;
3850 /* First, try to find a fixed host entry for the specified
3851 client identifier... */
3852 if (find_hosts_by_uid (&hp
, client_identifier
.data
,
3853 client_identifier
.len
, MDL
)) {
3854 /* Remember if we know of this client. */
3855 packet
-> known
= 1;
3856 mockup_lease (&fixed_lease
, packet
, share
, hp
);
3859 #if defined (DEBUG_FIND_LEASE)
3861 log_info ("Found host for client identifier: %s.",
3862 piaddr (fixed_lease
-> ip_addr
));
3866 if (!fixed_lease
) /* Save the host if we found one. */
3867 host_reference (&host
, hp
, MDL
);
3868 host_dereference (&hp
, MDL
);
3871 find_lease_by_uid (&uid_lease
, client_identifier
.data
,
3872 client_identifier
.len
, MDL
);
3875 /* If we didn't find a fixed lease using the uid, try doing
3876 it with the hardware address... */
3877 if (!fixed_lease
&& !host
) {
3878 if (find_hosts_by_haddr (&hp
, packet
-> raw
-> htype
,
3879 packet
-> raw
-> chaddr
,
3880 packet
-> raw
-> hlen
, MDL
)) {
3881 /* Remember if we know of this client. */
3882 packet
-> known
= 1;
3884 host_dereference (&host
, MDL
);
3885 host_reference (&host
, hp
, MDL
);
3886 host_dereference (&hp
, MDL
);
3887 mockup_lease (&fixed_lease
, packet
, share
, host
);
3888 #if defined (DEBUG_FIND_LEASE)
3890 log_info ("Found host for link address: %s.",
3891 piaddr (fixed_lease
-> ip_addr
));
3897 /* Finally, if we haven't found anything yet try again with the
3898 * host-identifier option ... */
3899 if (!fixed_lease
&& !host
) {
3900 if (find_hosts_by_option(&hp
, packet
,
3901 packet
->options
, MDL
) == 1) {
3904 host_dereference(&host
, MDL
);
3905 host_reference(&host
, hp
, MDL
);
3906 host_dereference(&hp
, MDL
);
3907 mockup_lease (&fixed_lease
, packet
, share
, host
);
3908 #if defined (DEBUG_FIND_LEASE)
3910 log_info ("Found host via host-identifier");
3916 /* If fixed_lease is present but does not match the requested
3917 IP address, and this is a DHCPREQUEST, then we can't return
3918 any other lease, so we might as well return now. */
3919 if (packet
-> packet_type
== DHCPREQUEST
&& fixed_lease
&&
3920 (fixed_lease
-> ip_addr
.len
!= cip
.len
||
3921 memcmp (fixed_lease
-> ip_addr
.iabuf
,
3922 cip
.iabuf
, cip
.len
))) {
3925 strcpy (dhcp_message
, "requested address is incorrect");
3926 #if defined (DEBUG_FIND_LEASE)
3927 log_info ("Client's fixed-address %s doesn't match %s%s",
3928 piaddr (fixed_lease
-> ip_addr
), "request ",
3929 print_dotted_quads (cip
.len
, cip
.iabuf
));
3935 * If we found leases matching the client identifier, loop through
3936 * the n_uid pointer looking for one that's actually valid. We
3937 * can't do this until we get here because we depend on
3938 * packet -> known, which may be set by either the uid host
3939 * lookup or the haddr host lookup.
3941 * Note that the n_uid lease chain is sorted in order of
3942 * preference, so the first one is the best one.
3945 #if defined (DEBUG_FIND_LEASE)
3946 log_info ("trying next lease matching client id: %s",
3947 piaddr (uid_lease
-> ip_addr
));
3950 #if defined (FAILOVER_PROTOCOL)
3952 * When we lookup a lease by uid, we know the client identifier
3953 * matches the lease's record. If it is active, or was last
3954 * active with the same client, we can trivially extend it.
3955 * If is not or was not active, we can allocate it to this
3956 * client if it matches the usual free/backup criteria (which
3957 * is contained in lease_mine_to_reallocate()).
3959 if (uid_lease
->binding_state
!= FTS_ACTIVE
&&
3960 uid_lease
->rewind_binding_state
!= FTS_ACTIVE
&&
3961 !lease_mine_to_reallocate(uid_lease
)) {
3962 #if defined (DEBUG_FIND_LEASE)
3963 log_info("not active or not mine to allocate: %s",
3964 piaddr(uid_lease
->ip_addr
));
3970 if (uid_lease
-> subnet
-> shared_network
!= share
) {
3971 #if defined (DEBUG_FIND_LEASE)
3972 log_info ("wrong network segment: %s",
3973 piaddr (uid_lease
-> ip_addr
));
3978 if ((uid_lease
-> pool
-> prohibit_list
&&
3979 permitted (packet
, uid_lease
-> pool
-> prohibit_list
)) ||
3980 (uid_lease
-> pool
-> permit_list
&&
3981 !permitted (packet
, uid_lease
-> pool
-> permit_list
))) {
3982 #if defined (DEBUG_FIND_LEASE)
3983 log_info ("not permitted: %s",
3984 piaddr (uid_lease
-> ip_addr
));
3987 if (uid_lease
-> n_uid
)
3988 lease_reference (&next
,
3989 uid_lease
-> n_uid
, MDL
);
3990 if (!packet
-> raw
-> ciaddr
.s_addr
)
3991 release_lease (uid_lease
, packet
);
3992 lease_dereference (&uid_lease
, MDL
);
3994 lease_reference (&uid_lease
, next
, MDL
);
3995 lease_dereference (&next
, MDL
);
4001 #if defined (DEBUG_FIND_LEASE)
4003 log_info ("Found lease for client id: %s.",
4004 piaddr (uid_lease
-> ip_addr
));
4007 /* Find a lease whose hardware address matches, whose client
4008 * identifier matches (or equally doesn't have one), that's
4009 * permitted, and that's on the correct subnet.
4011 * Note that the n_hw chain is sorted in order of preference, so
4012 * the first one found is the best one.
4014 h
.hlen
= packet
-> raw
-> hlen
+ 1;
4015 h
.hbuf
[0] = packet
-> raw
-> htype
;
4016 memcpy (&h
.hbuf
[1], packet
-> raw
-> chaddr
, packet
-> raw
-> hlen
);
4017 find_lease_by_hw_addr (&hw_lease
, h
.hbuf
, h
.hlen
, MDL
);
4019 #if defined (DEBUG_FIND_LEASE)
4020 log_info ("trying next lease matching hw addr: %s",
4021 piaddr (hw_lease
-> ip_addr
));
4023 #if defined (FAILOVER_PROTOCOL)
4025 * When we lookup a lease by chaddr, we know the MAC address
4026 * matches the lease record (we will check if the lease has a
4027 * client-id the client does not next). If the lease is
4028 * currently active or was last active with this client, we can
4029 * trivially extend it. Otherwise, there are a set of rules
4030 * that govern if we can reallocate this lease to any client
4031 * ("lease_mine_to_reallocate()") including this one.
4033 if (hw_lease
->binding_state
!= FTS_ACTIVE
&&
4034 hw_lease
->rewind_binding_state
!= FTS_ACTIVE
&&
4035 !lease_mine_to_reallocate(hw_lease
)) {
4036 #if defined (DEBUG_FIND_LEASE)
4037 log_info("not active or not mine to allocate: %s",
4038 piaddr(hw_lease
->ip_addr
));
4045 * This conditional skips "potentially active" leases (leases
4046 * we think are expired may be extended by the peer, etc) that
4047 * may be assigned to a differently /client-identified/ client
4048 * with the same MAC address.
4050 if (hw_lease
-> binding_state
!= FTS_FREE
&&
4051 hw_lease
-> binding_state
!= FTS_BACKUP
&&
4053 (!have_client_identifier
||
4054 hw_lease
-> uid_len
!= client_identifier
.len
||
4055 memcmp (hw_lease
-> uid
, client_identifier
.data
,
4056 hw_lease
-> uid_len
))) {
4057 #if defined (DEBUG_FIND_LEASE)
4058 log_info ("wrong client identifier: %s",
4059 piaddr (hw_lease
-> ip_addr
));
4063 if (hw_lease
-> subnet
-> shared_network
!= share
) {
4064 #if defined (DEBUG_FIND_LEASE)
4065 log_info ("wrong network segment: %s",
4066 piaddr (hw_lease
-> ip_addr
));
4070 if ((hw_lease
-> pool
-> prohibit_list
&&
4071 permitted (packet
, hw_lease
-> pool
-> prohibit_list
)) ||
4072 (hw_lease
-> pool
-> permit_list
&&
4073 !permitted (packet
, hw_lease
-> pool
-> permit_list
))) {
4074 #if defined (DEBUG_FIND_LEASE)
4075 log_info ("not permitted: %s",
4076 piaddr (hw_lease
-> ip_addr
));
4078 if (!packet
-> raw
-> ciaddr
.s_addr
)
4079 release_lease (hw_lease
, packet
);
4081 if (hw_lease
-> n_hw
)
4082 lease_reference (&next
, hw_lease
-> n_hw
, MDL
);
4083 lease_dereference (&hw_lease
, MDL
);
4085 lease_reference (&hw_lease
, next
, MDL
);
4086 lease_dereference (&next
, MDL
);
4092 #if defined (DEBUG_FIND_LEASE)
4094 log_info ("Found lease for hardware address: %s.",
4095 piaddr (hw_lease
-> ip_addr
));
4098 /* Try to find a lease that's been allocated to the client's
4101 lease_reference (&ip_lease
, ip_lease_in
, MDL
);
4103 find_lease_by_ip_addr (&ip_lease
, cip
, MDL
);
4105 #if defined (DEBUG_FIND_LEASE)
4107 log_info ("Found lease for requested address: %s.",
4108 piaddr (ip_lease
-> ip_addr
));
4111 /* If ip_lease is valid at this point, set ours to one, so that
4112 even if we choose a different lease, we know that the address
4113 the client was requesting was ours, and thus we can NAK it. */
4114 if (ip_lease
&& ours
)
4117 /* If the requested IP address isn't on the network the packet
4118 came from, don't use it. Allow abandoned leases to be matched
4119 here - if the client is requesting it, there's a decent chance
4120 that it's because the lease database got trashed and a client
4121 that thought it had this lease answered an ARP or PING, causing the
4122 lease to be abandoned. If so, this request probably came from
4124 if (ip_lease
&& (ip_lease
-> subnet
-> shared_network
!= share
)) {
4127 #if defined (DEBUG_FIND_LEASE)
4128 log_info ("...but it was on the wrong shared network.");
4130 strcpy (dhcp_message
, "requested address on bad subnet");
4131 lease_dereference (&ip_lease
, MDL
);
4135 * If the requested address is in use (or potentially in use) by
4136 * a different client, it can't be granted.
4138 * This first conditional only detects if the lease is currently
4139 * identified to a different client (client-id and/or chaddr
4140 * mismatch). In this case we may not want to give the client the
4141 * lease, if doing so may potentially be an addressing conflict.
4145 (!have_client_identifier
||
4146 ip_lease
-> uid_len
!= client_identifier
.len
||
4147 memcmp (ip_lease
-> uid
, client_identifier
.data
,
4148 ip_lease
-> uid_len
)) :
4149 (ip_lease
-> hardware_addr
.hbuf
[0] != packet
-> raw
-> htype
||
4150 ip_lease
-> hardware_addr
.hlen
!= packet
-> raw
-> hlen
+ 1 ||
4151 memcmp (&ip_lease
-> hardware_addr
.hbuf
[1],
4152 packet
-> raw
-> chaddr
,
4153 (unsigned)(ip_lease
-> hardware_addr
.hlen
- 1))))) {
4155 * A lease is unavailable for allocation to a new client if
4156 * it is not in the FREE or BACKUP state. There may be
4157 * leases that are in the expired state with a rewinding
4158 * state that is free or backup, but these will be processed
4159 * into the free or backup states by expiration processes, so
4160 * checking for them here is superfluous.
4162 if (ip_lease
-> binding_state
!= FTS_FREE
&&
4163 ip_lease
-> binding_state
!= FTS_BACKUP
) {
4164 #if defined (DEBUG_FIND_LEASE)
4165 log_info ("rejecting lease for requested address.");
4167 /* If we're rejecting it because the peer has
4168 it, don't set "ours", because we shouldn't NAK. */
4169 if (ours
&& ip_lease
-> binding_state
!= FTS_ACTIVE
)
4171 lease_dereference (&ip_lease
, MDL
);
4176 * If we got an ip_lease and a uid_lease or hw_lease, and ip_lease
4177 * is/was not active, and is not ours to reallocate, forget about it.
4179 if (ip_lease
&& (uid_lease
|| hw_lease
) &&
4180 ip_lease
->binding_state
!= FTS_ACTIVE
&&
4181 ip_lease
->rewind_binding_state
!= FTS_ACTIVE
&&
4182 #if defined(FAILOVER_PROTOCOL)
4183 !lease_mine_to_reallocate(ip_lease
) &&
4185 packet
->packet_type
== DHCPDISCOVER
) {
4186 #if defined (DEBUG_FIND_LEASE)
4187 log_info("ip lease not active or not ours to offer.");
4189 lease_dereference(&ip_lease
, MDL
);
4192 /* If for some reason the client has more than one lease
4193 on the subnet that matches its uid, pick the one that
4194 it asked for and (if we can) free the other. */
4195 if (ip_lease
&& ip_lease
->binding_state
== FTS_ACTIVE
&&
4196 ip_lease
->uid
&& ip_lease
!= uid_lease
) {
4197 if (have_client_identifier
&&
4198 (ip_lease
-> uid_len
== client_identifier
.len
) &&
4199 !memcmp (client_identifier
.data
,
4200 ip_lease
-> uid
, ip_lease
-> uid_len
)) {
4202 if (uid_lease
->binding_state
== FTS_ACTIVE
) {
4203 log_error ("client %s has duplicate%s on %s",
4205 (packet
-> raw
-> htype
,
4206 packet
-> raw
-> hlen
,
4207 packet
-> raw
-> chaddr
)),
4209 (ip_lease
-> subnet
->
4210 shared_network
-> name
));
4212 /* If the client is REQUESTing the lease,
4213 it shouldn't still be using the old
4214 one, so we can free it for allocation. */
4216 uid_lease
->binding_state
== FTS_ACTIVE
&&
4217 !packet
-> raw
-> ciaddr
.s_addr
&&
4219 uid_lease
-> subnet
-> shared_network
) &&
4220 packet
-> packet_type
== DHCPREQUEST
)
4221 release_lease (uid_lease
, packet
);
4223 lease_dereference (&uid_lease
, MDL
);
4224 lease_reference (&uid_lease
, ip_lease
, MDL
);
4228 /* If we get to here and fixed_lease is not null, that means
4229 that there are both a dynamic lease and a fixed-address
4230 declaration for the same IP address. */
4231 if (packet
-> packet_type
== DHCPREQUEST
&& fixed_lease
) {
4232 lease_dereference (&fixed_lease
, MDL
);
4234 log_error ("Dynamic and static leases present for %s.",
4236 log_error ("Remove host declaration %s or remove %s",
4237 (fixed_lease
&& fixed_lease
-> host
4238 ? (fixed_lease
-> host
-> name
4239 ? fixed_lease
-> host
-> name
4243 log_error ("from the dynamic address pool for %s",
4244 ip_lease
-> subnet
-> shared_network
-> name
4247 lease_dereference (&ip_lease
, MDL
);
4248 strcpy (dhcp_message
,
4249 "database conflict - call for help!");
4252 if (ip_lease
&& ip_lease
!= uid_lease
) {
4253 #if defined (DEBUG_FIND_LEASE)
4254 log_info ("requested address not available.");
4256 lease_dereference (&ip_lease
, MDL
);
4260 /* If we get to here with both fixed_lease and ip_lease not
4261 null, then we have a configuration file bug. */
4262 if (packet
-> packet_type
== DHCPREQUEST
&& fixed_lease
&& ip_lease
)
4265 /* Toss extra pointers to the same lease... */
4266 if (hw_lease
&& hw_lease
== uid_lease
) {
4267 #if defined (DEBUG_FIND_LEASE)
4268 log_info ("hardware lease and uid lease are identical.");
4270 lease_dereference (&hw_lease
, MDL
);
4272 if (ip_lease
&& ip_lease
== hw_lease
) {
4273 lease_dereference (&hw_lease
, MDL
);
4274 #if defined (DEBUG_FIND_LEASE)
4275 log_info ("hardware lease and ip lease are identical.");
4278 if (ip_lease
&& ip_lease
== uid_lease
) {
4279 lease_dereference (&uid_lease
, MDL
);
4280 #if defined (DEBUG_FIND_LEASE)
4281 log_info ("uid lease and ip lease are identical.");
4285 /* Make sure the client is permitted to use the requested lease. */
4287 ((ip_lease
-> pool
-> prohibit_list
&&
4288 permitted (packet
, ip_lease
-> pool
-> prohibit_list
)) ||
4289 (ip_lease
-> pool
-> permit_list
&&
4290 !permitted (packet
, ip_lease
-> pool
-> permit_list
)))) {
4291 if (!packet
->raw
->ciaddr
.s_addr
&&
4292 (ip_lease
->binding_state
== FTS_ACTIVE
))
4293 release_lease (ip_lease
, packet
);
4295 lease_dereference (&ip_lease
, MDL
);
4299 ((uid_lease
-> pool
-> prohibit_list
&&
4300 permitted (packet
, uid_lease
-> pool
-> prohibit_list
)) ||
4301 (uid_lease
-> pool
-> permit_list
&&
4302 !permitted (packet
, uid_lease
-> pool
-> permit_list
)))) {
4303 if (!packet
-> raw
-> ciaddr
.s_addr
)
4304 release_lease (uid_lease
, packet
);
4305 lease_dereference (&uid_lease
, MDL
);
4309 ((hw_lease
-> pool
-> prohibit_list
&&
4310 permitted (packet
, hw_lease
-> pool
-> prohibit_list
)) ||
4311 (hw_lease
-> pool
-> permit_list
&&
4312 !permitted (packet
, hw_lease
-> pool
-> permit_list
)))) {
4313 if (!packet
-> raw
-> ciaddr
.s_addr
)
4314 release_lease (hw_lease
, packet
);
4315 lease_dereference (&hw_lease
, MDL
);
4318 /* If we've already eliminated the lease, it wasn't there to
4319 begin with. If we have come up with a matching lease,
4320 set the message to bad network in case we have to throw it out. */
4322 strcpy (dhcp_message
, "requested address not available");
4325 /* If this is a DHCPREQUEST, make sure the lease we're going to return
4326 matches the requested IP address. If it doesn't, don't return a
4328 if (packet
-> packet_type
== DHCPREQUEST
&&
4329 !ip_lease
&& !fixed_lease
) {
4330 #if defined (DEBUG_FIND_LEASE)
4331 log_info ("no applicable lease found for DHCPREQUEST.");
4336 /* At this point, if fixed_lease is nonzero, we can assign it to
4339 lease_reference (&lease
, fixed_lease
, MDL
);
4340 lease_dereference (&fixed_lease
, MDL
);
4341 #if defined (DEBUG_FIND_LEASE)
4342 log_info ("choosing fixed address.");
4346 /* If we got a lease that matched the ip address and don't have
4347 a better offer, use that; otherwise, release it. */
4350 if (!packet
-> raw
-> ciaddr
.s_addr
)
4351 release_lease (ip_lease
, packet
);
4352 #if defined (DEBUG_FIND_LEASE)
4353 log_info ("not choosing requested address (!).");
4356 #if defined (DEBUG_FIND_LEASE)
4357 log_info ("choosing lease on requested address.");
4359 lease_reference (&lease
, ip_lease
, MDL
);
4361 host_dereference (&lease
-> host
, MDL
);
4363 lease_dereference (&ip_lease
, MDL
);
4366 /* If we got a lease that matched the client identifier, we may want
4367 to use it, but if we already have a lease we like, we must free
4368 the lease that matched the client identifier. */
4371 log_error("uid lease %s for client %s is duplicate "
4373 piaddr(uid_lease
->ip_addr
),
4374 print_hw_addr(packet
->raw
->htype
,
4376 packet
->raw
->chaddr
),
4377 uid_lease
->subnet
->shared_network
->name
);
4379 if (!packet
-> raw
-> ciaddr
.s_addr
&&
4380 packet
-> packet_type
== DHCPREQUEST
&&
4381 uid_lease
-> binding_state
== FTS_ACTIVE
)
4382 release_lease(uid_lease
, packet
);
4383 #if defined (DEBUG_FIND_LEASE)
4384 log_info ("not choosing uid lease.");
4387 lease_reference (&lease
, uid_lease
, MDL
);
4389 host_dereference (&lease
-> host
, MDL
);
4390 #if defined (DEBUG_FIND_LEASE)
4391 log_info ("choosing uid lease.");
4394 lease_dereference (&uid_lease
, MDL
);
4397 /* The lease that matched the hardware address is treated likewise. */
4400 #if defined (DEBUG_FIND_LEASE)
4401 log_info ("not choosing hardware lease.");
4404 /* We're a little lax here - if the client didn't
4405 send a client identifier and it's a bootp client,
4406 but the lease has a client identifier, we still
4407 let the client have a lease. */
4408 if (!hw_lease
-> uid_len
||
4409 (have_client_identifier
4410 ? (hw_lease
-> uid_len
==
4411 client_identifier
.len
&&
4412 !memcmp (hw_lease
-> uid
,
4413 client_identifier
.data
,
4414 client_identifier
.len
))
4415 : packet
-> packet_type
== 0)) {
4416 lease_reference (&lease
, hw_lease
, MDL
);
4418 host_dereference (&lease
-> host
, MDL
);
4419 #if defined (DEBUG_FIND_LEASE)
4420 log_info ("choosing hardware lease.");
4423 #if defined (DEBUG_FIND_LEASE)
4424 log_info ("not choosing hardware lease: %s.",
4429 lease_dereference (&hw_lease
, MDL
);
4433 * If we found a host_decl but no matching address, try to
4434 * find a host_decl that has no address, and if there is one,
4435 * hang it off the lease so that we can use the supplied
4438 if (lease
&& host
&& !lease
->host
) {
4439 struct host_decl
*p
= NULL
;
4440 struct host_decl
*n
= NULL
;
4442 host_reference(&p
, host
, MDL
);
4444 if (!p
->fixed_addr
) {
4446 * If the lease is currently active, then it
4447 * must be allocated to the present client.
4448 * We store a reference to the host record on
4449 * the lease to save a lookup later (in
4450 * ack_lease()). We mustn't refer to the host
4451 * record on non-active leases because the
4452 * client may be denied later.
4454 * XXX: Not having this reference (such as in
4455 * DHCPDISCOVER/INIT) means ack_lease will have
4456 * to perform this lookup a second time. This
4457 * hopefully isn't a problem as DHCPREQUEST is
4458 * more common than DHCPDISCOVER.
4460 if (lease
->binding_state
== FTS_ACTIVE
)
4461 host_reference(&lease
->host
, p
, MDL
);
4463 host_dereference(&p
, MDL
);
4466 if (p
->n_ipaddr
!= NULL
)
4467 host_reference(&n
, p
->n_ipaddr
, MDL
);
4468 host_dereference(&p
, MDL
);
4470 host_reference(&p
, n
, MDL
);
4471 host_dereference(&n
, MDL
);
4476 /* If we find an abandoned lease, but it's the one the client
4477 requested, we assume that previous bugginess on the part
4478 of the client, or a server database loss, caused the lease to
4479 be abandoned, so we reclaim it and let the client have it. */
4481 (lease
-> binding_state
== FTS_ABANDONED
) &&
4482 lease
== ip_lease
&&
4483 packet
-> packet_type
== DHCPREQUEST
) {
4484 log_error ("Reclaiming REQUESTed abandoned IP address %s.",
4485 piaddr (lease
-> ip_addr
));
4486 } else if (lease
&& (lease
-> binding_state
== FTS_ABANDONED
)) {
4487 /* Otherwise, if it's not the one the client requested, we do not
4488 return it - instead, we claim it's ours, causing a DHCPNAK to be
4489 sent if this lookup is for a DHCPREQUEST, and force the client
4490 to go back through the allocation process. */
4493 lease_dereference (&lease
, MDL
);
4497 if (have_client_identifier
)
4498 data_string_forget (&client_identifier
, MDL
);
4501 lease_dereference (&fixed_lease
, MDL
);
4503 lease_dereference (&hw_lease
, MDL
);
4505 lease_dereference (&uid_lease
, MDL
);
4507 lease_dereference (&ip_lease
, MDL
);
4509 host_dereference (&host
, MDL
);
4512 #if defined (DEBUG_FIND_LEASE)
4513 log_info ("Returning lease: %s.",
4514 piaddr (lease
-> ip_addr
));
4516 lease_reference (lp
, lease
, file
, line
);
4517 lease_dereference (&lease
, MDL
);
4520 #if defined (DEBUG_FIND_LEASE)
4521 log_info ("Not returning a lease.");
4526 /* Search the provided host_decl structure list for an address that's on
4527 the specified shared network. If one is found, mock up and return a
4528 lease structure for it; otherwise return the null pointer. */
4530 int mockup_lease (struct lease
**lp
, struct packet
*packet
,
4531 struct shared_network
*share
, struct host_decl
*hp
)
4533 struct lease
*lease
= (struct lease
*)0;
4534 struct host_decl
*rhp
= (struct host_decl
*)0;
4536 if (lease_allocate (&lease
, MDL
) != ISC_R_SUCCESS
)
4538 if (host_reference (&rhp
, hp
, MDL
) != ISC_R_SUCCESS
) {
4539 lease_dereference (&lease
, MDL
);
4542 if (!find_host_for_network (&lease
-> subnet
,
4543 &rhp
, &lease
-> ip_addr
, share
)) {
4544 lease_dereference (&lease
, MDL
);
4545 host_dereference (&rhp
, MDL
);
4548 host_reference (&lease
-> host
, rhp
, MDL
);
4549 if (rhp
-> client_identifier
.len
> sizeof lease
-> uid_buf
)
4550 lease
-> uid
= dmalloc (rhp
-> client_identifier
.len
, MDL
);
4552 lease
-> uid
= lease
-> uid_buf
;
4553 if (!lease
-> uid
) {
4554 lease_dereference (&lease
, MDL
);
4555 host_dereference (&rhp
, MDL
);
4558 memcpy (lease
-> uid
, rhp
-> client_identifier
.data
,
4559 rhp
-> client_identifier
.len
);
4560 lease
-> uid_len
= rhp
-> client_identifier
.len
;
4561 lease
-> hardware_addr
= rhp
-> interface
;
4562 lease
-> starts
= lease
-> cltt
= lease
-> ends
= MIN_TIME
;
4563 lease
-> flags
= STATIC_LEASE
;
4564 lease
-> binding_state
= FTS_FREE
;
4566 lease_reference (lp
, lease
, MDL
);
4568 lease_dereference (&lease
, MDL
);
4569 host_dereference (&rhp
, MDL
);
4573 /* Look through all the pools in a list starting with the specified pool
4574 for a free lease. We try to find a virgin lease if we can. If we
4575 don't find a virgin lease, we try to find a non-virgin lease that's
4576 free. If we can't find one of those, we try to reclaim an abandoned
4577 lease. If all of these possibilities fail to pan out, we don't return
4580 int allocate_lease (struct lease
**lp
, struct packet
*packet
,
4581 struct pool
*pool
, int *peer_has_leases
)
4583 struct lease
*lease
= (struct lease
*)0;
4584 struct lease
*candl
= (struct lease
*)0;
4586 for (; pool
; pool
= pool
-> next
) {
4587 if ((pool
-> prohibit_list
&&
4588 permitted (packet
, pool
-> prohibit_list
)) ||
4589 (pool
-> permit_list
&&
4590 !permitted (packet
, pool
-> permit_list
)))
4593 #if defined (FAILOVER_PROTOCOL)
4594 /* Peer_has_leases just says that we found at least one
4595 free lease. If no free lease is returned, the caller
4596 can deduce that this means the peer is hogging all the
4597 free leases, so we can print a better error message. */
4598 /* XXX Do we need code here to ignore PEER_IS_OWNER and
4599 * XXX just check tstp if we're in, e.g., PARTNER_DOWN?
4600 * XXX Where do we deal with CONFLICT_DETECTED, et al? */
4601 /* XXX This should be handled by the lease binding "state
4602 * XXX machine" - that is, when we get here, if a lease
4603 * XXX could be allocated, it will have the correct
4604 * XXX binding state so that the following code will
4605 * XXX result in its being allocated. */
4606 /* Skip to the most expired lease in the pool that is not
4607 * owned by a failover peer. */
4608 if (pool
->failover_peer
!= NULL
) {
4609 if (pool
->failover_peer
->i_am
== primary
) {
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 if (pool
->backup
!= NULL
) {
4619 if (((candl
== NULL
) ||
4621 pool
->backup
->ends
)) &&
4622 lease_mine_to_reallocate(
4624 candl
= pool
->backup
;
4626 *peer_has_leases
= 1;
4630 candl
= pool
->backup
;
4632 if (pool
->free
!= NULL
) {
4633 if (((candl
== NULL
) ||
4635 pool
->free
->ends
)) &&
4636 lease_mine_to_reallocate(
4640 *peer_has_leases
= 1;
4645 /* Try abandoned leases as a last resort. */
4646 if ((candl
== NULL
) &&
4647 (pool
->abandoned
!= NULL
) &&
4648 lease_mine_to_reallocate(pool
->abandoned
))
4649 candl
= pool
->abandoned
;
4654 candl
= pool
-> free
;
4656 candl
= pool
-> abandoned
;
4660 * XXX: This may not match with documented expectation.
4661 * It's expected that when we OFFER a lease, we set its
4662 * ends time forward 2 minutes so that it gets sorted to
4663 * the end of its free list (avoiding a similar allocation
4664 * to another client). It is not expected that we issue a
4665 * "no free leases" error when the last lease has been
4666 * offered, but it's not exactly broken either.
4668 if (!candl
|| (candl
-> ends
> cur_time
))
4677 * There are tiers of lease state preference, listed here in
4678 * reverse order (least to most preferential):
4683 * If the selected lease and candidate are both of the same
4684 * state, select the oldest (longest ago) expiration time
4685 * between the two. If the candidate lease is of a higher
4686 * preferred grade over the selected lease, use it.
4688 if ((lease
-> binding_state
== FTS_ABANDONED
) &&
4689 ((candl
-> binding_state
!= FTS_ABANDONED
) ||
4690 (candl
-> ends
< lease
-> ends
))) {
4693 } else if (candl
-> binding_state
== FTS_ABANDONED
)
4696 if ((lease
-> uid_len
|| lease
-> hardware_addr
.hlen
) &&
4697 ((!candl
-> uid_len
&& !candl
-> hardware_addr
.hlen
) ||
4698 (candl
-> ends
< lease
-> ends
))) {
4701 } else if (candl
-> uid_len
|| candl
-> hardware_addr
.hlen
)
4704 if (candl
-> ends
< lease
-> ends
)
4708 if (lease
!= NULL
) {
4709 if (lease
->binding_state
== FTS_ABANDONED
)
4710 log_error("Reclaiming abandoned lease %s.",
4711 piaddr(lease
->ip_addr
));
4714 * XXX: For reliability, we go ahead and remove the host
4715 * record and try to move on. For correctness, if there
4716 * are any other stale host vectors, we want to find them.
4718 if (lease
->host
!= NULL
) {
4719 log_debug("soft impossible condition (%s:%d): stale "
4720 "host \"%s\" found on lease %s", MDL
,
4722 piaddr(lease
->ip_addr
));
4723 host_dereference(&lease
->host
, MDL
);
4726 lease_reference (lp
, lease
, MDL
);
4733 /* Determine whether or not a permit exists on a particular permit list
4734 that matches the specified packet, returning nonzero if so, zero if
4737 int permitted (packet
, permit_list
)
4738 struct packet
*packet
;
4739 struct permit
*permit_list
;
4744 for (p
= permit_list
; p
; p
= p
-> next
) {
4745 switch (p
-> type
) {
4746 case permit_unknown_clients
:
4747 if (!packet
-> known
)
4751 case permit_known_clients
:
4752 if (packet
-> known
)
4756 case permit_authenticated_clients
:
4757 if (packet
-> authenticated
)
4761 case permit_unauthenticated_clients
:
4762 if (!packet
-> authenticated
)
4766 case permit_all_clients
:
4769 case permit_dynamic_bootp_clients
:
4770 if (!packet
-> options_valid
||
4771 !packet
-> packet_type
)
4776 for (i
= 0; i
< packet
-> class_count
; i
++) {
4777 if (p
-> class == packet
-> classes
[i
])
4779 if (packet
-> classes
[i
] &&
4780 packet
-> classes
[i
] -> superclass
&&
4781 (packet
-> classes
[i
] -> superclass
==
4788 if (cur_time
> p
->after
)
4796 int locate_network (packet
)
4797 struct packet
*packet
;
4800 struct data_string data
;
4801 struct subnet
*subnet
= (struct subnet
*)0;
4802 struct option_cache
*oc
;
4804 /* See if there's a Relay Agent Link Selection Option, or a
4805 * Subnet Selection Option. The Link-Select and Subnet-Select
4806 * are formatted and used precisely the same, but we must prefer
4807 * the link-select over the subnet-select.
4809 if ((oc
= lookup_option(&agent_universe
, packet
->options
,
4810 RAI_LINK_SELECT
)) == NULL
)
4811 oc
= lookup_option(&dhcp_universe
, packet
->options
,
4812 DHO_SUBNET_SELECTION
);
4814 /* If there's no SSO and no giaddr, then use the shared_network
4815 from the interface, if there is one. If not, fail. */
4816 if (!oc
&& !packet
-> raw
-> giaddr
.s_addr
) {
4817 if (packet
-> interface
-> shared_network
) {
4818 shared_network_reference
4819 (&packet
-> shared_network
,
4820 packet
-> interface
-> shared_network
, MDL
);
4826 /* If there's an option indicating link connection, and it's valid,
4827 * use it to figure out the subnet. If it's not valid, fail.
4830 memset (&data
, 0, sizeof data
);
4831 if (!evaluate_option_cache (&data
, packet
, (struct lease
*)0,
4832 (struct client_state
*)0,
4834 (struct option_state
*)0,
4835 &global_scope
, oc
, MDL
)) {
4838 if (data
.len
!= 4) {
4842 memcpy (ia
.iabuf
, data
.data
, 4);
4843 data_string_forget (&data
, MDL
);
4846 memcpy (ia
.iabuf
, &packet
-> raw
-> giaddr
, 4);
4849 /* If we know the subnet on which the IP address lives, use it. */
4850 if (find_subnet (&subnet
, ia
, MDL
)) {
4851 shared_network_reference (&packet
-> shared_network
,
4852 subnet
-> shared_network
, MDL
);
4853 subnet_dereference (&subnet
, MDL
);
4857 /* Otherwise, fail. */
4862 * Try to figure out the source address to send packets from.
4864 * from is the address structure we use to return any address
4867 * options is the option cache to search. This may include
4868 * options from the incoming packet and configuration information.
4870 * out_options is the outgoing option cache. This cache
4871 * may be the same as options. If out_options isn't NULL
4872 * we may save the server address option into it. We do so
4873 * if out_options is different than options or if the option
4874 * wasn't in options and we needed to find the address elsewhere.
4876 * packet is the state structure for the incoming packet
4878 * When finding the address we first check to see if it is
4879 * in the options list. If it isn't we use the first address
4880 * from the interface.
4882 * While this is slightly more complicated than I'd like it allows
4883 * us to use the same code in several different places. ack,
4884 * inform and lease query use it to find the address and fill
4885 * in the options if we get the address from the interface.
4886 * nack uses it to find the address and copy it to the outgoing
4887 * cache. dhcprequest uses it to find the address for comparison
4888 * and doesn't need to add it to an outgoing list.
4892 get_server_source_address(struct in_addr
*from
,
4893 struct option_state
*options
,
4894 struct option_state
*out_options
,
4895 struct packet
*packet
) {
4896 unsigned option_num
;
4897 struct option_cache
*oc
= NULL
;
4898 struct data_string d
;
4899 struct in_addr
*a
= NULL
;
4900 isc_boolean_t found
= ISC_FALSE
;
4903 memset(&d
, 0, sizeof(d
));
4904 memset(from
, 0, sizeof(*from
));
4906 option_num
= DHO_DHCP_SERVER_IDENTIFIER
;
4907 oc
= lookup_option(&dhcp_universe
, options
, option_num
);
4909 if (evaluate_option_cache(&d
, packet
, NULL
, NULL
,
4910 packet
->options
, options
,
4911 &global_scope
, oc
, MDL
)) {
4912 if (d
.len
== sizeof(*from
)) {
4914 memcpy(from
, d
.data
, sizeof(*from
));
4917 * Arrange to save a copy of the data
4918 * to the outgoing list.
4920 if ((out_options
!= NULL
) &&
4921 (options
!= out_options
)) {
4926 data_string_forget(&d
, MDL
);
4931 if ((found
== ISC_FALSE
) &&
4932 (packet
->interface
->address_count
> 0)) {
4933 *from
= packet
->interface
->addresses
[0];
4935 if (out_options
!= NULL
) {
4936 a
= &packet
->interface
->addresses
[0];
4941 (option_cache_allocate(&oc
, MDL
))) {
4942 if (make_const_data(&oc
->expression
,
4943 (unsigned char *)a
, sizeof(*a
),
4944 0, allocate
, MDL
)) {
4945 option_code_hash_lookup(&oc
->option
,
4946 dhcp_universe
.code_hash
,
4947 &option_num
, 0, MDL
);
4948 save_option(&dhcp_universe
, out_options
, oc
);
4950 option_cache_dereference(&oc
, MDL
);
4957 * \brief Builds option set from statements at the global and network scope
4959 * Set up an option state list based on the global and network scopes.
4960 * These are primarily used by NAK logic to locate dhcp-server-id and
4963 * We don't go through all possible options - in particualr we skip the hosts
4964 * and we don't include the lease to avoid making changes to it. This means
4965 * that using these, we won't get the correct server id if the admin puts them
4966 * on hosts or builds the server id with information from the lease.
4968 * As this is a fallback function (used to handle NAKs or sort out server id
4969 * mismatch in failover) and requires configuration by the admin, it should be
4972 * \param network_options option_state to which options will be added. If it
4973 * refers to NULL, it will be allocated. Caller is responsible to delete it.
4974 * \param packet inbound packet
4975 * \param network_group scope group to use if packet->shared_network is null.
4978 eval_network_statements(struct option_state
**network_options
,
4979 struct packet
*packet
,
4980 struct group
*network_group
) {
4982 if (*network_options
== NULL
) {
4983 option_state_allocate (network_options
, MDL
);
4986 /* Use the packet's shared_network if it has one. If not use
4987 * network_group and if it is null then use global scope. */
4988 if (packet
->shared_network
!= NULL
) {
4990 * If we have a subnet and group start with that else start
4991 * with the shared network group. The first will recurse and
4992 * include the second.
4994 if ((packet
->shared_network
->subnets
!= NULL
) &&
4995 (packet
->shared_network
->subnets
->group
!= NULL
)) {
4996 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
4997 packet
->options
, *network_options
,
4999 packet
->shared_network
->subnets
->group
,
5002 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5003 packet
->options
, *network_options
,
5005 packet
->shared_network
->group
,
5009 /* do the pool if there is one */
5010 if (packet
->shared_network
->pools
!= NULL
) {
5011 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5012 packet
->options
, *network_options
,
5014 packet
->shared_network
->pools
->group
,
5015 packet
->shared_network
->group
,
5018 } else if (network_group
!= NULL
) {
5019 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5020 packet
->options
, *network_options
,
5021 &global_scope
, network_group
,
5024 execute_statements_in_scope(NULL
, packet
, NULL
, NULL
,
5025 packet
->options
, *network_options
,
5026 &global_scope
, root_group
,
5032 * Look for the lowest numbered site code number and
5033 * apply a log warning if it is less than 224. Do not
5034 * permit site codes less than 128 (old code never did).
5036 * Note that we could search option codes 224 down to 128
5037 * on the hash table, but the table is (probably) smaller
5038 * than that if it was declared as a standalone table with
5039 * defaults. So we traverse the option code hash.
5042 find_min_site_code(struct universe
*u
)
5044 if (u
->site_code_min
)
5045 return u
->site_code_min
;
5048 * Note that site_code_min has to be global as we can't pass an
5049 * argument through hash_foreach(). The value 224 is taken from
5052 site_code_min
= 224;
5053 option_code_hash_foreach(u
->code_hash
, lowest_site_code
);
5055 if (site_code_min
< 224) {
5056 log_error("WARNING: site-local option codes less than 224 have "
5057 "been deprecated by RFC3942. You have options "
5058 "listed in site local space %s that number as low as "
5059 "%d. Please investigate if these should be declared "
5060 "as regular options rather than site-local options, "
5061 "or migrated up past 224.",
5062 u
->name
, site_code_min
);
5066 * don't even bother logging, this is just silly, and never worked
5067 * on any old version of software.
5069 if (site_code_min
< 128)
5070 site_code_min
= 128;
5073 * Cache the determined minimum site code on the universe structure.
5074 * Note that due to the < 128 check above, a value of zero is
5077 u
->site_code_min
= site_code_min
;
5079 return site_code_min
;
5083 lowest_site_code(const void *key
, unsigned len
, void *object
)
5085 struct option
*option
= object
;
5087 if (option
->code
< site_code_min
)
5088 site_code_min
= option
->code
;
5090 return ISC_R_SUCCESS
;
5094 maybe_return_agent_options(struct packet
*packet
, struct option_state
*options
)
5096 /* If there were agent options in the incoming packet, return
5097 * them. Do not return the agent options if they were stashed
5098 * on the lease. We do not check giaddr to detect the presence of
5099 * a relay, as this excludes "l2" relay agents which have no giaddr
5102 * XXX: If the user configures options for the relay agent information
5103 * (state->options->universes[agent_universe.index] is not NULL),
5104 * we're still required to duplicate other values provided by the
5105 * relay agent. So we need to merge the old values not configured
5106 * by the user into the new state, not just give up.
5108 if (!packet
->agent_options_stashed
&&
5109 (packet
->options
!= NULL
) &&
5110 packet
->options
->universe_count
> agent_universe
.index
&&
5111 packet
->options
->universes
[agent_universe
.index
] != NULL
&&
5112 (options
->universe_count
<= agent_universe
.index
||
5113 options
->universes
[agent_universe
.index
] == NULL
)) {
5114 option_chain_head_reference
5115 ((struct option_chain_head
**)
5116 &(options
->universes
[agent_universe
.index
]),
5117 (struct option_chain_head
*)
5118 packet
->options
->universes
[agent_universe
.index
], MDL
);
5120 if (options
->universe_count
<= agent_universe
.index
)
5121 options
->universe_count
= agent_universe
.index
+ 1;
5126 * \brief Adds hostname option when use-host-decl-names is enabled.
5128 * Constructs a hostname option from the name of the host declaration if
5129 * there is one and no hostname has otherwise been provided and the
5130 * use-host-decl-names flag is set, then adds the new option to the given
5131 * option_state. This funciton is used for both bootp and dhcp.
5133 * \param packet inbound packet received from the client
5134 * \param lease lease associated with the client
5135 * \param options option state to search and update
5137 void use_host_decl_name(struct packet
* packet
,
5138 struct lease
*lease
,
5139 struct option_state
*options
) {
5140 unsigned int ocode
= SV_USE_HOST_DECL_NAMES
;
5141 if ((lease
->host
&& lease
->host
->name
) &&
5142 !lookup_option(&dhcp_universe
, options
, DHO_HOST_NAME
) &&
5143 (evaluate_boolean_option_cache(NULL
, packet
, lease
, NULL
,
5144 packet
->options
, options
,
5146 lookup_option(&server_universe
,
5149 struct option_cache
*oc
= NULL
;
5150 if (option_cache_allocate (&oc
, MDL
)) {
5151 if (make_const_data(&oc
-> expression
,
5152 ((unsigned char*)lease
->host
->name
),
5153 strlen(lease
->host
->name
),
5155 ocode
= DHO_HOST_NAME
;
5156 option_code_hash_lookup(&oc
->option
,
5157 dhcp_universe
.code_hash
,
5159 save_option(&dhcp_universe
, options
, oc
);
5161 option_cache_dereference(&oc
, MDL
);