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$ 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 (!allocate_lease (&lease
, packet
,
324 packet
-> shared_network
-> pools
,
327 log_error ("%s: peer holds all free leases",
330 log_error ("%s: network %s: no free leases",
332 packet
-> shared_network
-> name
);
335 #if defined (FAILOVER_PROTOCOL)
336 if (lease
-> pool
&& lease
-> pool
-> failover_peer
)
337 dhcp_failover_pool_check (lease
-> pool
);
340 alloc_lease_called
= 1;
343 #if defined (FAILOVER_PROTOCOL)
344 if (lease
&& lease
-> pool
&& lease
-> pool
-> failover_peer
) {
345 peer
= lease
-> pool
-> failover_peer
;
346 if (peer
-> service_state
== not_responding
||
347 peer
-> service_state
== service_startup
) {
348 log_info ("%s: not responding%s",
349 msgbuf
, peer
-> nrr
);
353 peer
= (dhcp_failover_state_t
*)0;
355 /* Do load balancing if configured. */
356 /* If the lease is newly allocated, and we're not the server that
357 the client would normally get with load balancing, and the
358 failover protocol state is normal, let the other server get this.
359 XXX Check protocol spec to make sure that predicating this on
360 XXX allocatedp is okay - I'm doing this so that the client won't
361 XXX be forced to switch servers (and IP addresses) just because
362 XXX of bad luck, when it's possible for it to get the address it
363 XXX is requesting. Not sure this is allowed. */
364 if (allocatedp
&& peer
&& (peer
-> service_state
== cooperating
) &&
365 !load_balance_mine (packet
, peer
)) {
366 /* peer_has_leases only has a chance to be set if we called
367 * allocate_lease() above.
369 if (!alloc_lease_called
|| peer_has_leases
) {
370 log_debug ("%s: load balance to peer %s",
371 msgbuf
, peer
-> name
);
374 log_debug ("cancel load balance to peer %s - %s",
375 peer
-> name
, "no free leases");
380 /* If it's an expired lease, get rid of any bindings. */
381 if (lease
-> ends
< cur_time
&& lease
-> scope
)
382 binding_scope_dereference (&lease
-> scope
, MDL
);
384 /* Set the lease to really expire in 2 minutes, unless it has
385 not yet expired, in which case leave its expiry time alone. */
386 when
= cur_time
+ 120;
387 if (when
< lease
-> ends
)
388 when
= lease
-> ends
;
390 ack_lease (packet
, lease
, DHCPOFFER
, when
, msgbuf
, ms_nulltp
,
391 (struct host_decl
*)0);
394 lease_dereference (&lease
, MDL
);
397 void dhcprequest (packet
, ms_nulltp
, ip_lease
)
398 struct packet
*packet
;
400 struct lease
*ip_lease
;
405 struct subnet
*subnet
;
407 struct option_cache
*oc
;
408 struct data_string data
;
410 char msgbuf
[1024]; /* XXX */
413 #if defined (FAILOVER_PROTOCOL)
414 dhcp_failover_state_t
*peer
;
416 int have_server_identifier
= 0;
417 int have_requested_addr
= 0;
419 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
420 DHO_DHCP_REQUESTED_ADDRESS
);
421 memset (&data
, 0, sizeof data
);
423 evaluate_option_cache (&data
, packet
, (struct lease
*)0,
424 (struct client_state
*)0,
425 packet
-> options
, (struct option_state
*)0,
426 &global_scope
, oc
, MDL
)) {
428 memcpy (cip
.iabuf
, data
.data
, 4);
429 data_string_forget (&data
, MDL
);
430 have_requested_addr
= 1;
432 oc
= (struct option_cache
*)0;
434 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
.s_addr
, 4);
437 /* Find the lease that matches the address requested by the
440 subnet
= (struct subnet
*)0;
441 lease
= (struct lease
*)0;
442 if (find_subnet (&subnet
, cip
, MDL
))
443 find_lease (&lease
, packet
,
444 subnet
-> shared_network
, &ours
, 0, ip_lease
, MDL
);
445 /* XXX consider using allocatedp arg to find_lease to see
446 XXX that this isn't a compliant DHCPREQUEST. */
448 if (lease
&& lease
-> client_hostname
) {
449 if ((strlen (lease
-> client_hostname
) <= 64) &&
450 db_printable (lease
-> client_hostname
))
451 s
= lease
-> client_hostname
;
453 s
= "Hostname Unsuitable for Printing";
457 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
458 DHO_DHCP_SERVER_IDENTIFIER
);
459 memset (&data
, 0, sizeof data
);
461 evaluate_option_cache (&data
, packet
, (struct lease
*)0,
462 (struct client_state
*)0,
463 packet
-> options
, (struct option_state
*)0,
464 &global_scope
, oc
, MDL
)) {
466 memcpy (sip
.iabuf
, data
.data
, 4);
467 data_string_forget (&data
, MDL
);
468 /* piaddr() should not return more than a 15 byte string.
471 sprintf (smbuf
, " (%s)", piaddr (sip
));
472 have_server_identifier
= 1;
476 /* %Audit% This is log output. %2004.06.17,Safe%
477 * If we truncate we hope the user can get a hint from the log.
479 snprintf (msgbuf
, sizeof msgbuf
,
480 "DHCPREQUEST for %s%s from %s %s%s%svia %s",
482 (packet
-> raw
-> htype
483 ? print_hw_addr (packet
-> raw
-> htype
,
484 packet
-> raw
-> hlen
,
485 packet
-> raw
-> chaddr
)
487 ? print_hex_1 (lease
-> uid_len
, lease
-> uid
,
489 : "<no identifier>")),
490 s
? "(" : "", s
? s
: "", s
? ") " : "",
491 packet
-> raw
-> giaddr
.s_addr
492 ? inet_ntoa (packet
-> raw
-> giaddr
)
493 : packet
-> interface
-> name
);
495 #if defined (FAILOVER_PROTOCOL)
496 if (lease
&& lease
-> pool
&& lease
-> pool
-> failover_peer
) {
497 peer
= lease
-> pool
-> failover_peer
;
498 if (peer
-> service_state
== not_responding
||
499 peer
-> service_state
== service_startup
) {
500 log_info ("%s: not responding%s",
501 msgbuf
, peer
-> nrr
);
505 /* "load balance to peer" - is not done at all for request.
507 * If it's RENEWING, we are the only server to hear it, so
508 * we have to serve it. If it's REBINDING, it's out of
509 * communication with the other server, so there's no point
510 * in waiting to serve it. However, if the lease we're
511 * offering is not a free lease, then we may be the only
512 * server that can offer it, so we can't load balance if
513 * the lease isn't in the free or backup state. If it is
514 * in the free or backup state, then that state is what
515 * mandates one server or the other should perform the
516 * allocation, not the LBA...we know the peer cannot
517 * allocate a request for an address in our free state.
519 * So our only compass is lease_mine_to_reallocate(). This
520 * effects both load balancing, and a sanity-check that we
521 * are not going to try to allocate a lease that isn't ours.
523 if ((lease
-> binding_state
== FTS_FREE
||
524 lease
-> binding_state
== FTS_BACKUP
) &&
525 !lease_mine_to_reallocate (lease
)) {
526 log_debug ("%s: lease owned by peer", msgbuf
);
530 /* If the lease is in a transitional state, we can't
532 if ((lease
-> binding_state
== FTS_RELEASED
||
533 lease
-> binding_state
== FTS_EXPIRED
) &&
534 !lease_mine_to_reallocate (lease
)) {
535 log_debug ("%s: lease in transition state %s", msgbuf
,
536 lease
-> binding_state
== FTS_RELEASED
537 ? "released" : "expired");
541 /* It's actually very unlikely that we'll ever get here,
542 but if we do, tell the client to stop using the lease,
543 because the administrator reset it. */
544 if (lease
-> binding_state
== FTS_RESET
&&
545 !lease_mine_to_reallocate (lease
)) {
546 log_debug ("%s: lease reset by administrator", msgbuf
);
547 nak_lease (packet
, &cip
);
551 /* At this point it's possible that we will get a broadcast
552 DHCPREQUEST for a lease that we didn't offer, because
553 both we and the peer are in a position to offer it.
554 In that case, we probably shouldn't answer. In order
555 to not answer, we would have to compare the server
556 identifier sent by the client with the list of possible
557 server identifiers we can send, and if the client's
558 identifier isn't on the list, drop the DHCPREQUEST.
559 We aren't currently doing that for two reasons - first,
560 it's not clear that all clients do the right thing
561 with respect to sending the client identifier, which
562 could mean that we might simply not respond to a client
563 that is depending on us to respond. Secondly, we allow
564 the user to specify the server identifier to send, and
565 we don't enforce that the server identifier should be
566 one of our IP addresses. This is probably not a big
567 deal, but it's theoretically an issue.
569 The reason we care about this is that if both servers
570 send a DHCPACK to the DHCPREQUEST, they are then going
571 to send dueling BNDUPD messages, which could cause
572 trouble. I think it causes no harm, but it seems
575 peer
= (dhcp_failover_state_t
*)0;
578 /* If a client on a given network REQUESTs a lease on an
579 address on a different network, NAK it. If the Requested
580 Address option was used, the protocol says that it must
581 have been broadcast, so we can trust the source network
584 If ciaddr was specified and Requested Address was not, then
585 we really only know for sure what network a packet came from
586 if it came through a BOOTP gateway - if it came through an
587 IP router, we'll just have to assume that it's cool.
589 If we don't think we know where the packet came from, it
590 came through a gateway from an unknown network, so it's not
591 from a RENEWING client. If we recognize the network it
592 *thinks* it's on, we can NAK it even though we don't
593 recognize the network it's *actually* on; otherwise we just
596 We don't currently try to take advantage of access to the
597 raw packet, because it's not available on all platforms.
598 So a packet that was unicast to us through a router from a
599 RENEWING client is going to look exactly like a packet that
600 was broadcast to us from an INIT-REBOOT client.
602 Since we can't tell the difference between these two kinds
603 of packets, if the packet appears to have come in off the
604 local wire, we have to treat it as if it's a RENEWING
605 client. This means that we can't NAK a RENEWING client on
606 the local wire that has a bogus address. The good news is
607 that we won't ACK it either, so it should revert to INIT
608 state and send us a DHCPDISCOVER, which we *can* work with.
610 Because we can't detect that a RENEWING client is on the
611 wrong wire, it's going to sit there trying to renew until
612 it gets to the REBIND state, when we *can* NAK it because
613 the packet will get to us through a BOOTP gateway. We
614 shouldn't actually see DHCPREQUEST packets from RENEWING
615 clients on the wrong wire anyway, since their idea of their
616 local router will be wrong. In any case, the protocol
617 doesn't really allow us to NAK a DHCPREQUEST from a
618 RENEWING client, so we can punt on this issue. */
620 if (!packet
-> shared_network
||
621 (packet
-> raw
-> ciaddr
.s_addr
&&
622 packet
-> raw
-> giaddr
.s_addr
) ||
623 (have_requested_addr
&& !packet
-> raw
-> ciaddr
.s_addr
)) {
625 /* If we don't know where it came from but we do know
626 where it claims to have come from, it didn't come
628 if (!packet
-> shared_network
) {
629 if (subnet
&& subnet
-> group
-> authoritative
) {
630 log_info ("%s: wrong network.", msgbuf
);
631 nak_lease (packet
, &cip
);
634 /* Otherwise, ignore it. */
635 log_info ("%s: ignored (%s).", msgbuf
,
637 ? "not authoritative" : "unknown subnet"));
641 /* If we do know where it came from and it asked for an
642 address that is not on that shared network, nak it. */
644 subnet_dereference (&subnet
, MDL
);
645 if (!find_grouped_subnet (&subnet
, packet
-> shared_network
,
647 if (packet
-> shared_network
-> group
-> authoritative
)
649 log_info ("%s: wrong network.", msgbuf
);
650 nak_lease (packet
, &cip
);
653 log_info ("%s: ignored (not authoritative).", msgbuf
);
658 /* If the address the client asked for is ours, but it wasn't
659 available for the client, NAK it. */
660 if (!lease
&& ours
) {
661 log_info ("%s: lease %s unavailable.", msgbuf
, piaddr (cip
));
662 nak_lease (packet
, &cip
);
666 /* Otherwise, send the lease to the client if we found one. */
668 ack_lease (packet
, lease
, DHCPACK
, 0, msgbuf
, ms_nulltp
,
669 (struct host_decl
*)0);
671 log_info ("%s: unknown lease %s.", msgbuf
, piaddr (cip
));
675 subnet_dereference (&subnet
, MDL
);
677 lease_dereference (&lease
, MDL
);
681 void dhcprelease (packet
, ms_nulltp
)
682 struct packet
*packet
;
685 struct lease
*lease
= (struct lease
*)0, *next
= (struct lease
*)0;
687 struct option_cache
*oc
;
688 struct data_string data
;
690 char msgbuf
[1024], cstr
[16]; /* XXX */
693 /* DHCPRELEASE must not specify address in requested-address
694 option, but old protocol specs weren't explicit about this,
696 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
697 DHO_DHCP_REQUESTED_ADDRESS
))) {
698 log_info ("DHCPRELEASE from %s specified requested-address.",
699 print_hw_addr (packet
-> raw
-> htype
,
700 packet
-> raw
-> hlen
,
701 packet
-> raw
-> chaddr
));
704 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
705 DHO_DHCP_CLIENT_IDENTIFIER
);
706 memset (&data
, 0, sizeof data
);
708 evaluate_option_cache (&data
, packet
, (struct lease
*)0,
709 (struct client_state
*)0,
710 packet
-> options
, (struct option_state
*)0,
711 &global_scope
, oc
, MDL
)) {
712 find_lease_by_uid (&lease
, data
.data
, data
.len
, MDL
);
713 data_string_forget (&data
, MDL
);
715 /* See if we can find a lease that matches the IP address
716 the client is claiming. */
719 lease_reference (&next
, lease
-> n_uid
, MDL
);
720 if (!memcmp (&packet
-> raw
-> ciaddr
,
721 lease
-> ip_addr
.iabuf
, 4)) {
724 lease_dereference (&lease
, MDL
);
726 lease_reference (&lease
, next
, MDL
);
727 lease_dereference (&next
, MDL
);
731 lease_dereference (&next
, MDL
);
734 /* The client is supposed to pass a valid client-identifier,
735 but the spec on this has changed historically, so try the
736 IP address in ciaddr if the client-identifier fails. */
739 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
, 4);
740 find_lease_by_ip_addr (&lease
, cip
, MDL
);
744 /* If the hardware address doesn't match, don't do the release. */
746 (lease
-> hardware_addr
.hlen
!= packet
-> raw
-> hlen
+ 1 ||
747 lease
-> hardware_addr
.hbuf
[0] != packet
-> raw
-> htype
||
748 memcmp (&lease
-> hardware_addr
.hbuf
[1],
749 packet
-> raw
-> chaddr
, packet
-> raw
-> hlen
)))
750 lease_dereference (&lease
, MDL
);
752 if (lease
&& lease
-> client_hostname
) {
753 if ((strlen (lease
-> client_hostname
) <= 64) &&
754 db_printable (lease
-> client_hostname
))
755 s
= lease
-> client_hostname
;
757 s
= "Hostname Unsuitable for Printing";
761 /* %Audit% Cannot exceed 16 bytes. %2004.06.17,Safe%
762 * We copy this out to stack because we actually want to log two
763 * inet_ntoa()'s in this message.
765 strncpy(cstr
, inet_ntoa (packet
-> raw
-> ciaddr
), 15);
768 /* %Audit% This is log output. %2004.06.17,Safe%
769 * If we truncate we hope the user can get a hint from the log.
771 snprintf (msgbuf
, sizeof msgbuf
,
772 "DHCPRELEASE of %s from %s %s%s%svia %s (%sfound)",
774 (packet
-> raw
-> htype
775 ? print_hw_addr (packet
-> raw
-> htype
,
776 packet
-> raw
-> hlen
,
777 packet
-> raw
-> chaddr
)
779 ? print_hex_1 (lease
-> uid_len
, lease
-> uid
,
781 : "<no identifier>")),
782 s
? "(" : "", s
? s
: "", s
? ") " : "",
783 packet
-> raw
-> giaddr
.s_addr
784 ? inet_ntoa (packet
-> raw
-> giaddr
)
785 : packet
-> interface
-> name
,
786 lease
? "" : "not ");
788 #if defined (FAILOVER_PROTOCOL)
789 if (lease
&& lease
-> pool
&& lease
-> pool
-> failover_peer
) {
790 dhcp_failover_state_t
*peer
= lease
-> pool
-> failover_peer
;
791 if (peer
-> service_state
== not_responding
||
792 peer
-> service_state
== service_startup
) {
793 log_info ("%s: ignored%s",
794 peer
-> name
, peer
-> nrr
);
798 /* DHCPRELEASE messages are unicast, so if the client
799 sent the DHCPRELEASE to us, it's not going to send it
800 to the peer. Not sure why this would happen, and
801 if it does happen I think we still have to change the
802 lease state, so that's what we're doing.
803 XXX See what it says in the draft about this. */
807 /* If we found a lease, release it. */
808 if (lease
&& lease
-> ends
> cur_time
) {
809 release_lease (lease
, packet
);
811 log_info ("%s", msgbuf
);
814 lease_dereference (&lease
, MDL
);
817 void dhcpdecline (packet
, ms_nulltp
)
818 struct packet
*packet
;
821 struct lease
*lease
= (struct lease
*)0;
822 struct option_state
*options
= (struct option_state
*)0;
827 char msgbuf
[1024]; /* XXX */
829 struct option_cache
*oc
;
830 struct data_string data
;
832 /* DHCPDECLINE must specify address. */
833 if (!(oc
= lookup_option (&dhcp_universe
, packet
-> options
,
834 DHO_DHCP_REQUESTED_ADDRESS
)))
836 memset (&data
, 0, sizeof data
);
837 if (!evaluate_option_cache (&data
, packet
, (struct lease
*)0,
838 (struct client_state
*)0,
840 (struct option_state
*)0,
841 &global_scope
, oc
, MDL
))
845 memcpy (cip
.iabuf
, data
.data
, 4);
846 data_string_forget (&data
, MDL
);
847 find_lease_by_ip_addr (&lease
, cip
, MDL
);
849 if (lease
&& lease
-> client_hostname
) {
850 if ((strlen (lease
-> client_hostname
) <= 64) &&
851 db_printable (lease
-> client_hostname
))
852 s
= lease
-> client_hostname
;
854 s
= "Hostname Unsuitable for Printing";
858 /* %Audit% This is log output. %2004.06.17,Safe%
859 * If we truncate we hope the user can get a hint from the log.
861 snprintf (msgbuf
, sizeof msgbuf
,
862 "DHCPDECLINE of %s from %s %s%s%svia %s",
864 (packet
-> raw
-> htype
865 ? print_hw_addr (packet
-> raw
-> htype
,
866 packet
-> raw
-> hlen
,
867 packet
-> raw
-> chaddr
)
869 ? print_hex_1 (lease
-> uid_len
, lease
-> uid
,
871 : "<no identifier>")),
872 s
? "(" : "", s
? s
: "", s
? ") " : "",
873 packet
-> raw
-> giaddr
.s_addr
874 ? inet_ntoa (packet
-> raw
-> giaddr
)
875 : packet
-> interface
-> name
);
877 option_state_allocate (&options
, MDL
);
879 /* Execute statements in scope starting with the subnet scope. */
881 execute_statements_in_scope ((struct binding_value
**)0,
882 packet
, (struct lease
*)0,
883 (struct client_state
*)0,
884 packet
-> options
, options
,
886 lease
-> subnet
-> group
,
889 /* Execute statements in the class scopes. */
890 for (i
= packet
-> class_count
; i
> 0; i
--) {
891 execute_statements_in_scope
892 ((struct binding_value
**)0, packet
, (struct lease
*)0,
893 (struct client_state
*)0, packet
-> options
, options
,
894 &global_scope
, packet
-> classes
[i
- 1] -> group
,
895 lease
? lease
-> subnet
-> group
: (struct group
*)0);
898 /* Drop the request if dhcpdeclines are being ignored. */
899 oc
= lookup_option (&server_universe
, options
, SV_DECLINES
);
901 evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
902 (struct client_state
*)0,
903 packet
-> options
, options
,
904 &lease
-> scope
, oc
, MDL
)) {
905 /* If we found a lease, mark it as unusable and complain. */
907 #if defined (FAILOVER_PROTOCOL)
908 if (lease
-> pool
&& lease
-> pool
-> failover_peer
) {
909 dhcp_failover_state_t
*peer
=
910 lease
-> pool
-> failover_peer
;
911 if (peer
-> service_state
== not_responding
||
912 peer
-> service_state
== service_startup
) {
914 log_info ("%s: ignored%s",
915 peer
-> name
, peer
-> nrr
);
919 /* DHCPDECLINE messages are broadcast, so we can safely
920 ignore the DHCPDECLINE if the peer has the lease.
921 XXX Of course, at this point that information has been
926 abandon_lease (lease
, "declined.");
927 status
= "abandoned";
929 status
= "not found";
934 log_info ("%s: %s", msgbuf
, status
);
938 option_state_dereference (&options
, MDL
);
940 lease_dereference (&lease
, MDL
);
943 void dhcpinform (packet
, ms_nulltp
)
944 struct packet
*packet
;
948 struct data_string d1
, prl
;
949 struct option_cache
*oc
;
950 struct expression
*expr
;
951 struct option_state
*options
= (struct option_state
*)0;
952 struct dhcp_packet raw
;
953 struct packet outgoing
;
954 unsigned char dhcpack
= DHCPACK
;
955 struct subnet
*subnet
= (struct subnet
*)0;
959 struct sockaddr_in to
;
962 /* The client should set ciaddr to its IP address, but apparently
963 it's common for clients not to do this, so we'll use their IP
964 source address if they didn't set ciaddr. */
965 if (!packet
-> raw
-> ciaddr
.s_addr
) {
967 memcpy (cip
.iabuf
, &packet
-> client_addr
.iabuf
, 4);
970 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
, 4);
973 /* %Audit% This is log output. %2004.06.17,Safe%
974 * If we truncate we hope the user can get a hint from the log.
976 snprintf (msgbuf
, sizeof msgbuf
, "DHCPINFORM from %s via %s",
977 piaddr (cip
), packet
-> interface
-> name
);
979 /* If the IP source address is zero, don't respond. */
980 if (!memcmp (cip
.iabuf
, "\0\0\0", 4)) {
981 log_info ("%s: ignored (null source address).", msgbuf
);
985 /* Find the subnet that the client is on. */
986 oc
= (struct option_cache
*)0;
987 find_subnet (&subnet
, cip
, MDL
);
989 /* Sourceless packets don't make sense here. */
991 log_info ("%s: unknown subnet %s",
992 msgbuf
, inet_ntoa (packet
-> raw
-> giaddr
));
996 /* We don't respond to DHCPINFORM packets if we're not authoritative.
997 It would be nice if a per-host value could override this, but
998 there's overhead involved in checking this, so let's see how people
1000 if (subnet
&& !subnet
-> group
-> authoritative
) {
1002 log_info ("%s: not authoritative for subnet %s",
1003 msgbuf
, piaddr (subnet
-> net
));
1005 log_info ("If this DHCP server is authoritative for%s",
1007 log_info ("please write an `authoritative;' directi%s",
1008 "ve either in the");
1009 log_info ("subnet declaration or in some scope that%s",
1011 log_info ("subnet declaration - for example, write %s",
1013 log_info ("of the dhcpd.conf file.");
1017 subnet_dereference (&subnet
, MDL
);
1021 memset (&d1
, 0, sizeof d1
);
1022 option_state_allocate (&options
, MDL
);
1023 memset (&outgoing
, 0, sizeof outgoing
);
1024 memset (&raw
, 0, sizeof raw
);
1025 outgoing
.raw
= &raw
;
1027 /* Execute statements in scope starting with the subnet scope. */
1029 execute_statements_in_scope ((struct binding_value
**)0,
1030 packet
, (struct lease
*)0,
1031 (struct client_state
*)0,
1032 packet
-> options
, options
,
1033 &global_scope
, subnet
-> group
,
1036 /* Execute statements in the class scopes. */
1037 for (i
= packet
-> class_count
; i
> 0; i
--) {
1038 execute_statements_in_scope
1039 ((struct binding_value
**)0, packet
, (struct lease
*)0,
1040 (struct client_state
*)0, packet
-> options
, options
,
1041 &global_scope
, packet
-> classes
[i
- 1] -> group
,
1042 subnet
? subnet
-> group
: (struct group
*)0);
1045 /* Figure out the filename. */
1046 memset (&d1
, 0, sizeof d1
);
1047 oc
= lookup_option (&server_universe
, options
, SV_FILENAME
);
1049 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1050 (struct client_state
*)0,
1051 packet
-> options
, (struct option_state
*)0,
1052 &global_scope
, oc
, MDL
)) {
1054 if (i
> sizeof raw
.file
)
1055 i
= sizeof raw
.file
;
1058 memcpy (raw
.file
, d1
.data
, i
);
1059 data_string_forget (&d1
, MDL
);
1062 /* Choose a server name as above. */
1063 oc
= lookup_option (&server_universe
, options
, SV_SERVER_NAME
);
1065 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1066 (struct client_state
*)0,
1067 packet
-> options
, (struct option_state
*)0,
1068 &global_scope
, oc
, MDL
)) {
1070 if (i
> sizeof raw
.sname
)
1071 i
= sizeof raw
.sname
;
1074 memcpy (raw
.sname
, d1
.data
, i
);
1075 data_string_forget (&d1
, MDL
);
1078 /* Set a flag if this client is a lame Microsoft client that NUL
1079 terminates string options and expects us to do likewise. */
1081 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
1083 if (evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1084 (struct client_state
*)0,
1085 packet
-> options
, options
,
1086 &global_scope
, oc
, MDL
)) {
1087 if (d1
.data
[d1
.len
- 1] == '\0')
1089 data_string_forget (&d1
, MDL
);
1093 /* Put in DHCP-specific options. */
1094 i
= DHO_DHCP_MESSAGE_TYPE
;
1095 oc
= (struct option_cache
*)0;
1096 if (option_cache_allocate (&oc
, MDL
)) {
1097 if (make_const_data (&oc
-> expression
,
1098 &dhcpack
, 1, 0, 0, MDL
)) {
1099 oc
-> option
= dhcp_universe
.options
[i
];
1100 save_option (&dhcp_universe
, options
, oc
);
1102 option_cache_dereference (&oc
, MDL
);
1105 i
= DHO_DHCP_SERVER_IDENTIFIER
;
1106 if (!(oc
= lookup_option (&dhcp_universe
, options
, i
))) {
1108 oc
= (struct option_cache
*)0;
1109 if (option_cache_allocate (&oc
, MDL
)) {
1113 &packet
-> interface
-> primary_address
),
1114 sizeof packet
-> interface
-> primary_address
,
1117 dhcp_universe
.options
[i
];
1118 save_option (&dhcp_universe
,
1121 option_cache_dereference (&oc
, MDL
);
1123 from
= packet
-> interface
-> primary_address
;
1125 if (evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1126 (struct client_state
*)0,
1127 packet
-> options
, options
,
1128 &global_scope
, oc
, MDL
)) {
1129 if (!d1
.len
|| d1
.len
!= sizeof from
) {
1130 data_string_forget (&d1
, MDL
);
1133 memcpy (&from
, d1
.data
, sizeof from
);
1134 data_string_forget (&d1
, MDL
);
1139 /* Use the subnet mask from the subnet declaration if no other
1140 mask has been provided. */
1141 i
= DHO_SUBNET_MASK
;
1142 if (subnet
&& !lookup_option (&dhcp_universe
, options
, i
)) {
1143 oc
= (struct option_cache
*)0;
1144 if (option_cache_allocate (&oc
, MDL
)) {
1145 if (make_const_data (&oc
-> expression
,
1146 subnet
-> netmask
.iabuf
,
1147 subnet
-> netmask
.len
,
1149 oc
-> option
= dhcp_universe
.options
[i
];
1150 save_option (&dhcp_universe
, options
, oc
);
1152 option_cache_dereference (&oc
, MDL
);
1156 /* If a site option space has been specified, use that for
1157 site option codes. */
1158 i
= SV_SITE_OPTION_SPACE
;
1159 if ((oc
= lookup_option (&server_universe
, options
, i
)) &&
1160 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1161 (struct client_state
*)0,
1162 packet
-> options
, options
,
1163 &global_scope
, oc
, MDL
)) {
1164 struct universe
*u
= (struct universe
*)0;
1166 if (!universe_hash_lookup (&u
, universe_hash
,
1167 (const char *)d1
.data
, d1
.len
,
1169 log_error ("unknown option space %s.", d1
.data
);
1170 option_state_dereference (&options
, MDL
);
1172 subnet_dereference (&subnet
, MDL
);
1176 options
-> site_universe
= u
-> index
;
1177 options
-> site_code_min
= 128; /* XXX */
1178 data_string_forget (&d1
, MDL
);
1180 options
-> site_universe
= dhcp_universe
.index
;
1181 options
-> site_code_min
= 0; /* Trust me, it works. */
1184 memset (&prl
, 0, sizeof prl
);
1186 /* Use the parameter list from the scope if there is one. */
1187 oc
= lookup_option (&dhcp_universe
, options
,
1188 DHO_DHCP_PARAMETER_REQUEST_LIST
);
1190 /* Otherwise, if the client has provided a list of options
1191 that it wishes returned, use it to prioritize. Otherwise,
1192 prioritize based on the default priority list. */
1195 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
1196 DHO_DHCP_PARAMETER_REQUEST_LIST
);
1199 evaluate_option_cache (&prl
, packet
, (struct lease
*)0,
1200 (struct client_state
*)0,
1201 packet
-> options
, options
,
1202 &global_scope
, oc
, MDL
);
1205 dump_packet (packet
);
1206 dump_raw ((unsigned char *)packet
-> raw
, packet
-> packet_length
);
1209 log_info ("%s", msgbuf
);
1211 /* Figure out the address of the boot file server. */
1213 lookup_option (&server_universe
, options
, SV_NEXT_SERVER
))) {
1214 if (evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
1215 (struct client_state
*)0,
1216 packet
-> options
, options
,
1217 &global_scope
, oc
, MDL
)) {
1218 /* If there was more than one answer,
1220 if (d1
.len
>= 4 && d1
.data
)
1221 memcpy (&raw
.siaddr
, d1
.data
, 4);
1222 data_string_forget (&d1
, MDL
);
1226 /* Set up the option buffer... */
1227 outgoing
.packet_length
=
1228 cons_options (packet
, outgoing
.raw
, (struct lease
*)0,
1229 (struct client_state
*)0,
1230 0, packet
-> options
, options
, &global_scope
,
1232 prl
.len
? &prl
: (struct data_string
*)0,
1234 option_state_dereference (&options
, MDL
);
1235 data_string_forget (&prl
, MDL
);
1237 /* Make sure that the packet is at least as big as a BOOTP packet. */
1238 if (outgoing
.packet_length
< BOOTP_MIN_LEN
)
1239 outgoing
.packet_length
= BOOTP_MIN_LEN
;
1241 raw
.giaddr
= packet
-> raw
-> giaddr
;
1242 raw
.ciaddr
= packet
-> raw
-> ciaddr
;
1243 memcpy (raw
.chaddr
, packet
-> raw
-> chaddr
, sizeof raw
.chaddr
);
1244 raw
.hlen
= packet
-> raw
-> hlen
;
1245 raw
.htype
= packet
-> raw
-> htype
;
1247 raw
.xid
= packet
-> raw
-> xid
;
1248 raw
.secs
= packet
-> raw
-> secs
;
1249 raw
.flags
= packet
-> raw
-> flags
;
1250 raw
.hops
= packet
-> raw
-> hops
;
1253 /* Report what we're sending... */
1254 log_info ("DHCPACK to %s", inet_ntoa (raw
.ciaddr
));
1257 dump_packet (&outgoing
);
1258 dump_raw ((unsigned char *)&raw
, outgoing
.packet_length
);
1261 /* Set up the common stuff... */
1262 to
.sin_family
= AF_INET
;
1264 to
.sin_len
= sizeof to
;
1266 memset (to
.sin_zero
, 0, sizeof to
.sin_zero
);
1268 /* Use the IP address we derived for the client. */
1269 memcpy (&to
.sin_addr
, cip
.iabuf
, 4);
1270 to
.sin_port
= remote_port
;
1273 send_packet ((fallback_interface
1274 ? fallback_interface
: packet
-> interface
),
1275 &outgoing
, &raw
, outgoing
.packet_length
,
1276 from
, &to
, (struct hardware
*)0);
1278 subnet_dereference (&subnet
, MDL
);
1281 void nak_lease (packet
, cip
)
1282 struct packet
*packet
;
1285 struct sockaddr_in to
;
1286 struct in_addr from
;
1288 struct dhcp_packet raw
;
1289 unsigned char nak
= DHCPNAK
;
1290 struct packet outgoing
;
1291 struct hardware hto
;
1293 struct data_string data
;
1294 struct option_state
*options
= (struct option_state
*)0;
1295 struct expression
*expr
;
1296 struct option_cache
*oc
= (struct option_cache
*)0;
1297 struct iaddr myfrom
;
1299 option_state_allocate (&options
, MDL
);
1300 memset (&outgoing
, 0, sizeof outgoing
);
1301 memset (&raw
, 0, sizeof raw
);
1302 outgoing
.raw
= &raw
;
1304 /* Set DHCP_MESSAGE_TYPE to DHCPNAK */
1305 if (!option_cache_allocate (&oc
, MDL
)) {
1306 log_error ("No memory for DHCPNAK message type.");
1307 option_state_dereference (&options
, MDL
);
1310 if (!make_const_data (&oc
-> expression
, &nak
, sizeof nak
,
1312 log_error ("No memory for expr_const expression.");
1313 option_cache_dereference (&oc
, MDL
);
1314 option_state_dereference (&options
, MDL
);
1317 oc
-> option
= dhcp_universe
.options
[DHO_DHCP_MESSAGE_TYPE
];
1318 save_option (&dhcp_universe
, options
, oc
);
1319 option_cache_dereference (&oc
, MDL
);
1321 /* Set DHCP_MESSAGE to whatever the message is */
1322 if (!option_cache_allocate (&oc
, MDL
)) {
1323 log_error ("No memory for DHCPNAK message type.");
1324 option_state_dereference (&options
, MDL
);
1327 if (!make_const_data (&oc
-> expression
,
1328 (unsigned char *)dhcp_message
,
1329 strlen (dhcp_message
), 1, 0, MDL
)) {
1330 log_error ("No memory for expr_const expression.");
1331 option_cache_dereference (&oc
, MDL
);
1332 option_state_dereference (&options
, MDL
);
1335 oc
-> option
= dhcp_universe
.options
[DHO_DHCP_MESSAGE
];
1336 save_option (&dhcp_universe
, options
, oc
);
1337 option_cache_dereference (&oc
, MDL
);
1339 i
= DHO_DHCP_SERVER_IDENTIFIER
;
1340 if (!(oc
= lookup_option (&dhcp_universe
, options
, i
))) {
1342 oc
= (struct option_cache
*)0;
1343 if (option_cache_allocate (&oc
, MDL
)) {
1347 &packet
-> interface
-> primary_address
),
1348 sizeof packet
-> interface
-> primary_address
,
1351 dhcp_universe
.options
[i
];
1352 save_option (&dhcp_universe
, options
, oc
);
1354 option_cache_dereference (&oc
, MDL
);
1356 myfrom
.len
= sizeof packet
-> interface
-> primary_address
;
1357 memcpy (myfrom
.iabuf
,
1358 &packet
-> interface
-> primary_address
, myfrom
.len
);
1360 memset (&data
, 0, sizeof data
);
1361 if (evaluate_option_cache (&data
, packet
, (struct lease
*)0,
1362 (struct client_state
*)0,
1363 packet
-> options
, options
,
1364 &global_scope
, oc
, MDL
)) {
1366 data
.len
> sizeof myfrom
.iabuf
) {
1367 data_string_forget (&data
, MDL
);
1370 memcpy (myfrom
.iabuf
, data
.data
, data
.len
);
1371 myfrom
.len
= data
.len
;
1372 data_string_forget (&data
, MDL
);
1377 /* If there were agent options in the incoming packet, return
1379 if (packet
-> raw
-> giaddr
.s_addr
&&
1380 packet
-> options
-> universe_count
> agent_universe
.index
&&
1381 packet
-> options
-> universes
[agent_universe
.index
]) {
1382 option_chain_head_reference
1383 ((struct option_chain_head
**)
1384 &(options
-> universes
[agent_universe
.index
]),
1385 (struct option_chain_head
*)
1386 packet
-> options
-> universes
[agent_universe
.index
],
1390 /* Do not use the client's requested parameter list. */
1391 delete_option (&dhcp_universe
, packet
-> options
,
1392 DHO_DHCP_PARAMETER_REQUEST_LIST
);
1394 /* Set up the option buffer... */
1395 outgoing
.packet_length
=
1396 cons_options (packet
, outgoing
.raw
, (struct lease
*)0,
1397 (struct client_state
*)0,
1398 0, packet
-> options
, options
, &global_scope
,
1399 0, 0, 0, (struct data_string
*)0, (char *)0);
1400 option_state_dereference (&options
, MDL
);
1402 /* memset (&raw.ciaddr, 0, sizeof raw.ciaddr);*/
1403 raw
.siaddr
= packet
-> interface
-> primary_address
;
1404 raw
.giaddr
= packet
-> raw
-> giaddr
;
1405 memcpy (raw
.chaddr
, packet
-> raw
-> chaddr
, sizeof raw
.chaddr
);
1406 raw
.hlen
= packet
-> raw
-> hlen
;
1407 raw
.htype
= packet
-> raw
-> htype
;
1409 raw
.xid
= packet
-> raw
-> xid
;
1410 raw
.secs
= packet
-> raw
-> secs
;
1411 raw
.flags
= packet
-> raw
-> flags
| htons (BOOTP_BROADCAST
);
1412 raw
.hops
= packet
-> raw
-> hops
;
1415 /* Report what we're sending... */
1416 log_info ("DHCPNAK on %s to %s via %s",
1418 print_hw_addr (packet
-> raw
-> htype
,
1419 packet
-> raw
-> hlen
,
1420 packet
-> raw
-> chaddr
),
1421 packet
-> raw
-> giaddr
.s_addr
1422 ? inet_ntoa (packet
-> raw
-> giaddr
)
1423 : packet
-> interface
-> name
);
1428 dump_packet (packet
);
1429 dump_raw ((unsigned char *)packet
-> raw
, packet
-> packet_length
);
1430 dump_packet (&outgoing
);
1431 dump_raw ((unsigned char *)&raw
, outgoing
.packet_length
);
1435 hto
.hbuf
[0] = packet
-> raw
-> htype
;
1436 hto
.hlen
= packet
-> raw
-> hlen
;
1437 memcpy (&hto
.hbuf
[1], packet
-> raw
-> chaddr
, hto
.hlen
);
1441 /* Set up the common stuff... */
1442 to
.sin_family
= AF_INET
;
1444 to
.sin_len
= sizeof to
;
1446 memset (to
.sin_zero
, 0, sizeof to
.sin_zero
);
1448 memcpy (&from
, myfrom
.iabuf
, sizeof from
);
1450 /* Make sure that the packet is at least as big as a BOOTP packet. */
1451 if (outgoing
.packet_length
< BOOTP_MIN_LEN
)
1452 outgoing
.packet_length
= BOOTP_MIN_LEN
;
1454 /* If this was gatewayed, send it back to the gateway.
1455 Otherwise, broadcast it on the local network. */
1456 if (raw
.giaddr
.s_addr
) {
1457 to
.sin_addr
= raw
.giaddr
;
1458 if (raw
.giaddr
.s_addr
!= htonl (INADDR_LOOPBACK
))
1459 to
.sin_port
= local_port
;
1461 to
.sin_port
= remote_port
; /* for testing. */
1463 if (fallback_interface
) {
1464 result
= send_packet (fallback_interface
,
1466 outgoing
.packet_length
,
1471 to
.sin_addr
= limited_broadcast
;
1472 to
.sin_port
= remote_port
;
1476 result
= send_packet (packet
-> interface
,
1477 packet
, &raw
, outgoing
.packet_length
,
1478 from
, &to
, (struct hardware
*)0);
1481 void ack_lease (packet
, lease
, offer
, when
, msg
, ms_nulltp
, hp
)
1482 struct packet
*packet
;
1483 struct lease
*lease
;
1488 struct host_decl
*hp
;
1491 struct lease_state
*state
;
1493 struct host_decl
*host
= (struct host_decl
*)0;
1495 TIME offered_lease_time
;
1496 struct data_string d1
;
1497 TIME min_lease_time
;
1498 TIME max_lease_time
;
1499 TIME default_lease_time
;
1500 struct option_cache
*oc
;
1501 struct expression
*expr
;
1503 isc_result_t result
;
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
);
1766 find_hosts_by_haddr (&hp
,
1767 packet
-> raw
-> htype
,
1768 packet
-> raw
-> chaddr
,
1769 packet
-> raw
-> hlen
,
1771 for (h
= hp
; h
; h
= h
-> n_ipaddr
) {
1772 if (!h
-> fixed_addr
)
1776 host_reference (&host
, h
, MDL
);
1779 host_dereference (&hp
, MDL
);
1782 /* If we have a host_decl structure, run the options associated
1783 with its group. Wether the host decl struct is old or not. */
1785 execute_statements_in_scope ((struct binding_value
**)0,
1787 (struct client_state
*)0,
1789 state
-> options
, &lease
-> scope
,
1792 ? lease
-> pool
-> group
1793 : lease
-> subnet
-> group
));
1795 /* Drop the request if it's not allowed for this client. By
1796 default, unknown clients are allowed. */
1798 (oc
= lookup_option (&server_universe
, state
-> options
,
1799 SV_BOOT_UNKNOWN_CLIENTS
)) &&
1800 !evaluate_boolean_option_cache (&ignorep
,
1802 (struct client_state
*)0,
1805 &lease
-> scope
, oc
, MDL
)) {
1807 log_info ("%s: unknown client", msg
);
1808 free_lease_state (state
, MDL
);
1810 host_dereference (&host
, MDL
);
1814 /* Drop the request if it's not allowed for this client. */
1816 (oc
= lookup_option (&server_universe
, state
-> options
,
1818 !evaluate_boolean_option_cache (&ignorep
,
1820 (struct client_state
*)0,
1823 &lease
-> scope
, oc
, MDL
)) {
1825 log_info ("%s: bootp disallowed", msg
);
1826 free_lease_state (state
, MDL
);
1828 host_dereference (&host
, MDL
);
1832 /* Drop the request if booting is specifically denied. */
1833 oc
= lookup_option (&server_universe
, state
-> options
,
1836 !evaluate_boolean_option_cache (&ignorep
,
1838 (struct client_state
*)0,
1841 &lease
-> scope
, oc
, MDL
)) {
1843 log_info ("%s: booting disallowed", msg
);
1844 free_lease_state (state
, MDL
);
1846 host_dereference (&host
, MDL
);
1850 /* If we are configured to do per-class billing, do it. */
1851 if (have_billing_classes
&& !(lease
-> flags
& STATIC_LEASE
)) {
1852 /* See if the lease is currently being billed to a
1853 class, and if so, whether or not it can continue to
1854 be billed to that class. */
1855 if (lease
-> billing_class
) {
1856 for (i
= 0; i
< packet
-> class_count
; i
++)
1857 if (packet
-> classes
[i
] ==
1858 lease
-> billing_class
)
1860 if (i
== packet
-> class_count
)
1861 unbill_class (lease
, lease
-> billing_class
);
1864 /* If we don't have an active billing, see if we need
1865 one, and if we do, try to do so. */
1866 if (!lease
-> billing_class
) {
1867 for (i
= 0; i
< packet
-> class_count
; i
++) {
1868 if (packet
-> classes
[i
] -> lease_limit
)
1871 if (i
!= packet
-> class_count
) {
1872 for (i
= 0; i
< packet
-> class_count
; i
++)
1874 classes
[i
] -> lease_limit
) &&
1876 packet
-> classes
[i
]))
1878 if (i
== packet
-> class_count
) {
1879 log_info ("%s: no available billing",
1881 free_lease_state (state
, MDL
);
1883 host_dereference (&host
, MDL
);
1884 /* XXX possibly not necessary: */
1891 /* Figure out the filename. */
1892 oc
= lookup_option (&server_universe
, state
-> options
, SV_FILENAME
);
1894 evaluate_option_cache (&state
-> filename
, packet
, lease
,
1895 (struct client_state
*)0,
1896 packet
-> options
, state
-> options
,
1897 &lease
-> scope
, oc
, MDL
);
1899 /* Choose a server name as above. */
1900 oc
= lookup_option (&server_universe
, state
-> options
,
1903 evaluate_option_cache (&state
-> server_name
, packet
, lease
,
1904 (struct client_state
*)0,
1905 packet
-> options
, state
-> options
,
1906 &lease
-> scope
, oc
, MDL
);
1908 /* At this point, we have a lease that we can offer the client.
1909 Now we construct a lease structure that contains what we want,
1910 and call supersede_lease to do the right thing with it. */
1911 lt
= (struct lease
*)0;
1912 result
= lease_allocate (<
, MDL
);
1913 if (result
!= ISC_R_SUCCESS
) {
1914 log_info ("%s: can't allocate temporary lease structure: %s",
1915 msg
, isc_result_totext (result
));
1916 free_lease_state (state
, MDL
);
1918 host_dereference (&host
, MDL
);
1922 /* Use the ip address of the lease that we finally found in
1924 lt
-> ip_addr
= lease
-> ip_addr
;
1927 lt
-> starts
= cur_time
;
1929 /* Figure out how long a lease to assign. If this is a
1930 dynamic BOOTP lease, its duration must be infinite. */
1932 default_lease_time
= DEFAULT_DEFAULT_LEASE_TIME
;
1933 if ((oc
= lookup_option (&server_universe
, state
-> options
,
1934 SV_DEFAULT_LEASE_TIME
))) {
1935 if (evaluate_option_cache (&d1
, packet
, lease
,
1936 (struct client_state
*)0,
1939 &lease
-> scope
, oc
, MDL
)) {
1940 if (d1
.len
== sizeof (u_int32_t
))
1941 default_lease_time
=
1943 data_string_forget (&d1
, MDL
);
1947 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
1948 DHO_DHCP_LEASE_TIME
)))
1949 s1
= evaluate_option_cache (&d1
, packet
, lease
,
1950 (struct client_state
*)0,
1953 &lease
-> scope
, oc
, MDL
);
1957 if (s1
&& d1
.len
== sizeof (u_int32_t
)) {
1958 lease_time
= getULong (d1
.data
);
1959 data_string_forget (&d1
, MDL
);
1962 data_string_forget (&d1
, MDL
);
1963 lease_time
= default_lease_time
;
1966 /* See if there's a maximum lease time. */
1967 max_lease_time
= DEFAULT_MAX_LEASE_TIME
;
1968 if ((oc
= lookup_option (&server_universe
, state
-> options
,
1969 SV_MAX_LEASE_TIME
))) {
1970 if (evaluate_option_cache (&d1
, packet
, lease
,
1971 (struct client_state
*)0,
1974 &lease
-> scope
, oc
, MDL
)) {
1975 if (d1
.len
== sizeof (u_int32_t
))
1978 data_string_forget (&d1
, MDL
);
1982 /* Enforce the maximum lease length. */
1983 if (lease_time
< 0 /* XXX */
1984 || lease_time
> max_lease_time
)
1985 lease_time
= max_lease_time
;
1987 min_lease_time
= DEFAULT_MIN_LEASE_TIME
;
1988 if (min_lease_time
> max_lease_time
)
1989 min_lease_time
= max_lease_time
;
1991 if ((oc
= lookup_option (&server_universe
, state
-> options
,
1992 SV_MIN_LEASE_TIME
))) {
1993 if (evaluate_option_cache (&d1
, packet
, lease
,
1994 (struct client_state
*)0,
1997 &lease
-> scope
, oc
, MDL
)) {
1998 if (d1
.len
== sizeof (u_int32_t
))
1999 min_lease_time
= getULong (d1
.data
);
2000 data_string_forget (&d1
, MDL
);
2004 if (lease_time
< min_lease_time
) {
2006 lease_time
= min_lease_time
;
2008 lease_time
= default_lease_time
;
2011 #if defined (FAILOVER_PROTOCOL)
2012 /* Okay, we know the lease duration. Now check the
2013 failover state, if any. */
2014 if (lease
-> tsfp
) {
2015 lt
->tsfp
= lease
->tsfp
;
2017 if (lease
-> pool
&& lease
-> pool
-> failover_peer
) {
2018 dhcp_failover_state_t
*peer
=
2019 lease
-> pool
-> failover_peer
;
2021 /* If the lease time we arrived at exceeds what
2022 the peer has, we can only issue a lease of
2023 peer -> mclt, but we can tell the peer we
2024 want something longer in the future. */
2025 /* XXX This may result in updates that only push
2026 XXX the peer's expiry time for this lease up
2027 XXX by a few seconds - think about this again
2029 if (lease_time
> peer
-> mclt
&&
2030 cur_time
+ lease_time
> lease
-> tsfp
) {
2031 /* Here we're assuming that if we don't have
2032 to update tstp, there's already an update
2033 queued. May want to revisit this. */
2034 if (peer
-> me
.state
!= partner_down
&&
2035 cur_time
+ lease_time
> lease
-> tstp
)
2036 lt
-> tstp
= (cur_time
+ lease_time
+
2039 /* Now choose a lease time that is either
2040 MCLT, for a lease that's never before been
2041 assigned, or TSFP + MCLT for a lease that
2043 XXX Note that TSFP may be < cur_time.
2044 XXX What do we do in this case?
2045 XXX should the expiry timer on the lease
2046 XXX set tsfp and tstp to zero? */
2047 if (lease
-> tsfp
< cur_time
) {
2048 lease_time
= peer
-> mclt
;
2050 lease_time
= (lease
-> tsfp
- cur_time
2054 if (cur_time
+ lease_time
> lease
-> tsfp
&&
2055 lease_time
> peer
-> mclt
/ 2) {
2056 lt
-> tstp
= (cur_time
+ lease_time
+
2059 lt
-> tstp
= (cur_time
+ lease_time
+
2064 lt
-> cltt
= cur_time
;
2066 #endif /* FAILOVER_PROTOCOL */
2068 /* If the lease duration causes the time value to wrap,
2069 use the maximum expiry time. */
2070 if (cur_time
+ lease_time
< cur_time
)
2071 state
-> offered_expiry
= MAX_TIME
- 1;
2073 state
-> offered_expiry
= cur_time
+ lease_time
;
2077 lt
-> ends
= state
-> offered_expiry
;
2079 /* Don't make lease active until we actually get a
2081 if (offer
== DHCPACK
)
2082 lt
-> next_binding_state
= FTS_ACTIVE
;
2084 lt
-> next_binding_state
= lease
-> binding_state
;
2086 lease_time
= MAX_TIME
- cur_time
;
2088 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2089 SV_BOOTP_LEASE_LENGTH
))) {
2090 if (evaluate_option_cache (&d1
, packet
, lease
,
2091 (struct client_state
*)0,
2094 &lease
-> scope
, oc
, MDL
)) {
2095 if (d1
.len
== sizeof (u_int32_t
))
2096 lease_time
= getULong (d1
.data
);
2097 data_string_forget (&d1
, MDL
);
2101 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2102 SV_BOOTP_LEASE_CUTOFF
))) {
2103 if (evaluate_option_cache (&d1
, packet
, lease
,
2104 (struct client_state
*)0,
2107 &lease
-> scope
, oc
, MDL
)) {
2108 if (d1
.len
== sizeof (u_int32_t
))
2109 lease_time
= (getULong (d1
.data
) -
2111 data_string_forget (&d1
, MDL
);
2115 lt
-> ends
= state
-> offered_expiry
= cur_time
+ lease_time
;
2116 lt
-> next_binding_state
= FTS_ACTIVE
;
2119 lt
-> timestamp
= cur_time
;
2121 /* Record the uid, if given... */
2122 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
2123 DHO_DHCP_CLIENT_IDENTIFIER
);
2125 evaluate_option_cache (&d1
, packet
, lease
,
2126 (struct client_state
*)0,
2127 packet
-> options
, state
-> options
,
2128 &lease
-> scope
, oc
, MDL
)) {
2129 if (d1
.len
<= sizeof lt
-> uid_buf
) {
2130 memcpy (lt
-> uid_buf
, d1
.data
, d1
.len
);
2131 lt
-> uid
= lt
-> uid_buf
;
2132 lt
-> uid_max
= sizeof lt
-> uid_buf
;
2133 lt
-> uid_len
= d1
.len
;
2135 unsigned char *tuid
;
2136 lt
-> uid_max
= d1
.len
;
2137 lt
-> uid_len
= d1
.len
;
2138 tuid
= (unsigned char *)dmalloc (lt
-> uid_max
, MDL
);
2141 log_fatal ("no memory for large uid.");
2142 memcpy (tuid
, d1
.data
, lt
-> uid_len
);
2145 data_string_forget (&d1
, MDL
);
2149 host_reference (<
-> host
, host
, MDL
);
2150 host_dereference (&host
, MDL
);
2152 if (lease
-> subnet
)
2153 subnet_reference (<
-> subnet
, lease
-> subnet
, MDL
);
2154 if (lease
-> billing_class
)
2155 class_reference (<
-> billing_class
,
2156 lease
-> billing_class
, MDL
);
2158 /* Set a flag if this client is a broken client that NUL
2159 terminates string options and expects us to do likewise. */
2161 lease
-> flags
|= MS_NULL_TERMINATION
;
2163 lease
-> flags
&= ~MS_NULL_TERMINATION
;
2165 /* Save any bindings. */
2166 if (lease
-> scope
) {
2167 binding_scope_reference (<
-> scope
, lease
-> scope
, MDL
);
2168 binding_scope_dereference (&lease
-> scope
, MDL
);
2170 if (lease
-> agent_options
)
2171 option_chain_head_reference (<
-> agent_options
,
2172 lease
-> agent_options
, MDL
);
2174 /* If we got relay agent information options, and the packet really
2175 looks like it came through a relay agent, and if this feature is
2176 not disabled, save the relay agent information options that came
2177 in with the packet, so that we can use them at renewal time when
2178 the packet won't have gone through a relay agent. */
2179 if (packet
-> raw
-> giaddr
.s_addr
&&
2180 packet
-> options
-> universe_count
> agent_universe
.index
&&
2181 packet
-> options
-> universes
[agent_universe
.index
] &&
2182 (state
-> options
-> universe_count
<= agent_universe
.index
||
2183 state
-> options
-> universes
[agent_universe
.index
] ==
2184 packet
-> options
-> universes
[agent_universe
.index
])) {
2185 oc
= lookup_option (&server_universe
, state
-> options
,
2186 SV_STASH_AGENT_OPTIONS
);
2188 evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
2189 (struct client_state
*)0,
2192 &lease
-> scope
, oc
, MDL
)) {
2193 if (lt
-> agent_options
)
2194 option_chain_head_dereference (<
-> agent_options
, MDL
);
2195 option_chain_head_reference
2196 (<
-> agent_options
,
2197 (struct option_chain_head
*)
2198 packet
-> options
-> universes
[agent_universe
.index
],
2203 /* Replace the old lease hostname with the new one, if it's changed. */
2204 oc
= lookup_option (&dhcp_universe
, packet
-> options
, DHO_HOST_NAME
);
2206 s1
= evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
2207 (struct client_state
*)0,
2209 (struct option_state
*)0,
2210 &global_scope
, oc
, MDL
);
2215 lease
-> client_hostname
&&
2216 strlen (lease
-> client_hostname
) == d1
.len
&&
2217 !memcmp (lease
-> client_hostname
, d1
.data
, d1
.len
)) {
2218 /* Hasn't changed. */
2219 data_string_forget (&d1
, MDL
);
2220 lt
-> client_hostname
= lease
-> client_hostname
;
2221 lease
-> client_hostname
= (char *)0;
2222 } else if (oc
&& s1
) {
2223 lt
-> client_hostname
= dmalloc (d1
.len
+ 1, MDL
);
2224 if (!lt
-> client_hostname
)
2225 log_error ("no memory for client hostname.");
2227 memcpy (lt
-> client_hostname
, d1
.data
, d1
.len
);
2228 lt
-> client_hostname
[d1
.len
] = 0;
2230 data_string_forget (&d1
, MDL
);
2233 /* Record the hardware address, if given... */
2234 lt
-> hardware_addr
.hlen
= packet
-> raw
-> hlen
+ 1;
2235 lt
-> hardware_addr
.hbuf
[0] = packet
-> raw
-> htype
;
2236 memcpy (<
-> hardware_addr
.hbuf
[1], packet
-> raw
-> chaddr
,
2237 sizeof packet
-> raw
-> chaddr
);
2239 lt
-> flags
= lease
-> flags
& ~PERSISTENT_FLAGS
;
2241 /* If there are statements to execute when the lease is
2242 committed, execute them. */
2243 if (lease
-> on_commit
&& (!offer
|| offer
== DHCPACK
)) {
2244 execute_statements ((struct binding_value
**)0,
2245 packet
, lt
, (struct client_state
*)0,
2247 state
-> options
, <
-> scope
,
2248 lease
-> on_commit
);
2249 if (lease
-> on_commit
)
2250 executable_statement_dereference (&lease
-> on_commit
,
2255 /* Perform DDNS updates, if configured to. */
2256 if ((!offer
|| offer
== DHCPACK
) &&
2257 (!(oc
= lookup_option (&server_universe
, state
-> options
,
2258 SV_DDNS_UPDATES
)) ||
2259 evaluate_boolean_option_cache (&ignorep
, packet
, lt
,
2260 (struct client_state
*)0,
2263 <
-> scope
, oc
, MDL
))) {
2264 ddns_updates (packet
, lt
, lease
, state
);
2266 #endif /* NSUPDATE */
2268 /* Don't call supersede_lease on a mocked-up lease. */
2269 if (lease
-> flags
& STATIC_LEASE
) {
2270 /* Copy the hardware address into the static lease
2272 lease
-> hardware_addr
.hlen
= packet
-> raw
-> hlen
+ 1;
2273 lease
-> hardware_addr
.hbuf
[0] = packet
-> raw
-> htype
;
2274 memcpy (&lease
-> hardware_addr
.hbuf
[1],
2275 packet
-> raw
-> chaddr
,
2276 sizeof packet
-> raw
-> chaddr
); /* XXX */
2278 /* Install the new information about this lease in the
2279 database. If this is a DHCPACK or a dynamic BOOTREPLY
2280 and we can't write the lease, don't ACK it (or BOOTREPLY
2283 if (!supersede_lease (lease
, lt
, !offer
|| offer
== DHCPACK
,
2284 offer
== DHCPACK
, offer
== DHCPACK
)) {
2285 log_info ("%s: database update failed", msg
);
2286 free_lease_state (state
, MDL
);
2287 lease_dereference (<
, MDL
);
2291 lease_dereference (<
, MDL
);
2293 /* Remember the interface on which the packet arrived. */
2294 state
-> ip
= packet
-> interface
;
2296 /* Remember the giaddr, xid, secs, flags and hops. */
2297 state
-> giaddr
= packet
-> raw
-> giaddr
;
2298 state
-> ciaddr
= packet
-> raw
-> ciaddr
;
2299 state
-> xid
= packet
-> raw
-> xid
;
2300 state
-> secs
= packet
-> raw
-> secs
;
2301 state
-> bootp_flags
= packet
-> raw
-> flags
;
2302 state
-> hops
= packet
-> raw
-> hops
;
2303 state
-> offer
= offer
;
2305 /* If we're always supposed to broadcast to this client, set
2306 the broadcast bit in the bootp flags field. */
2307 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2308 SV_ALWAYS_BROADCAST
)) &&
2309 evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
2310 (struct client_state
*)0,
2311 packet
-> options
, state
-> options
,
2312 &lease
-> scope
, oc
, MDL
))
2313 state
-> bootp_flags
|= htons (BOOTP_BROADCAST
);
2315 /* Get the Maximum Message Size option from the packet, if one
2317 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
2318 DHO_DHCP_MAX_MESSAGE_SIZE
);
2320 evaluate_option_cache (&d1
, packet
, lease
,
2321 (struct client_state
*)0,
2322 packet
-> options
, state
-> options
,
2323 &lease
-> scope
, oc
, MDL
)) {
2324 if (d1
.len
== sizeof (u_int16_t
))
2325 state
-> max_message_size
= getUShort (d1
.data
);
2326 data_string_forget (&d1
, MDL
);
2328 oc
= lookup_option (&dhcp_universe
, state
-> options
,
2329 DHO_DHCP_MAX_MESSAGE_SIZE
);
2331 evaluate_option_cache (&d1
, packet
, lease
,
2332 (struct client_state
*)0,
2333 packet
-> options
, state
-> options
,
2334 &lease
-> scope
, oc
, MDL
)) {
2335 if (d1
.len
== sizeof (u_int16_t
))
2336 state
-> max_message_size
=
2337 getUShort (d1
.data
);
2338 data_string_forget (&d1
, MDL
);
2342 /* Get the Subnet Selection option from the packet, if one
2344 if ((oc
= lookup_option (&dhcp_universe
, packet
-> options
,
2345 DHO_SUBNET_SELECTION
))) {
2347 /* Make a copy of the data. */
2348 struct option_cache
*noc
= (struct option_cache
*)0;
2349 if (option_cache_allocate (&noc
, MDL
)) {
2351 data_string_copy (&noc
-> data
,
2353 if (oc
-> expression
)
2354 expression_reference (&noc
-> expression
,
2355 oc
-> expression
, MDL
);
2357 noc
-> option
= oc
-> option
;
2360 save_option (&dhcp_universe
, state
-> options
, noc
);
2361 option_cache_dereference (&noc
, MDL
);
2364 /* Now, if appropriate, put in DHCP-specific options that
2366 if (state
-> offer
) {
2367 i
= DHO_DHCP_MESSAGE_TYPE
;
2368 oc
= (struct option_cache
*)0;
2369 if (option_cache_allocate (&oc
, MDL
)) {
2370 if (make_const_data (&oc
-> expression
,
2371 &state
-> offer
, 1, 0, 0, MDL
)) {
2373 dhcp_universe
.options
[i
];
2374 save_option (&dhcp_universe
,
2375 state
-> options
, oc
);
2377 option_cache_dereference (&oc
, MDL
);
2379 i
= DHO_DHCP_SERVER_IDENTIFIER
;
2380 if (!(oc
= lookup_option (&dhcp_universe
,
2381 state
-> options
, i
))) {
2383 oc
= (struct option_cache
*)0;
2384 if (option_cache_allocate (&oc
, MDL
)) {
2388 &state
-> ip
-> primary_address
),
2389 sizeof state
-> ip
-> primary_address
,
2392 dhcp_universe
.options
[i
];
2393 save_option (&dhcp_universe
,
2394 state
-> options
, oc
);
2396 option_cache_dereference (&oc
, MDL
);
2399 sizeof state
-> ip
-> primary_address
;
2400 memcpy (state
-> from
.iabuf
,
2401 &state
-> ip
-> primary_address
,
2404 if (evaluate_option_cache (&d1
, packet
, lease
,
2405 (struct client_state
*)0,
2408 &lease
-> scope
, oc
, MDL
)) {
2410 d1
.len
> sizeof state
-> from
.iabuf
) {
2411 data_string_forget (&d1
, MDL
);
2414 memcpy (state
-> from
.iabuf
, d1
.data
, d1
.len
);
2415 state
-> from
.len
= d1
.len
;
2416 data_string_forget (&d1
, MDL
);
2421 offered_lease_time
=
2422 state
-> offered_expiry
- cur_time
;
2424 putULong ((unsigned char *)&state
-> expiry
,
2425 (unsigned long)offered_lease_time
);
2426 i
= DHO_DHCP_LEASE_TIME
;
2427 if (lookup_option (&dhcp_universe
, state
-> options
, i
))
2428 log_error ("dhcp-lease-time option for %s overridden.",
2429 inet_ntoa (state
-> ciaddr
));
2430 oc
= (struct option_cache
*)0;
2431 if (option_cache_allocate (&oc
, MDL
)) {
2432 if (make_const_data (&oc
-> expression
,
2433 (unsigned char *)&state
-> expiry
,
2434 sizeof state
-> expiry
,
2436 oc
-> option
= dhcp_universe
.options
[i
];
2437 save_option (&dhcp_universe
,
2438 state
-> options
, oc
);
2440 option_cache_dereference (&oc
, MDL
);
2443 /* Renewal time is lease time * 0.5. */
2444 offered_lease_time
/= 2;
2445 putULong ((unsigned char *)&state
-> renewal
,
2446 (unsigned long)offered_lease_time
);
2447 i
= DHO_DHCP_RENEWAL_TIME
;
2448 if (lookup_option (&dhcp_universe
, state
-> options
, i
))
2449 log_error ("overriding dhcp-renewal-time for %s.",
2450 inet_ntoa (state
-> ciaddr
));
2451 oc
= (struct option_cache
*)0;
2452 if (option_cache_allocate (&oc
, MDL
)) {
2453 if (make_const_data (&oc
-> expression
,
2456 sizeof state
-> renewal
,
2458 oc
-> option
= dhcp_universe
.options
[i
];
2459 save_option (&dhcp_universe
,
2460 state
-> options
, oc
);
2462 option_cache_dereference (&oc
, MDL
);
2465 /* Rebinding time is lease time * 0.875. */
2466 offered_lease_time
+= (offered_lease_time
/ 2
2467 + offered_lease_time
/ 4);
2468 putULong ((unsigned char *)&state
-> rebind
,
2469 (unsigned)offered_lease_time
);
2470 i
= DHO_DHCP_REBINDING_TIME
;
2471 if (lookup_option (&dhcp_universe
, state
-> options
, i
))
2472 log_error ("overriding dhcp-rebinding-time for %s.",
2473 inet_ntoa (state
-> ciaddr
));
2474 oc
= (struct option_cache
*)0;
2475 if (option_cache_allocate (&oc
, MDL
)) {
2476 if (make_const_data (&oc
-> expression
,
2477 (unsigned char *)&state
-> rebind
,
2478 sizeof state
-> rebind
,
2480 oc
-> option
= dhcp_universe
.options
[i
];
2481 save_option (&dhcp_universe
,
2482 state
-> options
, oc
);
2484 option_cache_dereference (&oc
, MDL
);
2488 sizeof state
-> ip
-> primary_address
;
2489 memcpy (state
-> from
.iabuf
,
2490 &state
-> ip
-> primary_address
,
2494 /* Figure out the address of the boot file server. */
2495 memset (&state
-> siaddr
, 0, sizeof state
-> siaddr
);
2497 lookup_option (&server_universe
,
2498 state
-> options
, SV_NEXT_SERVER
))) {
2499 if (evaluate_option_cache (&d1
, packet
, lease
,
2500 (struct client_state
*)0,
2501 packet
-> options
, state
-> options
,
2502 &lease
-> scope
, oc
, MDL
)) {
2503 /* If there was more than one answer,
2505 if (d1
.len
>= 4 && d1
.data
)
2506 memcpy (&state
-> siaddr
, d1
.data
, 4);
2507 data_string_forget (&d1
, MDL
);
2511 /* Use the subnet mask from the subnet declaration if no other
2512 mask has been provided. */
2513 i
= DHO_SUBNET_MASK
;
2514 if (!lookup_option (&dhcp_universe
, state
-> options
, i
)) {
2515 oc
= (struct option_cache
*)0;
2516 if (option_cache_allocate (&oc
, MDL
)) {
2517 if (make_const_data (&oc
-> expression
,
2518 lease
-> subnet
-> netmask
.iabuf
,
2519 lease
-> subnet
-> netmask
.len
,
2521 oc
-> option
= dhcp_universe
.options
[i
];
2522 save_option (&dhcp_universe
,
2523 state
-> options
, oc
);
2525 option_cache_dereference (&oc
, MDL
);
2529 /* Use the hostname from the host declaration if there is one
2530 and no hostname has otherwise been provided, and if the
2531 use-host-decl-name flag is set. */
2533 j
= SV_USE_HOST_DECL_NAMES
;
2534 if (!lookup_option (&dhcp_universe
, state
-> options
, i
) &&
2535 lease
-> host
&& lease
-> host
-> name
&&
2536 (evaluate_boolean_option_cache
2537 (&ignorep
, packet
, lease
, (struct client_state
*)0,
2538 packet
-> options
, state
-> options
, &lease
-> scope
,
2539 lookup_option (&server_universe
, state
-> options
, j
), MDL
))) {
2540 oc
= (struct option_cache
*)0;
2541 if (option_cache_allocate (&oc
, MDL
)) {
2542 if (make_const_data (&oc
-> expression
,
2544 lease
-> host
-> name
),
2545 strlen (lease
-> host
-> name
),
2547 oc
-> option
= dhcp_universe
.options
[i
];
2548 save_option (&dhcp_universe
,
2549 state
-> options
, oc
);
2551 option_cache_dereference (&oc
, MDL
);
2555 /* If we don't have a hostname yet, and we've been asked to do
2556 a reverse lookup to find the hostname, do it. */
2557 j
= SV_GET_LEASE_HOSTNAMES
;
2558 if (!lookup_option (&server_universe
, state
-> options
, i
) &&
2559 (evaluate_boolean_option_cache
2560 (&ignorep
, packet
, lease
, (struct client_state
*)0,
2561 packet
-> options
, state
-> options
, &lease
-> scope
,
2562 lookup_option (&server_universe
, state
-> options
, j
), MDL
))) {
2566 memcpy (&ia
, lease
-> ip_addr
.iabuf
, 4);
2568 h
= gethostbyaddr ((char *)&ia
, sizeof ia
, AF_INET
);
2570 log_error ("No hostname for %s", inet_ntoa (ia
));
2572 oc
= (struct option_cache
*)0;
2573 if (option_cache_allocate (&oc
, MDL
)) {
2574 if (make_const_data (&oc
-> expression
,
2577 strlen (h
-> h_name
) + 1,
2580 dhcp_universe
.options
[i
];
2581 save_option (&dhcp_universe
,
2582 state
-> options
, oc
);
2584 option_cache_dereference (&oc
, MDL
);
2589 /* If so directed, use the leased IP address as the router address.
2590 This supposedly makes Win95 machines ARP for all IP addresses,
2591 so if the local router does proxy arp, you win. */
2593 if (evaluate_boolean_option_cache
2594 (&ignorep
, packet
, lease
, (struct client_state
*)0,
2595 packet
-> options
, state
-> options
, &lease
-> scope
,
2596 lookup_option (&server_universe
, state
-> options
,
2597 SV_USE_LEASE_ADDR_FOR_DEFAULT_ROUTE
), MDL
)) {
2599 oc
= lookup_option (&dhcp_universe
, state
-> options
, i
);
2601 oc
= (struct option_cache
*)0;
2602 if (option_cache_allocate (&oc
, MDL
)) {
2603 if (make_const_data (&oc
-> expression
,
2604 lease
-> ip_addr
.iabuf
,
2605 lease
-> ip_addr
.len
,
2608 dhcp_universe
.options
[i
];
2609 save_option (&dhcp_universe
,
2610 state
-> options
, oc
);
2612 option_cache_dereference (&oc
, MDL
);
2617 /* If a site option space has been specified, use that for
2618 site option codes. */
2619 i
= SV_SITE_OPTION_SPACE
;
2620 if ((oc
= lookup_option (&server_universe
, state
-> options
, i
)) &&
2621 evaluate_option_cache (&d1
, packet
, lease
,
2622 (struct client_state
*)0,
2623 packet
-> options
, state
-> options
,
2624 &lease
-> scope
, oc
, MDL
)) {
2625 struct universe
*u
= (struct universe
*)0;
2627 if (!universe_hash_lookup (&u
, universe_hash
,
2628 (const char *)d1
.data
, d1
.len
,
2630 log_error ("unknown option space %s.", d1
.data
);
2634 state
-> options
-> site_universe
= u
-> index
;
2635 state
-> options
-> site_code_min
= 128; /* XXX */
2636 data_string_forget (&d1
, MDL
);
2638 state
-> options
-> site_code_min
= 0;
2639 state
-> options
-> site_universe
= dhcp_universe
.index
;
2642 /* If the client has provided a list of options that it wishes
2643 returned, use it to prioritize. If there's a parameter
2644 request list in scope, use that in preference. Otherwise
2645 use the default priority list. */
2647 oc
= lookup_option (&dhcp_universe
, state
-> options
,
2648 DHO_DHCP_PARAMETER_REQUEST_LIST
);
2651 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
2652 DHO_DHCP_PARAMETER_REQUEST_LIST
);
2654 evaluate_option_cache (&state
-> parameter_request_list
,
2655 packet
, lease
, (struct client_state
*)0,
2656 packet
-> options
, state
-> options
,
2657 &lease
-> scope
, oc
, MDL
);
2660 dump_packet (packet
);
2661 dump_raw ((unsigned char *)packet
-> raw
, packet
-> packet_length
);
2664 lease
-> state
= state
;
2666 log_info ("%s", msg
);
2668 /* Hang the packet off the lease state. */
2669 packet_reference (&lease
-> state
-> packet
, packet
, MDL
);
2671 /* If this is a DHCPOFFER, ping the lease address before actually
2672 sending the offer. */
2673 if (offer
== DHCPOFFER
&& !(lease
-> flags
& STATIC_LEASE
) &&
2674 cur_time
- lease
-> timestamp
> 60 &&
2675 (!(oc
= lookup_option (&server_universe
, state
-> options
,
2677 evaluate_boolean_option_cache (&ignorep
, packet
, lease
,
2678 (struct client_state
*)0,
2681 &lease
-> scope
, oc
, MDL
))) {
2682 lease
-> timestamp
= cur_time
;
2683 icmp_echorequest (&lease
-> ip_addr
);
2685 /* Determine wether to use configured or default ping timeout.
2687 if ((oc
= lookup_option (&server_universe
, state
-> options
,
2688 SV_PING_TIMEOUT
)) &&
2689 evaluate_option_cache (&d1
, packet
, lease
, NULL
,
2692 &lease
-> scope
, oc
, MDL
)) {
2693 if (d1
.len
== sizeof (u_int32_t
))
2694 ping_timeout
= getULong (d1
.data
);
2696 ping_timeout
= DEFAULT_PING_TIMEOUT
;
2698 data_string_forget (&d1
, MDL
);
2700 ping_timeout
= DEFAULT_PING_TIMEOUT
;
2703 log_debug ("Ping timeout: %ld", (long)ping_timeout
);
2706 add_timeout (cur_time
+ ping_timeout
, lease_ping_timeout
, lease
,
2707 (tvref_t
)lease_reference
,
2708 (tvunref_t
)lease_dereference
);
2709 ++outstanding_pings
;
2711 lease
-> timestamp
= cur_time
;
2716 void dhcp_reply (lease
)
2717 struct lease
*lease
;
2720 unsigned packet_length
;
2721 struct dhcp_packet raw
;
2722 struct sockaddr_in to
;
2723 struct in_addr from
;
2724 struct hardware hto
;
2727 struct lease_state
*state
= lease
-> state
;
2728 int nulltp
, bootpp
, unicastp
= 1;
2729 struct option_tag
*ot
, *not;
2730 struct data_string d1
;
2731 struct option_cache
*oc
;
2735 log_fatal ("dhcp_reply was supplied lease with no state!");
2737 /* Compose a response for the client... */
2738 memset (&raw
, 0, sizeof raw
);
2739 memset (&d1
, 0, sizeof d1
);
2741 /* Copy in the filename if given; otherwise, flag the filename
2742 buffer as available for options. */
2743 if (state
-> filename
.len
&& state
-> filename
.data
) {
2745 state
-> filename
.data
,
2746 state
-> filename
.len
> sizeof raw
.file
2747 ? sizeof raw
.file
: state
-> filename
.len
);
2748 if (sizeof raw
.file
> state
-> filename
.len
)
2749 memset (&raw
.file
[state
-> filename
.len
], 0,
2750 (sizeof raw
.file
) - state
-> filename
.len
);
2754 /* Copy in the server name if given; otherwise, flag the
2755 server_name buffer as available for options. */
2756 if (state
-> server_name
.len
&& state
-> server_name
.data
) {
2758 state
-> server_name
.data
,
2759 state
-> server_name
.len
> sizeof raw
.sname
2760 ? sizeof raw
.sname
: state
-> server_name
.len
);
2761 if (sizeof raw
.sname
> state
-> server_name
.len
)
2762 memset (&raw
.sname
[state
-> server_name
.len
], 0,
2763 (sizeof raw
.sname
) - state
-> server_name
.len
);
2765 bufs
|= 2; /* XXX */
2768 &lease
-> hardware_addr
.hbuf
[1], sizeof raw
.chaddr
);
2769 raw
.hlen
= lease
-> hardware_addr
.hlen
- 1;
2770 raw
.htype
= lease
-> hardware_addr
.hbuf
[0];
2772 /* See if this is a Microsoft client that NUL-terminates its
2773 strings and expects us to do likewise... */
2774 if (lease
-> flags
& MS_NULL_TERMINATION
)
2779 /* See if this is a bootp client... */
2785 /* Insert such options as will fit into the buffer. */
2786 packet_length
= cons_options (state
-> packet
, &raw
, lease
,
2787 (struct client_state
*)0,
2788 state
-> max_message_size
,
2789 state
-> packet
-> options
,
2790 state
-> options
, &global_scope
,
2791 bufs
, nulltp
, bootpp
,
2792 &state
-> parameter_request_list
,
2795 memcpy (&raw
.ciaddr
, &state
-> ciaddr
, sizeof raw
.ciaddr
);
2796 memcpy (&raw
.yiaddr
, lease
-> ip_addr
.iabuf
, 4);
2797 raw
.siaddr
= state
-> siaddr
;
2798 raw
.giaddr
= state
-> giaddr
;
2800 raw
.xid
= state
-> xid
;
2801 raw
.secs
= state
-> secs
;
2802 raw
.flags
= state
-> bootp_flags
;
2803 raw
.hops
= state
-> hops
;
2806 if (lease
-> client_hostname
) {
2807 if ((strlen (lease
-> client_hostname
) <= 64) &&
2808 db_printable (lease
-> client_hostname
))
2809 s
= lease
-> client_hostname
;
2811 s
= "Hostname Unsuitable for Printing";
2815 /* Say what we're doing... */
2816 log_info ("%s on %s to %s %s%s%svia %s",
2818 ? (state
-> offer
== DHCPACK
? "DHCPACK" : "DHCPOFFER")
2820 piaddr (lease
-> ip_addr
),
2821 (lease
-> hardware_addr
.hlen
2822 ? print_hw_addr (lease
-> hardware_addr
.hbuf
[0],
2823 lease
-> hardware_addr
.hlen
- 1,
2824 &lease
-> hardware_addr
.hbuf
[1])
2825 : print_hex_1 (lease
-> uid_len
, lease
-> uid
,
2827 s
? "(" : "", s
? s
: "", s
? ") " : "",
2828 (state
-> giaddr
.s_addr
2829 ? inet_ntoa (state
-> giaddr
)
2830 : state
-> ip
-> name
));
2832 /* Set up the hardware address... */
2833 hto
.hlen
= lease
-> hardware_addr
.hlen
;
2834 memcpy (hto
.hbuf
, lease
-> hardware_addr
.hbuf
, hto
.hlen
);
2836 to
.sin_family
= AF_INET
;
2838 to
.sin_len
= sizeof to
;
2840 memset (to
.sin_zero
, 0, sizeof to
.sin_zero
);
2843 dump_raw ((unsigned char *)&raw
, packet_length
);
2846 /* Make sure outgoing packets are at least as big
2847 as a BOOTP packet. */
2848 if (packet_length
< BOOTP_MIN_LEN
)
2849 packet_length
= BOOTP_MIN_LEN
;
2851 /* If this was gatewayed, send it back to the gateway... */
2852 if (raw
.giaddr
.s_addr
) {
2853 to
.sin_addr
= raw
.giaddr
;
2854 if (raw
.giaddr
.s_addr
!= htonl (INADDR_LOOPBACK
))
2855 to
.sin_port
= local_port
;
2857 to
.sin_port
= remote_port
; /* For debugging. */
2859 if (fallback_interface
) {
2860 result
= send_packet (fallback_interface
,
2862 &raw
, packet_length
,
2864 (struct hardware
*)0);
2866 free_lease_state (state
, MDL
);
2867 lease
-> state
= (struct lease_state
*)0;
2871 /* If the client is RENEWING, unicast to the client using the
2872 regular IP stack. Some clients, particularly those that
2873 follow RFC1541, are buggy, and send both ciaddr and server
2874 identifier. We deal with this situation by assuming that
2875 if we got both dhcp-server-identifier and ciaddr, and
2876 giaddr was not set, then the client is on the local
2877 network, and we can therefore unicast or broadcast to it
2878 successfully. A client in REQUESTING state on another
2879 network that's making this mistake will have set giaddr,
2880 and will therefore get a relayed response from the above
2882 } else if (raw
.ciaddr
.s_addr
&&
2883 !((state
-> got_server_identifier
||
2884 (raw
.flags
& htons (BOOTP_BROADCAST
))) &&
2885 /* XXX This won't work if giaddr isn't zero, but it is: */
2886 (state
-> shared_network
==
2887 lease
-> subnet
-> shared_network
)) &&
2888 state
-> offer
== DHCPACK
) {
2889 to
.sin_addr
= raw
.ciaddr
;
2890 to
.sin_port
= remote_port
;
2892 if (fallback_interface
) {
2893 result
= send_packet (fallback_interface
,
2895 &raw
, packet_length
,
2897 (struct hardware
*)0);
2898 free_lease_state (state
, MDL
);
2899 lease
-> state
= (struct lease_state
*)0;
2903 /* If it comes from a client that already knows its address
2904 and is not requesting a broadcast response, and we can
2905 unicast to a client without using the ARP protocol, sent it
2906 directly to that client. */
2907 } else if (!(raw
.flags
& htons (BOOTP_BROADCAST
)) &&
2908 can_unicast_without_arp (state
-> ip
)) {
2909 to
.sin_addr
= raw
.yiaddr
;
2910 to
.sin_port
= remote_port
;
2912 /* Otherwise, broadcast it on the local network. */
2914 to
.sin_addr
= limited_broadcast
;
2915 to
.sin_port
= remote_port
;
2916 if (!(lease
-> flags
& UNICAST_BROADCAST_HACK
))
2920 memcpy (&from
, state
-> from
.iabuf
, sizeof from
);
2922 result
= send_packet (state
-> ip
,
2923 (struct packet
*)0, &raw
, packet_length
,
2925 unicastp
? &hto
: (struct hardware
*)0);
2927 /* Free all of the entries in the option_state structure
2928 now that we're done with them. */
2930 free_lease_state (state
, MDL
);
2931 lease
-> state
= (struct lease_state
*)0;
2934 int find_lease (struct lease
**lp
,
2935 struct packet
*packet
, struct shared_network
*share
, int *ours
,
2936 int *allocatedp
, struct lease
*ip_lease_in
,
2937 const char *file
, int line
)
2939 struct lease
*uid_lease
= (struct lease
*)0;
2940 struct lease
*ip_lease
= (struct lease
*)0;
2941 struct lease
*hw_lease
= (struct lease
*)0;
2942 struct lease
*lease
= (struct lease
*)0;
2944 struct host_decl
*hp
= (struct host_decl
*)0;
2945 struct host_decl
*host
= (struct host_decl
*)0;
2946 struct lease
*fixed_lease
= (struct lease
*)0;
2947 struct lease
*next
= (struct lease
*)0;
2948 struct option_cache
*oc
;
2949 struct data_string d1
;
2950 int have_client_identifier
= 0;
2951 struct data_string client_identifier
;
2955 if (packet
-> raw
-> ciaddr
.s_addr
) {
2957 memcpy (cip
.iabuf
, &packet
-> raw
-> ciaddr
, 4);
2959 /* Look up the requested address. */
2960 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
2961 DHO_DHCP_REQUESTED_ADDRESS
);
2962 memset (&d1
, 0, sizeof d1
);
2964 evaluate_option_cache (&d1
, packet
, (struct lease
*)0,
2965 (struct client_state
*)0,
2967 (struct option_state
*)0,
2968 &global_scope
, oc
, MDL
)) {
2969 packet
-> got_requested_address
= 1;
2971 memcpy (cip
.iabuf
, d1
.data
, cip
.len
);
2972 data_string_forget (&d1
, MDL
);
2977 /* Try to find a host or lease that's been assigned to the
2978 specified unique client identifier. */
2979 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
2980 DHO_DHCP_CLIENT_IDENTIFIER
);
2981 memset (&client_identifier
, 0, sizeof client_identifier
);
2983 evaluate_option_cache (&client_identifier
,
2984 packet
, (struct lease
*)0,
2985 (struct client_state
*)0,
2986 packet
-> options
, (struct option_state
*)0,
2987 &global_scope
, oc
, MDL
)) {
2988 /* Remember this for later. */
2989 have_client_identifier
= 1;
2991 /* First, try to find a fixed host entry for the specified
2992 client identifier... */
2993 if (find_hosts_by_uid (&hp
, client_identifier
.data
,
2994 client_identifier
.len
, MDL
)) {
2995 /* Remember if we know of this client. */
2996 packet
-> known
= 1;
2997 mockup_lease (&fixed_lease
, packet
, share
, hp
);
3000 #if defined (DEBUG_FIND_LEASE)
3002 log_info ("Found host for client identifier: %s.",
3003 piaddr (fixed_lease
-> ip_addr
));
3007 if (!fixed_lease
) /* Save the host if we found one. */
3008 host_reference (&host
, hp
, MDL
);
3009 host_dereference (&hp
, MDL
);
3012 find_lease_by_uid (&uid_lease
, client_identifier
.data
,
3013 client_identifier
.len
, MDL
);
3016 /* If we didn't find a fixed lease using the uid, try doing
3017 it with the hardware address... */
3018 if (!fixed_lease
&& !host
) {
3019 if (find_hosts_by_haddr (&hp
, packet
-> raw
-> htype
,
3020 packet
-> raw
-> chaddr
,
3021 packet
-> raw
-> hlen
, MDL
)) {
3022 /* Remember if we know of this client. */
3023 packet
-> known
= 1;
3025 host_dereference (&host
, MDL
);
3026 host_reference (&host
, hp
, MDL
);
3027 host_dereference (&hp
, MDL
);
3028 mockup_lease (&fixed_lease
, packet
, share
, host
);
3029 #if defined (DEBUG_FIND_LEASE)
3031 log_info ("Found host for link address: %s.",
3032 piaddr (fixed_lease
-> ip_addr
));
3038 /* If fixed_lease is present but does not match the requested
3039 IP address, and this is a DHCPREQUEST, then we can't return
3040 any other lease, so we might as well return now. */
3041 if (packet
-> packet_type
== DHCPREQUEST
&& fixed_lease
&&
3042 (fixed_lease
-> ip_addr
.len
!= cip
.len
||
3043 memcmp (fixed_lease
-> ip_addr
.iabuf
,
3044 cip
.iabuf
, cip
.len
))) {
3047 strcpy (dhcp_message
, "requested address is incorrect");
3048 #if defined (DEBUG_FIND_LEASE)
3049 log_info ("Client's fixed-address %s doesn't match %s%s",
3050 piaddr (fixed_lease
-> ip_addr
), "request ",
3051 print_dotted_quads (cip
.len
, cip
.iabuf
));
3056 /* If we found leases matching the client identifier, loop through
3057 the n_uid pointer looking for one that's actually valid. We
3058 can't do this until we get here because we depend on
3059 packet -> known, which may be set by either the uid host
3060 lookup or the haddr host lookup. */
3062 #if defined (DEBUG_FIND_LEASE)
3063 log_info ("trying next lease matching client id: %s",
3064 piaddr (uid_lease
-> ip_addr
));
3067 #if defined (FAILOVER_PROTOCOL)
3068 /* When failover is active, it's possible that there could
3069 be two "free" leases for the same uid, but only one of
3070 them that's available for this failover peer to allocate. */
3071 if (uid_lease
-> binding_state
!= FTS_ACTIVE
&&
3072 !lease_mine_to_reallocate (uid_lease
)) {
3073 #if defined (DEBUG_FIND_LEASE)
3074 log_info ("not mine to allocate: %s",
3075 piaddr (uid_lease
-> ip_addr
));
3081 if (uid_lease
-> subnet
-> shared_network
!= share
) {
3082 #if defined (DEBUG_FIND_LEASE)
3083 log_info ("wrong network segment: %s",
3084 piaddr (uid_lease
-> ip_addr
));
3089 if ((uid_lease
-> pool
-> prohibit_list
&&
3090 permitted (packet
, uid_lease
-> pool
-> prohibit_list
)) ||
3091 (uid_lease
-> pool
-> permit_list
&&
3092 !permitted (packet
, uid_lease
-> pool
-> permit_list
))) {
3093 #if defined (DEBUG_FIND_LEASE)
3094 log_info ("not permitted: %s",
3095 piaddr (uid_lease
-> ip_addr
));
3098 if (uid_lease
-> n_uid
)
3099 lease_reference (&next
,
3100 uid_lease
-> n_uid
, MDL
);
3101 if (!packet
-> raw
-> ciaddr
.s_addr
)
3102 release_lease (uid_lease
, packet
);
3103 lease_dereference (&uid_lease
, MDL
);
3105 lease_reference (&uid_lease
, next
, MDL
);
3106 lease_dereference (&next
, MDL
);
3112 #if defined (DEBUG_FIND_LEASE)
3114 log_info ("Found lease for client id: %s.",
3115 piaddr (uid_lease
-> ip_addr
));
3118 /* Find a lease whose hardware address matches, whose client
3119 identifier matches, that's permitted, and that's on the
3121 h
.hlen
= packet
-> raw
-> hlen
+ 1;
3122 h
.hbuf
[0] = packet
-> raw
-> htype
;
3123 memcpy (&h
.hbuf
[1], packet
-> raw
-> chaddr
, packet
-> raw
-> hlen
);
3124 find_lease_by_hw_addr (&hw_lease
, h
.hbuf
, h
.hlen
, MDL
);
3126 #if defined (DEBUG_FIND_LEASE)
3127 log_info ("trying next lease matching hw addr: %s",
3128 piaddr (hw_lease
-> ip_addr
));
3130 #if defined (FAILOVER_PROTOCOL)
3131 /* When failover is active, it's possible that there could
3132 be two "free" leases for the same uid, but only one of
3133 them that's available for this failover peer to allocate. */
3134 if (hw_lease
-> binding_state
!= FTS_ACTIVE
&&
3135 !lease_mine_to_reallocate (hw_lease
)) {
3136 #if defined (DEBUG_FIND_LEASE)
3137 log_info ("not mine to allocate: %s",
3138 piaddr (hw_lease
-> ip_addr
));
3144 if (hw_lease
-> binding_state
!= FTS_FREE
&&
3145 hw_lease
-> binding_state
!= FTS_BACKUP
&&
3147 (!have_client_identifier
||
3148 hw_lease
-> uid_len
!= client_identifier
.len
||
3149 memcmp (hw_lease
-> uid
, client_identifier
.data
,
3150 hw_lease
-> uid_len
))) {
3151 #if defined (DEBUG_FIND_LEASE)
3152 log_info ("wrong client identifier: %s",
3153 piaddr (hw_lease
-> ip_addr
));
3158 if (hw_lease
-> subnet
-> shared_network
!= share
) {
3159 #if defined (DEBUG_FIND_LEASE)
3160 log_info ("wrong network segment: %s",
3161 piaddr (hw_lease
-> ip_addr
));
3166 if ((hw_lease
-> pool
-> prohibit_list
&&
3167 permitted (packet
, hw_lease
-> pool
-> prohibit_list
)) ||
3168 (hw_lease
-> pool
-> permit_list
&&
3169 !permitted (packet
, hw_lease
-> pool
-> permit_list
))) {
3170 #if defined (DEBUG_FIND_LEASE)
3171 log_info ("not permitted: %s",
3172 piaddr (hw_lease
-> ip_addr
));
3174 if (!packet
-> raw
-> ciaddr
.s_addr
)
3175 release_lease (hw_lease
, packet
);
3177 if (hw_lease
-> n_hw
)
3178 lease_reference (&next
, hw_lease
-> n_hw
, MDL
);
3179 lease_dereference (&hw_lease
, MDL
);
3181 lease_reference (&hw_lease
, next
, MDL
);
3182 lease_dereference (&next
, MDL
);
3188 #if defined (DEBUG_FIND_LEASE)
3190 log_info ("Found lease for hardware address: %s.",
3191 piaddr (hw_lease
-> ip_addr
));
3194 /* Try to find a lease that's been allocated to the client's
3197 lease_reference (&ip_lease
, ip_lease_in
, MDL
);
3199 find_lease_by_ip_addr (&ip_lease
, cip
, MDL
);
3201 #if defined (DEBUG_FIND_LEASE)
3203 log_info ("Found lease for requested address: %s.",
3204 piaddr (ip_lease
-> ip_addr
));
3207 /* If ip_lease is valid at this point, set ours to one, so that
3208 even if we choose a different lease, we know that the address
3209 the client was requesting was ours, and thus we can NAK it. */
3210 if (ip_lease
&& ours
)
3213 /* If the requested IP address isn't on the network the packet
3214 came from, don't use it. Allow abandoned leases to be matched
3215 here - if the client is requesting it, there's a decent chance
3216 that it's because the lease database got trashed and a client
3217 that thought it had this lease answered an ARP or PING, causing the
3218 lease to be abandoned. If so, this request probably came from
3220 if (ip_lease
&& (ip_lease
-> subnet
-> shared_network
!= share
)) {
3223 #if defined (DEBUG_FIND_LEASE)
3224 log_info ("...but it was on the wrong shared network.");
3226 strcpy (dhcp_message
, "requested address on bad subnet");
3227 lease_dereference (&ip_lease
, MDL
);
3230 /* Toss ip_lease if it hasn't yet expired and doesn't belong to the
3234 (!have_client_identifier
||
3235 ip_lease
-> uid_len
!= client_identifier
.len
||
3236 memcmp (ip_lease
-> uid
, client_identifier
.data
,
3237 ip_lease
-> uid_len
)) :
3238 (ip_lease
-> hardware_addr
.hbuf
[0] != packet
-> raw
-> htype
||
3239 ip_lease
-> hardware_addr
.hlen
!= packet
-> raw
-> hlen
+ 1 ||
3240 memcmp (&ip_lease
-> hardware_addr
.hbuf
[1],
3241 packet
-> raw
-> chaddr
,
3242 (unsigned)(ip_lease
-> hardware_addr
.hlen
- 1))))) {
3243 /* If we're not doing failover, the only state in which
3244 we can allocate this lease to the client is FTS_FREE.
3245 If we are doing failover, things are more complicated.
3246 If the lease is free or backup, we let the caller decide
3247 whether or not to give it out. */
3248 if (ip_lease
-> binding_state
!= FTS_FREE
&&
3249 ip_lease
-> binding_state
!= FTS_BACKUP
) {
3250 #if defined (DEBUG_FIND_LEASE)
3251 log_info ("rejecting lease for requested address.");
3253 /* If we're rejecting it because the peer has
3254 it, don't set "ours", because we shouldn't NAK. */
3255 if (ours
&& ip_lease
-> binding_state
!= FTS_ACTIVE
)
3257 lease_dereference (&ip_lease
, MDL
);
3263 /* If we got an ip_lease and a uid_lease or hw_lease, and ip_lease
3264 is not active, and is not ours to reallocate, forget about it. */
3265 if (ip_lease
&& (uid_lease
|| hw_lease
) &&
3266 ip_lease
-> binding_state
!= FTS_ACTIVE
&&
3267 !lease_mine_to_reallocate (ip_lease
) &&
3268 packet
-> packet_type
== DHCPDISCOVER
) {
3269 #if defined (DEBUG_FIND_LEASE)
3270 log_info ("ip lease not ours to offer.");
3272 lease_dereference (&ip_lease
, MDL
);
3275 /* If for some reason the client has more than one lease
3276 on the subnet that matches its uid, pick the one that
3277 it asked for and (if we can) free the other. */
3279 ip_lease
-> binding_state
== FTS_ACTIVE
&&
3280 ip_lease
-> uid
&& ip_lease
!= uid_lease
) {
3281 if (have_client_identifier
&&
3282 (ip_lease
-> uid_len
== client_identifier
.len
) &&
3283 !memcmp (client_identifier
.data
,
3284 ip_lease
-> uid
, ip_lease
-> uid_len
)) {
3286 if (uid_lease
-> binding_state
== FTS_ACTIVE
) {
3287 log_error ("client %s has duplicate%s on %s",
3289 (packet
-> raw
-> htype
,
3290 packet
-> raw
-> hlen
,
3291 packet
-> raw
-> chaddr
)),
3293 (ip_lease
-> subnet
->
3294 shared_network
-> name
));
3296 /* If the client is REQUESTing the lease,
3297 it shouldn't still be using the old
3298 one, so we can free it for allocation. */
3300 uid_lease
-> binding_state
== FTS_ACTIVE
&&
3301 !packet
-> raw
-> ciaddr
.s_addr
&&
3303 uid_lease
-> subnet
-> shared_network
) &&
3304 packet
-> packet_type
== DHCPREQUEST
)
3305 dissociate_lease (uid_lease
);
3307 lease_dereference (&uid_lease
, MDL
);
3308 lease_reference (&uid_lease
, ip_lease
, MDL
);
3312 /* If we get to here and fixed_lease is not null, that means
3313 that there are both a dynamic lease and a fixed-address
3314 declaration for the same IP address. */
3315 if (packet
-> packet_type
== DHCPREQUEST
&& fixed_lease
) {
3316 lease_dereference (&fixed_lease
, MDL
);
3318 log_error ("Dynamic and static leases present for %s.",
3320 log_error ("Remove host declaration %s or remove %s",
3321 (fixed_lease
&& fixed_lease
-> host
3322 ? (fixed_lease
-> host
-> name
3323 ? fixed_lease
-> host
-> name
3327 log_error ("from the dynamic address pool for %s",
3328 ip_lease
-> subnet
-> shared_network
-> name
3331 lease_dereference (&ip_lease
, MDL
);
3332 strcpy (dhcp_message
,
3333 "database conflict - call for help!");
3336 if (ip_lease
&& ip_lease
!= uid_lease
) {
3337 #if defined (DEBUG_FIND_LEASE)
3338 log_info ("requested address not available.");
3340 lease_dereference (&ip_lease
, MDL
);
3344 /* If we get to here with both fixed_lease and ip_lease not
3345 null, then we have a configuration file bug. */
3346 if (packet
-> packet_type
== DHCPREQUEST
&& fixed_lease
&& ip_lease
)
3349 /* Toss extra pointers to the same lease... */
3350 if (hw_lease
&& hw_lease
== uid_lease
) {
3351 #if defined (DEBUG_FIND_LEASE)
3352 log_info ("hardware lease and uid lease are identical.");
3354 lease_dereference (&hw_lease
, MDL
);
3356 if (ip_lease
&& ip_lease
== hw_lease
) {
3357 lease_dereference (&hw_lease
, MDL
);
3358 #if defined (DEBUG_FIND_LEASE)
3359 log_info ("hardware lease and ip lease are identical.");
3362 if (ip_lease
&& ip_lease
== uid_lease
) {
3363 lease_dereference (&uid_lease
, MDL
);
3364 #if defined (DEBUG_FIND_LEASE)
3365 log_info ("uid lease and ip lease are identical.");
3369 /* Make sure the client is permitted to use the requested lease. */
3371 ((ip_lease
-> pool
-> prohibit_list
&&
3372 permitted (packet
, ip_lease
-> pool
-> prohibit_list
)) ||
3373 (ip_lease
-> pool
-> permit_list
&&
3374 !permitted (packet
, ip_lease
-> pool
-> permit_list
)))) {
3375 if (!packet
-> raw
-> ciaddr
.s_addr
)
3376 release_lease (ip_lease
, packet
);
3377 lease_dereference (&ip_lease
, MDL
);
3381 ((uid_lease
-> pool
-> prohibit_list
&&
3382 permitted (packet
, uid_lease
-> pool
-> prohibit_list
)) ||
3383 (uid_lease
-> pool
-> permit_list
&&
3384 !permitted (packet
, uid_lease
-> pool
-> permit_list
)))) {
3385 if (!packet
-> raw
-> ciaddr
.s_addr
)
3386 release_lease (uid_lease
, packet
);
3387 lease_dereference (&uid_lease
, MDL
);
3391 ((hw_lease
-> pool
-> prohibit_list
&&
3392 permitted (packet
, hw_lease
-> pool
-> prohibit_list
)) ||
3393 (hw_lease
-> pool
-> permit_list
&&
3394 !permitted (packet
, hw_lease
-> pool
-> permit_list
)))) {
3395 if (!packet
-> raw
-> ciaddr
.s_addr
)
3396 release_lease (hw_lease
, packet
);
3397 lease_dereference (&hw_lease
, MDL
);
3400 /* If we've already eliminated the lease, it wasn't there to
3401 begin with. If we have come up with a matching lease,
3402 set the message to bad network in case we have to throw it out. */
3404 strcpy (dhcp_message
, "requested address not available");
3407 /* If this is a DHCPREQUEST, make sure the lease we're going to return
3408 matches the requested IP address. If it doesn't, don't return a
3410 if (packet
-> packet_type
== DHCPREQUEST
&&
3411 !ip_lease
&& !fixed_lease
) {
3412 #if defined (DEBUG_FIND_LEASE)
3413 log_info ("no applicable lease found for DHCPREQUEST.");
3418 /* At this point, if fixed_lease is nonzero, we can assign it to
3421 lease_reference (&lease
, fixed_lease
, MDL
);
3422 lease_dereference (&fixed_lease
, MDL
);
3423 #if defined (DEBUG_FIND_LEASE)
3424 log_info ("choosing fixed address.");
3428 /* If we got a lease that matched the ip address and don't have
3429 a better offer, use that; otherwise, release it. */
3432 if (!packet
-> raw
-> ciaddr
.s_addr
)
3433 release_lease (ip_lease
, packet
);
3434 #if defined (DEBUG_FIND_LEASE)
3435 log_info ("not choosing requested address (!).");
3438 #if defined (DEBUG_FIND_LEASE)
3439 log_info ("choosing lease on requested address.");
3441 lease_reference (&lease
, ip_lease
, MDL
);
3443 host_dereference (&lease
-> host
, MDL
);
3445 lease_dereference (&ip_lease
, MDL
);
3448 /* If we got a lease that matched the client identifier, we may want
3449 to use it, but if we already have a lease we like, we must free
3450 the lease that matched the client identifier. */
3453 if (!packet
-> raw
-> ciaddr
.s_addr
&&
3454 packet
-> packet_type
== DHCPREQUEST
&&
3455 uid_lease
-> binding_state
== FTS_ACTIVE
)
3456 dissociate_lease (uid_lease
);
3457 #if defined (DEBUG_FIND_LEASE)
3458 log_info ("not choosing uid lease.");
3461 lease_reference (&lease
, uid_lease
, MDL
);
3463 host_dereference (&lease
-> host
, MDL
);
3464 #if defined (DEBUG_FIND_LEASE)
3465 log_info ("choosing uid lease.");
3468 lease_dereference (&uid_lease
, MDL
);
3471 /* The lease that matched the hardware address is treated likewise. */
3474 #if defined (DEBUG_FIND_LEASE)
3475 log_info ("not choosing hardware lease.");
3478 /* We're a little lax here - if the client didn't
3479 send a client identifier and it's a bootp client,
3480 but the lease has a client identifier, we still
3481 let the client have a lease. */
3482 if (!hw_lease
-> uid_len
||
3483 (have_client_identifier
3484 ? (hw_lease
-> uid_len
==
3485 client_identifier
.len
&&
3486 !memcmp (hw_lease
-> uid
,
3487 client_identifier
.data
,
3488 client_identifier
.len
))
3489 : packet
-> packet_type
== 0)) {
3490 lease_reference (&lease
, hw_lease
, MDL
);
3492 host_dereference (&lease
-> host
, MDL
);
3493 #if defined (DEBUG_FIND_LEASE)
3494 log_info ("choosing hardware lease.");
3497 #if defined (DEBUG_FIND_LEASE)
3498 log_info ("not choosing hardware lease: %s.",
3503 lease_dereference (&hw_lease
, MDL
);
3506 /* If we found a host_decl but no matching address, try to
3507 find a host_decl that has no address, and if there is one,
3508 hang it off the lease so that we can use the supplied
3510 if (lease
&& host
&& !lease
-> host
) {
3511 struct host_decl
*p
= (struct host_decl
*)0;
3512 struct host_decl
*n
= (struct host_decl
*)0;
3513 host_reference (&p
, host
, MDL
);
3515 if (!p
-> fixed_addr
) {
3516 host_reference (&lease
-> host
, p
, MDL
);
3517 host_dereference (&p
, MDL
);
3521 host_reference (&n
, p
-> n_ipaddr
, MDL
);
3522 host_dereference (&p
, MDL
);
3524 host_reference (&p
, n
, MDL
);
3525 host_dereference (&n
, MDL
);
3530 /* If we find an abandoned lease, but it's the one the client
3531 requested, we assume that previous bugginess on the part
3532 of the client, or a server database loss, caused the lease to
3533 be abandoned, so we reclaim it and let the client have it. */
3535 (lease
-> binding_state
== FTS_ABANDONED
) &&
3536 lease
== ip_lease
&&
3537 packet
-> packet_type
== DHCPREQUEST
) {
3538 log_error ("Reclaiming REQUESTed abandoned IP address %s.",
3539 piaddr (lease
-> ip_addr
));
3540 } else if (lease
&& (lease
-> binding_state
== FTS_ABANDONED
)) {
3541 /* Otherwise, if it's not the one the client requested, we do not
3542 return it - instead, we claim it's ours, causing a DHCPNAK to be
3543 sent if this lookup is for a DHCPREQUEST, and force the client
3544 to go back through the allocation process. */
3547 lease_dereference (&lease
, MDL
);
3550 if (lease
&& allocatedp
&& lease
-> ends
<= cur_time
)
3554 if (have_client_identifier
)
3555 data_string_forget (&client_identifier
, MDL
);
3558 lease_dereference (&fixed_lease
, MDL
);
3560 lease_dereference (&hw_lease
, MDL
);
3562 lease_dereference (&uid_lease
, MDL
);
3564 lease_dereference (&ip_lease
, MDL
);
3566 host_dereference (&host
, MDL
);
3569 #if defined (DEBUG_FIND_LEASE)
3570 log_info ("Returning lease: %s.",
3571 piaddr (lease
-> ip_addr
));
3573 lease_reference (lp
, lease
, file
, line
);
3574 lease_dereference (&lease
, MDL
);
3577 #if defined (DEBUG_FIND_LEASE)
3578 log_info ("Not returning a lease.");
3583 /* Search the provided host_decl structure list for an address that's on
3584 the specified shared network. If one is found, mock up and return a
3585 lease structure for it; otherwise return the null pointer. */
3587 int mockup_lease (struct lease
**lp
, struct packet
*packet
,
3588 struct shared_network
*share
, struct host_decl
*hp
)
3590 struct lease
*lease
= (struct lease
*)0;
3591 struct host_decl
*rhp
= (struct host_decl
*)0;
3593 if (lease_allocate (&lease
, MDL
) != ISC_R_SUCCESS
)
3595 if (host_reference (&rhp
, hp
, MDL
) != ISC_R_SUCCESS
) {
3596 lease_dereference (&lease
, MDL
);
3599 if (!find_host_for_network (&lease
-> subnet
,
3600 &rhp
, &lease
-> ip_addr
, share
)) {
3601 lease_dereference (&lease
, MDL
);
3602 host_dereference (&rhp
, MDL
);
3605 host_reference (&lease
-> host
, rhp
, MDL
);
3606 if (rhp
-> client_identifier
.len
> sizeof lease
-> uid_buf
)
3607 lease
-> uid
= dmalloc (rhp
-> client_identifier
.len
, MDL
);
3609 lease
-> uid
= lease
-> uid_buf
;
3610 if (!lease
-> uid
) {
3611 lease_dereference (&lease
, MDL
);
3612 host_dereference (&rhp
, MDL
);
3615 memcpy (lease
-> uid
, rhp
-> client_identifier
.data
,
3616 rhp
-> client_identifier
.len
);
3617 lease
-> uid_len
= rhp
-> client_identifier
.len
;
3618 lease
-> hardware_addr
= rhp
-> interface
;
3619 lease
-> starts
= lease
-> timestamp
= lease
-> ends
= MIN_TIME
;
3620 lease
-> flags
= STATIC_LEASE
;
3621 lease
-> binding_state
= FTS_FREE
;
3623 lease_reference (lp
, lease
, MDL
);
3625 lease_dereference (&lease
, MDL
);
3626 host_dereference (&rhp
, MDL
);
3630 /* Look through all the pools in a list starting with the specified pool
3631 for a free lease. We try to find a virgin lease if we can. If we
3632 don't find a virgin lease, we try to find a non-virgin lease that's
3633 free. If we can't find one of those, we try to reclaim an abandoned
3634 lease. If all of these possibilities fail to pan out, we don't return
3637 int allocate_lease (struct lease
**lp
, struct packet
*packet
,
3638 struct pool
*pool
, int *peer_has_leases
)
3640 struct lease
*lease
= (struct lease
*)0;
3641 struct lease
*candl
= (struct lease
*)0;
3643 for (; pool
; pool
= pool
-> next
) {
3644 if ((pool
-> prohibit_list
&&
3645 permitted (packet
, pool
-> prohibit_list
)) ||
3646 (pool
-> permit_list
&&
3647 !permitted (packet
, pool
-> permit_list
)))
3650 #if defined (FAILOVER_PROTOCOL)
3651 /* Peer_has_leases just says that we found at least one
3652 free lease. If no free lease is returned, the caller
3653 can deduce that this means the peer is hogging all the
3654 free leases, so we can print a better error message. */
3655 /* XXX Do we need code here to ignore PEER_IS_OWNER and
3656 * XXX just check tstp if we're in, e.g., PARTNER_DOWN?
3657 * XXX Where do we deal with CONFLICT_DETECTED, et al? */
3658 /* XXX This should be handled by the lease binding "state
3659 * XXX machine" - that is, when we get here, if a lease
3660 * XXX could be allocated, it will have the correct
3661 * XXX binding state so that the following code will
3662 * XXX result in its being allocated. */
3663 /* Skip to the most expired lease in the pool that is not
3664 * owned by a failover peer. */
3665 if (pool
-> failover_peer
) {
3666 if (pool
-> failover_peer
-> i_am
== primary
) {
3668 *peer_has_leases
= 1;
3669 candl
= pool
-> free
;
3671 candl
= pool
-> abandoned
;
3674 *peer_has_leases
= 1;
3675 candl
= pool
-> backup
;
3681 candl
= pool
-> free
;
3683 candl
= pool
-> abandoned
;
3686 if (!candl
|| (candl
-> ends
> cur_time
))
3694 if ((lease
-> binding_state
== FTS_ABANDONED
) &&
3695 ((candl
-> binding_state
!= FTS_ABANDONED
) ||
3696 (candl
-> ends
< lease
-> ends
))) {
3699 } else if (candl
-> binding_state
== FTS_ABANDONED
)
3702 if ((lease
-> uid_len
|| lease
-> hardware_addr
.hlen
) &&
3703 ((!candl
-> uid_len
&& !candl
-> hardware_addr
.hlen
) ||
3704 (candl
-> ends
< lease
-> ends
))) {
3707 } else if (candl
-> uid_len
|| candl
-> hardware_addr
.hlen
)
3710 if (candl
-> ends
< lease
-> ends
)
3715 if (lease
-> binding_state
== FTS_ABANDONED
)
3716 log_error ("Reclaiming abandoned lease %s.",
3717 piaddr (lease
-> ip_addr
));
3719 lease_reference (lp
, lease
, MDL
);
3726 /* Determine whether or not a permit exists on a particular permit list
3727 that matches the specified packet, returning nonzero if so, zero if
3730 int permitted (packet
, permit_list
)
3731 struct packet
*packet
;
3732 struct permit
*permit_list
;
3737 for (p
= permit_list
; p
; p
= p
-> next
) {
3738 switch (p
-> type
) {
3739 case permit_unknown_clients
:
3740 if (!packet
-> known
)
3744 case permit_known_clients
:
3745 if (packet
-> known
)
3749 case permit_authenticated_clients
:
3750 if (packet
-> authenticated
)
3754 case permit_unauthenticated_clients
:
3755 if (!packet
-> authenticated
)
3759 case permit_all_clients
:
3762 case permit_dynamic_bootp_clients
:
3763 if (!packet
-> options_valid
||
3764 !packet
-> packet_type
)
3769 for (i
= 0; i
< packet
-> class_count
; i
++) {
3770 if (p
-> class == packet
-> classes
[i
])
3772 if (packet
-> classes
[i
] &&
3773 packet
-> classes
[i
] -> superclass
&&
3774 (packet
-> classes
[i
] -> superclass
==
3784 int locate_network (packet
)
3785 struct packet
*packet
;
3788 struct data_string data
;
3789 struct subnet
*subnet
= (struct subnet
*)0;
3790 struct option_cache
*oc
;
3792 /* See if there's a subnet selection option. */
3793 oc
= lookup_option (&dhcp_universe
, packet
-> options
,
3794 DHO_SUBNET_SELECTION
);
3796 /* If there's no SSO and no giaddr, then use the shared_network
3797 from the interface, if there is one. If not, fail. */
3798 if (!oc
&& !packet
-> raw
-> giaddr
.s_addr
) {
3799 if (packet
-> interface
-> shared_network
) {
3800 shared_network_reference
3801 (&packet
-> shared_network
,
3802 packet
-> interface
-> shared_network
, MDL
);
3808 /* If there's an SSO, and it's valid, use it to figure out the
3809 subnet. If it's not valid, fail. */
3811 memset (&data
, 0, sizeof data
);
3812 if (!evaluate_option_cache (&data
, packet
, (struct lease
*)0,
3813 (struct client_state
*)0,
3815 (struct option_state
*)0,
3816 &global_scope
, oc
, MDL
)) {
3819 if (data
.len
!= 4) {
3823 memcpy (ia
.iabuf
, data
.data
, 4);
3824 data_string_forget (&data
, MDL
);
3827 memcpy (ia
.iabuf
, &packet
-> raw
-> giaddr
, 4);
3830 /* If we know the subnet on which the IP address lives, use it. */
3831 if (find_subnet (&subnet
, ia
, MDL
)) {
3832 shared_network_reference (&packet
-> shared_network
,
3833 subnet
-> shared_network
, MDL
);
3834 subnet_dereference (&subnet
, MDL
);
3838 /* Otherwise, fail. */