3 DHCP Protocol engine. */
6 * Copyright (c) 2004-2008 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/
27 * This software has been written for Internet Systems Consortium
28 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
29 * To learn more about Internet Systems Consortium, see
30 * ``https://www.isc.org/''. To learn more about Vixie Enterprises,
31 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
32 * ``http://www.nominum.com''.
40 static void commit_leases_ackout(void *foo
);
41 static void maybe_return_agent_options(struct packet
*packet
,
42 struct option_state
*options
);
44 int outstanding_pings
;
46 struct leasequeue
*ackqueue_head
, *ackqueue_tail
;
47 static struct leasequeue
*free_ackqueue
;
48 static struct timeval next_fsync
;
50 int max_outstanding_acks
= DEFAULT_DELAYED_ACK
;
51 int max_ack_delay_secs
= DEFAULT_ACK_DELAY_SECS
;
52 int max_ack_delay_usecs
= DEFAULT_ACK_DELAY_USECS
;
54 static char dhcp_message
[256];
55 static int site_code_min
;
57 static int find_min_site_code(struct universe
*);
58 static isc_result_t
lowest_site_code(const void *, unsigned, void *);
60 static const char *dhcp_type_names
[] = {
71 "DHCPLEASEUNASSIGNED",
75 const int dhcp_type_name_max
= ((sizeof dhcp_type_names
) / sizeof (char *));
78 # define send_packet trace_packet_send
82 dhcp (struct packet
*packet
) {
84 struct option_cache
*oc
;
85 struct lease
*lease
= NULL
;
87 struct data_string data
;
89 if (!locate_network(packet
) &&
90 packet
->packet_type
!= DHCPREQUEST
&&
91 packet
->packet_type
!= DHCPINFORM
&&
92 packet
->packet_type
!= DHCPLEASEQUERY
) {
95 errmsg
= "unknown network segment";
98 if (packet
->packet_type
> 0 &&
99 packet
->packet_type
<= dhcp_type_name_max
) {
100 s
= dhcp_type_names
[packet
->packet_type
- 1];
102 /* %Audit% Cannot exceed 28 bytes. %2004.06.17,Safe% */
103 sprintf(typebuf
, "type %d", packet
->packet_type
);
107 log_info("%s from %s via %s: %s", s
,
109 ? print_hw_addr(packet
->raw
->htype
,
112 : "<no identifier>"),
113 packet
->raw
->giaddr
.s_addr
114 ? inet_ntoa(packet
->raw
->giaddr
)
115 : packet
->interface
->name
, errmsg
);
119 /* There is a problem with the relay agent information option,
120 * which is that in order for a normal relay agent to append
121 * this option, the relay agent has to have been involved in
122 * getting the packet from the client to the server. Note
123 * that this is the software entity known as the relay agent,
124 * _not_ the hardware entity known as a router in which the
125 * relay agent may be running, so the fact that a router has
126 * forwarded a packet does not mean that the relay agent in
127 * the router was involved.
129 * So when the client broadcasts (DHCPDISCOVER, or giaddr is set),
130 * we can be sure that there are either agent options in the
131 * packet, or there aren't supposed to be. When the giaddr is not
132 * set, it's still possible that the client is on a directly
133 * attached subnet, and agent options are being appended by an l2
134 * device that has no address, and so sets no giaddr.
136 * But in either case it's possible that the packets we receive
137 * from the client in RENEW state may not include the agent options,
138 * so if they are not in the packet we must "pretend" the last values
139 * we observed were provided.
141 if (packet
->packet_type
== DHCPREQUEST
&&
142 packet
->raw
->ciaddr
.s_addr
&& !packet
->raw
->giaddr
.s_addr
&&
143 (packet
->options
->universe_count
<= agent_universe
.index
||
144 packet
->options
->universes
[agent_universe
.index
] == NULL
))
148 cip
.len
= sizeof packet
-> raw
-> ciaddr
;
149 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
,
150 sizeof packet
-> raw
-> ciaddr
);
151 if (!find_lease_by_ip_addr (&lease
, cip
, MDL
))
154 /* If there are no agent options on the lease, it's not
156 if (!lease
-> agent_options
)
159 /* The client should not be unicasting a renewal if its lease
160 has expired, so make it go through the process of getting
161 its agent options legally. */
162 if (lease
-> ends
< cur_time
)
165 if (lease
-> uid_len
) {
166 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
167 DHO_DHCP_CLIENT_IDENTIFIER
);
171 memset (&data
, 0, sizeof data
);
172 if (!evaluate_option_cache (&data
,
173 packet
, (struct lease
*)0,
174 (struct client_state
*)0,
176 (struct option_state
*)0,
177 &global_scope
, oc
, MDL
))
179 if (lease
-> uid_len
!= data
.len
||
180 memcmp (lease
-> uid
, data
.data
, data
.len
)) {
181 data_string_forget (&data
, MDL
);
184 data_string_forget (&data
, MDL
);
186 if ((lease
-> hardware_addr
.hbuf
[0] !=
187 packet
-> raw
-> htype
) ||
188 (lease
-> hardware_addr
.hlen
- 1 !=
189 packet
-> raw
-> hlen
) ||
190 memcmp (&lease
-> hardware_addr
.hbuf
[1],
191 packet
-> raw
-> chaddr
,
192 packet
-> raw
-> hlen
))
195 /* Okay, so we found a lease that matches the client. */
196 option_chain_head_reference ((struct option_chain_head
**)
197 &(packet
-> options
-> universes
198 [agent_universe
.index
]),
199 lease
-> agent_options
, MDL
);
201 if (packet
->options
->universe_count
<= agent_universe
.index
)
202 packet
->options
->universe_count
=
203 agent_universe
.index
+ 1;
205 packet
->agent_options_stashed
= ISC_TRUE
;
209 /* If a client null terminates options it sends, it probably
210 * expects the server to reciprocate.
212 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
214 if (!oc
-> expression
)
215 ms_nulltp
= oc
->flags
& OPTION_HAD_NULLS
;
218 /* Classify the client. */
219 classify_client (packet
);
221 switch (packet
-> packet_type
) {
223 dhcpdiscover (packet
, ms_nulltp
);
227 dhcprequest (packet
, ms_nulltp
, lease
);
231 dhcprelease (packet
, ms_nulltp
);
235 dhcpdecline (packet
, ms_nulltp
);
239 dhcpinform (packet
, ms_nulltp
);
243 dhcpleasequery(packet
, ms_nulltp
);
249 case DHCPLEASEUNASSIGNED
:
250 case DHCPLEASEUNKNOWN
:
251 case DHCPLEASEACTIVE
:
255 errmsg
= "unknown packet type";
260 lease_dereference (&lease
, MDL
);
263 void dhcpdiscover (packet
, ms_nulltp
)
264 struct packet
*packet
;
267 struct lease
*lease
= (struct lease
*)0;
268 char msgbuf
[1024]; /* XXX */
271 int peer_has_leases
= 0;
272 #if defined (FAILOVER_PROTOCOL)
273 dhcp_failover_state_t
*peer
;
276 find_lease (&lease
, packet
, packet
-> shared_network
,
277 0, &peer_has_leases
, (struct lease
*)0, MDL
);
279 if (lease
&& lease
-> client_hostname
) {
280 if ((strlen (lease
-> client_hostname
) <= 64) &&
281 db_printable((unsigned char *)lease
->client_hostname
))
282 s
= lease
-> client_hostname
;
284 s
= "Hostname Unsuitable for Printing";
288 /* %Audit% This is log output. %2004.06.17,Safe%
289 * If we truncate we hope the user can get a hint from the log.
291 snprintf (msgbuf
, sizeof msgbuf
, "DHCPDISCOVER from %s %s%s%svia %s",
292 (packet
-> raw
-> htype
293 ? print_hw_addr (packet
-> raw
-> htype
,
294 packet
-> raw
-> hlen
,
295 packet
-> raw
-> chaddr
)
297 ? print_hex_1(lease
->uid_len
, lease
->uid
, 60)
298 : "<no identifier>")),
299 s
? "(" : "", s
? s
: "", s
? ") " : "",
300 packet
-> raw
-> giaddr
.s_addr
301 ? inet_ntoa (packet
-> raw
-> giaddr
)
302 : packet
-> interface
-> name
);
304 /* Sourceless packets don't make sense here. */
305 if (!packet
-> shared_network
) {
306 log_info ("Packet from unknown subnet: %s",
307 inet_ntoa (packet
-> raw
-> giaddr
));
311 #if defined (FAILOVER_PROTOCOL)
312 if (lease
&& lease
-> pool
&& lease
-> pool
-> failover_peer
) {
313 peer
= lease
-> pool
-> failover_peer
;
315 /* If the lease is ours to allocate, then allocate it.
316 * If the lease is active, it belongs to the client. This
317 * is the right lease, if we are to offer one. We decide
318 * whether or not to offer later on.
320 if (lease
->binding_state
== FTS_ACTIVE
||
321 lease_mine_to_reallocate(lease
)) {
322 ; /* This space intentionally left blank. */
324 /* Otherwise, we can't let the client have this lease. */
326 #if defined (DEBUG_FIND_LEASE)
327 log_debug ("discarding %s - %s",
328 piaddr (lease
-> ip_addr
),
329 binding_state_print (lease
-> binding_state
));
331 lease_dereference (&lease
, MDL
);
336 /* If we didn't find a lease, try to allocate one... */
338 if (!allocate_lease (&lease
, packet
,
339 packet
-> shared_network
-> pools
,
342 log_error ("%s: peer holds all free leases",
345 log_error ("%s: network %s: no free leases",
347 packet
-> shared_network
-> name
);
352 #if defined (FAILOVER_PROTOCOL)
353 if (lease
&& lease
-> pool
&& lease
-> pool
-> failover_peer
) {
354 peer
= lease
-> pool
-> failover_peer
;
355 if (peer
-> service_state
== not_responding
||
356 peer
-> service_state
== service_startup
) {
357 log_info ("%s: not responding%s",
358 msgbuf
, peer
-> nrr
);
362 peer
= (dhcp_failover_state_t
*)0;
364 /* Do load balancing if configured. */
365 if (peer
&& (peer
-> service_state
== cooperating
) &&
366 !load_balance_mine (packet
, peer
)) {
367 if (peer_has_leases
) {
368 log_debug ("%s: load balance to peer %s",
369 msgbuf
, peer
-> name
);
372 log_debug ("%s: cancel load balance to peer %s - %s",
373 msgbuf
, peer
-> name
, "no free leases");
378 /* If it's an expired lease, get rid of any bindings. */
379 if (lease
-> ends
< cur_time
&& lease
-> scope
)
380 binding_scope_dereference (&lease
-> scope
, MDL
);
382 /* Set the lease to really expire in 2 minutes, unless it has
383 not yet expired, in which case leave its expiry time alone. */
384 when
= cur_time
+ 120;
385 if (when
< lease
-> ends
)
386 when
= lease
-> ends
;
388 ack_lease (packet
, lease
, DHCPOFFER
, when
, msgbuf
, ms_nulltp
,
389 (struct host_decl
*)0);
392 lease_dereference (&lease
, MDL
);
395 void dhcprequest (packet
, ms_nulltp
, ip_lease
)
396 struct packet
*packet
;
398 struct lease
*ip_lease
;
403 struct subnet
*subnet
;
405 struct option_cache
*oc
;
406 struct data_string data
;
407 char msgbuf
[1024]; /* XXX */
410 #if defined (FAILOVER_PROTOCOL)
411 dhcp_failover_state_t
*peer
;
413 int have_server_identifier
= 0;
414 int have_requested_addr
= 0;
416 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
417 DHO_DHCP_REQUESTED_ADDRESS
);
418 memset (&data
, 0, sizeof data
);
420 evaluate_option_cache (&data
, packet
, (struct lease
*)0,
421 (struct client_state
*)0,
422 packet
-> options
, (struct option_state
*)0,
423 &global_scope
, oc
, MDL
)) {
425 memcpy (cip
.iabuf
, data
.data
, 4);
426 data_string_forget (&data
, MDL
);
427 have_requested_addr
= 1;
429 oc
= (struct option_cache
*)0;
431 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
.s_addr
, 4);
434 /* Find the lease that matches the address requested by the
437 subnet
= (struct subnet
*)0;
438 lease
= (struct lease
*)0;
439 if (find_subnet (&subnet
, cip
, MDL
))
440 find_lease (&lease
, packet
,
441 subnet
-> shared_network
, &ours
, 0, ip_lease
, MDL
);
443 if (lease
&& lease
-> client_hostname
) {
444 if ((strlen (lease
-> client_hostname
) <= 64) &&
445 db_printable((unsigned char *)lease
->client_hostname
))
446 s
= lease
-> client_hostname
;
448 s
= "Hostname Unsuitable for Printing";
452 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
453 DHO_DHCP_SERVER_IDENTIFIER
);
454 memset (&data
, 0, sizeof data
);
456 evaluate_option_cache (&data
, packet
, (struct lease
*)0,
457 (struct client_state
*)0,
458 packet
-> options
, (struct option_state
*)0,
459 &global_scope
, oc
, MDL
)) {
461 memcpy (sip
.iabuf
, data
.data
, 4);
462 data_string_forget (&data
, MDL
);
463 /* piaddr() should not return more than a 15 byte string.
466 sprintf (smbuf
, " (%s)", piaddr (sip
));
467 have_server_identifier
= 1;
471 /* %Audit% This is log output. %2004.06.17,Safe%
472 * If we truncate we hope the user can get a hint from the log.
474 snprintf (msgbuf
, sizeof msgbuf
,
475 "DHCPREQUEST for %s%s from %s %s%s%svia %s",
477 (packet
-> raw
-> htype
478 ? print_hw_addr (packet
-> raw
-> htype
,
479 packet
-> raw
-> hlen
,
480 packet
-> raw
-> chaddr
)
482 ? print_hex_1(lease
->uid_len
, lease
->uid
, 60)
483 : "<no identifier>")),
484 s
? "(" : "", s
? s
: "", s
? ") " : "",
485 packet
-> raw
-> giaddr
.s_addr
486 ? inet_ntoa (packet
-> raw
-> giaddr
)
487 : packet
-> interface
-> name
);
489 #if defined (FAILOVER_PROTOCOL)
490 if (lease
&& lease
-> pool
&& lease
-> pool
-> failover_peer
) {
491 peer
= lease
-> pool
-> failover_peer
;
492 if (peer
-> service_state
== not_responding
||
493 peer
-> service_state
== service_startup
) {
494 log_info ("%s: not responding%s",
495 msgbuf
, peer
-> nrr
);
499 /* "load balance to peer" - is not done at all for request.
501 * If it's RENEWING, we are the only server to hear it, so
502 * we have to serve it. If it's REBINDING, it's out of
503 * communication with the other server, so there's no point
504 * in waiting to serve it. However, if the lease we're
505 * offering is not a free lease, then we may be the only
506 * server that can offer it, so we can't load balance if
507 * the lease isn't in the free or backup state. If it is
508 * in the free or backup state, then that state is what
509 * mandates one server or the other should perform the
510 * allocation, not the LBA...we know the peer cannot
511 * allocate a request for an address in our free state.
513 * So our only compass is lease_mine_to_reallocate(). This
514 * effects both load balancing, and a sanity-check that we
515 * are not going to try to allocate a lease that isn't ours.
517 if ((lease
-> binding_state
== FTS_FREE
||
518 lease
-> binding_state
== FTS_BACKUP
) &&
519 !lease_mine_to_reallocate (lease
)) {
520 log_debug ("%s: lease owned by peer", msgbuf
);
524 /* If the lease is in a transitional state, we can't
526 if ((lease
-> binding_state
== FTS_RELEASED
||
527 lease
-> binding_state
== FTS_EXPIRED
) &&
528 !lease_mine_to_reallocate (lease
)) {
529 log_debug ("%s: lease in transition state %s", msgbuf
,
530 lease
-> binding_state
== FTS_RELEASED
531 ? "released" : "expired");
535 /* It's actually very unlikely that we'll ever get here,
536 but if we do, tell the client to stop using the lease,
537 because the administrator reset it. */
538 if (lease
-> binding_state
== FTS_RESET
&&
539 !lease_mine_to_reallocate (lease
)) {
540 log_debug ("%s: lease reset by administrator", msgbuf
);
541 nak_lease (packet
, &cip
);
545 /* At this point it's possible that we will get a broadcast
546 DHCPREQUEST for a lease that we didn't offer, because
547 both we and the peer are in a position to offer it.
548 In that case, we probably shouldn't answer. In order
549 to not answer, we would have to compare the server
550 identifier sent by the client with the list of possible
551 server identifiers we can send, and if the client's
552 identifier isn't on the list, drop the DHCPREQUEST.
553 We aren't currently doing that for two reasons - first,
554 it's not clear that all clients do the right thing
555 with respect to sending the client identifier, which
556 could mean that we might simply not respond to a client
557 that is depending on us to respond. Secondly, we allow
558 the user to specify the server identifier to send, and
559 we don't enforce that the server identifier should be
560 one of our IP addresses. This is probably not a big
561 deal, but it's theoretically an issue.
563 The reason we care about this is that if both servers
564 send a DHCPACK to the DHCPREQUEST, they are then going
565 to send dueling BNDUPD messages, which could cause
566 trouble. I think it causes no harm, but it seems
569 peer
= (dhcp_failover_state_t
*)0;
572 /* If a client on a given network REQUESTs a lease on an
573 address on a different network, NAK it. If the Requested
574 Address option was used, the protocol says that it must
575 have been broadcast, so we can trust the source network
578 If ciaddr was specified and Requested Address was not, then
579 we really only know for sure what network a packet came from
580 if it came through a BOOTP gateway - if it came through an
581 IP router, we'll just have to assume that it's cool.
583 If we don't think we know where the packet came from, it
584 came through a gateway from an unknown network, so it's not
585 from a RENEWING client. If we recognize the network it
586 *thinks* it's on, we can NAK it even though we don't
587 recognize the network it's *actually* on; otherwise we just
590 We don't currently try to take advantage of access to the
591 raw packet, because it's not available on all platforms.
592 So a packet that was unicast to us through a router from a
593 RENEWING client is going to look exactly like a packet that
594 was broadcast to us from an INIT-REBOOT client.
596 Since we can't tell the difference between these two kinds
597 of packets, if the packet appears to have come in off the
598 local wire, we have to treat it as if it's a RENEWING
599 client. This means that we can't NAK a RENEWING client on
600 the local wire that has a bogus address. The good news is
601 that we won't ACK it either, so it should revert to INIT
602 state and send us a DHCPDISCOVER, which we *can* work with.
604 Because we can't detect that a RENEWING client is on the
605 wrong wire, it's going to sit there trying to renew until
606 it gets to the REBIND state, when we *can* NAK it because
607 the packet will get to us through a BOOTP gateway. We
608 shouldn't actually see DHCPREQUEST packets from RENEWING
609 clients on the wrong wire anyway, since their idea of their
610 local router will be wrong. In any case, the protocol
611 doesn't really allow us to NAK a DHCPREQUEST from a
612 RENEWING client, so we can punt on this issue. */
614 if (!packet
-> shared_network
||
615 (packet
-> raw
-> ciaddr
.s_addr
&&
616 packet
-> raw
-> giaddr
.s_addr
) ||
617 (have_requested_addr
&& !packet
-> raw
-> ciaddr
.s_addr
)) {
619 /* If we don't know where it came from but we do know
620 where it claims to have come from, it didn't come
622 if (!packet
-> shared_network
) {
623 if (subnet
&& subnet
-> group
-> authoritative
) {
624 log_info ("%s: wrong network.", msgbuf
);
625 nak_lease (packet
, &cip
);
628 /* Otherwise, ignore it. */
629 log_info ("%s: ignored (%s).", msgbuf
,
631 ? "not authoritative" : "unknown subnet"));
635 /* If we do know where it came from and it asked for an
636 address that is not on that shared network, nak it. */
638 subnet_dereference (&subnet
, MDL
);
639 if (!find_grouped_subnet (&subnet
, packet
-> shared_network
,
641 if (packet
-> shared_network
-> group
-> authoritative
)
643 log_info ("%s: wrong network.", msgbuf
);
644 nak_lease (packet
, &cip
);
647 log_info ("%s: ignored (not authoritative).", msgbuf
);
652 /* If the address the client asked for is ours, but it wasn't
653 available for the client, NAK it. */
654 if (!lease
&& ours
) {
655 log_info ("%s: lease %s unavailable.", msgbuf
, piaddr (cip
));
656 nak_lease (packet
, &cip
);
660 /* Otherwise, send the lease to the client if we found one. */
662 ack_lease (packet
, lease
, DHCPACK
, 0, msgbuf
, ms_nulltp
,
663 (struct host_decl
*)0);
665 log_info ("%s: unknown lease %s.", msgbuf
, piaddr (cip
));
669 subnet_dereference (&subnet
, MDL
);
671 lease_dereference (&lease
, MDL
);
675 void dhcprelease (packet
, ms_nulltp
)
676 struct packet
*packet
;
679 struct lease
*lease
= (struct lease
*)0, *next
= (struct lease
*)0;
681 struct option_cache
*oc
;
682 struct data_string data
;
684 char msgbuf
[1024], cstr
[16]; /* XXX */
687 /* DHCPRELEASE must not specify address in requested-address
688 option, but old protocol specs weren't explicit about this,
690 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
691 DHO_DHCP_REQUESTED_ADDRESS
))) {
692 log_info ("DHCPRELEASE from %s specified requested-address.",
693 print_hw_addr (packet
-> raw
-> htype
,
694 packet
-> raw
-> hlen
,
695 packet
-> raw
-> chaddr
));
698 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
699 DHO_DHCP_CLIENT_IDENTIFIER
);
700 memset (&data
, 0, sizeof data
);
702 evaluate_option_cache (&data
, packet
, (struct lease
*)0,
703 (struct client_state
*)0,
704 packet
-> options
, (struct option_state
*)0,
705 &global_scope
, oc
, MDL
)) {
706 find_lease_by_uid (&lease
, data
.data
, data
.len
, MDL
);
707 data_string_forget (&data
, MDL
);
709 /* See if we can find a lease that matches the IP address
710 the client is claiming. */
713 lease_reference (&next
, lease
-> n_uid
, MDL
);
714 if (!memcmp (&packet
-> raw
-> ciaddr
,
715 lease
-> ip_addr
.iabuf
, 4)) {
718 lease_dereference (&lease
, MDL
);
720 lease_reference (&lease
, next
, MDL
);
721 lease_dereference (&next
, MDL
);
725 lease_dereference (&next
, MDL
);
728 /* The client is supposed to pass a valid client-identifier,
729 but the spec on this has changed historically, so try the
730 IP address in ciaddr if the client-identifier fails. */
733 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
, 4);
734 find_lease_by_ip_addr (&lease
, cip
, MDL
);
738 /* If the hardware address doesn't match, don't do the release. */
740 (lease
-> hardware_addr
.hlen
!= packet
-> raw
-> hlen
+ 1 ||
741 lease
-> hardware_addr
.hbuf
[0] != packet
-> raw
-> htype
||
742 memcmp (&lease
-> hardware_addr
.hbuf
[1],
743 packet
-> raw
-> chaddr
, packet
-> raw
-> hlen
)))
744 lease_dereference (&lease
, MDL
);
746 if (lease
&& lease
-> client_hostname
) {
747 if ((strlen (lease
-> client_hostname
) <= 64) &&
748 db_printable((unsigned char *)lease
->client_hostname
))
749 s
= lease
-> client_hostname
;
751 s
= "Hostname Unsuitable for Printing";
755 /* %Audit% Cannot exceed 16 bytes. %2004.06.17,Safe%
756 * We copy this out to stack because we actually want to log two
757 * inet_ntoa()'s in this message.
759 strncpy(cstr
, inet_ntoa (packet
-> raw
-> ciaddr
), 15);
762 /* %Audit% This is log output. %2004.06.17,Safe%
763 * If we truncate we hope the user can get a hint from the log.
765 snprintf (msgbuf
, sizeof msgbuf
,
766 "DHCPRELEASE of %s from %s %s%s%svia %s (%sfound)",
768 (packet
-> raw
-> htype
769 ? print_hw_addr (packet
-> raw
-> htype
,
770 packet
-> raw
-> hlen
,
771 packet
-> raw
-> chaddr
)
773 ? print_hex_1(lease
->uid_len
, lease
->uid
, 60)
774 : "<no identifier>")),
775 s
? "(" : "", s
? s
: "", s
? ") " : "",
776 packet
-> raw
-> giaddr
.s_addr
777 ? inet_ntoa (packet
-> raw
-> giaddr
)
778 : packet
-> interface
-> name
,
779 lease
? "" : "not ");
781 #if defined (FAILOVER_PROTOCOL)
782 if (lease
&& lease
-> pool
&& lease
-> pool
-> failover_peer
) {
783 dhcp_failover_state_t
*peer
= lease
-> pool
-> failover_peer
;
784 if (peer
-> service_state
== not_responding
||
785 peer
-> service_state
== service_startup
) {
786 log_info ("%s: ignored%s",
787 peer
-> name
, peer
-> nrr
);
791 /* DHCPRELEASE messages are unicast, so if the client
792 sent the DHCPRELEASE to us, it's not going to send it
793 to the peer. Not sure why this would happen, and
794 if it does happen I think we still have to change the
795 lease state, so that's what we're doing.
796 XXX See what it says in the draft about this. */
800 /* If we found a lease, release it. */
801 if (lease
&& lease
-> ends
> cur_time
) {
802 release_lease (lease
, packet
);
804 log_info ("%s", msgbuf
);
805 #if defined(FAILOVER_PROTOCOL)
809 lease_dereference (&lease
, MDL
);
812 void dhcpdecline (packet
, ms_nulltp
)
813 struct packet
*packet
;
816 struct lease
*lease
= (struct lease
*)0;
817 struct option_state
*options
= (struct option_state
*)0;
822 char msgbuf
[1024]; /* XXX */
824 struct option_cache
*oc
;
825 struct data_string data
;
827 /* DHCPDECLINE must specify address. */
828 if (!(oc
= lookup_option (&dhcp_universe
, packet
-> options
,
829 DHO_DHCP_REQUESTED_ADDRESS
)))
831 memset (&data
, 0, sizeof data
);
832 if (!evaluate_option_cache (&data
, packet
, (struct lease
*)0,
833 (struct client_state
*)0,
835 (struct option_state
*)0,
836 &global_scope
, oc
, MDL
))
840 memcpy (cip
.iabuf
, data
.data
, 4);
841 data_string_forget (&data
, MDL
);
842 find_lease_by_ip_addr (&lease
, cip
, MDL
);
844 if (lease
&& lease
-> client_hostname
) {
845 if ((strlen (lease
-> client_hostname
) <= 64) &&
846 db_printable((unsigned char *)lease
->client_hostname
))
847 s
= lease
-> client_hostname
;
849 s
= "Hostname Unsuitable for Printing";
853 /* %Audit% This is log output. %2004.06.17,Safe%
854 * If we truncate we hope the user can get a hint from the log.
856 snprintf (msgbuf
, sizeof msgbuf
,
857 "DHCPDECLINE of %s from %s %s%s%svia %s",
859 (packet
-> raw
-> htype
860 ? print_hw_addr (packet
-> raw
-> htype
,
861 packet
-> raw
-> hlen
,
862 packet
-> raw
-> chaddr
)
864 ? print_hex_1(lease
->uid_len
, lease
->uid
, 60)
865 : "<no identifier>")),
866 s
? "(" : "", s
? s
: "", s
? ") " : "",
867 packet
-> raw
-> giaddr
.s_addr
868 ? inet_ntoa (packet
-> raw
-> giaddr
)
869 : packet
-> interface
-> name
);
871 option_state_allocate (&options
, MDL
);
873 /* Execute statements in scope starting with the subnet scope. */
875 execute_statements_in_scope ((struct binding_value
**)0,
876 packet
, (struct lease
*)0,
877 (struct client_state
*)0,
878 packet
-> options
, options
,
880 lease
-> subnet
-> group
,
883 /* Execute statements in the class scopes. */
884 for (i
= packet
-> class_count
; i
> 0; i
--) {
885 execute_statements_in_scope
886 ((struct binding_value
**)0, packet
, (struct lease
*)0,
887 (struct client_state
*)0, packet
-> options
, options
,
888 &global_scope
, packet
-> classes
[i
- 1] -> group
,
889 lease
? lease
-> subnet
-> group
: (struct group
*)0);
892 /* Drop the request if dhcpdeclines are being ignored. */
893 oc
= lookup_option (&server_universe
, options
, SV_DECLINES
);
895 evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
896 (struct client_state
*)0,
897 packet
-> options
, options
,
898 &lease
-> scope
, oc
, MDL
)) {
899 /* If we found a lease, mark it as unusable and complain. */
901 #if defined (FAILOVER_PROTOCOL)
902 if (lease
-> pool
&& lease
-> pool
-> failover_peer
) {
903 dhcp_failover_state_t
*peer
=
904 lease
-> pool
-> failover_peer
;
905 if (peer
-> service_state
== not_responding
||
906 peer
-> service_state
== service_startup
) {
908 log_info ("%s: ignored%s",
909 peer
-> name
, peer
-> nrr
);
913 /* DHCPDECLINE messages are broadcast, so we can safely
914 ignore the DHCPDECLINE if the peer has the lease.
915 XXX Of course, at this point that information has been
920 abandon_lease (lease
, "declined.");
921 status
= "abandoned";
923 status
= "not found";
929 log_info ("%s: %s", msgbuf
, status
);
931 #if defined(FAILOVER_PROTOCOL)
935 option_state_dereference (&options
, MDL
);
937 lease_dereference (&lease
, MDL
);
940 void dhcpinform (packet
, ms_nulltp
)
941 struct packet
*packet
;
945 struct data_string d1
, prl
;
946 struct option_cache
*oc
;
947 struct option_state
*options
= (struct option_state
*)0;
948 struct dhcp_packet raw
;
949 struct packet outgoing
;
950 unsigned char dhcpack
= DHCPACK
;
951 struct subnet
*subnet
= NULL
;
952 struct iaddr cip
, gip
;
955 struct sockaddr_in to
;
957 isc_boolean_t zeroed_ciaddr
;
959 /* The client should set ciaddr to its IP address, but apparently
960 it's common for clients not to do this, so we'll use their IP
961 source address if they didn't set ciaddr. */
962 if (!packet
-> raw
-> ciaddr
.s_addr
) {
963 zeroed_ciaddr
= ISC_TRUE
;
965 memcpy (cip
.iabuf
, &packet
-> client_addr
.iabuf
, 4);
967 zeroed_ciaddr
= ISC_FALSE
;
969 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
, 4);
972 if (packet
->raw
->giaddr
.s_addr
) {
974 memcpy(gip
.iabuf
, &packet
->raw
->giaddr
, 4);
978 /* %Audit% This is log output. %2004.06.17,Safe%
979 * If we truncate we hope the user can get a hint from the log.
981 snprintf (msgbuf
, sizeof msgbuf
, "DHCPINFORM from %s via %s",
982 piaddr (cip
), packet
->raw
->giaddr
.s_addr
?
983 inet_ntoa(packet
->raw
->giaddr
) :
984 packet
-> interface
-> name
);
986 /* If the IP source address is zero, don't respond. */
987 if (!memcmp (cip
.iabuf
, "\0\0\0", 4)) {
988 log_info ("%s: ignored (null source address).", msgbuf
);
992 /* Find the subnet that the client is on. */
993 if (zeroed_ciaddr
&& (gip
.len
!= 0)) {
994 /* XXX - do subnet selection relay agent suboption here */
995 find_subnet(&subnet
, gip
, MDL
);
997 if (subnet
== NULL
) {
998 log_info("%s: unknown subnet for relay address %s",
999 msgbuf
, piaddr(gip
));
1003 /* XXX - do subnet selection (not relay agent) option here */
1004 find_subnet(&subnet
, cip
, MDL
);
1006 if (subnet
== NULL
) {
1007 log_info("%s: unknown subnet for %s address %s",
1008 msgbuf
, zeroed_ciaddr
? "source" : "client",
1014 /* We don't respond to DHCPINFORM packets if we're not authoritative.
1015 It would be nice if a per-host value could override this, but
1016 there's overhead involved in checking this, so let's see how people
1018 if (subnet
&& !subnet
-> group
-> authoritative
) {
1020 log_info ("%s: not authoritative for subnet %s",
1021 msgbuf
, piaddr (subnet
-> net
));
1023 log_info ("If this DHCP server is authoritative for%s",
1025 log_info ("please write an `authoritative;' directi%s",
1026 "ve either in the");
1027 log_info ("subnet declaration or in some scope that%s",
1029 log_info ("subnet declaration - for example, write %s",
1031 log_info ("of the dhcpd.conf file.");
1035 subnet_dereference (&subnet
, MDL
);
1039 option_state_allocate (&options
, MDL
);
1040 memset (&outgoing
, 0, sizeof outgoing
);
1041 memset (&raw
, 0, sizeof raw
);
1042 outgoing
.raw
= &raw
;
1044 maybe_return_agent_options(packet
, options
);
1046 /* Execute statements in scope starting with the subnet scope. */
1048 execute_statements_in_scope ((struct binding_value
**)0,
1049 packet
, (struct lease
*)0,
1050 (struct client_state
*)0,
1051 packet
-> options
, options
,
1052 &global_scope
, subnet
-> group
,
1055 /* Execute statements in the class scopes. */
1056 for (i
= packet
-> class_count
; i
> 0; i
--) {
1057 execute_statements_in_scope
1058 ((struct binding_value
**)0, packet
, (struct lease
*)0,
1059 (struct client_state
*)0, packet
-> options
, options
,
1060 &global_scope
, packet
-> classes
[i
- 1] -> group
,
1061 subnet
? subnet
-> group
: (struct group
*)0);
1064 /* Figure out the filename. */
1065 memset (&d1
, 0, sizeof d1
);
1066 oc
= lookup_option (&server_universe
, options
, SV_FILENAME
);
1068 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1069 (struct client_state
*)0,
1070 packet
-> options
, (struct option_state
*)0,
1071 &global_scope
, oc
, MDL
)) {
1073 if (i
> sizeof raw
.file
)
1074 i
= sizeof raw
.file
;
1077 memcpy (raw
.file
, d1
.data
, i
);
1078 data_string_forget (&d1
, MDL
);
1081 /* Choose a server name as above. */
1082 oc
= lookup_option (&server_universe
, options
, SV_SERVER_NAME
);
1084 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1085 (struct client_state
*)0,
1086 packet
-> options
, (struct option_state
*)0,
1087 &global_scope
, oc
, MDL
)) {
1089 if (i
> sizeof raw
.sname
)
1090 i
= sizeof raw
.sname
;
1093 memcpy (raw
.sname
, d1
.data
, i
);
1094 data_string_forget (&d1
, MDL
);
1097 /* Set a flag if this client is a lame Microsoft client that NUL
1098 terminates string options and expects us to do likewise. */
1100 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
1102 if (!oc
->expression
)
1103 nulltp
= oc
->flags
& OPTION_HAD_NULLS
;
1106 /* Put in DHCP-specific options. */
1107 i
= DHO_DHCP_MESSAGE_TYPE
;
1108 oc
= (struct option_cache
*)0;
1109 if (option_cache_allocate (&oc
, MDL
)) {
1110 if (make_const_data (&oc
-> expression
,
1111 &dhcpack
, 1, 0, 0, MDL
)) {
1112 option_code_hash_lookup(&oc
->option
,
1113 dhcp_universe
.code_hash
,
1115 save_option (&dhcp_universe
, options
, oc
);
1117 option_cache_dereference (&oc
, MDL
);
1120 get_server_source_address(&from
, options
, packet
);
1122 /* Use the subnet mask from the subnet declaration if no other
1123 mask has been provided. */
1124 i
= DHO_SUBNET_MASK
;
1125 if (subnet
&& !lookup_option (&dhcp_universe
, options
, i
)) {
1126 oc
= (struct option_cache
*)0;
1127 if (option_cache_allocate (&oc
, MDL
)) {
1128 if (make_const_data (&oc
-> expression
,
1129 subnet
-> netmask
.iabuf
,
1130 subnet
-> netmask
.len
,
1132 option_code_hash_lookup(&oc
->option
,
1133 dhcp_universe
.code_hash
,
1135 save_option (&dhcp_universe
, options
, oc
);
1137 option_cache_dereference (&oc
, MDL
);
1141 /* If a site option space has been specified, use that for
1142 site option codes. */
1143 i
= SV_SITE_OPTION_SPACE
;
1144 if ((oc
= lookup_option (&server_universe
, options
, i
)) &&
1145 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1146 (struct client_state
*)0,
1147 packet
-> options
, options
,
1148 &global_scope
, oc
, MDL
)) {
1149 struct universe
*u
= (struct universe
*)0;
1151 if (!universe_hash_lookup (&u
, universe_hash
,
1152 (const char *)d1
.data
, d1
.len
,
1154 log_error ("unknown option space %s.", d1
.data
);
1155 option_state_dereference (&options
, MDL
);
1157 subnet_dereference (&subnet
, MDL
);
1161 options
-> site_universe
= u
-> index
;
1162 options
->site_code_min
= find_min_site_code(u
);
1163 data_string_forget (&d1
, MDL
);
1165 options
-> site_universe
= dhcp_universe
.index
;
1166 options
-> site_code_min
= 0; /* Trust me, it works. */
1169 memset (&prl
, 0, sizeof prl
);
1171 /* Use the parameter list from the scope if there is one. */
1172 oc
= lookup_option (&dhcp_universe
, options
,
1173 DHO_DHCP_PARAMETER_REQUEST_LIST
);
1175 /* Otherwise, if the client has provided a list of options
1176 that it wishes returned, use it to prioritize. Otherwise,
1177 prioritize based on the default priority list. */
1180 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
1181 DHO_DHCP_PARAMETER_REQUEST_LIST
);
1184 evaluate_option_cache (&prl
, packet
, (struct lease
*)0,
1185 (struct client_state
*)0,
1186 packet
-> options
, options
,
1187 &global_scope
, oc
, MDL
);
1190 dump_packet (packet
);
1191 dump_raw ((unsigned char *)packet
-> raw
, packet
-> packet_length
);
1194 log_info ("%s", msgbuf
);
1196 /* Figure out the address of the boot file server. */
1198 lookup_option (&server_universe
, options
, SV_NEXT_SERVER
))) {
1199 if (evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1200 (struct client_state
*)0,
1201 packet
-> options
, options
,
1202 &global_scope
, oc
, MDL
)) {
1203 /* If there was more than one answer,
1205 if (d1
.len
>= 4 && d1
.data
)
1206 memcpy (&raw
.siaddr
, d1
.data
, 4);
1207 data_string_forget (&d1
, MDL
);
1211 /* Set up the option buffer... */
1212 outgoing
.packet_length
=
1213 cons_options (packet
, outgoing
.raw
, (struct lease
*)0,
1214 (struct client_state
*)0,
1215 0, packet
-> options
, options
, &global_scope
,
1217 prl
.len
? &prl
: (struct data_string
*)0,
1219 option_state_dereference (&options
, MDL
);
1220 data_string_forget (&prl
, MDL
);
1222 /* Make sure that the packet is at least as big as a BOOTP packet. */
1223 if (outgoing
.packet_length
< BOOTP_MIN_LEN
)
1224 outgoing
.packet_length
= BOOTP_MIN_LEN
;
1226 raw
.giaddr
= packet
-> raw
-> giaddr
;
1227 raw
.ciaddr
= packet
-> raw
-> ciaddr
;
1228 memcpy (raw
.chaddr
, packet
-> raw
-> chaddr
, sizeof raw
.chaddr
);
1229 raw
.hlen
= packet
-> raw
-> hlen
;
1230 raw
.htype
= packet
-> raw
-> htype
;
1232 raw
.xid
= packet
-> raw
-> xid
;
1233 raw
.secs
= packet
-> raw
-> secs
;
1234 raw
.flags
= packet
-> raw
-> flags
;
1235 raw
.hops
= packet
-> raw
-> hops
;
1239 dump_packet (&outgoing
);
1240 dump_raw ((unsigned char *)&raw
, outgoing
.packet_length
);
1243 /* Set up the common stuff... */
1244 to
.sin_family
= AF_INET
;
1246 to
.sin_len
= sizeof to
;
1248 memset (to
.sin_zero
, 0, sizeof to
.sin_zero
);
1250 /* RFC2131 states the server SHOULD unciast to ciaddr.
1251 * There are two wrinkles - relays, and when ciaddr is zero.
1252 * There's actually no mention of relays at all in rfc2131 in
1253 * regard to DHCPINFORM, except to say we might get packets from
1254 * clients via them. Note: relays unicast to clients to the
1255 * "yiaddr" address, which servers are forbidden to set when
1256 * answering an inform.
1258 * The solution: If ciaddr is zero, and giaddr is set, go via the
1259 * relay with the broadcast flag set to help the relay (with no
1260 * yiaddr and very likely no chaddr, it will have no idea where to
1263 * If the ciaddr is zero and giaddr is not set, go via the source
1264 * IP address (but you are permitted to barf on their shoes).
1266 * If ciaddr is not zero, send the packet there always.
1268 if (!raw
.ciaddr
.s_addr
&& gip
.len
) {
1269 memcpy(&to
.sin_addr
, gip
.iabuf
, 4);
1270 to
.sin_port
= local_port
;
1271 raw
.flags
|= htons(BOOTP_BROADCAST
);
1274 memcpy(&to
.sin_addr
, cip
.iabuf
, 4);
1275 to
.sin_port
= remote_port
;
1278 /* Report what we're sending. */
1279 snprintf(msgbuf
, sizeof msgbuf
, "DHCPACK to %s (%s) via", piaddr(cip
),
1280 (packet
->raw
->htype
&& packet
->raw
->hlen
) ?
1281 print_hw_addr(packet
->raw
->htype
, packet
->raw
->hlen
,
1282 packet
->raw
->chaddr
) :
1283 "<no client hardware address>");
1284 log_info("%s %s", msgbuf
, gip
.len
? piaddr(gip
) :
1285 packet
->interface
->name
);
1288 send_packet ((fallback_interface
1289 ? fallback_interface
: packet
-> interface
),
1290 &outgoing
, &raw
, outgoing
.packet_length
,
1291 from
, &to
, (struct hardware
*)0);
1293 subnet_dereference (&subnet
, MDL
);
1296 void nak_lease (packet
, cip
)
1297 struct packet
*packet
;
1300 struct sockaddr_in to
;
1301 struct in_addr from
;
1303 struct dhcp_packet raw
;
1304 unsigned char nak
= DHCPNAK
;
1305 struct packet outgoing
;
1306 struct hardware hto
;
1308 struct option_state
*options
= (struct option_state
*)0;
1309 struct option_cache
*oc
= (struct option_cache
*)0;
1311 option_state_allocate (&options
, MDL
);
1312 memset (&outgoing
, 0, sizeof outgoing
);
1313 memset (&raw
, 0, sizeof raw
);
1314 outgoing
.raw
= &raw
;
1316 /* Set DHCP_MESSAGE_TYPE to DHCPNAK */
1317 if (!option_cache_allocate (&oc
, MDL
)) {
1318 log_error ("No memory for DHCPNAK message type.");
1319 option_state_dereference (&options
, MDL
);
1322 if (!make_const_data (&oc
-> expression
, &nak
, sizeof nak
,
1324 log_error ("No memory for expr_const expression.");
1325 option_cache_dereference (&oc
, MDL
);
1326 option_state_dereference (&options
, MDL
);
1329 i
= DHO_DHCP_MESSAGE_TYPE
;
1330 option_code_hash_lookup(&oc
->option
, dhcp_universe
.code_hash
,
1332 save_option (&dhcp_universe
, options
, oc
);
1333 option_cache_dereference (&oc
, MDL
);
1335 /* Set DHCP_MESSAGE to whatever the message is */
1336 if (!option_cache_allocate (&oc
, MDL
)) {
1337 log_error ("No memory for DHCPNAK message type.");
1338 option_state_dereference (&options
, MDL
);
1341 if (!make_const_data (&oc
-> expression
,
1342 (unsigned char *)dhcp_message
,
1343 strlen (dhcp_message
), 1, 0, MDL
)) {
1344 log_error ("No memory for expr_const expression.");
1345 option_cache_dereference (&oc
, MDL
);
1346 option_state_dereference (&options
, MDL
);
1349 i
= DHO_DHCP_MESSAGE
;
1350 option_code_hash_lookup(&oc
->option
, dhcp_universe
.code_hash
,
1352 save_option (&dhcp_universe
, options
, oc
);
1353 option_cache_dereference (&oc
, MDL
);
1355 get_server_source_address(&from
, options
, packet
);
1357 /* If there were agent options in the incoming packet, return
1358 * them. We do not check giaddr to detect the presence of a
1359 * relay, as this excludes "l2" relay agents which have no
1362 if (packet
->options
->universe_count
> agent_universe
.index
&&
1363 packet
->options
->universes
[agent_universe
.index
]) {
1364 option_chain_head_reference
1365 ((struct option_chain_head
**)
1366 &(options
-> universes
[agent_universe
.index
]),
1367 (struct option_chain_head
*)
1368 packet
-> options
-> universes
[agent_universe
.index
],
1372 /* Do not use the client's requested parameter list. */
1373 delete_option (&dhcp_universe
, packet
-> options
,
1374 DHO_DHCP_PARAMETER_REQUEST_LIST
);
1376 /* Set up the option buffer... */
1377 outgoing
.packet_length
=
1378 cons_options (packet
, outgoing
.raw
, (struct lease
*)0,
1379 (struct client_state
*)0,
1380 0, packet
-> options
, options
, &global_scope
,
1381 0, 0, 0, (struct data_string
*)0, (char *)0);
1382 option_state_dereference (&options
, MDL
);
1384 /* memset (&raw.ciaddr, 0, sizeof raw.ciaddr);*/
1385 if (packet
->interface
->address_count
)
1386 raw
.siaddr
= packet
->interface
->addresses
[0];
1387 raw
.giaddr
= packet
-> raw
-> giaddr
;
1388 memcpy (raw
.chaddr
, packet
-> raw
-> chaddr
, sizeof raw
.chaddr
);
1389 raw
.hlen
= packet
-> raw
-> hlen
;
1390 raw
.htype
= packet
-> raw
-> htype
;
1392 raw
.xid
= packet
-> raw
-> xid
;
1393 raw
.secs
= packet
-> raw
-> secs
;
1394 raw
.flags
= packet
-> raw
-> flags
| htons (BOOTP_BROADCAST
);
1395 raw
.hops
= packet
-> raw
-> hops
;
1398 /* Report what we're sending... */
1399 log_info ("DHCPNAK on %s to %s via %s",
1401 print_hw_addr (packet
-> raw
-> htype
,
1402 packet
-> raw
-> hlen
,
1403 packet
-> raw
-> chaddr
),
1404 packet
-> raw
-> giaddr
.s_addr
1405 ? inet_ntoa (packet
-> raw
-> giaddr
)
1406 : packet
-> interface
-> name
);
1411 dump_packet (packet
);
1412 dump_raw ((unsigned char *)packet
-> raw
, packet
-> packet_length
);
1413 dump_packet (&outgoing
);
1414 dump_raw ((unsigned char *)&raw
, outgoing
.packet_length
);
1418 hto
.hbuf
[0] = packet
-> raw
-> htype
;
1419 hto
.hlen
= packet
-> raw
-> hlen
;
1420 memcpy (&hto
.hbuf
[1], packet
-> raw
-> chaddr
, hto
.hlen
);
1424 /* Set up the common stuff... */
1425 to
.sin_family
= AF_INET
;
1427 to
.sin_len
= sizeof to
;
1429 memset (to
.sin_zero
, 0, sizeof to
.sin_zero
);
1431 /* Make sure that the packet is at least as big as a BOOTP packet. */
1432 if (outgoing
.packet_length
< BOOTP_MIN_LEN
)
1433 outgoing
.packet_length
= BOOTP_MIN_LEN
;
1435 /* If this was gatewayed, send it back to the gateway.
1436 Otherwise, broadcast it on the local network. */
1437 if (raw
.giaddr
.s_addr
) {
1438 to
.sin_addr
= raw
.giaddr
;
1439 if (raw
.giaddr
.s_addr
!= htonl (INADDR_LOOPBACK
))
1440 to
.sin_port
= local_port
;
1442 to
.sin_port
= remote_port
; /* for testing. */
1444 if (fallback_interface
) {
1445 result
= send_packet (fallback_interface
,
1447 outgoing
.packet_length
,
1452 to
.sin_addr
= limited_broadcast
;
1453 to
.sin_port
= remote_port
;
1457 result
= send_packet (packet
-> interface
,
1458 packet
, &raw
, outgoing
.packet_length
,
1459 from
, &to
, (struct hardware
*)0);
1462 void ack_lease (packet
, lease
, offer
, when
, msg
, ms_nulltp
, hp
)
1463 struct packet
*packet
;
1464 struct lease
*lease
;
1469 struct host_decl
*hp
;
1472 struct lease_state
*state
;
1474 struct host_decl
*host
= (struct host_decl
*)0;
1476 TIME offered_lease_time
;
1477 struct data_string d1
;
1478 TIME min_lease_time
;
1479 TIME max_lease_time
;
1480 TIME default_lease_time
;
1481 struct option_cache
*oc
;
1482 isc_result_t result
;
1485 struct in_addr from
;
1486 TIME remaining_time
;
1494 /* If we're already acking this lease, don't do it again. */
1498 /* Save original cltt for comparison later. */
1499 lease_cltt
= lease
->cltt
;
1501 /* If the lease carries a host record, remember it. */
1503 host_reference (&host
, hp
, MDL
);
1504 else if (lease
-> host
)
1505 host_reference (&host
, lease
-> host
, MDL
);
1507 /* Allocate a lease state structure... */
1508 state
= new_lease_state (MDL
);
1510 log_fatal ("unable to allocate lease state!");
1511 state
-> got_requested_address
= packet
-> got_requested_address
;
1512 shared_network_reference (&state
-> shared_network
,
1513 packet
-> interface
-> shared_network
, MDL
);
1515 /* See if we got a server identifier option. */
1516 if (lookup_option (&dhcp_universe
,
1517 packet
-> options
, DHO_DHCP_SERVER_IDENTIFIER
))
1518 state
-> got_server_identifier
= 1;
1520 maybe_return_agent_options(packet
, state
->options
);
1522 /* If we are offering a lease that is still currently valid, preserve
1523 the events. We need to do this because if the client does not
1524 REQUEST our offer, it will expire in 2 minutes, overriding the
1525 expire time in the currently in force lease. We want the expire
1526 events to be executed at that point. */
1527 if (lease
-> ends
<= cur_time
&& offer
!= DHCPOFFER
) {
1528 /* Get rid of any old expiry or release statements - by
1529 executing the statements below, we will be inserting new
1530 ones if there are any to insert. */
1531 if (lease
-> on_expiry
)
1532 executable_statement_dereference (&lease
-> on_expiry
,
1534 if (lease
-> on_commit
)
1535 executable_statement_dereference (&lease
-> on_commit
,
1537 if (lease
-> on_release
)
1538 executable_statement_dereference (&lease
-> on_release
,
1542 /* Execute statements in scope starting with the subnet scope. */
1543 execute_statements_in_scope ((struct binding_value
**)0,
1544 packet
, lease
, (struct client_state
*)0,
1546 state
-> options
, &lease
-> scope
,
1547 lease
-> subnet
-> group
,
1550 /* If the lease is from a pool, run the pool scope. */
1552 (execute_statements_in_scope
1553 ((struct binding_value
**)0, packet
, lease
,
1554 (struct client_state
*)0, packet
-> options
,
1555 state
-> options
, &lease
-> scope
, lease
-> pool
-> group
,
1556 lease
-> pool
-> shared_network
-> group
));
1558 /* Execute statements from class scopes. */
1559 for (i
= packet
-> class_count
; i
> 0; i
--) {
1560 execute_statements_in_scope
1561 ((struct binding_value
**)0,
1562 packet
, lease
, (struct client_state
*)0,
1563 packet
-> options
, state
-> options
,
1564 &lease
-> scope
, packet
-> classes
[i
- 1] -> group
,
1566 ? lease
-> pool
-> group
1567 : lease
-> subnet
-> group
));
1570 /* See if the client is only supposed to have one lease at a time,
1571 and if so, find its other leases and release them. We can only
1572 do this on DHCPREQUEST. It's a little weird to do this before
1573 looking at permissions, because the client might not actually
1574 _get_ a lease after we've done the permission check, but the
1575 assumption for this option is that the client has exactly one
1576 network interface, and will only ever remember one lease. So
1577 if it sends a DHCPREQUEST, and doesn't get the lease, it's already
1578 forgotten about its old lease, so we can too. */
1579 if (packet
-> packet_type
== DHCPREQUEST
&&
1580 (oc
= lookup_option (&server_universe
, state
-> options
,
1581 SV_ONE_LEASE_PER_CLIENT
)) &&
1582 evaluate_boolean_option_cache (&ignorep
,
1584 (struct client_state
*)0,
1586 state
-> options
, &lease
-> scope
,
1589 if (lease
-> uid_len
) {
1591 seek
= (struct lease
*)0;
1592 find_lease_by_uid (&seek
, lease
-> uid
,
1593 lease
-> uid_len
, MDL
);
1596 if (seek
== lease
&& !seek
-> n_uid
) {
1597 lease_dereference (&seek
, MDL
);
1600 next
= (struct lease
*)0;
1602 /* Don't release expired leases, and don't
1603 release the lease we're going to assign. */
1604 next
= (struct lease
*)0;
1607 lease_reference (&next
, seek
-> n_uid
, MDL
);
1608 if (seek
!= lease
&&
1609 seek
-> binding_state
!= FTS_RELEASED
&&
1610 seek
-> binding_state
!= FTS_EXPIRED
&&
1611 seek
-> binding_state
!= FTS_RESET
&&
1612 seek
-> binding_state
!= FTS_FREE
&&
1613 seek
-> binding_state
!= FTS_BACKUP
)
1615 lease_dereference (&seek
, MDL
);
1617 lease_reference (&seek
, next
, MDL
);
1618 lease_dereference (&next
, MDL
);
1622 lease_dereference (&next
, MDL
);
1624 release_lease (seek
, packet
);
1625 lease_dereference (&seek
, MDL
);
1630 if (!lease
-> uid_len
||
1632 !host
-> client_identifier
.len
&&
1633 (oc
= lookup_option (&server_universe
, state
-> options
,
1635 !evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
1636 (struct client_state
*)0,
1642 seek
= (struct lease
*)0;
1643 find_lease_by_hw_addr
1644 (&seek
, lease
-> hardware_addr
.hbuf
,
1645 lease
-> hardware_addr
.hlen
, MDL
);
1648 if (seek
== lease
&& !seek
-> n_hw
) {
1649 lease_dereference (&seek
, MDL
);
1652 next
= (struct lease
*)0;
1655 lease_reference (&next
, seek
-> n_hw
, MDL
);
1656 if (seek
!= lease
&&
1657 seek
-> binding_state
!= FTS_RELEASED
&&
1658 seek
-> binding_state
!= FTS_EXPIRED
&&
1659 seek
-> binding_state
!= FTS_RESET
&&
1660 seek
-> binding_state
!= FTS_FREE
&&
1661 seek
-> binding_state
!= FTS_BACKUP
)
1663 lease_dereference (&seek
, MDL
);
1665 lease_reference (&seek
, next
, MDL
);
1666 lease_dereference (&next
, MDL
);
1670 lease_dereference (&next
, MDL
);
1672 release_lease (seek
, packet
);
1673 lease_dereference (&seek
, MDL
);
1681 /* Make sure this packet satisfies the configured minimum
1682 number of seconds. */
1683 memset (&d1
, 0, sizeof d1
);
1684 if (offer
== DHCPOFFER
&&
1685 (oc
= lookup_option (&server_universe
, state
-> options
,
1687 if (evaluate_option_cache (&d1
, packet
, lease
,
1688 (struct client_state
*)0,
1689 packet
-> options
, state
-> options
,
1690 &lease
-> scope
, oc
, MDL
)) {
1692 ntohs (packet
-> raw
-> secs
) < d1
.data
[0]) {
1693 log_info("%s: configured min-secs value (%d) "
1694 "is greater than secs field (%d). "
1695 "message dropped.", msg
, d1
.data
[0],
1696 ntohs(packet
->raw
->secs
));
1697 data_string_forget (&d1
, MDL
);
1698 free_lease_state (state
, MDL
);
1700 host_dereference (&host
, MDL
);
1703 data_string_forget (&d1
, MDL
);
1707 /* Try to find a matching host declaration for this lease.
1710 struct host_decl
*hp
= (struct host_decl
*)0;
1711 struct host_decl
*h
;
1713 /* Try to find a host_decl that matches the client
1714 identifier or hardware address on the packet, and
1715 has no fixed IP address. If there is one, hang
1716 it off the lease so that its option definitions
1718 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
1719 DHO_DHCP_CLIENT_IDENTIFIER
);
1721 evaluate_option_cache (&d1
, packet
, lease
,
1722 (struct client_state
*)0,
1723 packet
-> options
, state
-> options
,
1724 &lease
-> scope
, oc
, MDL
)) {
1725 find_hosts_by_uid (&hp
, d1
.data
, d1
.len
, MDL
);
1726 data_string_forget (&d1
, MDL
);
1727 for (h
= hp
; h
; h
= h
-> n_ipaddr
) {
1728 if (!h
-> fixed_addr
)
1732 host_reference (&host
, h
, MDL
);
1735 find_hosts_by_haddr (&hp
,
1736 packet
-> raw
-> htype
,
1737 packet
-> raw
-> chaddr
,
1738 packet
-> raw
-> hlen
,
1740 for (h
= hp
; h
; h
= h
-> n_ipaddr
) {
1741 if (!h
-> fixed_addr
)
1745 host_reference (&host
, h
, MDL
);
1748 host_dereference (&hp
, MDL
);
1751 /* If we have a host_decl structure, run the options associated
1752 with its group. Whether the host decl struct is old or not. */
1754 execute_statements_in_scope ((struct binding_value
**)0,
1756 (struct client_state
*)0,
1758 state
-> options
, &lease
-> scope
,
1761 ? lease
-> pool
-> group
1762 : lease
-> subnet
-> group
));
1764 /* Drop the request if it's not allowed for this client. By
1765 default, unknown clients are allowed. */
1767 (oc
= lookup_option (&server_universe
, state
-> options
,
1768 SV_BOOT_UNKNOWN_CLIENTS
)) &&
1769 !evaluate_boolean_option_cache (&ignorep
,
1771 (struct client_state
*)0,
1774 &lease
-> scope
, oc
, MDL
)) {
1776 log_info ("%s: unknown client", msg
);
1777 free_lease_state (state
, MDL
);
1779 host_dereference (&host
, MDL
);
1783 /* Drop the request if it's not allowed for this client. */
1785 (oc
= lookup_option (&server_universe
, state
-> options
,
1787 !evaluate_boolean_option_cache (&ignorep
,
1789 (struct client_state
*)0,
1792 &lease
-> scope
, oc
, MDL
)) {
1794 log_info ("%s: bootp disallowed", msg
);
1795 free_lease_state (state
, MDL
);
1797 host_dereference (&host
, MDL
);
1801 /* Drop the request if booting is specifically denied. */
1802 oc
= lookup_option (&server_universe
, state
-> options
,
1805 !evaluate_boolean_option_cache (&ignorep
,
1807 (struct client_state
*)0,
1810 &lease
-> scope
, oc
, MDL
)) {
1812 log_info ("%s: booting disallowed", msg
);
1813 free_lease_state (state
, MDL
);
1815 host_dereference (&host
, MDL
);
1819 /* If we are configured to do per-class billing, do it. */
1820 if (have_billing_classes
&& !(lease
-> flags
& STATIC_LEASE
)) {
1821 /* See if the lease is currently being billed to a
1822 class, and if so, whether or not it can continue to
1823 be billed to that class. */
1824 if (lease
-> billing_class
) {
1825 for (i
= 0; i
< packet
-> class_count
; i
++)
1826 if (packet
-> classes
[i
] ==
1827 lease
-> billing_class
)
1829 if (i
== packet
-> class_count
)
1830 unbill_class (lease
, lease
-> billing_class
);
1833 /* If we don't have an active billing, see if we need
1834 one, and if we do, try to do so. */
1835 if (lease
->billing_class
== NULL
) {
1837 for (i
= 0; i
< packet
->class_count
; i
++) {
1838 if (packet
->classes
[i
]->lease_limit
) {
1840 if (bill_class(lease
,
1841 packet
->classes
[i
]))
1845 if (bill
!= 0 && i
== packet
->class_count
) {
1846 log_info("%s: no available billing: lease "
1847 "limit reached in all matching "
1849 free_lease_state(state
, MDL
);
1851 host_dereference(&host
, MDL
);
1855 /* If this is an offer, undo the billing. We go
1856 * through all the steps above to bill a class so
1857 * we can hit the 'no available billing' mark and
1858 * abort without offering. But it just doesn't make
1859 * sense to permanently bill a class for a non-active
1860 * lease. This means on REQUEST, we will bill this
1861 * lease again (if there is a REQUEST).
1863 if (offer
== DHCPOFFER
&&
1864 lease
->billing_class
!= NULL
&&
1865 lease
->binding_state
!= FTS_ACTIVE
)
1866 unbill_class(lease
, lease
->billing_class
);
1870 /* Figure out the filename. */
1871 oc
= lookup_option (&server_universe
, state
-> options
, SV_FILENAME
);
1873 evaluate_option_cache (&state
-> filename
, packet
, lease
,
1874 (struct client_state
*)0,
1875 packet
-> options
, state
-> options
,
1876 &lease
-> scope
, oc
, MDL
);
1878 /* Choose a server name as above. */
1879 oc
= lookup_option (&server_universe
, state
-> options
,
1882 evaluate_option_cache (&state
-> server_name
, packet
, lease
,
1883 (struct client_state
*)0,
1884 packet
-> options
, state
-> options
,
1885 &lease
-> scope
, oc
, MDL
);
1887 /* At this point, we have a lease that we can offer the client.
1888 Now we construct a lease structure that contains what we want,
1889 and call supersede_lease to do the right thing with it. */
1890 lt
= (struct lease
*)0;
1891 result
= lease_allocate (<
, MDL
);
1892 if (result
!= ISC_R_SUCCESS
) {
1893 log_info ("%s: can't allocate temporary lease structure: %s",
1894 msg
, isc_result_totext (result
));
1895 free_lease_state (state
, MDL
);
1897 host_dereference (&host
, MDL
);
1901 /* Use the ip address of the lease that we finally found in
1903 lt
-> ip_addr
= lease
-> ip_addr
;
1906 lt
-> starts
= cur_time
;
1908 /* Figure out how long a lease to assign. If this is a
1909 dynamic BOOTP lease, its duration must be infinite. */
1911 lt
->flags
&= ~BOOTP_LEASE
;
1913 default_lease_time
= DEFAULT_DEFAULT_LEASE_TIME
;
1914 if ((oc
= lookup_option (&server_universe
, state
-> options
,
1915 SV_DEFAULT_LEASE_TIME
))) {
1916 if (evaluate_option_cache (&d1
, packet
, lease
,
1917 (struct client_state
*)0,
1920 &lease
-> scope
, oc
, MDL
)) {
1921 if (d1
.len
== sizeof (u_int32_t
))
1922 default_lease_time
=
1924 data_string_forget (&d1
, MDL
);
1928 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
1929 DHO_DHCP_LEASE_TIME
)))
1930 s1
= evaluate_option_cache (&d1
, packet
, lease
,
1931 (struct client_state
*)0,
1934 &lease
-> scope
, oc
, MDL
);
1938 if (s1
&& (d1
.len
== 4)) {
1939 u_int32_t ones
= 0xffffffff;
1941 /* One potential use of reserved leases is to allow
1942 * clients to signal reservation of their lease. They
1943 * can kinda sorta do this, if you squint hard enough,
1944 * by supplying an 'infinite' requested-lease-time
1945 * option. This is generally bad practice...you want
1946 * clients to return to the server on at least some
1947 * period (days, months, years) to get up-to-date
1950 * 1) A client requests 0xffffffff lease-time.
1951 * 2) The server reserves the lease, and assigns a
1952 * <= max_lease_time lease-time to the client, which
1953 * we presume is much smaller than 0xffffffff.
1954 * 3) The client ultimately fails to renew its lease
1955 * (all clients go offline at some point).
1956 * 4) The server retains the reservation, although
1957 * the lease expires and passes through those states
1958 * as normal, it's placed in the 'reserved' queue,
1959 * and is under no circumstances allocated to any
1962 * Whether the client knows its reserving its lease or
1963 * not, this can be a handy tool for a sysadmin.
1965 if ((memcmp(d1
.data
, &ones
, 4) == 0) &&
1966 (oc
= lookup_option(&server_universe
,
1968 SV_RESERVE_INFINITE
)) &&
1969 evaluate_boolean_option_cache(&ignorep
, packet
,
1970 lease
, NULL
, packet
->options
,
1971 state
->options
, &lease
->scope
,
1973 lt
->flags
|= RESERVED_LEASE
;
1975 log_info("Infinite-leasetime "
1976 "reservation made on %s.",
1977 piaddr(lt
->ip_addr
));
1980 lease_time
= getULong (d1
.data
);
1982 lease_time
= default_lease_time
;
1985 data_string_forget(&d1
, MDL
);
1987 /* See if there's a maximum lease time. */
1988 max_lease_time
= DEFAULT_MAX_LEASE_TIME
;
1989 if ((oc
= lookup_option (&server_universe
, state
-> options
,
1990 SV_MAX_LEASE_TIME
))) {
1991 if (evaluate_option_cache (&d1
, packet
, lease
,
1992 (struct client_state
*)0,
1995 &lease
-> scope
, oc
, MDL
)) {
1996 if (d1
.len
== sizeof (u_int32_t
))
1999 data_string_forget (&d1
, MDL
);
2003 /* Enforce the maximum lease length. */
2004 if (lease_time
< 0 /* XXX */
2005 || lease_time
> max_lease_time
)
2006 lease_time
= max_lease_time
;
2008 min_lease_time
= DEFAULT_MIN_LEASE_TIME
;
2009 if (min_lease_time
> max_lease_time
)
2010 min_lease_time
= max_lease_time
;
2012 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2013 SV_MIN_LEASE_TIME
))) {
2014 if (evaluate_option_cache (&d1
, packet
, lease
,
2015 (struct client_state
*)0,
2018 &lease
-> scope
, oc
, MDL
)) {
2019 if (d1
.len
== sizeof (u_int32_t
))
2020 min_lease_time
= getULong (d1
.data
);
2021 data_string_forget (&d1
, MDL
);
2025 /* CC: If there are less than
2026 adaptive-lease-time-threshold % free leases,
2027 hand out only short term leases */
2029 memset(&d1
, 0, sizeof(d1
));
2031 (oc
= lookup_option(&server_universe
, state
->options
,
2032 SV_ADAPTIVE_LEASE_TIME_THRESHOLD
)) &&
2033 evaluate_option_cache(&d1
, packet
, lease
, NULL
,
2034 packet
->options
, state
->options
,
2035 &lease
->scope
, oc
, MDL
)) {
2036 if (d1
.len
== 1 && d1
.data
[0] > 0 &&
2039 int poolfilled
, total
, count
;
2042 adaptive_time
= min_lease_time
;
2044 adaptive_time
= DEFAULT_MIN_LEASE_TIME
;
2046 /* Allow the client to keep its lease. */
2047 if (lease
->ends
- cur_time
> adaptive_time
)
2048 adaptive_time
= lease
->ends
- cur_time
;
2050 count
= lease
->pool
->lease_count
;
2051 total
= count
- (lease
->pool
->free_leases
+
2052 lease
->pool
->backup_leases
);
2054 poolfilled
= (total
> (INT_MAX
/ 100)) ?
2055 total
/ (count
/ 100) :
2056 (total
* 100) / count
;
2058 log_debug("Adap-lease: Total: %d, Free: %d, "
2059 "Ends: %d, Adaptive: %d, Fill: %d, "
2061 lease
->pool
->lease_count
,
2062 lease
->pool
->free_leases
,
2063 (int)(lease
->ends
- cur_time
),
2064 (int)adaptive_time
, poolfilled
,
2067 if (poolfilled
>= d1
.data
[0] &&
2068 lease_time
> adaptive_time
) {
2069 log_info("Pool over threshold, time "
2070 "for %s reduced from %d to "
2071 "%d.", piaddr(lease
->ip_addr
),
2073 (int)adaptive_time
);
2075 lease_time
= adaptive_time
;
2078 data_string_forget(&d1
, MDL
);
2081 /* a client requests an address which is not yet active*/
2082 if (lease
->pool
&& lease
->pool
->valid_from
&&
2083 cur_time
< lease
->pool
->valid_from
) {
2084 /* NAK leases before pool activation date */
2086 memcpy (cip
.iabuf
, <
->ip_addr
.iabuf
, 4);
2087 nak_lease(packet
, &cip
);
2088 free_lease_state (state
, MDL
);
2089 lease_dereference (<
, MDL
);
2091 host_dereference (&host
, MDL
);
2097 a) NAK current lease if past the expiration date
2098 b) extend lease only up to the expiration date, but not
2099 below min-lease-time
2100 Setting min-lease-time is essential for this to work!
2101 The value of min-lease-time determines the lenght
2102 of the transition window:
2103 A client renewing a second before the deadline will
2104 get a min-lease-time lease. Since the current ip might not
2105 be routable after the deadline, the client will
2106 be offline until it DISCOVERS again. Otherwise it will
2107 receive a NAK at T/2.
2108 A min-lease-time of 6 seconds effectively switches over
2109 all clients in this pool very quickly.
2112 if (lease
->pool
&& lease
->pool
->valid_until
) {
2113 if (cur_time
>= lease
->pool
->valid_until
) {
2114 /* NAK leases after pool expiration date */
2116 memcpy (cip
.iabuf
, <
->ip_addr
.iabuf
, 4);
2117 nak_lease(packet
, &cip
);
2118 free_lease_state (state
, MDL
);
2119 lease_dereference (<
, MDL
);
2121 host_dereference (&host
, MDL
);
2124 remaining_time
= lease
->pool
->valid_until
- cur_time
;
2125 if (lease_time
> remaining_time
)
2126 lease_time
= remaining_time
;
2129 if (lease_time
< min_lease_time
) {
2131 lease_time
= min_lease_time
;
2133 lease_time
= default_lease_time
;
2137 #if defined (FAILOVER_PROTOCOL)
2138 /* Okay, we know the lease duration. Now check the
2139 failover state, if any. */
2140 if (lease
-> pool
&& lease
-> pool
-> failover_peer
) {
2141 TIME new_lease_time
= lease_time
;
2142 dhcp_failover_state_t
*peer
=
2143 lease
-> pool
-> failover_peer
;
2145 /* Copy previous lease failover ack-state. */
2146 lt
->tsfp
= lease
->tsfp
;
2147 lt
->atsfp
= lease
->atsfp
;
2149 /* cltt set below */
2151 /* Lease times less than MCLT are not a concern. */
2152 if (lease_time
> peer
->mclt
) {
2153 /* Each server can only offer a lease time
2154 * that is either equal to MCLT (at least),
2155 * or up to TSFP+MCLT. Only if the desired
2156 * lease time falls within TSFP+MCLT, can
2157 * the server allow it.
2159 if (lt
->tsfp
<= cur_time
)
2160 new_lease_time
= peer
->mclt
;
2161 else if ((cur_time
+ lease_time
) >
2162 (lt
->tsfp
+ peer
->mclt
))
2163 new_lease_time
= (lt
->tsfp
- cur_time
)
2167 /* Update potential expiry. Allow for the desired
2168 * lease time plus one half the actual (whether
2169 * modified downward or not) lease time, which is
2170 * actually an estimate of when the client will
2171 * renew. This way, the client will be able to get
2172 * the desired lease time upon renewal.
2174 if (offer
== DHCPACK
) {
2175 lt
->tstp
= cur_time
+ lease_time
+
2176 (new_lease_time
/ 2);
2178 /* If we reduced the potential expiry time,
2179 * make sure we don't offer an old-expiry-time
2180 * lease for this lease before the change is
2183 if (lt
->tstp
< lt
->tsfp
)
2184 lt
->tsfp
= lt
->tstp
;
2186 lt
->tstp
= lease
->tstp
;
2188 /* Use failover-modified lease time. */
2189 lease_time
= new_lease_time
;
2191 #endif /* FAILOVER_PROTOCOL */
2193 /* If the lease duration causes the time value to wrap,
2194 use the maximum expiry time. */
2195 if (cur_time
+ lease_time
< cur_time
)
2196 state
-> offered_expiry
= MAX_TIME
- 1;
2198 state
-> offered_expiry
= cur_time
+ lease_time
;
2202 lt
-> ends
= state
-> offered_expiry
;
2204 /* Don't make lease active until we actually get a
2206 if (offer
== DHCPACK
)
2207 lt
-> next_binding_state
= FTS_ACTIVE
;
2209 lt
-> next_binding_state
= lease
-> binding_state
;
2211 lt
->flags
|= BOOTP_LEASE
;
2213 lease_time
= MAX_TIME
- cur_time
;
2215 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2216 SV_BOOTP_LEASE_LENGTH
))) {
2217 if (evaluate_option_cache (&d1
, packet
, lease
,
2218 (struct client_state
*)0,
2221 &lease
-> scope
, oc
, MDL
)) {
2222 if (d1
.len
== sizeof (u_int32_t
))
2223 lease_time
= getULong (d1
.data
);
2224 data_string_forget (&d1
, MDL
);
2228 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2229 SV_BOOTP_LEASE_CUTOFF
))) {
2230 if (evaluate_option_cache (&d1
, packet
, lease
,
2231 (struct client_state
*)0,
2234 &lease
-> scope
, oc
, MDL
)) {
2235 if (d1
.len
== sizeof (u_int32_t
))
2236 lease_time
= (getULong (d1
.data
) -
2238 data_string_forget (&d1
, MDL
);
2242 lt
-> ends
= state
-> offered_expiry
= cur_time
+ lease_time
;
2243 lt
-> next_binding_state
= FTS_ACTIVE
;
2246 /* Update Client Last Transaction Time. */
2247 lt
->cltt
= cur_time
;
2249 /* Record the uid, if given... */
2250 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
2251 DHO_DHCP_CLIENT_IDENTIFIER
);
2253 evaluate_option_cache (&d1
, packet
, lease
,
2254 (struct client_state
*)0,
2255 packet
-> options
, state
-> options
,
2256 &lease
-> scope
, oc
, MDL
)) {
2257 if (d1
.len
<= sizeof lt
-> uid_buf
) {
2258 memcpy (lt
-> uid_buf
, d1
.data
, d1
.len
);
2259 lt
-> uid
= lt
-> uid_buf
;
2260 lt
-> uid_max
= sizeof lt
-> uid_buf
;
2261 lt
-> uid_len
= d1
.len
;
2263 unsigned char *tuid
;
2264 lt
-> uid_max
= d1
.len
;
2265 lt
-> uid_len
= d1
.len
;
2266 tuid
= (unsigned char *)dmalloc (lt
-> uid_max
, MDL
);
2269 log_fatal ("no memory for large uid.");
2270 memcpy (tuid
, d1
.data
, lt
-> uid_len
);
2273 data_string_forget (&d1
, MDL
);
2277 host_reference (<
-> host
, host
, MDL
);
2278 host_dereference (&host
, MDL
);
2280 if (lease
-> subnet
)
2281 subnet_reference (<
-> subnet
, lease
-> subnet
, MDL
);
2282 if (lease
-> billing_class
)
2283 class_reference (<
-> billing_class
,
2284 lease
-> billing_class
, MDL
);
2286 /* Set a flag if this client is a broken client that NUL
2287 terminates string options and expects us to do likewise. */
2289 lease
-> flags
|= MS_NULL_TERMINATION
;
2291 lease
-> flags
&= ~MS_NULL_TERMINATION
;
2293 /* Save any bindings. */
2294 if (lease
-> scope
) {
2295 binding_scope_reference (<
-> scope
, lease
-> scope
, MDL
);
2296 binding_scope_dereference (&lease
-> scope
, MDL
);
2298 if (lease
-> agent_options
)
2299 option_chain_head_reference (<
-> agent_options
,
2300 lease
-> agent_options
, MDL
);
2302 /* If we got relay agent information options from the packet, then
2303 * cache them for renewal in case the relay agent can't supply them
2304 * when the client unicasts. The options may be from an addressed
2305 * "l3" relay, or from an unaddressed "l2" relay which does not set
2308 if (!packet
->agent_options_stashed
&&
2309 packet
->options
->universe_count
> agent_universe
.index
&&
2310 packet
->options
->universes
[agent_universe
.index
] != NULL
) {
2311 oc
= lookup_option (&server_universe
, state
-> options
,
2312 SV_STASH_AGENT_OPTIONS
);
2314 evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
2315 (struct client_state
*)0,
2318 &lease
-> scope
, oc
, MDL
)) {
2319 if (lt
-> agent_options
)
2320 option_chain_head_dereference (<
-> agent_options
, MDL
);
2321 option_chain_head_reference
2322 (<
-> agent_options
,
2323 (struct option_chain_head
*)
2324 packet
-> options
-> universes
[agent_universe
.index
],
2329 /* Replace the old lease hostname with the new one, if it's changed. */
2330 oc
= lookup_option (&dhcp_universe
, packet
-> options
, DHO_HOST_NAME
);
2332 s1
= evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
2333 (struct client_state
*)0,
2335 (struct option_state
*)0,
2336 &global_scope
, oc
, MDL
);
2341 lease
-> client_hostname
&&
2342 strlen (lease
-> client_hostname
) == d1
.len
&&
2343 !memcmp (lease
-> client_hostname
, d1
.data
, d1
.len
)) {
2344 /* Hasn't changed. */
2345 data_string_forget (&d1
, MDL
);
2346 lt
-> client_hostname
= lease
-> client_hostname
;
2347 lease
-> client_hostname
= (char *)0;
2348 } else if (oc
&& s1
) {
2349 lt
-> client_hostname
= dmalloc (d1
.len
+ 1, MDL
);
2350 if (!lt
-> client_hostname
)
2351 log_error ("no memory for client hostname.");
2353 memcpy (lt
-> client_hostname
, d1
.data
, d1
.len
);
2354 lt
-> client_hostname
[d1
.len
] = 0;
2356 data_string_forget (&d1
, MDL
);
2359 /* Record the hardware address, if given... */
2360 lt
-> hardware_addr
.hlen
= packet
-> raw
-> hlen
+ 1;
2361 lt
-> hardware_addr
.hbuf
[0] = packet
-> raw
-> htype
;
2362 memcpy (<
-> hardware_addr
.hbuf
[1], packet
-> raw
-> chaddr
,
2363 sizeof packet
-> raw
-> chaddr
);
2365 lt
-> flags
= lease
-> flags
& ~PERSISTENT_FLAGS
;
2367 /* If there are statements to execute when the lease is
2368 committed, execute them. */
2369 if (lease
-> on_commit
&& (!offer
|| offer
== DHCPACK
)) {
2370 execute_statements ((struct binding_value
**)0,
2371 packet
, lt
, (struct client_state
*)0,
2373 state
-> options
, <
-> scope
,
2374 lease
-> on_commit
);
2375 if (lease
-> on_commit
)
2376 executable_statement_dereference (&lease
-> on_commit
,
2381 /* Perform DDNS updates, if configured to. */
2382 if ((!offer
|| offer
== DHCPACK
) &&
2383 (!(oc
= lookup_option (&server_universe
, state
-> options
,
2384 SV_DDNS_UPDATES
)) ||
2385 evaluate_boolean_option_cache (&ignorep
, packet
, lt
,
2386 (struct client_state
*)0,
2389 <
-> scope
, oc
, MDL
))) {
2390 ddns_updates(packet
, lt
, lease
, NULL
, NULL
, state
->options
);
2392 #endif /* NSUPDATE */
2394 /* Don't call supersede_lease on a mocked-up lease. */
2395 if (lease
-> flags
& STATIC_LEASE
) {
2396 /* Copy the hardware address into the static lease
2398 lease
-> hardware_addr
.hlen
= packet
-> raw
-> hlen
+ 1;
2399 lease
-> hardware_addr
.hbuf
[0] = packet
-> raw
-> htype
;
2400 memcpy (&lease
-> hardware_addr
.hbuf
[1],
2401 packet
-> raw
-> chaddr
,
2402 sizeof packet
-> raw
-> chaddr
); /* XXX */
2404 #if !defined(DELAYED_ACK)
2405 /* Install the new information on 'lt' onto the lease at
2406 * 'lease'. If this is a DHCPOFFER, it is a 'soft' promise,
2407 * if it is a DHCPACK, it is a 'hard' binding, so it needs
2408 * to be recorded and propogated immediately. If the update
2409 * fails, don't ACK it (or BOOTREPLY) either; we may give
2410 * the same lease to another client later, and that would be
2413 if (!supersede_lease(lease
, lt
, !offer
|| (offer
== DHCPACK
),
2414 offer
== DHCPACK
, offer
== DHCPACK
)) {
2415 #else /* defined(DELAYED_ACK) */
2416 /* Install the new information on 'lt' onto the lease at
2417 * 'lease'. Â We will not 'commit' this information to disk
2418 * yet (fsync()), we will 'propogate' the information if
2419 * this is BOOTP or a DHCPACK, but we will not 'pimmediate'ly
2420 * transmit failover binding updates (this is delayed until
2421 * after the fsync()). If the update fails, don't ACK it (or
2422 * BOOTREPLY either); we may give the same lease out to a
2423 * different client, and that would be a conflict.
2425 if (!supersede_lease(lease
, lt
, 0, !offer
|| offer
== DHCPACK
,
2428 log_info ("%s: database update failed", msg
);
2429 free_lease_state (state
, MDL
);
2430 lease_dereference (<
, MDL
);
2434 lease_dereference (<
, MDL
);
2436 /* Remember the interface on which the packet arrived. */
2437 state
-> ip
= packet
-> interface
;
2439 /* Remember the giaddr, xid, secs, flags and hops. */
2440 state
-> giaddr
= packet
-> raw
-> giaddr
;
2441 state
-> ciaddr
= packet
-> raw
-> ciaddr
;
2442 state
-> xid
= packet
-> raw
-> xid
;
2443 state
-> secs
= packet
-> raw
-> secs
;
2444 state
-> bootp_flags
= packet
-> raw
-> flags
;
2445 state
-> hops
= packet
-> raw
-> hops
;
2446 state
-> offer
= offer
;
2448 /* If we're always supposed to broadcast to this client, set
2449 the broadcast bit in the bootp flags field. */
2450 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2451 SV_ALWAYS_BROADCAST
)) &&
2452 evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
2453 (struct client_state
*)0,
2454 packet
-> options
, state
-> options
,
2455 &lease
-> scope
, oc
, MDL
))
2456 state
-> bootp_flags
|= htons (BOOTP_BROADCAST
);
2458 /* Get the Maximum Message Size option from the packet, if one
2460 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
2461 DHO_DHCP_MAX_MESSAGE_SIZE
);
2463 evaluate_option_cache (&d1
, packet
, lease
,
2464 (struct client_state
*)0,
2465 packet
-> options
, state
-> options
,
2466 &lease
-> scope
, oc
, MDL
)) {
2467 if (d1
.len
== sizeof (u_int16_t
))
2468 state
-> max_message_size
= getUShort (d1
.data
);
2469 data_string_forget (&d1
, MDL
);
2471 oc
= lookup_option (&dhcp_universe
, state
-> options
,
2472 DHO_DHCP_MAX_MESSAGE_SIZE
);
2474 evaluate_option_cache (&d1
, packet
, lease
,
2475 (struct client_state
*)0,
2476 packet
-> options
, state
-> options
,
2477 &lease
-> scope
, oc
, MDL
)) {
2478 if (d1
.len
== sizeof (u_int16_t
))
2479 state
-> max_message_size
=
2480 getUShort (d1
.data
);
2481 data_string_forget (&d1
, MDL
);
2485 /* Get the Subnet Selection option from the packet, if one
2487 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
2488 DHO_SUBNET_SELECTION
))) {
2490 /* Make a copy of the data. */
2491 struct option_cache
*noc
= (struct option_cache
*)0;
2492 if (option_cache_allocate (&noc
, MDL
)) {
2494 data_string_copy (&noc
-> data
,
2496 if (oc
-> expression
)
2497 expression_reference (&noc
-> expression
,
2498 oc
-> expression
, MDL
);
2500 option_reference(&(noc
->option
), oc
->option
,
2504 save_option (&dhcp_universe
, state
-> options
, noc
);
2505 option_cache_dereference (&noc
, MDL
);
2508 /* Now, if appropriate, put in DHCP-specific options that
2510 if (state
-> offer
) {
2511 i
= DHO_DHCP_MESSAGE_TYPE
;
2512 oc
= (struct option_cache
*)0;
2513 if (option_cache_allocate (&oc
, MDL
)) {
2514 if (make_const_data (&oc
-> expression
,
2515 &state
-> offer
, 1, 0, 0, MDL
)) {
2516 option_code_hash_lookup(&oc
->option
,
2517 dhcp_universe
.code_hash
,
2519 save_option (&dhcp_universe
,
2520 state
-> options
, oc
);
2522 option_cache_dereference (&oc
, MDL
);
2525 get_server_source_address(&from
, state
->options
, packet
);
2526 memcpy(state
->from
.iabuf
, &from
, sizeof(from
));
2527 state
->from
.len
= sizeof(from
);
2529 offered_lease_time
=
2530 state
-> offered_expiry
- cur_time
;
2532 putULong(state
->expiry
, (u_int32_t
)offered_lease_time
);
2533 i
= DHO_DHCP_LEASE_TIME
;
2534 oc
= (struct option_cache
*)0;
2535 if (option_cache_allocate (&oc
, MDL
)) {
2536 if (make_const_data(&oc
->expression
, state
->expiry
,
2538 option_code_hash_lookup(&oc
->option
,
2539 dhcp_universe
.code_hash
,
2541 save_option (&dhcp_universe
,
2542 state
-> options
, oc
);
2544 option_cache_dereference (&oc
, MDL
);
2547 /* Renewal time is lease time * 0.5. */
2548 offered_lease_time
/= 2;
2549 putULong(state
->renewal
, (u_int32_t
)offered_lease_time
);
2550 i
= DHO_DHCP_RENEWAL_TIME
;
2551 oc
= (struct option_cache
*)0;
2552 if (option_cache_allocate (&oc
, MDL
)) {
2553 if (make_const_data(&oc
->expression
, state
->renewal
,
2555 option_code_hash_lookup(&oc
->option
,
2556 dhcp_universe
.code_hash
,
2558 save_option (&dhcp_universe
,
2559 state
-> options
, oc
);
2561 option_cache_dereference (&oc
, MDL
);
2564 /* Rebinding time is lease time * 0.875. */
2565 offered_lease_time
+= (offered_lease_time
/ 2
2566 + offered_lease_time
/ 4);
2567 putULong(state
->rebind
, (u_int32_t
)offered_lease_time
);
2568 i
= DHO_DHCP_REBINDING_TIME
;
2569 oc
= (struct option_cache
*)0;
2570 if (option_cache_allocate (&oc
, MDL
)) {
2571 if (make_const_data(&oc
->expression
, state
->rebind
,
2573 option_code_hash_lookup(&oc
->option
,
2574 dhcp_universe
.code_hash
,
2576 save_option (&dhcp_universe
,
2577 state
-> options
, oc
);
2579 option_cache_dereference (&oc
, MDL
);
2582 /* XXXSK: should we use get_server_source_address() here? */
2583 if (state
-> ip
-> address_count
) {
2585 sizeof state
-> ip
-> addresses
[0];
2586 memcpy (state
-> from
.iabuf
,
2587 &state
-> ip
-> addresses
[0],
2592 /* Figure out the address of the boot file server. */
2593 memset (&state
-> siaddr
, 0, sizeof state
-> siaddr
);
2595 lookup_option (&server_universe
,
2596 state
-> options
, SV_NEXT_SERVER
))) {
2597 if (evaluate_option_cache (&d1
, packet
, lease
,
2598 (struct client_state
*)0,
2599 packet
-> options
, state
-> options
,
2600 &lease
-> scope
, oc
, MDL
)) {
2601 /* If there was more than one answer,
2603 if (d1
.len
>= 4 && d1
.data
)
2604 memcpy (&state
-> siaddr
, d1
.data
, 4);
2605 data_string_forget (&d1
, MDL
);
2609 /* Use the subnet mask from the subnet declaration if no other
2610 mask has been provided. */
2611 i
= DHO_SUBNET_MASK
;
2612 if (!lookup_option (&dhcp_universe
, state
-> options
, i
)) {
2613 oc
= (struct option_cache
*)0;
2614 if (option_cache_allocate (&oc
, MDL
)) {
2615 if (make_const_data (&oc
-> expression
,
2616 lease
-> subnet
-> netmask
.iabuf
,
2617 lease
-> subnet
-> netmask
.len
,
2619 option_code_hash_lookup(&oc
->option
,
2620 dhcp_universe
.code_hash
,
2622 save_option (&dhcp_universe
,
2623 state
-> options
, oc
);
2625 option_cache_dereference (&oc
, MDL
);
2629 /* Use the hostname from the host declaration if there is one
2630 and no hostname has otherwise been provided, and if the
2631 use-host-decl-name flag is set. */
2633 j
= SV_USE_HOST_DECL_NAMES
;
2634 if (!lookup_option (&dhcp_universe
, state
-> options
, i
) &&
2635 lease
-> host
&& lease
-> host
-> name
&&
2636 (evaluate_boolean_option_cache
2637 (&ignorep
, packet
, lease
, (struct client_state
*)0,
2638 packet
-> options
, state
-> options
, &lease
-> scope
,
2639 lookup_option (&server_universe
, state
-> options
, j
), MDL
))) {
2640 oc
= (struct option_cache
*)0;
2641 if (option_cache_allocate (&oc
, MDL
)) {
2642 if (make_const_data (&oc
-> expression
,
2644 lease
-> host
-> name
),
2645 strlen (lease
-> host
-> name
),
2647 option_code_hash_lookup(&oc
->option
,
2648 dhcp_universe
.code_hash
,
2650 save_option (&dhcp_universe
,
2651 state
-> options
, oc
);
2653 option_cache_dereference (&oc
, MDL
);
2657 /* If we don't have a hostname yet, and we've been asked to do
2658 a reverse lookup to find the hostname, do it. */
2659 j
= SV_GET_LEASE_HOSTNAMES
;
2660 if (!lookup_option (&server_universe
, state
-> options
, i
) &&
2661 (evaluate_boolean_option_cache
2662 (&ignorep
, packet
, lease
, (struct client_state
*)0,
2663 packet
-> options
, state
-> options
, &lease
-> scope
,
2664 lookup_option (&server_universe
, state
-> options
, j
), MDL
))) {
2668 memcpy (&ia
, lease
-> ip_addr
.iabuf
, 4);
2670 h
= gethostbyaddr ((char *)&ia
, sizeof ia
, AF_INET
);
2672 log_error ("No hostname for %s", inet_ntoa (ia
));
2674 oc
= (struct option_cache
*)0;
2675 if (option_cache_allocate (&oc
, MDL
)) {
2676 if (make_const_data (&oc
-> expression
,
2679 strlen (h
-> h_name
) + 1,
2681 option_code_hash_lookup(&oc
->option
,
2682 dhcp_universe
.code_hash
,
2684 save_option (&dhcp_universe
,
2685 state
-> options
, oc
);
2687 option_cache_dereference (&oc
, MDL
);
2692 /* If so directed, use the leased IP address as the router address.
2693 This supposedly makes Win95 machines ARP for all IP addresses,
2694 so if the local router does proxy arp, you win. */
2696 if (evaluate_boolean_option_cache
2697 (&ignorep
, packet
, lease
, (struct client_state
*)0,
2698 packet
-> options
, state
-> options
, &lease
-> scope
,
2699 lookup_option (&server_universe
, state
-> options
,
2700 SV_USE_LEASE_ADDR_FOR_DEFAULT_ROUTE
), MDL
)) {
2702 oc
= lookup_option (&dhcp_universe
, state
-> options
, i
);
2704 oc
= (struct option_cache
*)0;
2705 if (option_cache_allocate (&oc
, MDL
)) {
2706 if (make_const_data (&oc
-> expression
,
2707 lease
-> ip_addr
.iabuf
,
2708 lease
-> ip_addr
.len
,
2710 option_code_hash_lookup(&oc
->option
,
2711 dhcp_universe
.code_hash
,
2713 save_option (&dhcp_universe
,
2714 state
-> options
, oc
);
2716 option_cache_dereference (&oc
, MDL
);
2721 /* If a site option space has been specified, use that for
2722 site option codes. */
2723 i
= SV_SITE_OPTION_SPACE
;
2724 if ((oc
= lookup_option (&server_universe
, state
-> options
, i
)) &&
2725 evaluate_option_cache (&d1
, packet
, lease
,
2726 (struct client_state
*)0,
2727 packet
-> options
, state
-> options
,
2728 &lease
-> scope
, oc
, MDL
)) {
2729 struct universe
*u
= (struct universe
*)0;
2731 if (!universe_hash_lookup (&u
, universe_hash
,
2732 (const char *)d1
.data
, d1
.len
,
2734 log_error ("unknown option space %s.", d1
.data
);
2738 state
-> options
-> site_universe
= u
-> index
;
2739 state
->options
->site_code_min
= find_min_site_code(u
);
2740 data_string_forget (&d1
, MDL
);
2742 state
-> options
-> site_code_min
= 0;
2743 state
-> options
-> site_universe
= dhcp_universe
.index
;
2746 /* If the client has provided a list of options that it wishes
2747 returned, use it to prioritize. If there's a parameter
2748 request list in scope, use that in preference. Otherwise
2749 use the default priority list. */
2751 oc
= lookup_option (&dhcp_universe
, state
-> options
,
2752 DHO_DHCP_PARAMETER_REQUEST_LIST
);
2755 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
2756 DHO_DHCP_PARAMETER_REQUEST_LIST
);
2758 evaluate_option_cache (&state
-> parameter_request_list
,
2759 packet
, lease
, (struct client_state
*)0,
2760 packet
-> options
, state
-> options
,
2761 &lease
-> scope
, oc
, MDL
);
2764 dump_packet (packet
);
2765 dump_raw ((unsigned char *)packet
-> raw
, packet
-> packet_length
);
2768 lease
-> state
= state
;
2770 log_info ("%s", msg
);
2772 /* Hang the packet off the lease state. */
2773 packet_reference (&lease
-> state
-> packet
, packet
, MDL
);
2775 /* If this is a DHCPOFFER, ping the lease address before actually
2776 sending the offer. */
2777 if (offer
== DHCPOFFER
&& !(lease
-> flags
& STATIC_LEASE
) &&
2778 ((cur_time
- lease_cltt
) > 60) &&
2779 (!(oc
= lookup_option (&server_universe
, state
-> options
,
2781 evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
2782 (struct client_state
*)0,
2785 &lease
-> scope
, oc
, MDL
))) {
2786 icmp_echorequest (&lease
-> ip_addr
);
2788 /* Determine whether to use configured or default ping timeout.
2790 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2791 SV_PING_TIMEOUT
)) &&
2792 evaluate_option_cache (&d1
, packet
, lease
, NULL
,
2795 &lease
-> scope
, oc
, MDL
)) {
2796 if (d1
.len
== sizeof (u_int32_t
))
2797 ping_timeout
= getULong (d1
.data
);
2799 ping_timeout
= DEFAULT_PING_TIMEOUT
;
2801 data_string_forget (&d1
, MDL
);
2803 ping_timeout
= DEFAULT_PING_TIMEOUT
;
2806 log_debug ("Ping timeout: %ld", (long)ping_timeout
);
2809 tv
. tv_sec
= cur_time
+ ping_timeout
;
2811 add_timeout (&tv
, lease_ping_timeout
, lease
,
2812 (tvref_t
)lease_reference
,
2813 (tvunref_t
)lease_dereference
);
2814 ++outstanding_pings
;
2816 lease
->cltt
= cur_time
;
2817 #if defined(DELAYED_ACK)
2818 if (!(lease
->flags
& STATIC_LEASE
) &&
2819 (!offer
|| (offer
== DHCPACK
)))
2820 delayed_ack_enqueue(lease
);
2827 /* CC: queue single ACK:
2828 - write the lease (but do not fsync it yet)
2829 - add to double linked list
2830 - commit if more than xx ACKs pending
2831 - Not yet: schedule a fsync at the next interval (1 second?)
2835 delayed_ack_enqueue(struct lease
*lease
)
2837 struct leasequeue
*q
;
2839 if (!write_lease(lease
))
2841 if (free_ackqueue
) {
2843 free_ackqueue
= q
->next
;
2845 q
= ((struct leasequeue
*)
2846 dmalloc(sizeof(struct leasequeue
), MDL
));
2848 log_fatal("delayed_ack_enqueue: no memory!");
2850 memset(q
, 0, sizeof *q
);
2851 /* prepend to ackqueue*/
2852 lease_reference(&q
->lease
, lease
, MDL
);
2853 q
->next
= ackqueue_head
;
2861 if (outstanding_acks
> max_outstanding_acks
)
2864 /* If next_fsync is not set, schedule an fsync. */
2865 if (next_fsync
.tv_sec
== 0 && next_fsync
.tv_usec
== 0) {
2866 next_fsync
.tv_sec
= cur_tv
.tv_sec
+ max_ack_delay_secs
;
2867 next_fsync
.tv_usec
= cur_tv
.tv_usec
+ max_ack_delay_usecs
;
2869 if (next_fsync
.tv_usec
>= 1000000) {
2870 next_fsync
.tv_sec
++;
2871 next_fsync
.tv_usec
-= 1000000;
2874 add_timeout(&next_fsync
, commit_leases_ackout
, NULL
,
2875 (tvref_t
) NULL
, (tvunref_t
) NULL
);
2880 commit_leases_readerdry(void *foo
)
2882 if (outstanding_acks
) {
2885 /* Reset next_fsync and cancel any pending timeout. */
2886 memset(&next_fsync
, 0, sizeof(next_fsync
));
2887 cancel_timeout(commit_leases_ackout
, NULL
);
2892 commit_leases_ackout(void *foo
)
2894 if (outstanding_acks
) {
2897 memset(&next_fsync
, 0, sizeof(next_fsync
));
2901 /* CC: process the delayed ACK responses:
2902 - send out the ACK packets
2903 - move the queue slots to the free list
2906 flush_ackqueue(void *foo
)
2908 struct leasequeue
*ack
, *p
;
2909 /* process from bottom to retain packet order */
2910 for (ack
= ackqueue_tail
; ack
; ack
= p
) {
2913 /* dhcp_reply() requires that the reply state still be valid */
2914 if (ack
->lease
->state
== NULL
)
2915 log_error("delayed ack for %s has gone stale",
2916 piaddr(ack
->lease
->ip_addr
));
2918 dhcp_reply(ack
->lease
);
2920 lease_dereference(&ack
->lease
, MDL
);
2921 ack
->next
= free_ackqueue
;
2922 free_ackqueue
= ack
;
2924 ackqueue_head
= NULL
;
2925 ackqueue_tail
= NULL
;
2926 outstanding_acks
= 0;
2929 #if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
2931 relinquish_ackqueue(void)
2933 struct leasequeue
*q
, *n
;
2935 for (q
= ackqueue_head
; q
; q
= n
) {
2939 for (q
= free_ackqueue
; q
; q
= n
) {
2946 void dhcp_reply (lease
)
2947 struct lease
*lease
;
2950 unsigned packet_length
;
2951 struct dhcp_packet raw
;
2952 struct sockaddr_in to
;
2953 struct in_addr from
;
2954 struct hardware hto
;
2956 struct lease_state
*state
= lease
-> state
;
2957 int nulltp
, bootpp
, unicastp
= 1;
2958 struct data_string d1
;
2962 log_fatal ("dhcp_reply was supplied lease with no state!");
2964 /* Compose a response for the client... */
2965 memset (&raw
, 0, sizeof raw
);
2966 memset (&d1
, 0, sizeof d1
);
2968 /* Copy in the filename if given; otherwise, flag the filename
2969 buffer as available for options. */
2970 if (state
-> filename
.len
&& state
-> filename
.data
) {
2972 state
-> filename
.data
,
2973 state
-> filename
.len
> sizeof raw
.file
2974 ? sizeof raw
.file
: state
-> filename
.len
);
2975 if (sizeof raw
.file
> state
-> filename
.len
)
2976 memset (&raw
.file
[state
-> filename
.len
], 0,
2977 (sizeof raw
.file
) - state
-> filename
.len
);
2981 /* Copy in the server name if given; otherwise, flag the
2982 server_name buffer as available for options. */
2983 if (state
-> server_name
.len
&& state
-> server_name
.data
) {
2985 state
-> server_name
.data
,
2986 state
-> server_name
.len
> sizeof raw
.sname
2987 ? sizeof raw
.sname
: state
-> server_name
.len
);
2988 if (sizeof raw
.sname
> state
-> server_name
.len
)
2989 memset (&raw
.sname
[state
-> server_name
.len
], 0,
2990 (sizeof raw
.sname
) - state
-> server_name
.len
);
2992 bufs
|= 2; /* XXX */
2995 &lease
-> hardware_addr
.hbuf
[1], sizeof raw
.chaddr
);
2996 raw
.hlen
= lease
-> hardware_addr
.hlen
- 1;
2997 raw
.htype
= lease
-> hardware_addr
.hbuf
[0];
2999 /* See if this is a Microsoft client that NUL-terminates its
3000 strings and expects us to do likewise... */
3001 if (lease
-> flags
& MS_NULL_TERMINATION
)
3006 /* See if this is a bootp client... */
3012 /* Insert such options as will fit into the buffer. */
3013 packet_length
= cons_options (state
-> packet
, &raw
, lease
,
3014 (struct client_state
*)0,
3015 state
-> max_message_size
,
3016 state
-> packet
-> options
,
3017 state
-> options
, &global_scope
,
3018 bufs
, nulltp
, bootpp
,
3019 &state
-> parameter_request_list
,
3022 memcpy (&raw
.ciaddr
, &state
-> ciaddr
, sizeof raw
.ciaddr
);
3023 memcpy (&raw
.yiaddr
, lease
-> ip_addr
.iabuf
, 4);
3024 raw
.siaddr
= state
-> siaddr
;
3025 raw
.giaddr
= state
-> giaddr
;
3027 raw
.xid
= state
-> xid
;
3028 raw
.secs
= state
-> secs
;
3029 raw
.flags
= state
-> bootp_flags
;
3030 raw
.hops
= state
-> hops
;
3033 if (lease
-> client_hostname
) {
3034 if ((strlen (lease
-> client_hostname
) <= 64) &&
3035 db_printable((unsigned char *)lease
->client_hostname
))
3036 s
= lease
-> client_hostname
;
3038 s
= "Hostname Unsuitable for Printing";
3042 /* Say what we're doing... */
3043 log_info ("%s on %s to %s %s%s%svia %s",
3045 ? (state
-> offer
== DHCPACK
? "DHCPACK" : "DHCPOFFER")
3047 piaddr (lease
-> ip_addr
),
3048 (lease
-> hardware_addr
.hlen
3049 ? print_hw_addr (lease
-> hardware_addr
.hbuf
[0],
3050 lease
-> hardware_addr
.hlen
- 1,
3051 &lease
-> hardware_addr
.hbuf
[1])
3052 : print_hex_1(lease
->uid_len
, lease
->uid
, 60)),
3053 s
? "(" : "", s
? s
: "", s
? ") " : "",
3054 (state
-> giaddr
.s_addr
3055 ? inet_ntoa (state
-> giaddr
)
3056 : state
-> ip
-> name
));
3058 /* Set up the hardware address... */
3059 hto
.hlen
= lease
-> hardware_addr
.hlen
;
3060 memcpy (hto
.hbuf
, lease
-> hardware_addr
.hbuf
, hto
.hlen
);
3062 to
.sin_family
= AF_INET
;
3064 to
.sin_len
= sizeof to
;
3066 memset (to
.sin_zero
, 0, sizeof to
.sin_zero
);
3069 dump_raw ((unsigned char *)&raw
, packet_length
);
3072 /* Make sure outgoing packets are at least as big
3073 as a BOOTP packet. */
3074 if (packet_length
< BOOTP_MIN_LEN
)
3075 packet_length
= BOOTP_MIN_LEN
;
3077 /* If this was gatewayed, send it back to the gateway... */
3078 if (raw
.giaddr
.s_addr
) {
3079 to
.sin_addr
= raw
.giaddr
;
3080 if (raw
.giaddr
.s_addr
!= htonl (INADDR_LOOPBACK
))
3081 to
.sin_port
= local_port
;
3083 to
.sin_port
= remote_port
; /* For debugging. */
3085 if (fallback_interface
) {
3086 result
= send_packet (fallback_interface
,
3088 &raw
, packet_length
,
3090 (struct hardware
*)0);
3092 free_lease_state (state
, MDL
);
3093 lease
-> state
= (struct lease_state
*)0;
3097 /* If the client is RENEWING, unicast to the client using the
3098 regular IP stack. Some clients, particularly those that
3099 follow RFC1541, are buggy, and send both ciaddr and server
3100 identifier. We deal with this situation by assuming that
3101 if we got both dhcp-server-identifier and ciaddr, and
3102 giaddr was not set, then the client is on the local
3103 network, and we can therefore unicast or broadcast to it
3104 successfully. A client in REQUESTING state on another
3105 network that's making this mistake will have set giaddr,
3106 and will therefore get a relayed response from the above
3108 } else if (raw
.ciaddr
.s_addr
&&
3109 !((state
-> got_server_identifier
||
3110 (raw
.flags
& htons (BOOTP_BROADCAST
))) &&
3111 /* XXX This won't work if giaddr isn't zero, but it is: */
3112 (state
-> shared_network
==
3113 lease
-> subnet
-> shared_network
)) &&
3114 state
-> offer
== DHCPACK
) {
3115 to
.sin_addr
= raw
.ciaddr
;
3116 to
.sin_port
= remote_port
;
3118 if (fallback_interface
) {
3119 result
= send_packet (fallback_interface
,
3121 &raw
, packet_length
,
3123 (struct hardware
*)0);
3124 free_lease_state (state
, MDL
);
3125 lease
-> state
= (struct lease_state
*)0;
3129 /* If it comes from a client that already knows its address
3130 and is not requesting a broadcast response, and we can
3131 unicast to a client without using the ARP protocol, sent it
3132 directly to that client. */
3133 } else if (!(raw
.flags
& htons (BOOTP_BROADCAST
)) &&
3134 can_unicast_without_arp (state
-> ip
)) {
3135 to
.sin_addr
= raw
.yiaddr
;
3136 to
.sin_port
= remote_port
;
3138 /* Otherwise, broadcast it on the local network. */
3140 to
.sin_addr
= limited_broadcast
;
3141 to
.sin_port
= remote_port
;
3142 if (!(lease
-> flags
& UNICAST_BROADCAST_HACK
))
3146 memcpy (&from
, state
-> from
.iabuf
, sizeof from
);
3148 result
= send_packet (state
-> ip
,
3149 (struct packet
*)0, &raw
, packet_length
,
3151 unicastp
? &hto
: (struct hardware
*)0);
3153 /* Free all of the entries in the option_state structure
3154 now that we're done with them. */
3156 free_lease_state (state
, MDL
);
3157 lease
-> state
= (struct lease_state
*)0;
3160 int find_lease (struct lease
**lp
,
3161 struct packet
*packet
, struct shared_network
*share
, int *ours
,
3162 int *peer_has_leases
, struct lease
*ip_lease_in
,
3163 const char *file
, int line
)
3165 struct lease
*uid_lease
= (struct lease
*)0;
3166 struct lease
*ip_lease
= (struct lease
*)0;
3167 struct lease
*hw_lease
= (struct lease
*)0;
3168 struct lease
*lease
= (struct lease
*)0;
3170 struct host_decl
*hp
= (struct host_decl
*)0;
3171 struct host_decl
*host
= (struct host_decl
*)0;
3172 struct lease
*fixed_lease
= (struct lease
*)0;
3173 struct lease
*next
= (struct lease
*)0;
3174 struct option_cache
*oc
;
3175 struct data_string d1
;
3176 int have_client_identifier
= 0;
3177 struct data_string client_identifier
;
3180 #if defined(FAILOVER_PROTOCOL)
3181 /* Quick check to see if the peer has leases. */
3182 if (peer_has_leases
) {
3185 for (pool
= share
->pools
; pool
; pool
= pool
->next
) {
3186 dhcp_failover_state_t
*peer
= pool
->failover_peer
;
3189 ((peer
->i_am
== primary
&& pool
->backup_leases
) ||
3190 (peer
->i_am
== secondary
&& pool
->free_leases
))) {
3191 *peer_has_leases
= 1;
3196 #endif /* FAILOVER_PROTOCOL */
3198 if (packet
-> raw
-> ciaddr
.s_addr
) {
3200 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
, 4);
3202 /* Look up the requested address. */
3203 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
3204 DHO_DHCP_REQUESTED_ADDRESS
);
3205 memset (&d1
, 0, sizeof d1
);
3207 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
3208 (struct client_state
*)0,
3210 (struct option_state
*)0,
3211 &global_scope
, oc
, MDL
)) {
3212 packet
-> got_requested_address
= 1;
3214 memcpy (cip
.iabuf
, d1
.data
, cip
.len
);
3215 data_string_forget (&d1
, MDL
);
3220 /* Try to find a host or lease that's been assigned to the
3221 specified unique client identifier. */
3222 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
3223 DHO_DHCP_CLIENT_IDENTIFIER
);
3224 memset (&client_identifier
, 0, sizeof client_identifier
);
3226 evaluate_option_cache (&client_identifier
,
3227 packet
, (struct lease
*)0,
3228 (struct client_state
*)0,
3229 packet
-> options
, (struct option_state
*)0,
3230 &global_scope
, oc
, MDL
)) {
3231 /* Remember this for later. */
3232 have_client_identifier
= 1;
3234 /* First, try to find a fixed host entry for the specified
3235 client identifier... */
3236 if (find_hosts_by_uid (&hp
, client_identifier
.data
,
3237 client_identifier
.len
, MDL
)) {
3238 /* Remember if we know of this client. */
3239 packet
-> known
= 1;
3240 mockup_lease (&fixed_lease
, packet
, share
, hp
);
3243 #if defined (DEBUG_FIND_LEASE)
3245 log_info ("Found host for client identifier: %s.",
3246 piaddr (fixed_lease
-> ip_addr
));
3250 if (!fixed_lease
) /* Save the host if we found one. */
3251 host_reference (&host
, hp
, MDL
);
3252 host_dereference (&hp
, MDL
);
3255 find_lease_by_uid (&uid_lease
, client_identifier
.data
,
3256 client_identifier
.len
, MDL
);
3259 /* If we didn't find a fixed lease using the uid, try doing
3260 it with the hardware address... */
3261 if (!fixed_lease
&& !host
) {
3262 if (find_hosts_by_haddr (&hp
, packet
-> raw
-> htype
,
3263 packet
-> raw
-> chaddr
,
3264 packet
-> raw
-> hlen
, MDL
)) {
3265 /* Remember if we know of this client. */
3266 packet
-> known
= 1;
3268 host_dereference (&host
, MDL
);
3269 host_reference (&host
, hp
, MDL
);
3270 host_dereference (&hp
, MDL
);
3271 mockup_lease (&fixed_lease
, packet
, share
, host
);
3272 #if defined (DEBUG_FIND_LEASE)
3274 log_info ("Found host for link address: %s.",
3275 piaddr (fixed_lease
-> ip_addr
));
3281 /* If fixed_lease is present but does not match the requested
3282 IP address, and this is a DHCPREQUEST, then we can't return
3283 any other lease, so we might as well return now. */
3284 if (packet
-> packet_type
== DHCPREQUEST
&& fixed_lease
&&
3285 (fixed_lease
-> ip_addr
.len
!= cip
.len
||
3286 memcmp (fixed_lease
-> ip_addr
.iabuf
,
3287 cip
.iabuf
, cip
.len
))) {
3290 strcpy (dhcp_message
, "requested address is incorrect");
3291 #if defined (DEBUG_FIND_LEASE)
3292 log_info ("Client's fixed-address %s doesn't match %s%s",
3293 piaddr (fixed_lease
-> ip_addr
), "request ",
3294 print_dotted_quads (cip
.len
, cip
.iabuf
));
3299 /* If we found leases matching the client identifier, loop through
3300 * the n_uid pointer looking for one that's actually valid. We
3301 * can't do this until we get here because we depend on
3302 * packet -> known, which may be set by either the uid host
3303 * lookup or the haddr host lookup.
3305 * Note that the n_uid lease chain is sorted in order of
3306 * preference, so the first one is the best one.
3309 #if defined (DEBUG_FIND_LEASE)
3310 log_info ("trying next lease matching client id: %s",
3311 piaddr (uid_lease
-> ip_addr
));
3314 #if defined (FAILOVER_PROTOCOL)
3315 /* When failover is active, it's possible that there could
3316 be two "free" leases for the same uid, but only one of
3317 them that's available for this failover peer to allocate. */
3318 if (uid_lease
-> binding_state
!= FTS_ACTIVE
&&
3319 !lease_mine_to_reallocate (uid_lease
)) {
3320 #if defined (DEBUG_FIND_LEASE)
3321 log_info ("not mine to allocate: %s",
3322 piaddr (uid_lease
-> ip_addr
));
3328 if (uid_lease
-> subnet
-> shared_network
!= share
) {
3329 #if defined (DEBUG_FIND_LEASE)
3330 log_info ("wrong network segment: %s",
3331 piaddr (uid_lease
-> ip_addr
));
3336 if ((uid_lease
-> pool
-> prohibit_list
&&
3337 permitted (packet
, uid_lease
-> pool
-> prohibit_list
)) ||
3338 (uid_lease
-> pool
-> permit_list
&&
3339 !permitted (packet
, uid_lease
-> pool
-> permit_list
))) {
3340 #if defined (DEBUG_FIND_LEASE)
3341 log_info ("not permitted: %s",
3342 piaddr (uid_lease
-> ip_addr
));
3345 if (uid_lease
-> n_uid
)
3346 lease_reference (&next
,
3347 uid_lease
-> n_uid
, MDL
);
3348 if (!packet
-> raw
-> ciaddr
.s_addr
)
3349 release_lease (uid_lease
, packet
);
3350 lease_dereference (&uid_lease
, MDL
);
3352 lease_reference (&uid_lease
, next
, MDL
);
3353 lease_dereference (&next
, MDL
);
3359 #if defined (DEBUG_FIND_LEASE)
3361 log_info ("Found lease for client id: %s.",
3362 piaddr (uid_lease
-> ip_addr
));
3365 /* Find a lease whose hardware address matches, whose client
3366 * identifier matches (or equally doesn't have one), that's
3367 * permitted, and that's on the correct subnet.
3369 * Note that the n_hw chain is sorted in order of preference, so
3370 * the first one found is the best one.
3372 h
.hlen
= packet
-> raw
-> hlen
+ 1;
3373 h
.hbuf
[0] = packet
-> raw
-> htype
;
3374 memcpy (&h
.hbuf
[1], packet
-> raw
-> chaddr
, packet
-> raw
-> hlen
);
3375 find_lease_by_hw_addr (&hw_lease
, h
.hbuf
, h
.hlen
, MDL
);
3377 #if defined (DEBUG_FIND_LEASE)
3378 log_info ("trying next lease matching hw addr: %s",
3379 piaddr (hw_lease
-> ip_addr
));
3381 #if defined (FAILOVER_PROTOCOL)
3382 /* When failover is active, it's possible that there could
3383 be two "free" leases for the same uid, but only one of
3384 them that's available for this failover peer to allocate. */
3385 if (hw_lease
-> binding_state
!= FTS_ACTIVE
&&
3386 !lease_mine_to_reallocate (hw_lease
)) {
3387 #if defined (DEBUG_FIND_LEASE)
3388 log_info ("not mine to allocate: %s",
3389 piaddr (hw_lease
-> ip_addr
));
3395 if (hw_lease
-> binding_state
!= FTS_FREE
&&
3396 hw_lease
-> binding_state
!= FTS_BACKUP
&&
3398 (!have_client_identifier
||
3399 hw_lease
-> uid_len
!= client_identifier
.len
||
3400 memcmp (hw_lease
-> uid
, client_identifier
.data
,
3401 hw_lease
-> uid_len
))) {
3402 #if defined (DEBUG_FIND_LEASE)
3403 log_info ("wrong client identifier: %s",
3404 piaddr (hw_lease
-> ip_addr
));
3409 if (hw_lease
-> subnet
-> shared_network
!= share
) {
3410 #if defined (DEBUG_FIND_LEASE)
3411 log_info ("wrong network segment: %s",
3412 piaddr (hw_lease
-> ip_addr
));
3417 if ((hw_lease
-> pool
-> prohibit_list
&&
3418 permitted (packet
, hw_lease
-> pool
-> prohibit_list
)) ||
3419 (hw_lease
-> pool
-> permit_list
&&
3420 !permitted (packet
, hw_lease
-> pool
-> permit_list
))) {
3421 #if defined (DEBUG_FIND_LEASE)
3422 log_info ("not permitted: %s",
3423 piaddr (hw_lease
-> ip_addr
));
3425 if (!packet
-> raw
-> ciaddr
.s_addr
)
3426 release_lease (hw_lease
, packet
);
3428 if (hw_lease
-> n_hw
)
3429 lease_reference (&next
, hw_lease
-> n_hw
, MDL
);
3430 lease_dereference (&hw_lease
, MDL
);
3432 lease_reference (&hw_lease
, next
, MDL
);
3433 lease_dereference (&next
, MDL
);
3439 #if defined (DEBUG_FIND_LEASE)
3441 log_info ("Found lease for hardware address: %s.",
3442 piaddr (hw_lease
-> ip_addr
));
3445 /* Try to find a lease that's been allocated to the client's
3448 lease_reference (&ip_lease
, ip_lease_in
, MDL
);
3450 find_lease_by_ip_addr (&ip_lease
, cip
, MDL
);
3452 #if defined (DEBUG_FIND_LEASE)
3454 log_info ("Found lease for requested address: %s.",
3455 piaddr (ip_lease
-> ip_addr
));
3458 /* If ip_lease is valid at this point, set ours to one, so that
3459 even if we choose a different lease, we know that the address
3460 the client was requesting was ours, and thus we can NAK it. */
3461 if (ip_lease
&& ours
)
3464 /* If the requested IP address isn't on the network the packet
3465 came from, don't use it. Allow abandoned leases to be matched
3466 here - if the client is requesting it, there's a decent chance
3467 that it's because the lease database got trashed and a client
3468 that thought it had this lease answered an ARP or PING, causing the
3469 lease to be abandoned. If so, this request probably came from
3471 if (ip_lease
&& (ip_lease
-> subnet
-> shared_network
!= share
)) {
3474 #if defined (DEBUG_FIND_LEASE)
3475 log_info ("...but it was on the wrong shared network.");
3477 strcpy (dhcp_message
, "requested address on bad subnet");
3478 lease_dereference (&ip_lease
, MDL
);
3481 /* Toss ip_lease if it hasn't yet expired and doesn't belong to the
3485 (!have_client_identifier
||
3486 ip_lease
-> uid_len
!= client_identifier
.len
||
3487 memcmp (ip_lease
-> uid
, client_identifier
.data
,
3488 ip_lease
-> uid_len
)) :
3489 (ip_lease
-> hardware_addr
.hbuf
[0] != packet
-> raw
-> htype
||
3490 ip_lease
-> hardware_addr
.hlen
!= packet
-> raw
-> hlen
+ 1 ||
3491 memcmp (&ip_lease
-> hardware_addr
.hbuf
[1],
3492 packet
-> raw
-> chaddr
,
3493 (unsigned)(ip_lease
-> hardware_addr
.hlen
- 1))))) {
3494 /* If we're not doing failover, the only state in which
3495 we can allocate this lease to the client is FTS_FREE.
3496 If we are doing failover, things are more complicated.
3497 If the lease is free or backup, we let the caller decide
3498 whether or not to give it out. */
3499 if (ip_lease
-> binding_state
!= FTS_FREE
&&
3500 ip_lease
-> binding_state
!= FTS_BACKUP
) {
3501 #if defined (DEBUG_FIND_LEASE)
3502 log_info ("rejecting lease for requested address.");
3504 /* If we're rejecting it because the peer has
3505 it, don't set "ours", because we shouldn't NAK. */
3506 if (ours
&& ip_lease
-> binding_state
!= FTS_ACTIVE
)
3508 lease_dereference (&ip_lease
, MDL
);
3512 /* If we got an ip_lease and a uid_lease or hw_lease, and ip_lease
3513 is not active, and is not ours to reallocate, forget about it. */
3514 if (ip_lease
&& (uid_lease
|| hw_lease
) &&
3515 ip_lease
-> binding_state
!= FTS_ACTIVE
&&
3516 #if defined(FAILOVER_PROTOCOL)
3517 !lease_mine_to_reallocate (ip_lease
) &&
3519 packet
-> packet_type
== DHCPDISCOVER
) {
3520 #if defined (DEBUG_FIND_LEASE)
3521 log_info ("ip lease not ours to offer.");
3523 lease_dereference (&ip_lease
, MDL
);
3526 /* If for some reason the client has more than one lease
3527 on the subnet that matches its uid, pick the one that
3528 it asked for and (if we can) free the other. */
3529 if (ip_lease
&& ip_lease
->binding_state
== FTS_ACTIVE
&&
3530 ip_lease
->uid
&& ip_lease
!= uid_lease
) {
3531 if (have_client_identifier
&&
3532 (ip_lease
-> uid_len
== client_identifier
.len
) &&
3533 !memcmp (client_identifier
.data
,
3534 ip_lease
-> uid
, ip_lease
-> uid_len
)) {
3536 if (uid_lease
->binding_state
== FTS_ACTIVE
) {
3537 log_error ("client %s has duplicate%s on %s",
3539 (packet
-> raw
-> htype
,
3540 packet
-> raw
-> hlen
,
3541 packet
-> raw
-> chaddr
)),
3543 (ip_lease
-> subnet
->
3544 shared_network
-> name
));
3546 /* If the client is REQUESTing the lease,
3547 it shouldn't still be using the old
3548 one, so we can free it for allocation. */
3550 uid_lease
->binding_state
== FTS_ACTIVE
&&
3551 !packet
-> raw
-> ciaddr
.s_addr
&&
3553 uid_lease
-> subnet
-> shared_network
) &&
3554 packet
-> packet_type
== DHCPREQUEST
)
3555 release_lease (uid_lease
, packet
);
3557 lease_dereference (&uid_lease
, MDL
);
3558 lease_reference (&uid_lease
, ip_lease
, MDL
);
3562 /* If we get to here and fixed_lease is not null, that means
3563 that there are both a dynamic lease and a fixed-address
3564 declaration for the same IP address. */
3565 if (packet
-> packet_type
== DHCPREQUEST
&& fixed_lease
) {
3566 lease_dereference (&fixed_lease
, MDL
);
3568 log_error ("Dynamic and static leases present for %s.",
3570 log_error ("Remove host declaration %s or remove %s",
3571 (fixed_lease
&& fixed_lease
-> host
3572 ? (fixed_lease
-> host
-> name
3573 ? fixed_lease
-> host
-> name
3577 log_error ("from the dynamic address pool for %s",
3578 ip_lease
-> subnet
-> shared_network
-> name
3581 lease_dereference (&ip_lease
, MDL
);
3582 strcpy (dhcp_message
,
3583 "database conflict - call for help!");
3586 if (ip_lease
&& ip_lease
!= uid_lease
) {
3587 #if defined (DEBUG_FIND_LEASE)
3588 log_info ("requested address not available.");
3590 lease_dereference (&ip_lease
, MDL
);
3594 /* If we get to here with both fixed_lease and ip_lease not
3595 null, then we have a configuration file bug. */
3596 if (packet
-> packet_type
== DHCPREQUEST
&& fixed_lease
&& ip_lease
)
3599 /* Toss extra pointers to the same lease... */
3600 if (hw_lease
&& hw_lease
== uid_lease
) {
3601 #if defined (DEBUG_FIND_LEASE)
3602 log_info ("hardware lease and uid lease are identical.");
3604 lease_dereference (&hw_lease
, MDL
);
3606 if (ip_lease
&& ip_lease
== hw_lease
) {
3607 lease_dereference (&hw_lease
, MDL
);
3608 #if defined (DEBUG_FIND_LEASE)
3609 log_info ("hardware lease and ip lease are identical.");
3612 if (ip_lease
&& ip_lease
== uid_lease
) {
3613 lease_dereference (&uid_lease
, MDL
);
3614 #if defined (DEBUG_FIND_LEASE)
3615 log_info ("uid lease and ip lease are identical.");
3619 /* Make sure the client is permitted to use the requested lease. */
3621 ((ip_lease
-> pool
-> prohibit_list
&&
3622 permitted (packet
, ip_lease
-> pool
-> prohibit_list
)) ||
3623 (ip_lease
-> pool
-> permit_list
&&
3624 !permitted (packet
, ip_lease
-> pool
-> permit_list
)))) {
3625 if (!packet
->raw
->ciaddr
.s_addr
&&
3626 (ip_lease
->binding_state
== FTS_ACTIVE
))
3627 release_lease (ip_lease
, packet
);
3629 lease_dereference (&ip_lease
, MDL
);
3633 ((uid_lease
-> pool
-> prohibit_list
&&
3634 permitted (packet
, uid_lease
-> pool
-> prohibit_list
)) ||
3635 (uid_lease
-> pool
-> permit_list
&&
3636 !permitted (packet
, uid_lease
-> pool
-> permit_list
)))) {
3637 if (!packet
-> raw
-> ciaddr
.s_addr
)
3638 release_lease (uid_lease
, packet
);
3639 lease_dereference (&uid_lease
, MDL
);
3643 ((hw_lease
-> pool
-> prohibit_list
&&
3644 permitted (packet
, hw_lease
-> pool
-> prohibit_list
)) ||
3645 (hw_lease
-> pool
-> permit_list
&&
3646 !permitted (packet
, hw_lease
-> pool
-> permit_list
)))) {
3647 if (!packet
-> raw
-> ciaddr
.s_addr
)
3648 release_lease (hw_lease
, packet
);
3649 lease_dereference (&hw_lease
, MDL
);
3652 /* If we've already eliminated the lease, it wasn't there to
3653 begin with. If we have come up with a matching lease,
3654 set the message to bad network in case we have to throw it out. */
3656 strcpy (dhcp_message
, "requested address not available");
3659 /* If this is a DHCPREQUEST, make sure the lease we're going to return
3660 matches the requested IP address. If it doesn't, don't return a
3662 if (packet
-> packet_type
== DHCPREQUEST
&&
3663 !ip_lease
&& !fixed_lease
) {
3664 #if defined (DEBUG_FIND_LEASE)
3665 log_info ("no applicable lease found for DHCPREQUEST.");
3670 /* At this point, if fixed_lease is nonzero, we can assign it to
3673 lease_reference (&lease
, fixed_lease
, MDL
);
3674 lease_dereference (&fixed_lease
, MDL
);
3675 #if defined (DEBUG_FIND_LEASE)
3676 log_info ("choosing fixed address.");
3680 /* If we got a lease that matched the ip address and don't have
3681 a better offer, use that; otherwise, release it. */
3684 if (!packet
-> raw
-> ciaddr
.s_addr
)
3685 release_lease (ip_lease
, packet
);
3686 #if defined (DEBUG_FIND_LEASE)
3687 log_info ("not choosing requested address (!).");
3690 #if defined (DEBUG_FIND_LEASE)
3691 log_info ("choosing lease on requested address.");
3693 lease_reference (&lease
, ip_lease
, MDL
);
3695 host_dereference (&lease
-> host
, MDL
);
3697 lease_dereference (&ip_lease
, MDL
);
3700 /* If we got a lease that matched the client identifier, we may want
3701 to use it, but if we already have a lease we like, we must free
3702 the lease that matched the client identifier. */
3705 log_error("uid lease %s for client %s is duplicate "
3707 piaddr(uid_lease
->ip_addr
),
3708 print_hw_addr(packet
->raw
->htype
,
3710 packet
->raw
->chaddr
),
3711 uid_lease
->subnet
->shared_network
->name
);
3713 if (!packet
-> raw
-> ciaddr
.s_addr
&&
3714 packet
-> packet_type
== DHCPREQUEST
&&
3715 uid_lease
-> binding_state
== FTS_ACTIVE
)
3716 release_lease(uid_lease
, packet
);
3717 #if defined (DEBUG_FIND_LEASE)
3718 log_info ("not choosing uid lease.");
3721 lease_reference (&lease
, uid_lease
, MDL
);
3723 host_dereference (&lease
-> host
, MDL
);
3724 #if defined (DEBUG_FIND_LEASE)
3725 log_info ("choosing uid lease.");
3728 lease_dereference (&uid_lease
, MDL
);
3731 /* The lease that matched the hardware address is treated likewise. */
3734 #if defined (DEBUG_FIND_LEASE)
3735 log_info ("not choosing hardware lease.");
3738 /* We're a little lax here - if the client didn't
3739 send a client identifier and it's a bootp client,
3740 but the lease has a client identifier, we still
3741 let the client have a lease. */
3742 if (!hw_lease
-> uid_len
||
3743 (have_client_identifier
3744 ? (hw_lease
-> uid_len
==
3745 client_identifier
.len
&&
3746 !memcmp (hw_lease
-> uid
,
3747 client_identifier
.data
,
3748 client_identifier
.len
))
3749 : packet
-> packet_type
== 0)) {
3750 lease_reference (&lease
, hw_lease
, MDL
);
3752 host_dereference (&lease
-> host
, MDL
);
3753 #if defined (DEBUG_FIND_LEASE)
3754 log_info ("choosing hardware lease.");
3757 #if defined (DEBUG_FIND_LEASE)
3758 log_info ("not choosing hardware lease: %s.",
3763 lease_dereference (&hw_lease
, MDL
);
3766 /* If we found a host_decl but no matching address, try to
3767 find a host_decl that has no address, and if there is one,
3768 hang it off the lease so that we can use the supplied
3770 if (lease
&& host
&& !lease
-> host
) {
3771 struct host_decl
*p
= (struct host_decl
*)0;
3772 struct host_decl
*n
= (struct host_decl
*)0;
3773 host_reference (&p
, host
, MDL
);
3775 if (!p
-> fixed_addr
) {
3776 host_reference (&lease
-> host
, p
, MDL
);
3777 host_dereference (&p
, MDL
);
3781 host_reference (&n
, p
-> n_ipaddr
, MDL
);
3782 host_dereference (&p
, MDL
);
3784 host_reference (&p
, n
, MDL
);
3785 host_dereference (&n
, MDL
);
3790 /* If we find an abandoned lease, but it's the one the client
3791 requested, we assume that previous bugginess on the part
3792 of the client, or a server database loss, caused the lease to
3793 be abandoned, so we reclaim it and let the client have it. */
3795 (lease
-> binding_state
== FTS_ABANDONED
) &&
3796 lease
== ip_lease
&&
3797 packet
-> packet_type
== DHCPREQUEST
) {
3798 log_error ("Reclaiming REQUESTed abandoned IP address %s.",
3799 piaddr (lease
-> ip_addr
));
3800 } else if (lease
&& (lease
-> binding_state
== FTS_ABANDONED
)) {
3801 /* Otherwise, if it's not the one the client requested, we do not
3802 return it - instead, we claim it's ours, causing a DHCPNAK to be
3803 sent if this lookup is for a DHCPREQUEST, and force the client
3804 to go back through the allocation process. */
3807 lease_dereference (&lease
, MDL
);
3811 if (have_client_identifier
)
3812 data_string_forget (&client_identifier
, MDL
);
3815 lease_dereference (&fixed_lease
, MDL
);
3817 lease_dereference (&hw_lease
, MDL
);
3819 lease_dereference (&uid_lease
, MDL
);
3821 lease_dereference (&ip_lease
, MDL
);
3823 host_dereference (&host
, MDL
);
3826 #if defined (DEBUG_FIND_LEASE)
3827 log_info ("Returning lease: %s.",
3828 piaddr (lease
-> ip_addr
));
3830 lease_reference (lp
, lease
, file
, line
);
3831 lease_dereference (&lease
, MDL
);
3834 #if defined (DEBUG_FIND_LEASE)
3835 log_info ("Not returning a lease.");
3840 /* Search the provided host_decl structure list for an address that's on
3841 the specified shared network. If one is found, mock up and return a
3842 lease structure for it; otherwise return the null pointer. */
3844 int mockup_lease (struct lease
**lp
, struct packet
*packet
,
3845 struct shared_network
*share
, struct host_decl
*hp
)
3847 struct lease
*lease
= (struct lease
*)0;
3848 struct host_decl
*rhp
= (struct host_decl
*)0;
3850 if (lease_allocate (&lease
, MDL
) != ISC_R_SUCCESS
)
3852 if (host_reference (&rhp
, hp
, MDL
) != ISC_R_SUCCESS
) {
3853 lease_dereference (&lease
, MDL
);
3856 if (!find_host_for_network (&lease
-> subnet
,
3857 &rhp
, &lease
-> ip_addr
, share
)) {
3858 lease_dereference (&lease
, MDL
);
3859 host_dereference (&rhp
, MDL
);
3862 host_reference (&lease
-> host
, rhp
, MDL
);
3863 if (rhp
-> client_identifier
.len
> sizeof lease
-> uid_buf
)
3864 lease
-> uid
= dmalloc (rhp
-> client_identifier
.len
, MDL
);
3866 lease
-> uid
= lease
-> uid_buf
;
3867 if (!lease
-> uid
) {
3868 lease_dereference (&lease
, MDL
);
3869 host_dereference (&rhp
, MDL
);
3872 memcpy (lease
-> uid
, rhp
-> client_identifier
.data
,
3873 rhp
-> client_identifier
.len
);
3874 lease
-> uid_len
= rhp
-> client_identifier
.len
;
3875 lease
-> hardware_addr
= rhp
-> interface
;
3876 lease
-> starts
= lease
-> cltt
= lease
-> ends
= MIN_TIME
;
3877 lease
-> flags
= STATIC_LEASE
;
3878 lease
-> binding_state
= FTS_FREE
;
3880 lease_reference (lp
, lease
, MDL
);
3882 lease_dereference (&lease
, MDL
);
3883 host_dereference (&rhp
, MDL
);
3887 /* Look through all the pools in a list starting with the specified pool
3888 for a free lease. We try to find a virgin lease if we can. If we
3889 don't find a virgin lease, we try to find a non-virgin lease that's
3890 free. If we can't find one of those, we try to reclaim an abandoned
3891 lease. If all of these possibilities fail to pan out, we don't return
3894 int allocate_lease (struct lease
**lp
, struct packet
*packet
,
3895 struct pool
*pool
, int *peer_has_leases
)
3897 struct lease
*lease
= (struct lease
*)0;
3898 struct lease
*candl
= (struct lease
*)0;
3900 for (; pool
; pool
= pool
-> next
) {
3901 if ((pool
-> prohibit_list
&&
3902 permitted (packet
, pool
-> prohibit_list
)) ||
3903 (pool
-> permit_list
&&
3904 !permitted (packet
, pool
-> permit_list
)))
3907 #if defined (FAILOVER_PROTOCOL)
3908 /* Peer_has_leases just says that we found at least one
3909 free lease. If no free lease is returned, the caller
3910 can deduce that this means the peer is hogging all the
3911 free leases, so we can print a better error message. */
3912 /* XXX Do we need code here to ignore PEER_IS_OWNER and
3913 * XXX just check tstp if we're in, e.g., PARTNER_DOWN?
3914 * XXX Where do we deal with CONFLICT_DETECTED, et al? */
3915 /* XXX This should be handled by the lease binding "state
3916 * XXX machine" - that is, when we get here, if a lease
3917 * XXX could be allocated, it will have the correct
3918 * XXX binding state so that the following code will
3919 * XXX result in its being allocated. */
3920 /* Skip to the most expired lease in the pool that is not
3921 * owned by a failover peer. */
3922 if (pool
->failover_peer
!= NULL
) {
3923 if (pool
->failover_peer
->i_am
== primary
) {
3927 * In normal operation, we never want to touch
3928 * the peer's leases. In partner-down
3929 * operation, we need to be able to pick up
3930 * the peer's leases after STOS+MCLT.
3932 if (pool
->backup
!= NULL
) {
3933 if (((candl
== NULL
) ||
3935 pool
->backup
->ends
)) &&
3936 lease_mine_to_reallocate(
3938 candl
= pool
->backup
;
3940 *peer_has_leases
= 1;
3944 candl
= pool
->backup
;
3946 if (pool
->free
!= NULL
) {
3947 if (((candl
== NULL
) ||
3949 pool
->free
->ends
)) &&
3950 lease_mine_to_reallocate(
3954 *peer_has_leases
= 1;
3959 if ((candl
== NULL
) &&
3960 (pool
->abandoned
!= NULL
) &&
3961 lease_mine_to_reallocate(pool
->abandoned
))
3962 candl
= pool
->abandoned
;
3967 candl
= pool
-> free
;
3969 candl
= pool
-> abandoned
;
3973 * XXX: This may not match with documented expectation.
3974 * It's expected that when we OFFER a lease, we set its
3975 * ends time forward 2 minutes so that it gets sorted to
3976 * the end of its free list (avoiding a similar allocation
3977 * to another client). It is not expected that we issue a
3978 * "no free leases" error when the last lease has been
3979 * offered, but it's not exactly broken either.
3981 if (!candl
|| (candl
-> ends
> cur_time
))
3989 if ((lease
-> binding_state
== FTS_ABANDONED
) &&
3990 ((candl
-> binding_state
!= FTS_ABANDONED
) ||
3991 (candl
-> ends
< lease
-> ends
))) {
3994 } else if (candl
-> binding_state
== FTS_ABANDONED
)
3997 if ((lease
-> uid_len
|| lease
-> hardware_addr
.hlen
) &&
3998 ((!candl
-> uid_len
&& !candl
-> hardware_addr
.hlen
) ||
3999 (candl
-> ends
< lease
-> ends
))) {
4002 } else if (candl
-> uid_len
|| candl
-> hardware_addr
.hlen
)
4005 if (candl
-> ends
< lease
-> ends
)
4010 if (lease
-> binding_state
== FTS_ABANDONED
)
4011 log_error ("Reclaiming abandoned lease %s.",
4012 piaddr (lease
-> ip_addr
));
4014 lease_reference (lp
, lease
, MDL
);
4021 /* Determine whether or not a permit exists on a particular permit list
4022 that matches the specified packet, returning nonzero if so, zero if
4025 int permitted (packet
, permit_list
)
4026 struct packet
*packet
;
4027 struct permit
*permit_list
;
4032 for (p
= permit_list
; p
; p
= p
-> next
) {
4033 switch (p
-> type
) {
4034 case permit_unknown_clients
:
4035 if (!packet
-> known
)
4039 case permit_known_clients
:
4040 if (packet
-> known
)
4044 case permit_authenticated_clients
:
4045 if (packet
-> authenticated
)
4049 case permit_unauthenticated_clients
:
4050 if (!packet
-> authenticated
)
4054 case permit_all_clients
:
4057 case permit_dynamic_bootp_clients
:
4058 if (!packet
-> options_valid
||
4059 !packet
-> packet_type
)
4064 for (i
= 0; i
< packet
-> class_count
; i
++) {
4065 if (p
-> class == packet
-> classes
[i
])
4067 if (packet
-> classes
[i
] &&
4068 packet
-> classes
[i
] -> superclass
&&
4069 (packet
-> classes
[i
] -> superclass
==
4076 if (cur_time
> p
->after
)
4084 int locate_network (packet
)
4085 struct packet
*packet
;
4088 struct data_string data
;
4089 struct subnet
*subnet
= (struct subnet
*)0;
4090 struct option_cache
*oc
;
4092 /* See if there's a Relay Agent Link Selection Option, or a
4093 * Subnet Selection Option. The Link-Select and Subnet-Select
4094 * are formatted and used precisely the same, but we must prefer
4095 * the link-select over the subnet-select.
4097 if ((oc
= lookup_option(&agent_universe
, packet
->options
,
4098 RAI_LINK_SELECT
)) == NULL
)
4099 oc
= lookup_option(&dhcp_universe
, packet
->options
,
4100 DHO_SUBNET_SELECTION
);
4102 /* If there's no SSO and no giaddr, then use the shared_network
4103 from the interface, if there is one. If not, fail. */
4104 if (!oc
&& !packet
-> raw
-> giaddr
.s_addr
) {
4105 if (packet
-> interface
-> shared_network
) {
4106 shared_network_reference
4107 (&packet
-> shared_network
,
4108 packet
-> interface
-> shared_network
, MDL
);
4114 /* If there's an option indicating link connection, and it's valid,
4115 * use it to figure out the subnet. If it's not valid, fail.
4118 memset (&data
, 0, sizeof data
);
4119 if (!evaluate_option_cache (&data
, packet
, (struct lease
*)0,
4120 (struct client_state
*)0,
4122 (struct option_state
*)0,
4123 &global_scope
, oc
, MDL
)) {
4126 if (data
.len
!= 4) {
4130 memcpy (ia
.iabuf
, data
.data
, 4);
4131 data_string_forget (&data
, MDL
);
4134 memcpy (ia
.iabuf
, &packet
-> raw
-> giaddr
, 4);
4137 /* If we know the subnet on which the IP address lives, use it. */
4138 if (find_subnet (&subnet
, ia
, MDL
)) {
4139 shared_network_reference (&packet
-> shared_network
,
4140 subnet
-> shared_network
, MDL
);
4141 subnet_dereference (&subnet
, MDL
);
4145 /* Otherwise, fail. */
4150 * Try to figure out the source address to send packets from.
4152 * If the packet we received specified the server address, then we
4155 * Otherwise, use the first address from the interface. If we do
4156 * this, we also save this into the option cache as the server
4160 get_server_source_address(struct in_addr
*from
,
4161 struct option_state
*options
,
4162 struct packet
*packet
) {
4163 unsigned option_num
;
4164 struct option_cache
*oc
;
4165 struct data_string d
;
4168 memset(&d
, 0, sizeof(d
));
4170 option_num
= DHO_DHCP_SERVER_IDENTIFIER
;
4171 oc
= lookup_option(&dhcp_universe
, options
, option_num
);
4173 evaluate_option_cache(&d
, packet
, NULL
, NULL
, packet
->options
,
4174 options
, &global_scope
, oc
, MDL
)) {
4175 if (d
.len
== sizeof(*from
)) {
4176 memcpy(from
, d
.data
, sizeof(*from
));
4177 data_string_forget(&d
, MDL
);
4180 data_string_forget(&d
, MDL
);
4183 if (packet
->interface
->address_count
> 0) {
4184 if (option_cache_allocate(&oc
, MDL
)) {
4185 a
= &packet
->interface
->addresses
[0];
4186 if (make_const_data(&oc
->expression
,
4187 (unsigned char *)a
, sizeof(*a
),
4189 option_code_hash_lookup(&oc
->option
,
4190 dhcp_universe
.code_hash
,
4191 &option_num
, 0, MDL
);
4192 save_option(&dhcp_universe
, options
, oc
);
4194 option_cache_dereference(&oc
, MDL
);
4196 *from
= packet
->interface
->addresses
[0];
4198 memset(from
, 0, sizeof(*from
));
4203 * Look for the lowest numbered site code number and
4204 * apply a log warning if it is less than 224. Do not
4205 * permit site codes less than 128 (old code never did).
4207 * Note that we could search option codes 224 down to 128
4208 * on the hash table, but the table is (probably) smaller
4209 * than that if it was declared as a standalone table with
4210 * defaults. So we traverse the option code hash.
4213 find_min_site_code(struct universe
*u
)
4215 if (u
->site_code_min
)
4216 return u
->site_code_min
;
4219 * Note that site_code_min has to be global as we can't pass an
4220 * argument through hash_foreach(). The value 224 is taken from
4223 site_code_min
= 224;
4224 option_code_hash_foreach(u
->code_hash
, lowest_site_code
);
4226 if (site_code_min
< 224) {
4227 log_error("WARNING: site-local option codes less than 224 have "
4228 "been deprecated by RFC3942. You have options "
4229 "listed in site local space %s that number as low as "
4230 "%d. Please investigate if these should be declared "
4231 "as regular options rather than site-local options, "
4232 "or migrated up past 224.",
4233 u
->name
, site_code_min
);
4237 * don't even bother logging, this is just silly, and never worked
4238 * on any old version of software.
4240 if (site_code_min
< 128)
4241 site_code_min
= 128;
4244 * Cache the determined minimum site code on the universe structure.
4245 * Note that due to the < 128 check above, a value of zero is
4248 u
->site_code_min
= site_code_min
;
4250 return site_code_min
;
4254 lowest_site_code(const void *key
, unsigned len
, void *object
)
4256 struct option
*option
= object
;
4258 if (option
->code
< site_code_min
)
4259 site_code_min
= option
->code
;
4261 return ISC_R_SUCCESS
;
4265 maybe_return_agent_options(struct packet
*packet
, struct option_state
*options
)
4267 /* If there were agent options in the incoming packet, return
4268 * them. Do not return the agent options if they were stashed
4269 * on the lease. We do not check giaddr to detect the presence of
4270 * a relay, as this excludes "l2" relay agents which have no giaddr
4273 * XXX: If the user configures options for the relay agent information
4274 * (state->options->universes[agent_universe.index] is not NULL),
4275 * we're still required to duplicate other values provided by the
4276 * relay agent. So we need to merge the old values not configured
4277 * by the user into the new state, not just give up.
4279 if (!packet
->agent_options_stashed
&&
4280 packet
->options
->universe_count
> agent_universe
.index
&&
4281 packet
->options
->universes
[agent_universe
.index
] != NULL
&&
4282 (options
->universe_count
<= agent_universe
.index
||
4283 options
->universes
[agent_universe
.index
] == NULL
)) {
4284 option_chain_head_reference
4285 ((struct option_chain_head
**)
4286 &(options
->universes
[agent_universe
.index
]),
4287 (struct option_chain_head
*)
4288 packet
->options
->universes
[agent_universe
.index
], MDL
);
4290 if (options
->universe_count
<= agent_universe
.index
)
4291 options
->universe_count
= agent_universe
.index
+ 1;