3 DHCP Protocol engine. */
6 * Copyright (c) 2004-2005 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
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 * ``http://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''.
36 static char copyright
[] =
37 "$Id: dhcp.c,v 1.11 2009/07/16 22:44:27 tonnerre Exp $ Copyright (c) 2004-2005 Internet Systems Consortium. All rights reserved.\n";
42 int outstanding_pings
;
44 static char dhcp_message
[256];
46 static const char *dhcp_type_names
[] = {
56 const int dhcp_type_name_max
= ((sizeof dhcp_type_names
) / sizeof (char *));
59 # define send_packet trace_packet_send
63 struct packet
*packet
;
66 struct option_cache
*oc
;
67 struct lease
*lease
= (struct lease
*)0;
69 struct data_string data
;
71 if (!locate_network (packet
) &&
72 packet
-> packet_type
!= DHCPREQUEST
&&
73 packet
-> packet_type
!= DHCPINFORM
) {
76 errmsg
= "unknown network segment";
79 if (packet
-> packet_type
> 0 &&
80 packet
-> packet_type
< dhcp_type_name_max
- 1) {
81 s
= dhcp_type_names
[packet
-> packet_type
- 1];
83 /* %Audit% Cannot exceed 28 bytes. %2004.06.17,Safe% */
84 sprintf (typebuf
, "type %d", packet
-> packet_type
);
88 log_info ("%s from %s via %s: %s", s
,
89 (packet
-> raw
-> htype
90 ? print_hw_addr (packet
-> raw
-> htype
,
91 packet
-> raw
-> hlen
,
92 packet
-> raw
-> chaddr
)
94 packet
-> raw
-> giaddr
.s_addr
95 ? inet_ntoa (packet
-> raw
-> giaddr
)
96 : packet
-> interface
-> name
, errmsg
);
100 /* There is a problem with the relay agent information option,
101 which is that in order for a normal relay agent to append
102 this option, the relay agent has to have been involved in
103 getting the packet from the client to the server. Note
104 that this is the software entity known as the relay agent,
105 _not_ the hardware entity known as a router in which the
106 relay agent may be running, so the fact that a router has
107 forwarded a packet does not mean that the relay agent in
108 the router was involved.
110 So when the client is in INIT or INIT-REBOOT or REBINDING
111 state, the relay agent gets to tack on its options, but
112 when it's not, the relay agent doesn't get to do this,
113 which means that any decisions the DHCP server may make
114 based on the agent options will be made incorrectly.
116 We work around this in the following way: if this is a
117 DHCPREQUEST and doesn't have relay agent information
118 options, we see if there's an existing lease for this IP
119 address and this client that _does_ have stashed agent
120 options. If so, then we tack those options onto the
121 packet as if they came from the client. Later on, when we
122 are deciding whether to steal the agent options from the
123 packet, if the agent options stashed on the lease are the
124 same as those stashed on the packet, we don't steal them -
125 this ensures that the client never receives its agent
128 if (packet
-> packet_type
== DHCPREQUEST
&&
129 packet
-> raw
-> ciaddr
.s_addr
&&
130 !packet
-> raw
-> giaddr
.s_addr
&&
131 (packet
-> options
-> universe_count
< agent_universe
.index
||
132 !packet
-> options
-> universes
[agent_universe
.index
]))
136 cip
.len
= sizeof packet
-> raw
-> ciaddr
;
137 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
,
138 sizeof packet
-> raw
-> ciaddr
);
139 if (!find_lease_by_ip_addr (&lease
, cip
, MDL
))
142 /* If there are no agent options on the lease, it's not
144 if (!lease
-> agent_options
)
147 /* The client should not be unicasting a renewal if its lease
148 has expired, so make it go through the process of getting
149 its agent options legally. */
150 if (lease
-> ends
< cur_time
)
153 if (lease
-> uid_len
) {
154 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
155 DHO_DHCP_CLIENT_IDENTIFIER
);
159 memset (&data
, 0, sizeof data
);
160 if (!evaluate_option_cache (&data
,
161 packet
, (struct lease
*)0,
162 (struct client_state
*)0,
164 (struct option_state
*)0,
165 &global_scope
, oc
, MDL
))
167 if (lease
-> uid_len
!= data
.len
||
168 memcmp (lease
-> uid
, data
.data
, data
.len
)) {
169 data_string_forget (&data
, MDL
);
172 data_string_forget (&data
, MDL
);
174 if ((lease
-> hardware_addr
.hbuf
[0] !=
175 packet
-> raw
-> htype
) ||
176 (lease
-> hardware_addr
.hlen
- 1 !=
177 packet
-> raw
-> hlen
) ||
178 memcmp (&lease
-> hardware_addr
.hbuf
[1],
179 packet
-> raw
-> chaddr
,
180 packet
-> raw
-> hlen
))
183 /* Okay, so we found a lease that matches the client. */
184 option_chain_head_reference ((struct option_chain_head
**)
185 &(packet
-> options
-> universes
186 [agent_universe
.index
]),
187 lease
-> agent_options
, MDL
);
191 /* Classify the client. */
192 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
194 if (!oc
-> expression
)
195 while (oc
-> data
.len
&&
196 oc
-> data
.data
[oc
-> data
.len
- 1] == 0) {
202 classify_client (packet
);
204 switch (packet
-> packet_type
) {
206 dhcpdiscover (packet
, ms_nulltp
);
210 dhcprequest (packet
, ms_nulltp
, lease
);
214 dhcprelease (packet
, ms_nulltp
);
218 dhcpdecline (packet
, ms_nulltp
);
222 dhcpinform (packet
, ms_nulltp
);
232 errmsg
= "unknown packet type";
237 lease_dereference (&lease
, MDL
);
240 void dhcpdiscover (packet
, ms_nulltp
)
241 struct packet
*packet
;
244 struct lease
*lease
= (struct lease
*)0;
245 char msgbuf
[1024]; /* XXX */
249 int peer_has_leases
= 0;
250 int alloc_lease_called
= 0;
251 #if defined (FAILOVER_PROTOCOL)
252 dhcp_failover_state_t
*peer
;
255 find_lease (&lease
, packet
, packet
-> shared_network
,
256 0, &allocatedp
, (struct lease
*)0, MDL
);
258 if (lease
&& lease
-> client_hostname
) {
259 if ((strlen (lease
-> client_hostname
) <= 64) &&
260 db_printable (lease
-> client_hostname
))
261 s
= lease
-> client_hostname
;
263 s
= "Hostname Unsuitable for Printing";
267 /* %Audit% This is log output. %2004.06.17,Safe%
268 * If we truncate we hope the user can get a hint from the log.
270 snprintf (msgbuf
, sizeof msgbuf
, "DHCPDISCOVER from %s %s%s%svia %s",
271 (packet
-> raw
-> htype
272 ? print_hw_addr (packet
-> raw
-> htype
,
273 packet
-> raw
-> hlen
,
274 packet
-> raw
-> chaddr
)
276 ? print_hex_1 (lease
-> uid_len
, lease
-> uid
,
278 : "<no identifier>")),
279 s
? "(" : "", s
? s
: "", s
? ") " : "",
280 packet
-> raw
-> giaddr
.s_addr
281 ? inet_ntoa (packet
-> raw
-> giaddr
)
282 : packet
-> interface
-> name
);
284 /* Sourceless packets don't make sense here. */
285 if (!packet
-> shared_network
) {
286 log_info ("Packet from unknown subnet: %s",
287 inet_ntoa (packet
-> raw
-> giaddr
));
291 #if defined (FAILOVER_PROTOCOL)
292 if (lease
&& lease
-> pool
&& lease
-> pool
-> failover_peer
) {
293 peer
= lease
-> pool
-> failover_peer
;
295 /* If the lease is ours to allocate, then allocate it,
296 but set the allocatedp flag. */
297 if (lease_mine_to_reallocate (lease
))
300 /* If the lease is active, do load balancing to see who
301 allocates the lease (if it's active, it already belongs
302 to the client, or we wouldn't have gotten it from
304 else if (lease
-> binding_state
== FTS_ACTIVE
&&
305 (peer
-> service_state
!= cooperating
||
306 load_balance_mine (packet
, peer
)))
309 /* Otherwise, we can't let the client have this lease. */
311 #if defined (DEBUG_FIND_LEASE)
312 log_debug ("discarding %s - %s",
313 piaddr (lease
-> ip_addr
),
314 binding_state_print (lease
-> binding_state
));
316 lease_dereference (&lease
, MDL
);
321 /* If we didn't find a lease, try to allocate one... */
323 if (!packet
-> shared_network
-> pools
) {
324 log_info ("%s: network %s: no address pool",
325 msgbuf
, packet
-> shared_network
-> name
);
328 if (!allocate_lease (&lease
, packet
,
329 packet
-> shared_network
-> pools
,
332 log_error ("%s: peer holds all free leases",
335 log_error ("%s: network %s: no free leases",
337 packet
-> shared_network
-> name
);
340 #if defined (FAILOVER_PROTOCOL)
341 if (lease
-> pool
&& lease
-> pool
-> failover_peer
)
342 dhcp_failover_pool_check (lease
-> pool
);
345 alloc_lease_called
= 1;
348 #if defined (FAILOVER_PROTOCOL)
349 if (lease
&& lease
-> pool
&& lease
-> pool
-> failover_peer
) {
350 peer
= lease
-> pool
-> failover_peer
;
351 if (peer
-> service_state
== not_responding
||
352 peer
-> service_state
== service_startup
) {
353 log_info ("%s: not responding%s",
354 msgbuf
, peer
-> nrr
);
358 peer
= (dhcp_failover_state_t
*)0;
360 /* Do load balancing if configured. */
361 /* If the lease is newly allocated, and we're not the server that
362 the client would normally get with load balancing, and the
363 failover protocol state is normal, let the other server get this.
364 XXX Check protocol spec to make sure that predicating this on
365 XXX allocatedp is okay - I'm doing this so that the client won't
366 XXX be forced to switch servers (and IP addresses) just because
367 XXX of bad luck, when it's possible for it to get the address it
368 XXX is requesting. Not sure this is allowed. */
369 if (allocatedp
&& peer
&& (peer
-> service_state
== cooperating
) &&
370 !load_balance_mine (packet
, peer
)) {
371 /* peer_has_leases only has a chance to be set if we called
372 * allocate_lease() above.
374 if (!alloc_lease_called
|| peer_has_leases
) {
375 log_debug ("%s: load balance to peer %s",
376 msgbuf
, peer
-> name
);
379 log_debug ("cancel load balance to peer %s - %s",
380 peer
-> name
, "no free leases");
385 /* If it's an expired lease, get rid of any bindings. */
386 if (lease
-> ends
< cur_time
&& lease
-> scope
)
387 binding_scope_dereference (&lease
-> scope
, MDL
);
389 /* Set the lease to really expire in 2 minutes, unless it has
390 not yet expired, in which case leave its expiry time alone. */
391 when
= cur_time
+ 120;
392 if (when
< lease
-> ends
)
393 when
= lease
-> ends
;
395 ack_lease (packet
, lease
, DHCPOFFER
, when
, msgbuf
, ms_nulltp
,
396 (struct host_decl
*)0);
399 lease_dereference (&lease
, MDL
);
402 void dhcprequest (packet
, ms_nulltp
, ip_lease
)
403 struct packet
*packet
;
405 struct lease
*ip_lease
;
410 struct subnet
*subnet
;
412 struct option_cache
*oc
;
413 struct data_string data
;
414 char msgbuf
[1024]; /* XXX */
417 #if defined (FAILOVER_PROTOCOL)
418 dhcp_failover_state_t
*peer
;
420 int have_server_identifier
= 0;
421 int have_requested_addr
= 0;
423 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
424 DHO_DHCP_REQUESTED_ADDRESS
);
425 memset (&data
, 0, sizeof data
);
427 evaluate_option_cache (&data
, packet
, (struct lease
*)0,
428 (struct client_state
*)0,
429 packet
-> options
, (struct option_state
*)0,
430 &global_scope
, oc
, MDL
)) {
432 memcpy (cip
.iabuf
, data
.data
, 4);
433 data_string_forget (&data
, MDL
);
434 have_requested_addr
= 1;
436 oc
= (struct option_cache
*)0;
438 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
.s_addr
, 4);
441 /* Find the lease that matches the address requested by the
444 subnet
= (struct subnet
*)0;
445 lease
= (struct lease
*)0;
446 if (find_subnet (&subnet
, cip
, MDL
))
447 find_lease (&lease
, packet
,
448 subnet
-> shared_network
, &ours
, 0, ip_lease
, MDL
);
449 /* XXX consider using allocatedp arg to find_lease to see
450 XXX that this isn't a compliant DHCPREQUEST. */
452 if (lease
&& lease
-> client_hostname
) {
453 if ((strlen (lease
-> client_hostname
) <= 64) &&
454 db_printable (lease
-> client_hostname
))
455 s
= lease
-> client_hostname
;
457 s
= "Hostname Unsuitable for Printing";
461 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
462 DHO_DHCP_SERVER_IDENTIFIER
);
463 memset (&data
, 0, sizeof data
);
465 evaluate_option_cache (&data
, packet
, (struct lease
*)0,
466 (struct client_state
*)0,
467 packet
-> options
, (struct option_state
*)0,
468 &global_scope
, oc
, MDL
)) {
470 memcpy (sip
.iabuf
, data
.data
, 4);
471 data_string_forget (&data
, MDL
);
472 /* piaddr() should not return more than a 15 byte string.
475 sprintf (smbuf
, " (%s)", piaddr (sip
));
476 have_server_identifier
= 1;
480 /* %Audit% This is log output. %2004.06.17,Safe%
481 * If we truncate we hope the user can get a hint from the log.
483 snprintf (msgbuf
, sizeof msgbuf
,
484 "DHCPREQUEST for %s%s from %s %s%s%svia %s",
486 (packet
-> raw
-> htype
487 ? print_hw_addr (packet
-> raw
-> htype
,
488 packet
-> raw
-> hlen
,
489 packet
-> raw
-> chaddr
)
491 ? print_hex_1 (lease
-> uid_len
, lease
-> uid
,
493 : "<no identifier>")),
494 s
? "(" : "", s
? s
: "", s
? ") " : "",
495 packet
-> raw
-> giaddr
.s_addr
496 ? inet_ntoa (packet
-> raw
-> giaddr
)
497 : packet
-> interface
-> name
);
499 #if defined (FAILOVER_PROTOCOL)
500 if (lease
&& lease
-> pool
&& lease
-> pool
-> failover_peer
) {
501 peer
= lease
-> pool
-> failover_peer
;
502 if (peer
-> service_state
== not_responding
||
503 peer
-> service_state
== service_startup
) {
504 log_info ("%s: not responding%s",
505 msgbuf
, peer
-> nrr
);
509 /* "load balance to peer" - is not done at all for request.
511 * If it's RENEWING, we are the only server to hear it, so
512 * we have to serve it. If it's REBINDING, it's out of
513 * communication with the other server, so there's no point
514 * in waiting to serve it. However, if the lease we're
515 * offering is not a free lease, then we may be the only
516 * server that can offer it, so we can't load balance if
517 * the lease isn't in the free or backup state. If it is
518 * in the free or backup state, then that state is what
519 * mandates one server or the other should perform the
520 * allocation, not the LBA...we know the peer cannot
521 * allocate a request for an address in our free state.
523 * So our only compass is lease_mine_to_reallocate(). This
524 * effects both load balancing, and a sanity-check that we
525 * are not going to try to allocate a lease that isn't ours.
527 if ((lease
-> binding_state
== FTS_FREE
||
528 lease
-> binding_state
== FTS_BACKUP
) &&
529 !lease_mine_to_reallocate (lease
)) {
530 log_debug ("%s: lease owned by peer", msgbuf
);
534 /* If the lease is in a transitional state, we can't
536 if ((lease
-> binding_state
== FTS_RELEASED
||
537 lease
-> binding_state
== FTS_EXPIRED
) &&
538 !lease_mine_to_reallocate (lease
)) {
539 log_debug ("%s: lease in transition state %s", msgbuf
,
540 lease
-> binding_state
== FTS_RELEASED
541 ? "released" : "expired");
545 /* It's actually very unlikely that we'll ever get here,
546 but if we do, tell the client to stop using the lease,
547 because the administrator reset it. */
548 if (lease
-> binding_state
== FTS_RESET
&&
549 !lease_mine_to_reallocate (lease
)) {
550 log_debug ("%s: lease reset by administrator", msgbuf
);
551 nak_lease (packet
, &cip
);
555 /* At this point it's possible that we will get a broadcast
556 DHCPREQUEST for a lease that we didn't offer, because
557 both we and the peer are in a position to offer it.
558 In that case, we probably shouldn't answer. In order
559 to not answer, we would have to compare the server
560 identifier sent by the client with the list of possible
561 server identifiers we can send, and if the client's
562 identifier isn't on the list, drop the DHCPREQUEST.
563 We aren't currently doing that for two reasons - first,
564 it's not clear that all clients do the right thing
565 with respect to sending the client identifier, which
566 could mean that we might simply not respond to a client
567 that is depending on us to respond. Secondly, we allow
568 the user to specify the server identifier to send, and
569 we don't enforce that the server identifier should be
570 one of our IP addresses. This is probably not a big
571 deal, but it's theoretically an issue.
573 The reason we care about this is that if both servers
574 send a DHCPACK to the DHCPREQUEST, they are then going
575 to send dueling BNDUPD messages, which could cause
576 trouble. I think it causes no harm, but it seems
579 peer
= (dhcp_failover_state_t
*)0;
582 /* If a client on a given network REQUESTs a lease on an
583 address on a different network, NAK it. If the Requested
584 Address option was used, the protocol says that it must
585 have been broadcast, so we can trust the source network
588 If ciaddr was specified and Requested Address was not, then
589 we really only know for sure what network a packet came from
590 if it came through a BOOTP gateway - if it came through an
591 IP router, we'll just have to assume that it's cool.
593 If we don't think we know where the packet came from, it
594 came through a gateway from an unknown network, so it's not
595 from a RENEWING client. If we recognize the network it
596 *thinks* it's on, we can NAK it even though we don't
597 recognize the network it's *actually* on; otherwise we just
600 We don't currently try to take advantage of access to the
601 raw packet, because it's not available on all platforms.
602 So a packet that was unicast to us through a router from a
603 RENEWING client is going to look exactly like a packet that
604 was broadcast to us from an INIT-REBOOT client.
606 Since we can't tell the difference between these two kinds
607 of packets, if the packet appears to have come in off the
608 local wire, we have to treat it as if it's a RENEWING
609 client. This means that we can't NAK a RENEWING client on
610 the local wire that has a bogus address. The good news is
611 that we won't ACK it either, so it should revert to INIT
612 state and send us a DHCPDISCOVER, which we *can* work with.
614 Because we can't detect that a RENEWING client is on the
615 wrong wire, it's going to sit there trying to renew until
616 it gets to the REBIND state, when we *can* NAK it because
617 the packet will get to us through a BOOTP gateway. We
618 shouldn't actually see DHCPREQUEST packets from RENEWING
619 clients on the wrong wire anyway, since their idea of their
620 local router will be wrong. In any case, the protocol
621 doesn't really allow us to NAK a DHCPREQUEST from a
622 RENEWING client, so we can punt on this issue. */
624 if (!packet
-> shared_network
||
625 (packet
-> raw
-> ciaddr
.s_addr
&&
626 packet
-> raw
-> giaddr
.s_addr
) ||
627 (have_requested_addr
&& !packet
-> raw
-> ciaddr
.s_addr
)) {
629 /* If we don't know where it came from but we do know
630 where it claims to have come from, it didn't come
632 if (!packet
-> shared_network
) {
633 if (subnet
&& subnet
-> group
-> authoritative
) {
634 log_info ("%s: wrong network.", msgbuf
);
635 nak_lease (packet
, &cip
);
638 /* Otherwise, ignore it. */
639 log_info ("%s: ignored (%s).", msgbuf
,
641 ? "not authoritative" : "unknown subnet"));
645 /* If we do know where it came from and it asked for an
646 address that is not on that shared network, nak it. */
648 subnet_dereference (&subnet
, MDL
);
649 if (!find_grouped_subnet (&subnet
, packet
-> shared_network
,
651 if (packet
-> shared_network
-> group
-> authoritative
)
653 log_info ("%s: wrong network.", msgbuf
);
654 nak_lease (packet
, &cip
);
657 log_info ("%s: ignored (not authoritative).", msgbuf
);
662 /* If the address the client asked for is ours, but it wasn't
663 available for the client, NAK it. */
664 if (!lease
&& ours
) {
665 log_info ("%s: lease %s unavailable.", msgbuf
, piaddr (cip
));
666 nak_lease (packet
, &cip
);
670 /* Otherwise, send the lease to the client if we found one. */
672 ack_lease (packet
, lease
, DHCPACK
, 0, msgbuf
, ms_nulltp
,
673 (struct host_decl
*)0);
675 log_info ("%s: unknown lease %s.", msgbuf
, piaddr (cip
));
679 subnet_dereference (&subnet
, MDL
);
681 lease_dereference (&lease
, MDL
);
685 void dhcprelease (packet
, ms_nulltp
)
686 struct packet
*packet
;
689 struct lease
*lease
= (struct lease
*)0, *next
= (struct lease
*)0;
691 struct option_cache
*oc
;
692 struct data_string data
;
694 char msgbuf
[1024], cstr
[16]; /* XXX */
697 /* DHCPRELEASE must not specify address in requested-address
698 option, but old protocol specs weren't explicit about this,
700 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
701 DHO_DHCP_REQUESTED_ADDRESS
))) {
702 log_info ("DHCPRELEASE from %s specified requested-address.",
703 print_hw_addr (packet
-> raw
-> htype
,
704 packet
-> raw
-> hlen
,
705 packet
-> raw
-> chaddr
));
708 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
709 DHO_DHCP_CLIENT_IDENTIFIER
);
710 memset (&data
, 0, sizeof data
);
712 evaluate_option_cache (&data
, packet
, (struct lease
*)0,
713 (struct client_state
*)0,
714 packet
-> options
, (struct option_state
*)0,
715 &global_scope
, oc
, MDL
)) {
716 find_lease_by_uid (&lease
, data
.data
, data
.len
, MDL
);
717 data_string_forget (&data
, MDL
);
719 /* See if we can find a lease that matches the IP address
720 the client is claiming. */
723 lease_reference (&next
, lease
-> n_uid
, MDL
);
724 if (!memcmp (&packet
-> raw
-> ciaddr
,
725 lease
-> ip_addr
.iabuf
, 4)) {
728 lease_dereference (&lease
, MDL
);
730 lease_reference (&lease
, next
, MDL
);
731 lease_dereference (&next
, MDL
);
735 lease_dereference (&next
, MDL
);
738 /* The client is supposed to pass a valid client-identifier,
739 but the spec on this has changed historically, so try the
740 IP address in ciaddr if the client-identifier fails. */
743 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
, 4);
744 find_lease_by_ip_addr (&lease
, cip
, MDL
);
748 /* If the hardware address doesn't match, don't do the release. */
750 (lease
-> hardware_addr
.hlen
!= packet
-> raw
-> hlen
+ 1 ||
751 lease
-> hardware_addr
.hbuf
[0] != packet
-> raw
-> htype
||
752 memcmp (&lease
-> hardware_addr
.hbuf
[1],
753 packet
-> raw
-> chaddr
, packet
-> raw
-> hlen
)))
754 lease_dereference (&lease
, MDL
);
756 if (lease
&& lease
-> client_hostname
) {
757 if ((strlen (lease
-> client_hostname
) <= 64) &&
758 db_printable (lease
-> client_hostname
))
759 s
= lease
-> client_hostname
;
761 s
= "Hostname Unsuitable for Printing";
765 /* %Audit% Cannot exceed 16 bytes. %2004.06.17,Safe%
766 * We copy this out to stack because we actually want to log two
767 * inet_ntoa()'s in this message.
769 strncpy(cstr
, inet_ntoa (packet
-> raw
-> ciaddr
), 15);
772 /* %Audit% This is log output. %2004.06.17,Safe%
773 * If we truncate we hope the user can get a hint from the log.
775 snprintf (msgbuf
, sizeof msgbuf
,
776 "DHCPRELEASE of %s from %s %s%s%svia %s (%sfound)",
778 (packet
-> raw
-> htype
779 ? print_hw_addr (packet
-> raw
-> htype
,
780 packet
-> raw
-> hlen
,
781 packet
-> raw
-> chaddr
)
783 ? print_hex_1 (lease
-> uid_len
, lease
-> uid
,
785 : "<no identifier>")),
786 s
? "(" : "", s
? s
: "", s
? ") " : "",
787 packet
-> raw
-> giaddr
.s_addr
788 ? inet_ntoa (packet
-> raw
-> giaddr
)
789 : packet
-> interface
-> name
,
790 lease
? "" : "not ");
792 #if defined (FAILOVER_PROTOCOL)
793 if (lease
&& lease
-> pool
&& lease
-> pool
-> failover_peer
) {
794 dhcp_failover_state_t
*peer
= lease
-> pool
-> failover_peer
;
795 if (peer
-> service_state
== not_responding
||
796 peer
-> service_state
== service_startup
) {
797 log_info ("%s: ignored%s",
798 peer
-> name
, peer
-> nrr
);
802 /* DHCPRELEASE messages are unicast, so if the client
803 sent the DHCPRELEASE to us, it's not going to send it
804 to the peer. Not sure why this would happen, and
805 if it does happen I think we still have to change the
806 lease state, so that's what we're doing.
807 XXX See what it says in the draft about this. */
811 /* If we found a lease, release it. */
812 if (lease
&& lease
-> ends
> cur_time
) {
813 release_lease (lease
, packet
);
815 log_info ("%s", msgbuf
);
818 lease_dereference (&lease
, MDL
);
821 void dhcpdecline (packet
, ms_nulltp
)
822 struct packet
*packet
;
825 struct lease
*lease
= (struct lease
*)0;
826 struct option_state
*options
= (struct option_state
*)0;
831 char msgbuf
[1024]; /* XXX */
833 struct option_cache
*oc
;
834 struct data_string data
;
836 /* DHCPDECLINE must specify address. */
837 if (!(oc
= lookup_option (&dhcp_universe
, packet
-> options
,
838 DHO_DHCP_REQUESTED_ADDRESS
)))
840 memset (&data
, 0, sizeof data
);
841 if (!evaluate_option_cache (&data
, packet
, (struct lease
*)0,
842 (struct client_state
*)0,
844 (struct option_state
*)0,
845 &global_scope
, oc
, MDL
))
849 memcpy (cip
.iabuf
, data
.data
, 4);
850 data_string_forget (&data
, MDL
);
851 find_lease_by_ip_addr (&lease
, cip
, MDL
);
853 if (lease
&& lease
-> client_hostname
) {
854 if ((strlen (lease
-> client_hostname
) <= 64) &&
855 db_printable (lease
-> client_hostname
))
856 s
= lease
-> client_hostname
;
858 s
= "Hostname Unsuitable for Printing";
862 /* %Audit% This is log output. %2004.06.17,Safe%
863 * If we truncate we hope the user can get a hint from the log.
865 snprintf (msgbuf
, sizeof msgbuf
,
866 "DHCPDECLINE of %s from %s %s%s%svia %s",
868 (packet
-> raw
-> htype
869 ? print_hw_addr (packet
-> raw
-> htype
,
870 packet
-> raw
-> hlen
,
871 packet
-> raw
-> chaddr
)
873 ? print_hex_1 (lease
-> uid_len
, lease
-> uid
,
875 : "<no identifier>")),
876 s
? "(" : "", s
? s
: "", s
? ") " : "",
877 packet
-> raw
-> giaddr
.s_addr
878 ? inet_ntoa (packet
-> raw
-> giaddr
)
879 : packet
-> interface
-> name
);
881 option_state_allocate (&options
, MDL
);
883 /* Execute statements in scope starting with the subnet scope. */
885 execute_statements_in_scope ((struct binding_value
**)0,
886 packet
, (struct lease
*)0,
887 (struct client_state
*)0,
888 packet
-> options
, options
,
890 lease
-> subnet
-> group
,
893 /* Execute statements in the class scopes. */
894 for (i
= packet
-> class_count
; i
> 0; i
--) {
895 execute_statements_in_scope
896 ((struct binding_value
**)0, packet
, (struct lease
*)0,
897 (struct client_state
*)0, packet
-> options
, options
,
898 &global_scope
, packet
-> classes
[i
- 1] -> group
,
899 lease
? lease
-> subnet
-> group
: (struct group
*)0);
902 /* Drop the request if dhcpdeclines are being ignored. */
903 oc
= lookup_option (&server_universe
, options
, SV_DECLINES
);
905 evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
906 (struct client_state
*)0,
907 packet
-> options
, options
,
908 &lease
-> scope
, oc
, MDL
)) {
909 /* If we found a lease, mark it as unusable and complain. */
911 #if defined (FAILOVER_PROTOCOL)
912 if (lease
-> pool
&& lease
-> pool
-> failover_peer
) {
913 dhcp_failover_state_t
*peer
=
914 lease
-> pool
-> failover_peer
;
915 if (peer
-> service_state
== not_responding
||
916 peer
-> service_state
== service_startup
) {
918 log_info ("%s: ignored%s",
919 peer
-> name
, peer
-> nrr
);
923 /* DHCPDECLINE messages are broadcast, so we can safely
924 ignore the DHCPDECLINE if the peer has the lease.
925 XXX Of course, at this point that information has been
930 abandon_lease (lease
, "declined.");
931 status
= "abandoned";
933 status
= "not found";
938 log_info ("%s: %s", msgbuf
, status
);
942 option_state_dereference (&options
, MDL
);
944 lease_dereference (&lease
, MDL
);
947 void dhcpinform (packet
, ms_nulltp
)
948 struct packet
*packet
;
952 struct data_string d1
, prl
;
953 struct option_cache
*oc
;
954 struct option_state
*options
= (struct option_state
*)0;
955 struct dhcp_packet raw
;
956 struct packet outgoing
;
957 unsigned char dhcpack
= DHCPACK
;
958 struct subnet
*subnet
= (struct subnet
*)0;
962 struct sockaddr_in to
;
965 /* The client should set ciaddr to its IP address, but apparently
966 it's common for clients not to do this, so we'll use their IP
967 source address if they didn't set ciaddr. */
968 if (!packet
-> raw
-> ciaddr
.s_addr
) {
970 memcpy (cip
.iabuf
, &packet
-> client_addr
.iabuf
, 4);
973 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
, 4);
976 /* %Audit% This is log output. %2004.06.17,Safe%
977 * If we truncate we hope the user can get a hint from the log.
979 snprintf (msgbuf
, sizeof msgbuf
, "DHCPINFORM from %s via %s",
980 piaddr (cip
), packet
-> interface
-> name
);
982 /* If the IP source address is zero, don't respond. */
983 if (!memcmp (cip
.iabuf
, "\0\0\0", 4)) {
984 log_info ("%s: ignored (null source address).", msgbuf
);
988 /* Find the subnet that the client is on. */
989 oc
= (struct option_cache
*)0;
990 find_subnet (&subnet
, cip
, MDL
);
992 /* Sourceless packets don't make sense here. */
994 log_info ("%s: unknown subnet %s",
995 msgbuf
, inet_ntoa (packet
-> raw
-> giaddr
));
999 /* We don't respond to DHCPINFORM packets if we're not authoritative.
1000 It would be nice if a per-host value could override this, but
1001 there's overhead involved in checking this, so let's see how people
1003 if (subnet
&& !subnet
-> group
-> authoritative
) {
1005 log_info ("%s: not authoritative for subnet %s",
1006 msgbuf
, piaddr (subnet
-> net
));
1008 log_info ("If this DHCP server is authoritative for%s",
1010 log_info ("please write an `authoritative;' directi%s",
1011 "ve either in the");
1012 log_info ("subnet declaration or in some scope that%s",
1014 log_info ("subnet declaration - for example, write %s",
1016 log_info ("of the dhcpd.conf file.");
1020 subnet_dereference (&subnet
, MDL
);
1024 memset (&d1
, 0, sizeof d1
);
1025 option_state_allocate (&options
, MDL
);
1026 memset (&outgoing
, 0, sizeof outgoing
);
1027 memset (&raw
, 0, sizeof raw
);
1028 outgoing
.raw
= &raw
;
1030 /* Execute statements in scope starting with the subnet scope. */
1032 execute_statements_in_scope ((struct binding_value
**)0,
1033 packet
, (struct lease
*)0,
1034 (struct client_state
*)0,
1035 packet
-> options
, options
,
1036 &global_scope
, subnet
-> group
,
1039 /* Execute statements in the class scopes. */
1040 for (i
= packet
-> class_count
; i
> 0; i
--) {
1041 execute_statements_in_scope
1042 ((struct binding_value
**)0, packet
, (struct lease
*)0,
1043 (struct client_state
*)0, packet
-> options
, options
,
1044 &global_scope
, packet
-> classes
[i
- 1] -> group
,
1045 subnet
? subnet
-> group
: (struct group
*)0);
1048 /* Figure out the filename. */
1049 memset (&d1
, 0, sizeof d1
);
1050 oc
= lookup_option (&server_universe
, options
, SV_FILENAME
);
1052 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1053 (struct client_state
*)0,
1054 packet
-> options
, (struct option_state
*)0,
1055 &global_scope
, oc
, MDL
)) {
1057 if (i
> sizeof raw
.file
)
1058 i
= sizeof raw
.file
;
1061 memcpy (raw
.file
, d1
.data
, i
);
1062 data_string_forget (&d1
, MDL
);
1065 /* Choose a server name as above. */
1066 oc
= lookup_option (&server_universe
, options
, SV_SERVER_NAME
);
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
.sname
)
1074 i
= sizeof raw
.sname
;
1077 memcpy (raw
.sname
, d1
.data
, i
);
1078 data_string_forget (&d1
, MDL
);
1081 /* Set a flag if this client is a lame Microsoft client that NUL
1082 terminates string options and expects us to do likewise. */
1084 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
1086 if (evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1087 (struct client_state
*)0,
1088 packet
-> options
, options
,
1089 &global_scope
, oc
, MDL
)) {
1090 if (d1
.data
[d1
.len
- 1] == '\0')
1092 data_string_forget (&d1
, MDL
);
1096 /* Put in DHCP-specific options. */
1097 i
= DHO_DHCP_MESSAGE_TYPE
;
1098 oc
= (struct option_cache
*)0;
1099 if (option_cache_allocate (&oc
, MDL
)) {
1100 if (make_const_data (&oc
-> expression
,
1101 &dhcpack
, 1, 0, 0, MDL
)) {
1102 oc
-> option
= dhcp_universe
.options
[i
];
1103 save_option (&dhcp_universe
, options
, oc
);
1105 option_cache_dereference (&oc
, MDL
);
1108 i
= DHO_DHCP_SERVER_IDENTIFIER
;
1109 if (!(oc
= lookup_option (&dhcp_universe
, options
, i
))) {
1111 oc
= (struct option_cache
*)0;
1112 if (option_cache_allocate (&oc
, MDL
)) {
1116 &packet
-> interface
-> primary_address
),
1117 sizeof packet
-> interface
-> primary_address
,
1120 dhcp_universe
.options
[i
];
1121 save_option (&dhcp_universe
,
1124 option_cache_dereference (&oc
, MDL
);
1126 from
= packet
-> interface
-> primary_address
;
1128 if (evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1129 (struct client_state
*)0,
1130 packet
-> options
, options
,
1131 &global_scope
, oc
, MDL
)) {
1132 if (!d1
.len
|| d1
.len
!= sizeof from
) {
1133 data_string_forget (&d1
, MDL
);
1136 memcpy (&from
, d1
.data
, sizeof from
);
1137 data_string_forget (&d1
, MDL
);
1142 /* Use the subnet mask from the subnet declaration if no other
1143 mask has been provided. */
1144 i
= DHO_SUBNET_MASK
;
1145 if (subnet
&& !lookup_option (&dhcp_universe
, options
, i
)) {
1146 oc
= (struct option_cache
*)0;
1147 if (option_cache_allocate (&oc
, MDL
)) {
1148 if (make_const_data (&oc
-> expression
,
1149 subnet
-> netmask
.iabuf
,
1150 subnet
-> netmask
.len
,
1152 oc
-> option
= dhcp_universe
.options
[i
];
1153 save_option (&dhcp_universe
, options
, oc
);
1155 option_cache_dereference (&oc
, MDL
);
1159 /* If a site option space has been specified, use that for
1160 site option codes. */
1161 i
= SV_SITE_OPTION_SPACE
;
1162 if ((oc
= lookup_option (&server_universe
, options
, i
)) &&
1163 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1164 (struct client_state
*)0,
1165 packet
-> options
, options
,
1166 &global_scope
, oc
, MDL
)) {
1167 struct universe
*u
= (struct universe
*)0;
1169 if (!universe_hash_lookup (&u
, universe_hash
,
1170 (const char *)d1
.data
, d1
.len
,
1172 log_error ("unknown option space %s.", d1
.data
);
1173 option_state_dereference (&options
, MDL
);
1175 subnet_dereference (&subnet
, MDL
);
1179 options
-> site_universe
= u
-> index
;
1180 options
-> site_code_min
= 128; /* XXX */
1181 data_string_forget (&d1
, MDL
);
1183 options
-> site_universe
= dhcp_universe
.index
;
1184 options
-> site_code_min
= 0; /* Trust me, it works. */
1187 memset (&prl
, 0, sizeof prl
);
1189 /* Use the parameter list from the scope if there is one. */
1190 oc
= lookup_option (&dhcp_universe
, options
,
1191 DHO_DHCP_PARAMETER_REQUEST_LIST
);
1193 /* Otherwise, if the client has provided a list of options
1194 that it wishes returned, use it to prioritize. Otherwise,
1195 prioritize based on the default priority list. */
1198 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
1199 DHO_DHCP_PARAMETER_REQUEST_LIST
);
1202 evaluate_option_cache (&prl
, packet
, (struct lease
*)0,
1203 (struct client_state
*)0,
1204 packet
-> options
, options
,
1205 &global_scope
, oc
, MDL
);
1208 dump_packet (packet
);
1209 dump_raw ((unsigned char *)packet
-> raw
, packet
-> packet_length
);
1212 log_info ("%s", msgbuf
);
1214 /* Figure out the address of the boot file server. */
1216 lookup_option (&server_universe
, options
, SV_NEXT_SERVER
))) {
1217 if (evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1218 (struct client_state
*)0,
1219 packet
-> options
, options
,
1220 &global_scope
, oc
, MDL
)) {
1221 /* If there was more than one answer,
1223 if (d1
.len
>= 4 && d1
.data
)
1224 memcpy (&raw
.siaddr
, d1
.data
, 4);
1225 data_string_forget (&d1
, MDL
);
1229 /* Set up the option buffer... */
1230 outgoing
.packet_length
=
1231 cons_options (packet
, outgoing
.raw
, (struct lease
*)0,
1232 (struct client_state
*)0,
1233 0, packet
-> options
, options
, &global_scope
,
1235 prl
.len
? &prl
: (struct data_string
*)0,
1237 option_state_dereference (&options
, MDL
);
1238 data_string_forget (&prl
, MDL
);
1240 /* Make sure that the packet is at least as big as a BOOTP packet. */
1241 if (outgoing
.packet_length
< BOOTP_MIN_LEN
)
1242 outgoing
.packet_length
= BOOTP_MIN_LEN
;
1244 raw
.giaddr
= packet
-> raw
-> giaddr
;
1245 raw
.ciaddr
= packet
-> raw
-> ciaddr
;
1246 memcpy (raw
.chaddr
, packet
-> raw
-> chaddr
, sizeof raw
.chaddr
);
1247 raw
.hlen
= packet
-> raw
-> hlen
;
1248 raw
.htype
= packet
-> raw
-> htype
;
1250 raw
.xid
= packet
-> raw
-> xid
;
1251 raw
.secs
= packet
-> raw
-> secs
;
1252 raw
.flags
= packet
-> raw
-> flags
;
1253 raw
.hops
= packet
-> raw
-> hops
;
1256 /* Report what we're sending... */
1257 log_info ("DHCPACK to %s", inet_ntoa (raw
.ciaddr
));
1260 dump_packet (&outgoing
);
1261 dump_raw ((unsigned char *)&raw
, outgoing
.packet_length
);
1264 /* Set up the common stuff... */
1265 memset (&to
, 0, sizeof to
);
1266 to
.sin_family
= AF_INET
;
1268 to
.sin_len
= sizeof to
;
1271 /* Use the IP address we derived for the client. */
1272 memcpy (&to
.sin_addr
, cip
.iabuf
, 4);
1273 to
.sin_port
= remote_port
;
1276 send_packet ((fallback_interface
1277 ? fallback_interface
: packet
-> interface
),
1278 &outgoing
, &raw
, outgoing
.packet_length
,
1279 from
, &to
, (struct hardware
*)0);
1281 subnet_dereference (&subnet
, MDL
);
1284 void nak_lease (packet
, cip
)
1285 struct packet
*packet
;
1288 struct sockaddr_in to
;
1289 struct in_addr from
;
1291 struct dhcp_packet raw
;
1292 unsigned char nak
= DHCPNAK
;
1293 struct packet outgoing
;
1294 struct hardware hto
;
1296 struct data_string data
;
1297 struct option_state
*options
= (struct option_state
*)0;
1298 struct option_cache
*oc
= (struct option_cache
*)0;
1299 struct iaddr myfrom
;
1301 option_state_allocate (&options
, MDL
);
1302 memset (&outgoing
, 0, sizeof outgoing
);
1303 memset (&raw
, 0, sizeof raw
);
1304 outgoing
.raw
= &raw
;
1306 /* Set DHCP_MESSAGE_TYPE to DHCPNAK */
1307 if (!option_cache_allocate (&oc
, MDL
)) {
1308 log_error ("No memory for DHCPNAK message type.");
1309 option_state_dereference (&options
, MDL
);
1312 if (!make_const_data (&oc
-> expression
, &nak
, sizeof nak
,
1314 log_error ("No memory for expr_const expression.");
1315 option_cache_dereference (&oc
, MDL
);
1316 option_state_dereference (&options
, MDL
);
1319 oc
-> option
= dhcp_universe
.options
[DHO_DHCP_MESSAGE_TYPE
];
1320 save_option (&dhcp_universe
, options
, oc
);
1321 option_cache_dereference (&oc
, MDL
);
1323 /* Set DHCP_MESSAGE to whatever the message is */
1324 if (!option_cache_allocate (&oc
, MDL
)) {
1325 log_error ("No memory for DHCPNAK message type.");
1326 option_state_dereference (&options
, MDL
);
1329 if (!make_const_data (&oc
-> expression
,
1330 (unsigned char *)dhcp_message
,
1331 strlen (dhcp_message
), 1, 0, MDL
)) {
1332 log_error ("No memory for expr_const expression.");
1333 option_cache_dereference (&oc
, MDL
);
1334 option_state_dereference (&options
, MDL
);
1337 oc
-> option
= dhcp_universe
.options
[DHO_DHCP_MESSAGE
];
1338 save_option (&dhcp_universe
, options
, oc
);
1339 option_cache_dereference (&oc
, MDL
);
1341 i
= DHO_DHCP_SERVER_IDENTIFIER
;
1342 if (!(oc
= lookup_option (&dhcp_universe
, options
, i
))) {
1344 oc
= (struct option_cache
*)0;
1345 if (option_cache_allocate (&oc
, MDL
)) {
1349 &packet
-> interface
-> primary_address
),
1350 sizeof packet
-> interface
-> primary_address
,
1353 dhcp_universe
.options
[i
];
1354 save_option (&dhcp_universe
, options
, oc
);
1356 option_cache_dereference (&oc
, MDL
);
1358 myfrom
.len
= sizeof packet
-> interface
-> primary_address
;
1359 memcpy (myfrom
.iabuf
,
1360 &packet
-> interface
-> primary_address
, myfrom
.len
);
1362 memset (&data
, 0, sizeof data
);
1363 if (evaluate_option_cache (&data
, packet
, (struct lease
*)0,
1364 (struct client_state
*)0,
1365 packet
-> options
, options
,
1366 &global_scope
, oc
, MDL
)) {
1368 data
.len
> sizeof myfrom
.iabuf
) {
1369 data_string_forget (&data
, MDL
);
1372 memcpy (myfrom
.iabuf
, data
.data
, data
.len
);
1373 myfrom
.len
= data
.len
;
1374 data_string_forget (&data
, MDL
);
1379 /* If there were agent options in the incoming packet, return
1381 if (packet
-> raw
-> giaddr
.s_addr
&&
1382 packet
-> options
-> universe_count
> agent_universe
.index
&&
1383 packet
-> options
-> universes
[agent_universe
.index
]) {
1384 option_chain_head_reference
1385 ((struct option_chain_head
**)
1386 &(options
-> universes
[agent_universe
.index
]),
1387 (struct option_chain_head
*)
1388 packet
-> options
-> universes
[agent_universe
.index
],
1392 /* Do not use the client's requested parameter list. */
1393 delete_option (&dhcp_universe
, packet
-> options
,
1394 DHO_DHCP_PARAMETER_REQUEST_LIST
);
1396 /* Set up the option buffer... */
1397 outgoing
.packet_length
=
1398 cons_options (packet
, outgoing
.raw
, (struct lease
*)0,
1399 (struct client_state
*)0,
1400 0, packet
-> options
, options
, &global_scope
,
1401 0, 0, 0, (struct data_string
*)0, (char *)0);
1402 option_state_dereference (&options
, MDL
);
1404 /* memset (&raw.ciaddr, 0, sizeof raw.ciaddr);*/
1405 raw
.siaddr
= packet
-> interface
-> primary_address
;
1406 raw
.giaddr
= packet
-> raw
-> giaddr
;
1407 memcpy (raw
.chaddr
, packet
-> raw
-> chaddr
, sizeof raw
.chaddr
);
1408 raw
.hlen
= packet
-> raw
-> hlen
;
1409 raw
.htype
= packet
-> raw
-> htype
;
1411 raw
.xid
= packet
-> raw
-> xid
;
1412 raw
.secs
= packet
-> raw
-> secs
;
1413 raw
.flags
= packet
-> raw
-> flags
| htons (BOOTP_BROADCAST
);
1414 raw
.hops
= packet
-> raw
-> hops
;
1417 /* Report what we're sending... */
1418 log_info ("DHCPNAK on %s to %s via %s",
1420 print_hw_addr (packet
-> raw
-> htype
,
1421 packet
-> raw
-> hlen
,
1422 packet
-> raw
-> chaddr
),
1423 packet
-> raw
-> giaddr
.s_addr
1424 ? inet_ntoa (packet
-> raw
-> giaddr
)
1425 : packet
-> interface
-> name
);
1430 dump_packet (packet
);
1431 dump_raw ((unsigned char *)packet
-> raw
, packet
-> packet_length
);
1432 dump_packet (&outgoing
);
1433 dump_raw ((unsigned char *)&raw
, outgoing
.packet_length
);
1437 hto
.hbuf
[0] = packet
-> raw
-> htype
;
1438 hto
.hlen
= packet
-> raw
-> hlen
;
1439 memcpy (&hto
.hbuf
[1], packet
-> raw
-> chaddr
, hto
.hlen
);
1443 /* Set up the common stuff... */
1444 memset (&to
, 0, sizeof to
);
1445 to
.sin_family
= AF_INET
;
1447 to
.sin_len
= sizeof to
;
1450 memcpy (&from
, myfrom
.iabuf
, sizeof from
);
1452 /* Make sure that the packet is at least as big as a BOOTP packet. */
1453 if (outgoing
.packet_length
< BOOTP_MIN_LEN
)
1454 outgoing
.packet_length
= BOOTP_MIN_LEN
;
1456 /* If this was gatewayed, send it back to the gateway.
1457 Otherwise, broadcast it on the local network. */
1458 if (raw
.giaddr
.s_addr
) {
1459 to
.sin_addr
= raw
.giaddr
;
1460 if (raw
.giaddr
.s_addr
!= htonl (INADDR_LOOPBACK
))
1461 to
.sin_port
= local_port
;
1463 to
.sin_port
= remote_port
; /* for testing. */
1465 if (fallback_interface
) {
1466 result
= send_packet (fallback_interface
,
1468 outgoing
.packet_length
,
1473 to
.sin_addr
= limited_broadcast
;
1474 to
.sin_port
= remote_port
;
1478 result
= send_packet (packet
-> interface
,
1479 packet
, &raw
, outgoing
.packet_length
,
1480 from
, &to
, (struct hardware
*)0);
1483 void ack_lease (packet
, lease
, offer
, when
, msg
, ms_nulltp
, hp
)
1484 struct packet
*packet
;
1485 struct lease
*lease
;
1490 struct host_decl
*hp
;
1493 struct lease_state
*state
;
1495 struct host_decl
*host
= (struct host_decl
*)0;
1497 TIME offered_lease_time
;
1498 struct data_string d1
;
1499 TIME min_lease_time
;
1500 TIME max_lease_time
;
1501 TIME default_lease_time
;
1502 struct option_cache
*oc
;
1503 isc_result_t result
;
1510 s1
= 0; /* XXXGCC -Wuninitialized [arm / sparc64] */
1512 /* If we're already acking this lease, don't do it again. */
1516 /* If the lease carries a host record, remember it. */
1518 host_reference (&host
, hp
, MDL
);
1519 else if (lease
-> host
)
1520 host_reference (&host
, lease
-> host
, MDL
);
1522 /* Allocate a lease state structure... */
1523 state
= new_lease_state (MDL
);
1525 log_fatal ("unable to allocate lease state!");
1526 state
-> got_requested_address
= packet
-> got_requested_address
;
1527 shared_network_reference (&state
-> shared_network
,
1528 packet
-> interface
-> shared_network
, MDL
);
1530 /* See if we got a server identifier option. */
1531 if (lookup_option (&dhcp_universe
,
1532 packet
-> options
, DHO_DHCP_SERVER_IDENTIFIER
))
1533 state
-> got_server_identifier
= 1;
1535 /* If there were agent options in the incoming packet, return
1536 them. Do not return the agent options if they were stashed
1538 if (packet
-> raw
-> giaddr
.s_addr
&&
1539 packet
-> options
-> universe_count
> agent_universe
.index
&&
1540 packet
-> options
-> universes
[agent_universe
.index
] &&
1541 (state
-> options
-> universe_count
<= agent_universe
.index
||
1542 !state
-> options
-> universes
[agent_universe
.index
]) &&
1543 lease
-> agent_options
!=
1544 ((struct option_chain_head
*)
1545 packet
-> options
-> universes
[agent_universe
.index
])) {
1546 option_chain_head_reference
1547 ((struct option_chain_head
**)
1548 &(state
-> options
-> universes
[agent_universe
.index
]),
1549 (struct option_chain_head
*)
1550 packet
-> options
-> universes
[agent_universe
.index
],
1554 /* If we are offering a lease that is still currently valid, preserve
1555 the events. We need to do this because if the client does not
1556 REQUEST our offer, it will expire in 2 minutes, overriding the
1557 expire time in the currently in force lease. We want the expire
1558 events to be executed at that point. */
1559 if (lease
-> ends
<= cur_time
&& offer
!= DHCPOFFER
) {
1560 /* Get rid of any old expiry or release statements - by
1561 executing the statements below, we will be inserting new
1562 ones if there are any to insert. */
1563 if (lease
-> on_expiry
)
1564 executable_statement_dereference (&lease
-> on_expiry
,
1566 if (lease
-> on_commit
)
1567 executable_statement_dereference (&lease
-> on_commit
,
1569 if (lease
-> on_release
)
1570 executable_statement_dereference (&lease
-> on_release
,
1574 /* Execute statements in scope starting with the subnet scope. */
1575 execute_statements_in_scope ((struct binding_value
**)0,
1576 packet
, lease
, (struct client_state
*)0,
1578 state
-> options
, &lease
-> scope
,
1579 lease
-> subnet
-> group
,
1582 /* If the lease is from a pool, run the pool scope. */
1584 (execute_statements_in_scope
1585 ((struct binding_value
**)0, packet
, lease
,
1586 (struct client_state
*)0, packet
-> options
,
1587 state
-> options
, &lease
-> scope
, lease
-> pool
-> group
,
1588 lease
-> pool
-> shared_network
-> group
));
1590 /* Execute statements from class scopes. */
1591 for (i
= packet
-> class_count
; i
> 0; i
--) {
1592 execute_statements_in_scope
1593 ((struct binding_value
**)0,
1594 packet
, lease
, (struct client_state
*)0,
1595 packet
-> options
, state
-> options
,
1596 &lease
-> scope
, packet
-> classes
[i
- 1] -> group
,
1598 ? lease
-> pool
-> group
1599 : lease
-> subnet
-> group
));
1602 /* See if the client is only supposed to have one lease at a time,
1603 and if so, find its other leases and release them. We can only
1604 do this on DHCPREQUEST. It's a little weird to do this before
1605 looking at permissions, because the client might not actually
1606 _get_ a lease after we've done the permission check, but the
1607 assumption for this option is that the client has exactly one
1608 network interface, and will only ever remember one lease. So
1609 if it sends a DHCPREQUEST, and doesn't get the lease, it's already
1610 forgotten about its old lease, so we can too. */
1611 if (packet
-> packet_type
== DHCPREQUEST
&&
1612 (oc
= lookup_option (&server_universe
, state
-> options
,
1613 SV_ONE_LEASE_PER_CLIENT
)) &&
1614 evaluate_boolean_option_cache (&ignorep
,
1616 (struct client_state
*)0,
1618 state
-> options
, &lease
-> scope
,
1621 if (lease
-> uid_len
) {
1623 seek
= (struct lease
*)0;
1624 find_lease_by_uid (&seek
, lease
-> uid
,
1625 lease
-> uid_len
, MDL
);
1628 if (seek
== lease
&& !seek
-> n_uid
) {
1629 lease_dereference (&seek
, MDL
);
1632 next
= (struct lease
*)0;
1634 /* Don't release expired leases, and don't
1635 release the lease we're going to assign. */
1636 next
= (struct lease
*)0;
1639 lease_reference (&next
, seek
-> n_uid
, MDL
);
1640 if (seek
!= lease
&&
1641 seek
-> binding_state
!= FTS_RELEASED
&&
1642 seek
-> binding_state
!= FTS_EXPIRED
&&
1643 seek
-> binding_state
!= FTS_RESET
&&
1644 seek
-> binding_state
!= FTS_FREE
&&
1645 seek
-> binding_state
!= FTS_BACKUP
)
1647 lease_dereference (&seek
, MDL
);
1649 lease_reference (&seek
, next
, MDL
);
1650 lease_dereference (&next
, MDL
);
1654 lease_dereference (&next
, MDL
);
1656 release_lease (seek
, packet
);
1657 lease_dereference (&seek
, MDL
);
1662 if (!lease
-> uid_len
||
1664 !host
-> client_identifier
.len
&&
1665 (oc
= lookup_option (&server_universe
, state
-> options
,
1667 !evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
1668 (struct client_state
*)0,
1674 seek
= (struct lease
*)0;
1675 find_lease_by_hw_addr
1676 (&seek
, lease
-> hardware_addr
.hbuf
,
1677 lease
-> hardware_addr
.hlen
, MDL
);
1680 if (seek
== lease
&& !seek
-> n_hw
) {
1681 lease_dereference (&seek
, MDL
);
1684 next
= (struct lease
*)0;
1687 lease_reference (&next
, seek
-> n_hw
, MDL
);
1688 if (seek
!= lease
&&
1689 seek
-> binding_state
!= FTS_RELEASED
&&
1690 seek
-> binding_state
!= FTS_EXPIRED
&&
1691 seek
-> binding_state
!= FTS_RESET
&&
1692 seek
-> binding_state
!= FTS_FREE
&&
1693 seek
-> binding_state
!= FTS_BACKUP
)
1695 lease_dereference (&seek
, MDL
);
1697 lease_reference (&seek
, next
, MDL
);
1698 lease_dereference (&next
, MDL
);
1702 lease_dereference (&next
, MDL
);
1704 release_lease (seek
, packet
);
1705 lease_dereference (&seek
, MDL
);
1713 /* Make sure this packet satisfies the configured minimum
1714 number of seconds. */
1715 memset (&d1
, 0, sizeof d1
);
1716 if (offer
== DHCPOFFER
&&
1717 (oc
= lookup_option (&server_universe
, state
-> options
,
1719 if (evaluate_option_cache (&d1
, packet
, lease
,
1720 (struct client_state
*)0,
1721 packet
-> options
, state
-> options
,
1722 &lease
-> scope
, oc
, MDL
)) {
1724 ntohs (packet
-> raw
-> secs
) < d1
.data
[0]) {
1725 log_info ("%s: %d secs < %d", msg
,
1726 ntohs (packet
-> raw
-> secs
),
1728 data_string_forget (&d1
, MDL
);
1729 free_lease_state (state
, MDL
);
1731 host_dereference (&host
, MDL
);
1734 data_string_forget (&d1
, MDL
);
1738 /* Try to find a matching host declaration for this lease.
1741 struct host_decl
*hp
= (struct host_decl
*)0;
1742 struct host_decl
*h
;
1744 /* Try to find a host_decl that matches the client
1745 identifier or hardware address on the packet, and
1746 has no fixed IP address. If there is one, hang
1747 it off the lease so that its option definitions
1749 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
1750 DHO_DHCP_CLIENT_IDENTIFIER
);
1752 evaluate_option_cache (&d1
, packet
, lease
,
1753 (struct client_state
*)0,
1754 packet
-> options
, state
-> options
,
1755 &lease
-> scope
, oc
, MDL
)) {
1756 find_hosts_by_uid (&hp
, d1
.data
, d1
.len
, MDL
);
1757 data_string_forget (&d1
, MDL
);
1758 for (h
= hp
; h
; h
= h
-> n_ipaddr
) {
1759 if (!h
-> fixed_addr
)
1763 host_reference (&host
, h
, MDL
);
1767 host_dereference (&hp
, MDL
);
1768 find_hosts_by_haddr (&hp
,
1769 packet
-> raw
-> htype
,
1770 packet
-> raw
-> chaddr
,
1771 packet
-> raw
-> hlen
,
1773 for (h
= hp
; h
; h
= h
-> n_ipaddr
) {
1774 if (!h
-> fixed_addr
)
1778 host_reference (&host
, h
, MDL
);
1781 host_dereference (&hp
, MDL
);
1784 /* If we have a host_decl structure, run the options associated
1785 with its group. Wether the host decl struct is old or not. */
1787 execute_statements_in_scope ((struct binding_value
**)0,
1789 (struct client_state
*)0,
1791 state
-> options
, &lease
-> scope
,
1794 ? lease
-> pool
-> group
1795 : lease
-> subnet
-> group
));
1797 /* Drop the request if it's not allowed for this client. By
1798 default, unknown clients are allowed. */
1800 (oc
= lookup_option (&server_universe
, state
-> options
,
1801 SV_BOOT_UNKNOWN_CLIENTS
)) &&
1802 !evaluate_boolean_option_cache (&ignorep
,
1804 (struct client_state
*)0,
1807 &lease
-> scope
, oc
, MDL
)) {
1809 log_info ("%s: unknown client", msg
);
1810 free_lease_state (state
, MDL
);
1812 host_dereference (&host
, MDL
);
1816 /* Drop the request if it's not allowed for this client. */
1818 (oc
= lookup_option (&server_universe
, state
-> options
,
1820 !evaluate_boolean_option_cache (&ignorep
,
1822 (struct client_state
*)0,
1825 &lease
-> scope
, oc
, MDL
)) {
1827 log_info ("%s: bootp disallowed", msg
);
1828 free_lease_state (state
, MDL
);
1830 host_dereference (&host
, MDL
);
1834 /* Drop the request if booting is specifically denied. */
1835 oc
= lookup_option (&server_universe
, state
-> options
,
1838 !evaluate_boolean_option_cache (&ignorep
,
1840 (struct client_state
*)0,
1843 &lease
-> scope
, oc
, MDL
)) {
1845 log_info ("%s: booting disallowed", msg
);
1846 free_lease_state (state
, MDL
);
1848 host_dereference (&host
, MDL
);
1852 /* If we are configured to do per-class billing, do it. */
1853 if (have_billing_classes
&& !(lease
-> flags
& STATIC_LEASE
)) {
1854 /* See if the lease is currently being billed to a
1855 class, and if so, whether or not it can continue to
1856 be billed to that class. */
1857 if (lease
-> billing_class
) {
1858 for (i
= 0; i
< packet
-> class_count
; i
++)
1859 if (packet
-> classes
[i
] ==
1860 lease
-> billing_class
)
1862 if (i
== packet
-> class_count
)
1863 unbill_class (lease
, lease
-> billing_class
);
1866 /* If we don't have an active billing, see if we need
1867 one, and if we do, try to do so. */
1868 if (!lease
-> billing_class
) {
1869 for (i
= 0; i
< packet
-> class_count
; i
++) {
1870 if (packet
-> classes
[i
] -> lease_limit
)
1873 if (i
!= packet
-> class_count
) {
1874 for (i
= 0; i
< packet
-> class_count
; i
++)
1876 classes
[i
] -> lease_limit
) &&
1878 packet
-> classes
[i
]))
1880 if (i
== packet
-> class_count
) {
1881 log_info ("%s: no available billing",
1883 free_lease_state (state
, MDL
);
1885 host_dereference (&host
, MDL
);
1886 /* XXX possibly not necessary: */
1893 /* Figure out the filename. */
1894 oc
= lookup_option (&server_universe
, state
-> options
, SV_FILENAME
);
1896 evaluate_option_cache (&state
-> filename
, packet
, lease
,
1897 (struct client_state
*)0,
1898 packet
-> options
, state
-> options
,
1899 &lease
-> scope
, oc
, MDL
);
1901 /* Choose a server name as above. */
1902 oc
= lookup_option (&server_universe
, state
-> options
,
1905 evaluate_option_cache (&state
-> server_name
, packet
, lease
,
1906 (struct client_state
*)0,
1907 packet
-> options
, state
-> options
,
1908 &lease
-> scope
, oc
, MDL
);
1910 /* At this point, we have a lease that we can offer the client.
1911 Now we construct a lease structure that contains what we want,
1912 and call supersede_lease to do the right thing with it. */
1913 lt
= (struct lease
*)0;
1914 result
= lease_allocate (<
, MDL
);
1915 if (result
!= ISC_R_SUCCESS
) {
1916 log_info ("%s: can't allocate temporary lease structure: %s",
1917 msg
, isc_result_totext (result
));
1918 free_lease_state (state
, MDL
);
1920 host_dereference (&host
, MDL
);
1924 /* Use the ip address of the lease that we finally found in
1926 lt
-> ip_addr
= lease
-> ip_addr
;
1929 lt
-> starts
= cur_time
;
1931 /* Figure out how long a lease to assign. If this is a
1932 dynamic BOOTP lease, its duration must be infinite. */
1934 default_lease_time
= DEFAULT_DEFAULT_LEASE_TIME
;
1935 if ((oc
= lookup_option (&server_universe
, state
-> options
,
1936 SV_DEFAULT_LEASE_TIME
))) {
1937 if (evaluate_option_cache (&d1
, packet
, lease
,
1938 (struct client_state
*)0,
1941 &lease
-> scope
, oc
, MDL
)) {
1942 if (d1
.len
== sizeof (u_int32_t
))
1943 default_lease_time
=
1945 data_string_forget (&d1
, MDL
);
1949 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
1950 DHO_DHCP_LEASE_TIME
)))
1951 s1
= evaluate_option_cache (&d1
, packet
, lease
,
1952 (struct client_state
*)0,
1955 &lease
-> scope
, oc
, MDL
);
1959 if (s1
&& d1
.len
== sizeof (u_int32_t
)) {
1960 lease_time
= getULong (d1
.data
);
1961 data_string_forget (&d1
, MDL
);
1964 data_string_forget (&d1
, MDL
);
1965 lease_time
= default_lease_time
;
1968 /* See if there's a maximum lease time. */
1969 max_lease_time
= DEFAULT_MAX_LEASE_TIME
;
1970 if ((oc
= lookup_option (&server_universe
, state
-> options
,
1971 SV_MAX_LEASE_TIME
))) {
1972 if (evaluate_option_cache (&d1
, packet
, lease
,
1973 (struct client_state
*)0,
1976 &lease
-> scope
, oc
, MDL
)) {
1977 if (d1
.len
== sizeof (u_int32_t
))
1980 data_string_forget (&d1
, MDL
);
1984 /* Enforce the maximum lease length. */
1985 if (lease_time
< 0 /* XXX */
1986 || lease_time
> max_lease_time
)
1987 lease_time
= max_lease_time
;
1989 min_lease_time
= DEFAULT_MIN_LEASE_TIME
;
1990 if (min_lease_time
> max_lease_time
)
1991 min_lease_time
= max_lease_time
;
1993 if ((oc
= lookup_option (&server_universe
, state
-> options
,
1994 SV_MIN_LEASE_TIME
))) {
1995 if (evaluate_option_cache (&d1
, packet
, lease
,
1996 (struct client_state
*)0,
1999 &lease
-> scope
, oc
, MDL
)) {
2000 if (d1
.len
== sizeof (u_int32_t
))
2001 min_lease_time
= getULong (d1
.data
);
2002 data_string_forget (&d1
, MDL
);
2006 if (lease_time
< min_lease_time
) {
2008 lease_time
= min_lease_time
;
2010 lease_time
= default_lease_time
;
2013 #if defined (FAILOVER_PROTOCOL)
2014 /* Okay, we know the lease duration. Now check the
2015 failover state, if any. */
2016 if (lease
-> tsfp
) {
2017 lt
->tsfp
= lease
->tsfp
;
2019 if (lease
-> pool
&& lease
-> pool
-> failover_peer
) {
2020 dhcp_failover_state_t
*peer
=
2021 lease
-> pool
-> failover_peer
;
2023 /* If the lease time we arrived at exceeds what
2024 the peer has, we can only issue a lease of
2025 peer -> mclt, but we can tell the peer we
2026 want something longer in the future. */
2027 /* XXX This may result in updates that only push
2028 XXX the peer's expiry time for this lease up
2029 XXX by a few seconds - think about this again
2031 if (lease_time
> peer
-> mclt
&&
2032 cur_time
+ lease_time
> lease
-> tsfp
) {
2033 /* Here we're assuming that if we don't have
2034 to update tstp, there's already an update
2035 queued. May want to revisit this. */
2036 if (peer
-> me
.state
!= partner_down
&&
2037 cur_time
+ lease_time
> lease
-> tstp
)
2038 lt
-> tstp
= (cur_time
+ lease_time
+
2041 /* Now choose a lease time that is either
2042 MCLT, for a lease that's never before been
2043 assigned, or TSFP + MCLT for a lease that
2045 XXX Note that TSFP may be < cur_time.
2046 XXX What do we do in this case?
2047 XXX should the expiry timer on the lease
2048 XXX set tsfp and tstp to zero? */
2049 if (lease
-> tsfp
< cur_time
) {
2050 lease_time
= peer
-> mclt
;
2052 lease_time
= (lease
-> tsfp
- cur_time
2056 if (cur_time
+ lease_time
> lease
-> tsfp
&&
2057 lease_time
> peer
-> mclt
/ 2) {
2058 lt
-> tstp
= (cur_time
+ lease_time
+
2061 lt
-> tstp
= (cur_time
+ lease_time
+
2066 lt
-> cltt
= cur_time
;
2068 #endif /* FAILOVER_PROTOCOL */
2070 /* If the lease duration causes the time value to wrap,
2071 use the maximum expiry time. */
2072 if (cur_time
+ lease_time
< cur_time
)
2073 state
-> offered_expiry
= MAX_TIME
- 1;
2075 state
-> offered_expiry
= cur_time
+ lease_time
;
2079 lt
-> ends
= state
-> offered_expiry
;
2081 /* Don't make lease active until we actually get a
2083 if (offer
== DHCPACK
)
2084 lt
-> next_binding_state
= FTS_ACTIVE
;
2086 lt
-> next_binding_state
= lease
-> binding_state
;
2088 lease_time
= MAX_TIME
- cur_time
;
2090 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2091 SV_BOOTP_LEASE_LENGTH
))) {
2092 if (evaluate_option_cache (&d1
, packet
, lease
,
2093 (struct client_state
*)0,
2096 &lease
-> scope
, oc
, MDL
)) {
2097 if (d1
.len
== sizeof (u_int32_t
))
2098 lease_time
= getULong (d1
.data
);
2099 data_string_forget (&d1
, MDL
);
2103 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2104 SV_BOOTP_LEASE_CUTOFF
))) {
2105 if (evaluate_option_cache (&d1
, packet
, lease
,
2106 (struct client_state
*)0,
2109 &lease
-> scope
, oc
, MDL
)) {
2110 if (d1
.len
== sizeof (u_int32_t
))
2111 lease_time
= (getULong (d1
.data
) -
2113 data_string_forget (&d1
, MDL
);
2117 lt
-> ends
= state
-> offered_expiry
= cur_time
+ lease_time
;
2118 lt
-> next_binding_state
= FTS_ACTIVE
;
2121 lt
-> timestamp
= cur_time
;
2123 /* Record the uid, if given... */
2124 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
2125 DHO_DHCP_CLIENT_IDENTIFIER
);
2127 evaluate_option_cache (&d1
, packet
, lease
,
2128 (struct client_state
*)0,
2129 packet
-> options
, state
-> options
,
2130 &lease
-> scope
, oc
, MDL
)) {
2131 if (d1
.len
<= sizeof lt
-> uid_buf
) {
2132 memcpy (lt
-> uid_buf
, d1
.data
, d1
.len
);
2133 lt
-> uid
= lt
-> uid_buf
;
2134 lt
-> uid_max
= sizeof lt
-> uid_buf
;
2135 lt
-> uid_len
= d1
.len
;
2137 unsigned char *tuid
;
2138 lt
-> uid_max
= d1
.len
;
2139 lt
-> uid_len
= d1
.len
;
2140 tuid
= (unsigned char *)dmalloc (lt
-> uid_max
, MDL
);
2143 log_fatal ("no memory for large uid.");
2144 memcpy (tuid
, d1
.data
, lt
-> uid_len
);
2147 data_string_forget (&d1
, MDL
);
2151 host_reference (<
-> host
, host
, MDL
);
2152 host_dereference (&host
, MDL
);
2154 if (lease
-> subnet
)
2155 subnet_reference (<
-> subnet
, lease
-> subnet
, MDL
);
2156 if (lease
-> billing_class
)
2157 class_reference (<
-> billing_class
,
2158 lease
-> billing_class
, MDL
);
2160 /* Set a flag if this client is a broken client that NUL
2161 terminates string options and expects us to do likewise. */
2163 lease
-> flags
|= MS_NULL_TERMINATION
;
2165 lease
-> flags
&= ~MS_NULL_TERMINATION
;
2167 /* Save any bindings. */
2168 if (lease
-> scope
) {
2169 binding_scope_reference (<
-> scope
, lease
-> scope
, MDL
);
2170 binding_scope_dereference (&lease
-> scope
, MDL
);
2172 if (lease
-> agent_options
)
2173 option_chain_head_reference (<
-> agent_options
,
2174 lease
-> agent_options
, MDL
);
2176 /* If we got relay agent information options, and the packet really
2177 looks like it came through a relay agent, and if this feature is
2178 not disabled, save the relay agent information options that came
2179 in with the packet, so that we can use them at renewal time when
2180 the packet won't have gone through a relay agent. */
2181 if (packet
-> raw
-> giaddr
.s_addr
&&
2182 packet
-> options
-> universe_count
> agent_universe
.index
&&
2183 packet
-> options
-> universes
[agent_universe
.index
] &&
2184 (state
-> options
-> universe_count
<= agent_universe
.index
||
2185 state
-> options
-> universes
[agent_universe
.index
] ==
2186 packet
-> options
-> universes
[agent_universe
.index
])) {
2187 oc
= lookup_option (&server_universe
, state
-> options
,
2188 SV_STASH_AGENT_OPTIONS
);
2190 evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
2191 (struct client_state
*)0,
2194 &lease
-> scope
, oc
, MDL
)) {
2195 if (lt
-> agent_options
)
2196 option_chain_head_dereference (<
-> agent_options
, MDL
);
2197 option_chain_head_reference
2198 (<
-> agent_options
,
2199 (struct option_chain_head
*)
2200 packet
-> options
-> universes
[agent_universe
.index
],
2205 /* Replace the old lease hostname with the new one, if it's changed. */
2206 oc
= lookup_option (&dhcp_universe
, packet
-> options
, DHO_HOST_NAME
);
2208 s1
= evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
2209 (struct client_state
*)0,
2211 (struct option_state
*)0,
2212 &global_scope
, oc
, MDL
);
2217 lease
-> client_hostname
&&
2218 strlen (lease
-> client_hostname
) == d1
.len
&&
2219 !memcmp (lease
-> client_hostname
, d1
.data
, d1
.len
)) {
2220 /* Hasn't changed. */
2221 data_string_forget (&d1
, MDL
);
2222 lt
-> client_hostname
= lease
-> client_hostname
;
2223 lease
-> client_hostname
= (char *)0;
2224 } else if (oc
&& s1
) {
2225 lt
-> client_hostname
= dmalloc (d1
.len
+ 1, MDL
);
2226 if (!lt
-> client_hostname
)
2227 log_error ("no memory for client hostname.");
2229 memcpy (lt
-> client_hostname
, d1
.data
, d1
.len
);
2230 lt
-> client_hostname
[d1
.len
] = 0;
2232 data_string_forget (&d1
, MDL
);
2235 /* Record the hardware address, if given... */
2236 lt
-> hardware_addr
.hlen
= packet
-> raw
-> hlen
+ 1;
2237 lt
-> hardware_addr
.hbuf
[0] = packet
-> raw
-> htype
;
2238 memcpy (<
-> hardware_addr
.hbuf
[1], packet
-> raw
-> chaddr
,
2239 sizeof packet
-> raw
-> chaddr
);
2241 lt
-> flags
= lease
-> flags
& ~PERSISTENT_FLAGS
;
2243 /* If there are statements to execute when the lease is
2244 committed, execute them. */
2245 if (lease
-> on_commit
&& (!offer
|| offer
== DHCPACK
)) {
2246 execute_statements ((struct binding_value
**)0,
2247 packet
, lt
, (struct client_state
*)0,
2249 state
-> options
, <
-> scope
,
2250 lease
-> on_commit
);
2251 if (lease
-> on_commit
)
2252 executable_statement_dereference (&lease
-> on_commit
,
2257 /* Perform DDNS updates, if configured to. */
2258 if ((!offer
|| offer
== DHCPACK
) &&
2259 (!(oc
= lookup_option (&server_universe
, state
-> options
,
2260 SV_DDNS_UPDATES
)) ||
2261 evaluate_boolean_option_cache (&ignorep
, packet
, lt
,
2262 (struct client_state
*)0,
2265 <
-> scope
, oc
, MDL
))) {
2266 ddns_updates (packet
, lt
, lease
, state
);
2268 #endif /* NSUPDATE */
2270 /* Don't call supersede_lease on a mocked-up lease. */
2271 if (lease
-> flags
& STATIC_LEASE
) {
2272 /* Copy the hardware address into the static lease
2274 lease
-> hardware_addr
.hlen
= packet
-> raw
-> hlen
+ 1;
2275 lease
-> hardware_addr
.hbuf
[0] = packet
-> raw
-> htype
;
2276 memcpy (&lease
-> hardware_addr
.hbuf
[1],
2277 packet
-> raw
-> chaddr
,
2278 sizeof packet
-> raw
-> chaddr
); /* XXX */
2280 /* Install the new information about this lease in the
2281 database. If this is a DHCPACK or a dynamic BOOTREPLY
2282 and we can't write the lease, don't ACK it (or BOOTREPLY
2285 if (!supersede_lease (lease
, lt
, !offer
|| offer
== DHCPACK
,
2286 offer
== DHCPACK
, offer
== DHCPACK
)) {
2287 log_info ("%s: database update failed", msg
);
2288 free_lease_state (state
, MDL
);
2289 lease_dereference (<
, MDL
);
2293 lease_dereference (<
, MDL
);
2295 /* Remember the interface on which the packet arrived. */
2296 state
-> ip
= packet
-> interface
;
2298 /* Remember the giaddr, xid, secs, flags and hops. */
2299 state
-> giaddr
= packet
-> raw
-> giaddr
;
2300 state
-> ciaddr
= packet
-> raw
-> ciaddr
;
2301 state
-> xid
= packet
-> raw
-> xid
;
2302 state
-> secs
= packet
-> raw
-> secs
;
2303 state
-> bootp_flags
= packet
-> raw
-> flags
;
2304 state
-> hops
= packet
-> raw
-> hops
;
2305 state
-> offer
= offer
;
2307 /* If we're always supposed to broadcast to this client, set
2308 the broadcast bit in the bootp flags field. */
2309 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2310 SV_ALWAYS_BROADCAST
)) &&
2311 evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
2312 (struct client_state
*)0,
2313 packet
-> options
, state
-> options
,
2314 &lease
-> scope
, oc
, MDL
))
2315 state
-> bootp_flags
|= htons (BOOTP_BROADCAST
);
2317 /* Get the Maximum Message Size option from the packet, if one
2319 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
2320 DHO_DHCP_MAX_MESSAGE_SIZE
);
2322 evaluate_option_cache (&d1
, packet
, lease
,
2323 (struct client_state
*)0,
2324 packet
-> options
, state
-> options
,
2325 &lease
-> scope
, oc
, MDL
)) {
2326 if (d1
.len
== sizeof (u_int16_t
))
2327 state
-> max_message_size
= getUShort (d1
.data
);
2328 data_string_forget (&d1
, MDL
);
2330 oc
= lookup_option (&dhcp_universe
, state
-> options
,
2331 DHO_DHCP_MAX_MESSAGE_SIZE
);
2333 evaluate_option_cache (&d1
, packet
, lease
,
2334 (struct client_state
*)0,
2335 packet
-> options
, state
-> options
,
2336 &lease
-> scope
, oc
, MDL
)) {
2337 if (d1
.len
== sizeof (u_int16_t
))
2338 state
-> max_message_size
=
2339 getUShort (d1
.data
);
2340 data_string_forget (&d1
, MDL
);
2344 /* Get the Subnet Selection option from the packet, if one
2346 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
2347 DHO_SUBNET_SELECTION
))) {
2349 /* Make a copy of the data. */
2350 struct option_cache
*noc
= (struct option_cache
*)0;
2351 if (option_cache_allocate (&noc
, MDL
)) {
2353 data_string_copy (&noc
-> data
,
2355 if (oc
-> expression
)
2356 expression_reference (&noc
-> expression
,
2357 oc
-> expression
, MDL
);
2359 noc
-> option
= oc
-> option
;
2362 save_option (&dhcp_universe
, state
-> options
, noc
);
2363 option_cache_dereference (&noc
, MDL
);
2366 /* Now, if appropriate, put in DHCP-specific options that
2368 if (state
-> offer
) {
2369 i
= DHO_DHCP_MESSAGE_TYPE
;
2370 oc
= (struct option_cache
*)0;
2371 if (option_cache_allocate (&oc
, MDL
)) {
2372 if (make_const_data (&oc
-> expression
,
2373 &state
-> offer
, 1, 0, 0, MDL
)) {
2375 dhcp_universe
.options
[i
];
2376 save_option (&dhcp_universe
,
2377 state
-> options
, oc
);
2379 option_cache_dereference (&oc
, MDL
);
2381 i
= DHO_DHCP_SERVER_IDENTIFIER
;
2382 if (!(oc
= lookup_option (&dhcp_universe
,
2383 state
-> options
, i
))) {
2385 oc
= (struct option_cache
*)0;
2386 if (option_cache_allocate (&oc
, MDL
)) {
2390 &state
-> ip
-> primary_address
),
2391 sizeof state
-> ip
-> primary_address
,
2394 dhcp_universe
.options
[i
];
2395 save_option (&dhcp_universe
,
2396 state
-> options
, oc
);
2398 option_cache_dereference (&oc
, MDL
);
2401 sizeof state
-> ip
-> primary_address
;
2402 memcpy (state
-> from
.iabuf
,
2403 &state
-> ip
-> primary_address
,
2406 if (evaluate_option_cache (&d1
, packet
, lease
,
2407 (struct client_state
*)0,
2410 &lease
-> scope
, oc
, MDL
)) {
2412 d1
.len
> sizeof state
-> from
.iabuf
) {
2413 data_string_forget (&d1
, MDL
);
2416 memcpy (state
-> from
.iabuf
, d1
.data
, d1
.len
);
2417 state
-> from
.len
= d1
.len
;
2418 data_string_forget (&d1
, MDL
);
2423 offered_lease_time
=
2424 state
-> offered_expiry
- cur_time
;
2426 putULong ((unsigned char *)&state
-> expiry
,
2427 (unsigned long)offered_lease_time
);
2428 i
= DHO_DHCP_LEASE_TIME
;
2429 if (lookup_option (&dhcp_universe
, state
-> options
, i
))
2430 log_error ("dhcp-lease-time option for %s overridden.",
2431 inet_ntoa (state
-> ciaddr
));
2432 oc
= (struct option_cache
*)0;
2433 if (option_cache_allocate (&oc
, MDL
)) {
2434 if (make_const_data (&oc
-> expression
,
2435 (unsigned char *)&state
-> expiry
,
2436 sizeof state
-> expiry
,
2438 oc
-> option
= dhcp_universe
.options
[i
];
2439 save_option (&dhcp_universe
,
2440 state
-> options
, oc
);
2442 option_cache_dereference (&oc
, MDL
);
2445 /* Renewal time is lease time * 0.5. */
2446 offered_lease_time
/= 2;
2447 putULong ((unsigned char *)&state
-> renewal
,
2448 (unsigned long)offered_lease_time
);
2449 i
= DHO_DHCP_RENEWAL_TIME
;
2450 if (lookup_option (&dhcp_universe
, state
-> options
, i
))
2451 log_error ("overriding dhcp-renewal-time for %s.",
2452 inet_ntoa (state
-> ciaddr
));
2453 oc
= (struct option_cache
*)0;
2454 if (option_cache_allocate (&oc
, MDL
)) {
2455 if (make_const_data (&oc
-> expression
,
2458 sizeof state
-> renewal
,
2460 oc
-> option
= dhcp_universe
.options
[i
];
2461 save_option (&dhcp_universe
,
2462 state
-> options
, oc
);
2464 option_cache_dereference (&oc
, MDL
);
2467 /* Rebinding time is lease time * 0.875. */
2468 offered_lease_time
+= (offered_lease_time
/ 2
2469 + offered_lease_time
/ 4);
2470 putULong ((unsigned char *)&state
-> rebind
,
2471 (unsigned)offered_lease_time
);
2472 i
= DHO_DHCP_REBINDING_TIME
;
2473 if (lookup_option (&dhcp_universe
, state
-> options
, i
))
2474 log_error ("overriding dhcp-rebinding-time for %s.",
2475 inet_ntoa (state
-> ciaddr
));
2476 oc
= (struct option_cache
*)0;
2477 if (option_cache_allocate (&oc
, MDL
)) {
2478 if (make_const_data (&oc
-> expression
,
2479 (unsigned char *)&state
-> rebind
,
2480 sizeof state
-> rebind
,
2482 oc
-> option
= dhcp_universe
.options
[i
];
2483 save_option (&dhcp_universe
,
2484 state
-> options
, oc
);
2486 option_cache_dereference (&oc
, MDL
);
2490 sizeof state
-> ip
-> primary_address
;
2491 memcpy (state
-> from
.iabuf
,
2492 &state
-> ip
-> primary_address
,
2496 /* Figure out the address of the boot file server. */
2497 memset (&state
-> siaddr
, 0, sizeof state
-> siaddr
);
2499 lookup_option (&server_universe
,
2500 state
-> options
, SV_NEXT_SERVER
))) {
2501 if (evaluate_option_cache (&d1
, packet
, lease
,
2502 (struct client_state
*)0,
2503 packet
-> options
, state
-> options
,
2504 &lease
-> scope
, oc
, MDL
)) {
2505 /* If there was more than one answer,
2507 if (d1
.len
>= 4 && d1
.data
)
2508 memcpy (&state
-> siaddr
, d1
.data
, 4);
2509 data_string_forget (&d1
, MDL
);
2513 /* Use the subnet mask from the subnet declaration if no other
2514 mask has been provided. */
2515 i
= DHO_SUBNET_MASK
;
2516 if (!lookup_option (&dhcp_universe
, state
-> options
, i
)) {
2517 oc
= (struct option_cache
*)0;
2518 if (option_cache_allocate (&oc
, MDL
)) {
2519 if (make_const_data (&oc
-> expression
,
2520 lease
-> subnet
-> netmask
.iabuf
,
2521 lease
-> subnet
-> netmask
.len
,
2523 oc
-> option
= dhcp_universe
.options
[i
];
2524 save_option (&dhcp_universe
,
2525 state
-> options
, oc
);
2527 option_cache_dereference (&oc
, MDL
);
2531 /* Use the hostname from the host declaration if there is one
2532 and no hostname has otherwise been provided, and if the
2533 use-host-decl-name flag is set. */
2535 j
= SV_USE_HOST_DECL_NAMES
;
2536 if (!lookup_option (&dhcp_universe
, state
-> options
, i
) &&
2537 lease
-> host
&& lease
-> host
-> name
&&
2538 (evaluate_boolean_option_cache
2539 (&ignorep
, packet
, lease
, (struct client_state
*)0,
2540 packet
-> options
, state
-> options
, &lease
-> scope
,
2541 lookup_option (&server_universe
, state
-> options
, j
), MDL
))) {
2542 oc
= (struct option_cache
*)0;
2543 if (option_cache_allocate (&oc
, MDL
)) {
2544 if (make_const_data (&oc
-> expression
,
2546 lease
-> host
-> name
),
2547 strlen (lease
-> host
-> name
),
2549 oc
-> option
= dhcp_universe
.options
[i
];
2550 save_option (&dhcp_universe
,
2551 state
-> options
, oc
);
2553 option_cache_dereference (&oc
, MDL
);
2557 /* If we don't have a hostname yet, and we've been asked to do
2558 a reverse lookup to find the hostname, do it. */
2559 j
= SV_GET_LEASE_HOSTNAMES
;
2560 if (!lookup_option (&dhcp_universe
, state
-> options
, i
) &&
2561 (evaluate_boolean_option_cache
2562 (&ignorep
, packet
, lease
, (struct client_state
*)0,
2563 packet
-> options
, state
-> options
, &lease
-> scope
,
2564 lookup_option (&server_universe
, state
-> options
, j
), MDL
))) {
2568 memcpy (&ia
, lease
-> ip_addr
.iabuf
, 4);
2570 h
= gethostbyaddr ((char *)&ia
, sizeof ia
, AF_INET
);
2572 log_error ("No hostname for %s", inet_ntoa (ia
));
2574 oc
= (struct option_cache
*)0;
2575 if (option_cache_allocate (&oc
, MDL
)) {
2576 if (make_const_data (&oc
-> expression
,
2579 strlen (h
-> h_name
) + 1,
2582 dhcp_universe
.options
[i
];
2583 save_option (&dhcp_universe
,
2584 state
-> options
, oc
);
2586 option_cache_dereference (&oc
, MDL
);
2591 /* If so directed, use the leased IP address as the router address.
2592 This supposedly makes Win95 machines ARP for all IP addresses,
2593 so if the local router does proxy arp, you win. */
2595 if (evaluate_boolean_option_cache
2596 (&ignorep
, packet
, lease
, (struct client_state
*)0,
2597 packet
-> options
, state
-> options
, &lease
-> scope
,
2598 lookup_option (&server_universe
, state
-> options
,
2599 SV_USE_LEASE_ADDR_FOR_DEFAULT_ROUTE
), MDL
)) {
2601 oc
= lookup_option (&dhcp_universe
, state
-> options
, i
);
2603 oc
= (struct option_cache
*)0;
2604 if (option_cache_allocate (&oc
, MDL
)) {
2605 if (make_const_data (&oc
-> expression
,
2606 lease
-> ip_addr
.iabuf
,
2607 lease
-> ip_addr
.len
,
2610 dhcp_universe
.options
[i
];
2611 save_option (&dhcp_universe
,
2612 state
-> options
, oc
);
2614 option_cache_dereference (&oc
, MDL
);
2619 /* If a site option space has been specified, use that for
2620 site option codes. */
2621 i
= SV_SITE_OPTION_SPACE
;
2622 if ((oc
= lookup_option (&server_universe
, state
-> options
, i
)) &&
2623 evaluate_option_cache (&d1
, packet
, lease
,
2624 (struct client_state
*)0,
2625 packet
-> options
, state
-> options
,
2626 &lease
-> scope
, oc
, MDL
)) {
2627 struct universe
*u
= (struct universe
*)0;
2629 if (!universe_hash_lookup (&u
, universe_hash
,
2630 (const char *)d1
.data
, d1
.len
,
2632 log_error ("unknown option space %s.", d1
.data
);
2636 state
-> options
-> site_universe
= u
-> index
;
2637 state
-> options
-> site_code_min
= 128; /* XXX */
2638 data_string_forget (&d1
, MDL
);
2640 state
-> options
-> site_code_min
= 0;
2641 state
-> options
-> site_universe
= dhcp_universe
.index
;
2644 /* If the client has provided a list of options that it wishes
2645 returned, use it to prioritize. If there's a parameter
2646 request list in scope, use that in preference. Otherwise
2647 use the default priority list. */
2649 oc
= lookup_option (&dhcp_universe
, state
-> options
,
2650 DHO_DHCP_PARAMETER_REQUEST_LIST
);
2653 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
2654 DHO_DHCP_PARAMETER_REQUEST_LIST
);
2656 evaluate_option_cache (&state
-> parameter_request_list
,
2657 packet
, lease
, (struct client_state
*)0,
2658 packet
-> options
, state
-> options
,
2659 &lease
-> scope
, oc
, MDL
);
2662 dump_packet (packet
);
2663 dump_raw ((unsigned char *)packet
-> raw
, packet
-> packet_length
);
2666 lease
-> state
= state
;
2668 log_info ("%s", msg
);
2670 /* Hang the packet off the lease state. */
2671 packet_reference (&lease
-> state
-> packet
, packet
, MDL
);
2673 /* If this is a DHCPOFFER, ping the lease address before actually
2674 sending the offer. */
2675 if (offer
== DHCPOFFER
&& !(lease
-> flags
& STATIC_LEASE
) &&
2676 cur_time
- lease
-> timestamp
> 60 &&
2677 (!(oc
= lookup_option (&server_universe
, state
-> options
,
2679 evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
2680 (struct client_state
*)0,
2683 &lease
-> scope
, oc
, MDL
))) {
2684 lease
-> timestamp
= cur_time
;
2685 icmp_echorequest (&lease
-> ip_addr
);
2687 /* Determine wether to use configured or default ping timeout.
2689 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2690 SV_PING_TIMEOUT
)) &&
2691 evaluate_option_cache (&d1
, packet
, lease
, NULL
,
2694 &lease
-> scope
, oc
, MDL
)) {
2695 if (d1
.len
== sizeof (u_int32_t
))
2696 ping_timeout
= getULong (d1
.data
);
2698 ping_timeout
= DEFAULT_PING_TIMEOUT
;
2700 data_string_forget (&d1
, MDL
);
2702 ping_timeout
= DEFAULT_PING_TIMEOUT
;
2705 log_debug ("Ping timeout: %ld", (long)ping_timeout
);
2708 add_timeout (cur_time
+ ping_timeout
, lease_ping_timeout
, lease
,
2709 (tvref_t
)lease_reference
,
2710 (tvunref_t
)lease_dereference
);
2711 ++outstanding_pings
;
2713 lease
-> timestamp
= cur_time
;
2718 void dhcp_reply (lease
)
2719 struct lease
*lease
;
2722 unsigned packet_length
;
2723 struct dhcp_packet raw
;
2724 struct sockaddr_in to
;
2725 struct in_addr from
;
2726 struct hardware hto
;
2728 struct lease_state
*state
= lease
-> state
;
2729 int nulltp
, bootpp
, unicastp
= 1;
2730 struct data_string d1
;
2734 log_fatal ("dhcp_reply was supplied lease with no state!");
2736 /* Compose a response for the client... */
2737 memset (&raw
, 0, sizeof raw
);
2738 memset (&d1
, 0, sizeof d1
);
2740 /* Copy in the filename if given; otherwise, flag the filename
2741 buffer as available for options. */
2742 if (state
-> filename
.len
&& state
-> filename
.data
) {
2744 state
-> filename
.data
,
2745 state
-> filename
.len
> sizeof raw
.file
2746 ? sizeof raw
.file
: state
-> filename
.len
);
2747 if (sizeof raw
.file
> state
-> filename
.len
)
2748 memset (&raw
.file
[state
-> filename
.len
], 0,
2749 (sizeof raw
.file
) - state
-> filename
.len
);
2753 /* Copy in the server name if given; otherwise, flag the
2754 server_name buffer as available for options. */
2755 if (state
-> server_name
.len
&& state
-> server_name
.data
) {
2757 state
-> server_name
.data
,
2758 state
-> server_name
.len
> sizeof raw
.sname
2759 ? sizeof raw
.sname
: state
-> server_name
.len
);
2760 if (sizeof raw
.sname
> state
-> server_name
.len
)
2761 memset (&raw
.sname
[state
-> server_name
.len
], 0,
2762 (sizeof raw
.sname
) - state
-> server_name
.len
);
2764 bufs
|= 2; /* XXX */
2767 &lease
-> hardware_addr
.hbuf
[1], sizeof raw
.chaddr
);
2768 raw
.hlen
= lease
-> hardware_addr
.hlen
- 1;
2769 raw
.htype
= lease
-> hardware_addr
.hbuf
[0];
2771 /* See if this is a Microsoft client that NUL-terminates its
2772 strings and expects us to do likewise... */
2773 if (lease
-> flags
& MS_NULL_TERMINATION
)
2778 /* See if this is a bootp client... */
2784 /* Insert such options as will fit into the buffer. */
2785 packet_length
= cons_options (state
-> packet
, &raw
, lease
,
2786 (struct client_state
*)0,
2787 state
-> max_message_size
,
2788 state
-> packet
-> options
,
2789 state
-> options
, &global_scope
,
2790 bufs
, nulltp
, bootpp
,
2791 &state
-> parameter_request_list
,
2794 memcpy (&raw
.ciaddr
, &state
-> ciaddr
, sizeof raw
.ciaddr
);
2795 memcpy (&raw
.yiaddr
, lease
-> ip_addr
.iabuf
, 4);
2796 raw
.siaddr
= state
-> siaddr
;
2797 raw
.giaddr
= state
-> giaddr
;
2799 raw
.xid
= state
-> xid
;
2800 raw
.secs
= state
-> secs
;
2801 raw
.flags
= state
-> bootp_flags
;
2802 raw
.hops
= state
-> hops
;
2805 if (lease
-> client_hostname
) {
2806 if ((strlen (lease
-> client_hostname
) <= 64) &&
2807 db_printable (lease
-> client_hostname
))
2808 s
= lease
-> client_hostname
;
2810 s
= "Hostname Unsuitable for Printing";
2814 /* Say what we're doing... */
2815 log_info ("%s on %s to %s %s%s%svia %s",
2817 ? (state
-> offer
== DHCPACK
? "DHCPACK" : "DHCPOFFER")
2819 piaddr (lease
-> ip_addr
),
2820 (lease
-> hardware_addr
.hlen
2821 ? print_hw_addr (lease
-> hardware_addr
.hbuf
[0],
2822 lease
-> hardware_addr
.hlen
- 1,
2823 &lease
-> hardware_addr
.hbuf
[1])
2824 : print_hex_1 (lease
-> uid_len
, lease
-> uid
,
2826 s
? "(" : "", s
? s
: "", s
? ") " : "",
2827 (state
-> giaddr
.s_addr
2828 ? inet_ntoa (state
-> giaddr
)
2829 : state
-> ip
-> name
));
2831 /* Set up the hardware address... */
2832 hto
.hlen
= lease
-> hardware_addr
.hlen
;
2833 memcpy (hto
.hbuf
, lease
-> hardware_addr
.hbuf
, hto
.hlen
);
2835 memset(&to
, 0, sizeof(to
));
2836 to
.sin_family
= AF_INET
;
2838 to
.sin_len
= sizeof to
;
2842 dump_raw ((unsigned char *)&raw
, packet_length
);
2845 /* Make sure outgoing packets are at least as big
2846 as a BOOTP packet. */
2847 if (packet_length
< BOOTP_MIN_LEN
)
2848 packet_length
= BOOTP_MIN_LEN
;
2850 /* If this was gatewayed, send it back to the gateway... */
2851 if (raw
.giaddr
.s_addr
) {
2852 to
.sin_addr
= raw
.giaddr
;
2853 if (raw
.giaddr
.s_addr
!= htonl (INADDR_LOOPBACK
))
2854 to
.sin_port
= local_port
;
2856 to
.sin_port
= remote_port
; /* For debugging. */
2858 if (fallback_interface
) {
2859 result
= send_packet (fallback_interface
,
2861 &raw
, packet_length
,
2863 (struct hardware
*)0);
2865 free_lease_state (state
, MDL
);
2866 lease
-> state
= (struct lease_state
*)0;
2870 /* If the client is RENEWING, unicast to the client using the
2871 regular IP stack. Some clients, particularly those that
2872 follow RFC1541, are buggy, and send both ciaddr and server
2873 identifier. We deal with this situation by assuming that
2874 if we got both dhcp-server-identifier and ciaddr, and
2875 giaddr was not set, then the client is on the local
2876 network, and we can therefore unicast or broadcast to it
2877 successfully. A client in REQUESTING state on another
2878 network that's making this mistake will have set giaddr,
2879 and will therefore get a relayed response from the above
2881 } else if (raw
.ciaddr
.s_addr
&&
2882 !((state
-> got_server_identifier
||
2883 (raw
.flags
& htons (BOOTP_BROADCAST
))) &&
2884 /* XXX This won't work if giaddr isn't zero, but it is: */
2885 (state
-> shared_network
==
2886 lease
-> subnet
-> shared_network
)) &&
2887 state
-> offer
== DHCPACK
) {
2888 to
.sin_addr
= raw
.ciaddr
;
2889 to
.sin_port
= remote_port
;
2891 if (fallback_interface
) {
2892 result
= send_packet (fallback_interface
,
2894 &raw
, packet_length
,
2896 (struct hardware
*)0);
2897 free_lease_state (state
, MDL
);
2898 lease
-> state
= (struct lease_state
*)0;
2902 /* If it comes from a client that already knows its address
2903 and is not requesting a broadcast response, and we can
2904 unicast to a client without using the ARP protocol, sent it
2905 directly to that client. */
2906 } else if (!(raw
.flags
& htons (BOOTP_BROADCAST
)) &&
2907 can_unicast_without_arp (state
-> ip
)) {
2908 to
.sin_addr
= raw
.yiaddr
;
2909 to
.sin_port
= remote_port
;
2911 /* Otherwise, broadcast it on the local network. */
2913 to
.sin_addr
= limited_broadcast
;
2914 to
.sin_port
= remote_port
;
2915 if (!(lease
-> flags
& UNICAST_BROADCAST_HACK
))
2919 memcpy (&from
, state
-> from
.iabuf
, sizeof from
);
2921 result
= send_packet (state
-> ip
,
2922 (struct packet
*)0, &raw
, packet_length
,
2924 unicastp
? &hto
: (struct hardware
*)0);
2926 /* Free all of the entries in the option_state structure
2927 now that we're done with them. */
2929 free_lease_state (state
, MDL
);
2930 lease
-> state
= (struct lease_state
*)0;
2933 int find_lease (struct lease
**lp
,
2934 struct packet
*packet
, struct shared_network
*share
, int *ours
,
2935 int *allocatedp
, struct lease
*ip_lease_in
,
2936 const char *file
, int line
)
2938 struct lease
*uid_lease
= (struct lease
*)0;
2939 struct lease
*ip_lease
= (struct lease
*)0;
2940 struct lease
*hw_lease
= (struct lease
*)0;
2941 struct lease
*lease
= (struct lease
*)0;
2943 struct host_decl
*hp
= (struct host_decl
*)0;
2944 struct host_decl
*host
= (struct host_decl
*)0;
2945 struct lease
*fixed_lease
= (struct lease
*)0;
2946 struct lease
*next
= (struct lease
*)0;
2947 struct option_cache
*oc
;
2948 struct data_string d1
;
2949 int have_client_identifier
= 0;
2950 struct data_string client_identifier
;
2953 if (packet
-> raw
-> ciaddr
.s_addr
) {
2955 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
, 4);
2957 /* Look up the requested address. */
2958 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
2959 DHO_DHCP_REQUESTED_ADDRESS
);
2960 memset (&d1
, 0, sizeof d1
);
2962 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
2963 (struct client_state
*)0,
2965 (struct option_state
*)0,
2966 &global_scope
, oc
, MDL
)) {
2967 packet
-> got_requested_address
= 1;
2969 memcpy (cip
.iabuf
, d1
.data
, cip
.len
);
2970 data_string_forget (&d1
, MDL
);
2975 /* Try to find a host or lease that's been assigned to the
2976 specified unique client identifier. */
2977 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
2978 DHO_DHCP_CLIENT_IDENTIFIER
);
2979 memset (&client_identifier
, 0, sizeof client_identifier
);
2981 evaluate_option_cache (&client_identifier
,
2982 packet
, (struct lease
*)0,
2983 (struct client_state
*)0,
2984 packet
-> options
, (struct option_state
*)0,
2985 &global_scope
, oc
, MDL
)) {
2986 /* Remember this for later. */
2987 have_client_identifier
= 1;
2989 /* First, try to find a fixed host entry for the specified
2990 client identifier... */
2991 if (find_hosts_by_uid (&hp
, client_identifier
.data
,
2992 client_identifier
.len
, MDL
)) {
2993 /* Remember if we know of this client. */
2994 packet
-> known
= 1;
2995 mockup_lease (&fixed_lease
, packet
, share
, hp
);
2998 #if defined (DEBUG_FIND_LEASE)
3000 log_info ("Found host for client identifier: %s.",
3001 piaddr (fixed_lease
-> ip_addr
));
3005 if (!fixed_lease
) /* Save the host if we found one. */
3006 host_reference (&host
, hp
, MDL
);
3007 host_dereference (&hp
, MDL
);
3010 find_lease_by_uid (&uid_lease
, client_identifier
.data
,
3011 client_identifier
.len
, MDL
);
3014 /* If we didn't find a fixed lease using the uid, try doing
3015 it with the hardware address... */
3016 if (!fixed_lease
&& !host
) {
3017 if (find_hosts_by_haddr (&hp
, packet
-> raw
-> htype
,
3018 packet
-> raw
-> chaddr
,
3019 packet
-> raw
-> hlen
, MDL
)) {
3020 /* Remember if we know of this client. */
3021 packet
-> known
= 1;
3023 host_dereference (&host
, MDL
);
3024 host_reference (&host
, hp
, MDL
);
3025 host_dereference (&hp
, MDL
);
3026 mockup_lease (&fixed_lease
, packet
, share
, host
);
3027 #if defined (DEBUG_FIND_LEASE)
3029 log_info ("Found host for link address: %s.",
3030 piaddr (fixed_lease
-> ip_addr
));
3036 /* If fixed_lease is present but does not match the requested
3037 IP address, and this is a DHCPREQUEST, then we can't return
3038 any other lease, so we might as well return now. */
3039 if (packet
-> packet_type
== DHCPREQUEST
&& fixed_lease
&&
3040 (fixed_lease
-> ip_addr
.len
!= cip
.len
||
3041 memcmp (fixed_lease
-> ip_addr
.iabuf
,
3042 cip
.iabuf
, cip
.len
))) {
3045 strcpy (dhcp_message
, "requested address is incorrect");
3046 #if defined (DEBUG_FIND_LEASE)
3047 log_info ("Client's fixed-address %s doesn't match %s%s",
3048 piaddr (fixed_lease
-> ip_addr
), "request ",
3049 print_dotted_quads (cip
.len
, cip
.iabuf
));
3054 /* If we found leases matching the client identifier, loop through
3055 the n_uid pointer looking for one that's actually valid. We
3056 can't do this until we get here because we depend on
3057 packet -> known, which may be set by either the uid host
3058 lookup or the haddr host lookup. */
3060 #if defined (DEBUG_FIND_LEASE)
3061 log_info ("trying next lease matching client id: %s",
3062 piaddr (uid_lease
-> ip_addr
));
3065 #if defined (FAILOVER_PROTOCOL)
3066 /* When failover is active, it's possible that there could
3067 be two "free" leases for the same uid, but only one of
3068 them that's available for this failover peer to allocate. */
3069 if (uid_lease
-> binding_state
!= FTS_ACTIVE
&&
3070 !lease_mine_to_reallocate (uid_lease
)) {
3071 #if defined (DEBUG_FIND_LEASE)
3072 log_info ("not mine to allocate: %s",
3073 piaddr (uid_lease
-> ip_addr
));
3079 if (uid_lease
-> subnet
-> shared_network
!= share
) {
3080 #if defined (DEBUG_FIND_LEASE)
3081 log_info ("wrong network segment: %s",
3082 piaddr (uid_lease
-> ip_addr
));
3087 if ((uid_lease
-> pool
-> prohibit_list
&&
3088 permitted (packet
, uid_lease
-> pool
-> prohibit_list
)) ||
3089 (uid_lease
-> pool
-> permit_list
&&
3090 !permitted (packet
, uid_lease
-> pool
-> permit_list
))) {
3091 #if defined (DEBUG_FIND_LEASE)
3092 log_info ("not permitted: %s",
3093 piaddr (uid_lease
-> ip_addr
));
3096 if (uid_lease
-> n_uid
)
3097 lease_reference (&next
,
3098 uid_lease
-> n_uid
, MDL
);
3099 if (!packet
-> raw
-> ciaddr
.s_addr
)
3100 release_lease (uid_lease
, packet
);
3101 lease_dereference (&uid_lease
, MDL
);
3103 lease_reference (&uid_lease
, next
, MDL
);
3104 lease_dereference (&next
, MDL
);
3110 #if defined (DEBUG_FIND_LEASE)
3112 log_info ("Found lease for client id: %s.",
3113 piaddr (uid_lease
-> ip_addr
));
3116 /* Find a lease whose hardware address matches, whose client
3117 identifier matches, that's permitted, and that's on the
3119 h
.hlen
= packet
-> raw
-> hlen
+ 1;
3120 h
.hbuf
[0] = packet
-> raw
-> htype
;
3121 memcpy (&h
.hbuf
[1], packet
-> raw
-> chaddr
, packet
-> raw
-> hlen
);
3122 find_lease_by_hw_addr (&hw_lease
, h
.hbuf
, h
.hlen
, MDL
);
3124 #if defined (DEBUG_FIND_LEASE)
3125 log_info ("trying next lease matching hw addr: %s",
3126 piaddr (hw_lease
-> ip_addr
));
3128 #if defined (FAILOVER_PROTOCOL)
3129 /* When failover is active, it's possible that there could
3130 be two "free" leases for the same uid, but only one of
3131 them that's available for this failover peer to allocate. */
3132 if (hw_lease
-> binding_state
!= FTS_ACTIVE
&&
3133 !lease_mine_to_reallocate (hw_lease
)) {
3134 #if defined (DEBUG_FIND_LEASE)
3135 log_info ("not mine to allocate: %s",
3136 piaddr (hw_lease
-> ip_addr
));
3142 if (hw_lease
-> binding_state
!= FTS_FREE
&&
3143 hw_lease
-> binding_state
!= FTS_BACKUP
&&
3145 (!have_client_identifier
||
3146 hw_lease
-> uid_len
!= client_identifier
.len
||
3147 memcmp (hw_lease
-> uid
, client_identifier
.data
,
3148 hw_lease
-> uid_len
))) {
3149 #if defined (DEBUG_FIND_LEASE)
3150 log_info ("wrong client identifier: %s",
3151 piaddr (hw_lease
-> ip_addr
));
3156 if (hw_lease
-> subnet
-> shared_network
!= share
) {
3157 #if defined (DEBUG_FIND_LEASE)
3158 log_info ("wrong network segment: %s",
3159 piaddr (hw_lease
-> ip_addr
));
3164 if ((hw_lease
-> pool
-> prohibit_list
&&
3165 permitted (packet
, hw_lease
-> pool
-> prohibit_list
)) ||
3166 (hw_lease
-> pool
-> permit_list
&&
3167 !permitted (packet
, hw_lease
-> pool
-> permit_list
))) {
3168 #if defined (DEBUG_FIND_LEASE)
3169 log_info ("not permitted: %s",
3170 piaddr (hw_lease
-> ip_addr
));
3172 if (!packet
-> raw
-> ciaddr
.s_addr
)
3173 release_lease (hw_lease
, packet
);
3175 if (hw_lease
-> n_hw
)
3176 lease_reference (&next
, hw_lease
-> n_hw
, MDL
);
3177 lease_dereference (&hw_lease
, MDL
);
3179 lease_reference (&hw_lease
, next
, MDL
);
3180 lease_dereference (&next
, MDL
);
3186 #if defined (DEBUG_FIND_LEASE)
3188 log_info ("Found lease for hardware address: %s.",
3189 piaddr (hw_lease
-> ip_addr
));
3192 /* Try to find a lease that's been allocated to the client's
3195 lease_reference (&ip_lease
, ip_lease_in
, MDL
);
3197 find_lease_by_ip_addr (&ip_lease
, cip
, MDL
);
3199 #if defined (DEBUG_FIND_LEASE)
3201 log_info ("Found lease for requested address: %s.",
3202 piaddr (ip_lease
-> ip_addr
));
3205 /* If ip_lease is valid at this point, set ours to one, so that
3206 even if we choose a different lease, we know that the address
3207 the client was requesting was ours, and thus we can NAK it. */
3208 if (ip_lease
&& ours
)
3211 /* If the requested IP address isn't on the network the packet
3212 came from, don't use it. Allow abandoned leases to be matched
3213 here - if the client is requesting it, there's a decent chance
3214 that it's because the lease database got trashed and a client
3215 that thought it had this lease answered an ARP or PING, causing the
3216 lease to be abandoned. If so, this request probably came from
3218 if (ip_lease
&& (ip_lease
-> subnet
-> shared_network
!= share
)) {
3221 #if defined (DEBUG_FIND_LEASE)
3222 log_info ("...but it was on the wrong shared network.");
3224 strcpy (dhcp_message
, "requested address on bad subnet");
3225 lease_dereference (&ip_lease
, MDL
);
3228 /* Toss ip_lease if it hasn't yet expired and doesn't belong to the
3232 (!have_client_identifier
||
3233 ip_lease
-> uid_len
!= client_identifier
.len
||
3234 memcmp (ip_lease
-> uid
, client_identifier
.data
,
3235 ip_lease
-> uid_len
)) :
3236 (ip_lease
-> hardware_addr
.hbuf
[0] != packet
-> raw
-> htype
||
3237 ip_lease
-> hardware_addr
.hlen
!= packet
-> raw
-> hlen
+ 1 ||
3238 memcmp (&ip_lease
-> hardware_addr
.hbuf
[1],
3239 packet
-> raw
-> chaddr
,
3240 (unsigned)(ip_lease
-> hardware_addr
.hlen
- 1))))) {
3241 /* If we're not doing failover, the only state in which
3242 we can allocate this lease to the client is FTS_FREE.
3243 If we are doing failover, things are more complicated.
3244 If the lease is free or backup, we let the caller decide
3245 whether or not to give it out. */
3246 if (ip_lease
-> binding_state
!= FTS_FREE
&&
3247 ip_lease
-> binding_state
!= FTS_BACKUP
) {
3248 #if defined (DEBUG_FIND_LEASE)
3249 log_info ("rejecting lease for requested address.");
3251 /* If we're rejecting it because the peer has
3252 it, don't set "ours", because we shouldn't NAK. */
3253 if (ours
&& ip_lease
-> binding_state
!= FTS_ACTIVE
)
3255 lease_dereference (&ip_lease
, MDL
);
3261 /* If we got an ip_lease and a uid_lease or hw_lease, and ip_lease
3262 is not active, and is not ours to reallocate, forget about it. */
3263 if (ip_lease
&& (uid_lease
|| hw_lease
) &&
3264 ip_lease
-> binding_state
!= FTS_ACTIVE
&&
3265 !lease_mine_to_reallocate (ip_lease
) &&
3266 packet
-> packet_type
== DHCPDISCOVER
) {
3267 #if defined (DEBUG_FIND_LEASE)
3268 log_info ("ip lease not ours to offer.");
3270 lease_dereference (&ip_lease
, MDL
);
3273 /* If for some reason the client has more than one lease
3274 on the subnet that matches its uid, pick the one that
3275 it asked for and (if we can) free the other. */
3277 ip_lease
-> binding_state
== FTS_ACTIVE
&&
3278 ip_lease
-> uid
&& ip_lease
!= uid_lease
) {
3279 if (have_client_identifier
&&
3280 (ip_lease
-> uid_len
== client_identifier
.len
) &&
3281 !memcmp (client_identifier
.data
,
3282 ip_lease
-> uid
, ip_lease
-> uid_len
)) {
3284 if (uid_lease
-> binding_state
== FTS_ACTIVE
) {
3285 log_error ("client %s has duplicate%s on %s",
3287 (packet
-> raw
-> htype
,
3288 packet
-> raw
-> hlen
,
3289 packet
-> raw
-> chaddr
)),
3291 (ip_lease
-> subnet
->
3292 shared_network
-> name
));
3294 /* If the client is REQUESTing the lease,
3295 it shouldn't still be using the old
3296 one, so we can free it for allocation. */
3298 uid_lease
-> binding_state
== FTS_ACTIVE
&&
3299 !packet
-> raw
-> ciaddr
.s_addr
&&
3301 uid_lease
-> subnet
-> shared_network
) &&
3302 packet
-> packet_type
== DHCPREQUEST
)
3303 dissociate_lease (uid_lease
);
3305 lease_dereference (&uid_lease
, MDL
);
3306 lease_reference (&uid_lease
, ip_lease
, MDL
);
3310 /* If we get to here and fixed_lease is not null, that means
3311 that there are both a dynamic lease and a fixed-address
3312 declaration for the same IP address. */
3313 if (packet
-> packet_type
== DHCPREQUEST
&& fixed_lease
) {
3314 lease_dereference (&fixed_lease
, MDL
);
3316 log_error ("Dynamic and static leases present for %s.",
3318 log_error ("Remove host declaration %s or remove %s",
3319 (fixed_lease
&& fixed_lease
-> host
3320 ? (fixed_lease
-> host
-> name
3321 ? fixed_lease
-> host
-> name
3325 log_error ("from the dynamic address pool for %s",
3326 ip_lease
-> subnet
-> shared_network
-> name
3329 lease_dereference (&ip_lease
, MDL
);
3330 strcpy (dhcp_message
,
3331 "database conflict - call for help!");
3334 if (ip_lease
&& ip_lease
!= uid_lease
) {
3335 #if defined (DEBUG_FIND_LEASE)
3336 log_info ("requested address not available.");
3338 lease_dereference (&ip_lease
, MDL
);
3342 /* If we get to here with both fixed_lease and ip_lease not
3343 null, then we have a configuration file bug. */
3344 if (packet
-> packet_type
== DHCPREQUEST
&& fixed_lease
&& ip_lease
)
3347 /* Toss extra pointers to the same lease... */
3348 if (hw_lease
&& hw_lease
== uid_lease
) {
3349 #if defined (DEBUG_FIND_LEASE)
3350 log_info ("hardware lease and uid lease are identical.");
3352 lease_dereference (&hw_lease
, MDL
);
3354 if (ip_lease
&& ip_lease
== hw_lease
) {
3355 lease_dereference (&hw_lease
, MDL
);
3356 #if defined (DEBUG_FIND_LEASE)
3357 log_info ("hardware lease and ip lease are identical.");
3360 if (ip_lease
&& ip_lease
== uid_lease
) {
3361 lease_dereference (&uid_lease
, MDL
);
3362 #if defined (DEBUG_FIND_LEASE)
3363 log_info ("uid lease and ip lease are identical.");
3367 /* Make sure the client is permitted to use the requested lease. */
3369 ((ip_lease
-> pool
-> prohibit_list
&&
3370 permitted (packet
, ip_lease
-> pool
-> prohibit_list
)) ||
3371 (ip_lease
-> pool
-> permit_list
&&
3372 !permitted (packet
, ip_lease
-> pool
-> permit_list
)))) {
3373 if (!packet
-> raw
-> ciaddr
.s_addr
)
3374 release_lease (ip_lease
, packet
);
3375 lease_dereference (&ip_lease
, MDL
);
3379 ((uid_lease
-> pool
-> prohibit_list
&&
3380 permitted (packet
, uid_lease
-> pool
-> prohibit_list
)) ||
3381 (uid_lease
-> pool
-> permit_list
&&
3382 !permitted (packet
, uid_lease
-> pool
-> permit_list
)))) {
3383 if (!packet
-> raw
-> ciaddr
.s_addr
)
3384 release_lease (uid_lease
, packet
);
3385 lease_dereference (&uid_lease
, MDL
);
3389 ((hw_lease
-> pool
-> prohibit_list
&&
3390 permitted (packet
, hw_lease
-> pool
-> prohibit_list
)) ||
3391 (hw_lease
-> pool
-> permit_list
&&
3392 !permitted (packet
, hw_lease
-> pool
-> permit_list
)))) {
3393 if (!packet
-> raw
-> ciaddr
.s_addr
)
3394 release_lease (hw_lease
, packet
);
3395 lease_dereference (&hw_lease
, MDL
);
3398 /* If we've already eliminated the lease, it wasn't there to
3399 begin with. If we have come up with a matching lease,
3400 set the message to bad network in case we have to throw it out. */
3402 strcpy (dhcp_message
, "requested address not available");
3405 /* If this is a DHCPREQUEST, make sure the lease we're going to return
3406 matches the requested IP address. If it doesn't, don't return a
3408 if (packet
-> packet_type
== DHCPREQUEST
&&
3409 !ip_lease
&& !fixed_lease
) {
3410 #if defined (DEBUG_FIND_LEASE)
3411 log_info ("no applicable lease found for DHCPREQUEST.");
3416 /* At this point, if fixed_lease is nonzero, we can assign it to
3419 lease_reference (&lease
, fixed_lease
, MDL
);
3420 lease_dereference (&fixed_lease
, MDL
);
3421 #if defined (DEBUG_FIND_LEASE)
3422 log_info ("choosing fixed address.");
3426 /* If we got a lease that matched the ip address and don't have
3427 a better offer, use that; otherwise, release it. */
3430 if (!packet
-> raw
-> ciaddr
.s_addr
)
3431 release_lease (ip_lease
, packet
);
3432 #if defined (DEBUG_FIND_LEASE)
3433 log_info ("not choosing requested address (!).");
3436 #if defined (DEBUG_FIND_LEASE)
3437 log_info ("choosing lease on requested address.");
3439 lease_reference (&lease
, ip_lease
, MDL
);
3441 host_dereference (&lease
-> host
, MDL
);
3443 lease_dereference (&ip_lease
, MDL
);
3446 /* If we got a lease that matched the client identifier, we may want
3447 to use it, but if we already have a lease we like, we must free
3448 the lease that matched the client identifier. */
3451 if (!packet
-> raw
-> ciaddr
.s_addr
&&
3452 packet
-> packet_type
== DHCPREQUEST
&&
3453 uid_lease
-> binding_state
== FTS_ACTIVE
)
3454 dissociate_lease (uid_lease
);
3455 #if defined (DEBUG_FIND_LEASE)
3456 log_info ("not choosing uid lease.");
3459 lease_reference (&lease
, uid_lease
, MDL
);
3461 host_dereference (&lease
-> host
, MDL
);
3462 #if defined (DEBUG_FIND_LEASE)
3463 log_info ("choosing uid lease.");
3466 lease_dereference (&uid_lease
, MDL
);
3469 /* The lease that matched the hardware address is treated likewise. */
3472 #if defined (DEBUG_FIND_LEASE)
3473 log_info ("not choosing hardware lease.");
3476 /* We're a little lax here - if the client didn't
3477 send a client identifier and it's a bootp client,
3478 but the lease has a client identifier, we still
3479 let the client have a lease. */
3480 if (!hw_lease
-> uid_len
||
3481 (have_client_identifier
3482 ? (hw_lease
-> uid_len
==
3483 client_identifier
.len
&&
3484 !memcmp (hw_lease
-> uid
,
3485 client_identifier
.data
,
3486 client_identifier
.len
))
3487 : packet
-> packet_type
== 0)) {
3488 lease_reference (&lease
, hw_lease
, MDL
);
3490 host_dereference (&lease
-> host
, MDL
);
3491 #if defined (DEBUG_FIND_LEASE)
3492 log_info ("choosing hardware lease.");
3495 #if defined (DEBUG_FIND_LEASE)
3496 log_info ("not choosing hardware lease: %s.",
3501 lease_dereference (&hw_lease
, MDL
);
3504 /* If we found a host_decl but no matching address, try to
3505 find a host_decl that has no address, and if there is one,
3506 hang it off the lease so that we can use the supplied
3508 if (lease
&& host
&& !lease
-> host
) {
3509 struct host_decl
*p
= (struct host_decl
*)0;
3510 struct host_decl
*n
= (struct host_decl
*)0;
3511 host_reference (&p
, host
, MDL
);
3513 if (!p
-> fixed_addr
) {
3514 host_reference (&lease
-> host
, p
, MDL
);
3515 host_dereference (&p
, MDL
);
3519 host_reference (&n
, p
-> n_ipaddr
, MDL
);
3520 host_dereference (&p
, MDL
);
3522 host_reference (&p
, n
, MDL
);
3523 host_dereference (&n
, MDL
);
3528 /* If we find an abandoned lease, but it's the one the client
3529 requested, we assume that previous bugginess on the part
3530 of the client, or a server database loss, caused the lease to
3531 be abandoned, so we reclaim it and let the client have it. */
3533 (lease
-> binding_state
== FTS_ABANDONED
) &&
3534 lease
== ip_lease
&&
3535 packet
-> packet_type
== DHCPREQUEST
) {
3536 log_error ("Reclaiming REQUESTed abandoned IP address %s.",
3537 piaddr (lease
-> ip_addr
));
3538 } else if (lease
&& (lease
-> binding_state
== FTS_ABANDONED
)) {
3539 /* Otherwise, if it's not the one the client requested, we do not
3540 return it - instead, we claim it's ours, causing a DHCPNAK to be
3541 sent if this lookup is for a DHCPREQUEST, and force the client
3542 to go back through the allocation process. */
3545 lease_dereference (&lease
, MDL
);
3548 if (lease
&& allocatedp
&& lease
-> ends
<= cur_time
)
3552 if (have_client_identifier
)
3553 data_string_forget (&client_identifier
, MDL
);
3556 lease_dereference (&fixed_lease
, MDL
);
3558 lease_dereference (&hw_lease
, MDL
);
3560 lease_dereference (&uid_lease
, MDL
);
3562 lease_dereference (&ip_lease
, MDL
);
3564 host_dereference (&host
, MDL
);
3567 #if defined (DEBUG_FIND_LEASE)
3568 log_info ("Returning lease: %s.",
3569 piaddr (lease
-> ip_addr
));
3571 lease_reference (lp
, lease
, file
, line
);
3572 lease_dereference (&lease
, MDL
);
3575 #if defined (DEBUG_FIND_LEASE)
3576 log_info ("Not returning a lease.");
3581 /* Search the provided host_decl structure list for an address that's on
3582 the specified shared network. If one is found, mock up and return a
3583 lease structure for it; otherwise return the null pointer. */
3585 int mockup_lease (struct lease
**lp
, struct packet
*packet
,
3586 struct shared_network
*share
, struct host_decl
*hp
)
3588 struct lease
*lease
= (struct lease
*)0;
3589 struct host_decl
*rhp
= (struct host_decl
*)0;
3591 if (lease_allocate (&lease
, MDL
) != ISC_R_SUCCESS
)
3593 if (host_reference (&rhp
, hp
, MDL
) != ISC_R_SUCCESS
) {
3594 lease_dereference (&lease
, MDL
);
3597 if (!find_host_for_network (&lease
-> subnet
,
3598 &rhp
, &lease
-> ip_addr
, share
)) {
3599 lease_dereference (&lease
, MDL
);
3600 host_dereference (&rhp
, MDL
);
3603 host_reference (&lease
-> host
, rhp
, MDL
);
3604 if (rhp
-> client_identifier
.len
> sizeof lease
-> uid_buf
)
3605 lease
-> uid
= dmalloc (rhp
-> client_identifier
.len
, MDL
);
3607 lease
-> uid
= lease
-> uid_buf
;
3608 if (!lease
-> uid
) {
3609 lease_dereference (&lease
, MDL
);
3610 host_dereference (&rhp
, MDL
);
3613 memcpy (lease
-> uid
, rhp
-> client_identifier
.data
,
3614 rhp
-> client_identifier
.len
);
3615 lease
-> uid_len
= rhp
-> client_identifier
.len
;
3616 lease
-> hardware_addr
= rhp
-> interface
;
3617 lease
-> starts
= lease
-> timestamp
= lease
-> ends
= MIN_TIME
;
3618 lease
-> flags
= STATIC_LEASE
;
3619 lease
-> binding_state
= FTS_FREE
;
3621 lease_reference (lp
, lease
, MDL
);
3623 lease_dereference (&lease
, MDL
);
3624 host_dereference (&rhp
, MDL
);
3628 /* Look through all the pools in a list starting with the specified pool
3629 for a free lease. We try to find a virgin lease if we can. If we
3630 don't find a virgin lease, we try to find a non-virgin lease that's
3631 free. If we can't find one of those, we try to reclaim an abandoned
3632 lease. If all of these possibilities fail to pan out, we don't return
3635 int allocate_lease (struct lease
**lp
, struct packet
*packet
,
3636 struct pool
*pool
, int *peer_has_leases
)
3638 struct lease
*lease
= (struct lease
*)0;
3639 struct lease
*candl
= (struct lease
*)0;
3641 for (; pool
; pool
= pool
-> next
) {
3642 if ((pool
-> prohibit_list
&&
3643 permitted (packet
, pool
-> prohibit_list
)) ||
3644 (pool
-> permit_list
&&
3645 !permitted (packet
, pool
-> permit_list
)))
3648 #if defined (FAILOVER_PROTOCOL)
3649 /* Peer_has_leases just says that we found at least one
3650 free lease. If no free lease is returned, the caller
3651 can deduce that this means the peer is hogging all the
3652 free leases, so we can print a better error message. */
3653 /* XXX Do we need code here to ignore PEER_IS_OWNER and
3654 * XXX just check tstp if we're in, e.g., PARTNER_DOWN?
3655 * XXX Where do we deal with CONFLICT_DETECTED, et al? */
3656 /* XXX This should be handled by the lease binding "state
3657 * XXX machine" - that is, when we get here, if a lease
3658 * XXX could be allocated, it will have the correct
3659 * XXX binding state so that the following code will
3660 * XXX result in its being allocated. */
3661 /* Skip to the most expired lease in the pool that is not
3662 * owned by a failover peer. */
3663 if (pool
-> failover_peer
) {
3664 if (pool
-> failover_peer
-> i_am
== primary
) {
3666 *peer_has_leases
= 1;
3667 candl
= pool
-> free
;
3669 candl
= pool
-> abandoned
;
3672 *peer_has_leases
= 1;
3673 candl
= pool
-> backup
;
3679 candl
= pool
-> free
;
3681 candl
= pool
-> abandoned
;
3684 if (!candl
|| (candl
-> ends
> cur_time
))
3692 if ((lease
-> binding_state
== FTS_ABANDONED
) &&
3693 ((candl
-> binding_state
!= FTS_ABANDONED
) ||
3694 (candl
-> ends
< lease
-> ends
))) {
3697 } else if (candl
-> binding_state
== FTS_ABANDONED
)
3700 if ((lease
-> uid_len
|| lease
-> hardware_addr
.hlen
) &&
3701 ((!candl
-> uid_len
&& !candl
-> hardware_addr
.hlen
) ||
3702 (candl
-> ends
< lease
-> ends
))) {
3705 } else if (candl
-> uid_len
|| candl
-> hardware_addr
.hlen
)
3708 if (candl
-> ends
< lease
-> ends
)
3713 if (lease
-> binding_state
== FTS_ABANDONED
)
3714 log_error ("Reclaiming abandoned lease %s.",
3715 piaddr (lease
-> ip_addr
));
3717 lease_reference (lp
, lease
, MDL
);
3724 /* Determine whether or not a permit exists on a particular permit list
3725 that matches the specified packet, returning nonzero if so, zero if
3728 int permitted (packet
, permit_list
)
3729 struct packet
*packet
;
3730 struct permit
*permit_list
;
3735 for (p
= permit_list
; p
; p
= p
-> next
) {
3736 switch (p
-> type
) {
3737 case permit_unknown_clients
:
3738 if (!packet
-> known
)
3742 case permit_known_clients
:
3743 if (packet
-> known
)
3747 case permit_authenticated_clients
:
3748 if (packet
-> authenticated
)
3752 case permit_unauthenticated_clients
:
3753 if (!packet
-> authenticated
)
3757 case permit_all_clients
:
3760 case permit_dynamic_bootp_clients
:
3761 if (!packet
-> options_valid
||
3762 !packet
-> packet_type
)
3767 for (i
= 0; i
< packet
-> class_count
; i
++) {
3768 if (p
-> class == packet
-> classes
[i
])
3770 if (packet
-> classes
[i
] &&
3771 packet
-> classes
[i
] -> superclass
&&
3772 (packet
-> classes
[i
] -> superclass
==
3782 int locate_network (packet
)
3783 struct packet
*packet
;
3786 struct data_string data
;
3787 struct subnet
*subnet
= (struct subnet
*)0;
3788 struct option_cache
*oc
;
3790 /* See if there's a subnet selection option. */
3791 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
3792 DHO_SUBNET_SELECTION
);
3794 /* If there's no SSO and no giaddr, then use the shared_network
3795 from the interface, if there is one. If not, fail. */
3796 if (!oc
&& !packet
-> raw
-> giaddr
.s_addr
) {
3797 if (packet
-> interface
-> shared_network
) {
3798 shared_network_reference
3799 (&packet
-> shared_network
,
3800 packet
-> interface
-> shared_network
, MDL
);
3806 /* If there's an SSO, and it's valid, use it to figure out the
3807 subnet. If it's not valid, fail. */
3809 memset (&data
, 0, sizeof data
);
3810 if (!evaluate_option_cache (&data
, packet
, (struct lease
*)0,
3811 (struct client_state
*)0,
3813 (struct option_state
*)0,
3814 &global_scope
, oc
, MDL
)) {
3817 if (data
.len
!= 4) {
3821 memcpy (ia
.iabuf
, data
.data
, 4);
3822 data_string_forget (&data
, MDL
);
3825 memcpy (ia
.iabuf
, &packet
-> raw
-> giaddr
, 4);
3828 /* If we know the subnet on which the IP address lives, use it. */
3829 if (find_subnet (&subnet
, ia
, MDL
)) {
3830 shared_network_reference (&packet
-> shared_network
,
3831 subnet
-> shared_network
, MDL
);
3832 subnet_dereference (&subnet
, MDL
);
3836 /* Otherwise, fail. */