ISC DHCP 4.4.3-P1
A reference DHCPv4 and DHCPv6 implementation
 
Loading...
Searching...
No Matches
dhcp.c
Go to the documentation of this file.
1/* dhcp.c
2
3 DHCP Protocol engine. */
4
5/*
6 * Copyright (C) 2004-2022 Internet Systems Consortium, Inc. ("ISC")
7 * Copyright (c) 1995-2003 by Internet Software Consortium
8 *
9 * This Source Code Form is subject to the terms of the Mozilla Public
10 * License, v. 2.0. If a copy of the MPL was not distributed with this
11 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 *
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.
20 *
21 * Internet Systems Consortium, Inc.
22 * PO Box 360
23 * Newmarket, NH 03857 USA
24 * <info@isc.org>
25 * https://www.isc.org/
26 *
27 */
28
29#include "dhcpd.h"
30#include <errno.h>
31#include <limits.h>
32#include <sys/time.h>
33
34static void maybe_return_agent_options(struct packet *packet,
35 struct option_state *options);
36
37static int reuse_lease (struct packet* packet, struct lease* new_lease,
38 struct lease* lease, struct lease_state *state,
39 int offer, int* same_client);
40
41static int do_ping_check(struct packet* packet, struct lease_state* state,
42 struct lease* lease, TIME original_cltt,
43 int same_client);
44
45#if defined(DHCPv6) && defined(DHCP4o6)
46static int locate_network6(struct packet *packet);
47#endif
48
50
51#if defined(DELAYED_ACK)
52static void delayed_ack_enqueue(struct lease *);
53static void delayed_acks_timer(void *);
54
55
56struct leasequeue *ackqueue_head, *ackqueue_tail;
57static struct leasequeue *free_ackqueue;
58static struct timeval max_fsync;
59
60int outstanding_acks;
64int min_ack_delay_usecs = DEFAULT_MIN_ACK_DELAY_USECS;
65#endif
66
67static char dhcp_message [256];
68static int site_code_min;
69
70static int find_min_site_code(struct universe *);
71static isc_result_t lowest_site_code(const void *, unsigned, void *);
72
73static const char *dhcp_type_names [] = {
74 "DHCPDISCOVER",
75 "DHCPOFFER",
76 "DHCPREQUEST",
77 "DHCPDECLINE",
78 "DHCPACK",
79 "DHCPNAK",
80 "DHCPRELEASE",
81 "DHCPINFORM",
82 "type 9",
83 "DHCPLEASEQUERY",
84 "DHCPLEASEUNASSIGNED",
85 "DHCPLEASEUNKNOWN",
86 "DHCPLEASEACTIVE"
87};
88const int dhcp_type_name_max = ((sizeof dhcp_type_names) / sizeof (char *));
89
90#if defined (TRACING)
91# define send_packet trace_packet_send
92#endif
93
94static TIME leaseTimeCheck(TIME calculated, TIME alternate);
95
97 struct packet *packet;
98{
99 struct option_cache *oc;
100 struct data_string client_identifier;
101 char *ci;
102
103 memset (&client_identifier, 0, sizeof client_identifier);
104
105 oc = lookup_option (&dhcp_universe, packet -> options,
107 if (oc &&
108 evaluate_option_cache (&client_identifier,
109 packet, (struct lease *)0,
110 (struct client_state *)0,
111 packet -> options,
112 (struct option_state *)0,
113 &global_scope, oc, MDL)) {
114 ci = print_hw_addr (HTYPE_INFINIBAND, client_identifier.len, client_identifier.data);
115 data_string_forget (&client_identifier, MDL);
116 return ci;
117 } else
118 return "\"no client id\"";
119}
120
122 struct packet *packet;
123{
124 if (packet -> raw -> htype == HTYPE_INFINIBAND)
126 else
127 return print_hw_addr (packet -> raw -> htype,
128 packet -> raw -> hlen,
129 packet -> raw -> chaddr);
130}
131
132void
133dhcp (struct packet *packet) {
134 int ms_nulltp = 0;
135 struct option_cache *oc;
136 struct lease *lease = NULL;
137 const char *errmsg;
138 struct data_string data;
139
140 if (!locate_network(packet) &&
144 const char *s;
145 char typebuf[32];
146 errmsg = "unknown network segment";
147 bad_packet:
148
149 if (packet->packet_type > 0 &&
151 s = dhcp_type_names[packet->packet_type - 1];
152 } else {
153 /* %Audit% Cannot exceed 28 bytes. %2004.06.17,Safe% */
154 sprintf(typebuf, "type %d", packet->packet_type);
155 s = typebuf;
156 }
157
158#if defined(DHCPv6) && defined(DHCP4o6)
159 if (dhcpv4_over_dhcpv6 && (packet->dhcp4o6_response != NULL)) {
160 log_info("DHCP4o6 %s from %s via %s: %s", s,
161 (packet->raw->htype
163 packet->raw->hlen,
164 packet->raw->chaddr)
165 : "<no identifier>"),
167 errmsg);
168 goto out;
169 }
170#endif
171
172 log_info("%s from %s via %s: %s", s,
173 (packet->raw->htype
175 : "<no identifier>"),
176 packet->raw->giaddr.s_addr
177 ? inet_ntoa(packet->raw->giaddr)
178 : packet->interface->name, errmsg);
179 goto out;
180 }
181
182 /* There is a problem with the relay agent information option,
183 * which is that in order for a normal relay agent to append
184 * this option, the relay agent has to have been involved in
185 * getting the packet from the client to the server. Note
186 * that this is the software entity known as the relay agent,
187 * _not_ the hardware entity known as a router in which the
188 * relay agent may be running, so the fact that a router has
189 * forwarded a packet does not mean that the relay agent in
190 * the router was involved.
191 *
192 * So when the client broadcasts (DHCPDISCOVER, or giaddr is set),
193 * we can be sure that there are either agent options in the
194 * packet, or there aren't supposed to be. When the giaddr is not
195 * set, it's still possible that the client is on a directly
196 * attached subnet, and agent options are being appended by an l2
197 * device that has no address, and so sets no giaddr.
198 *
199 * But in either case it's possible that the packets we receive
200 * from the client in RENEW state may not include the agent options,
201 * so if they are not in the packet we must "pretend" the last values
202 * we observed were provided.
203 */
205 packet->raw->ciaddr.s_addr && !packet->raw->giaddr.s_addr &&
207 packet->options->universes[agent_universe.index] == NULL))
208 {
209 struct iaddr cip;
210
211 cip.len = sizeof packet -> raw -> ciaddr;
212 memcpy (cip.iabuf, &packet -> raw -> ciaddr,
213 sizeof packet -> raw -> ciaddr);
214 if (!find_lease_by_ip_addr (&lease, cip, MDL))
215 goto nolease;
216
217 /* If there are no agent options on the lease, it's not
218 interesting. */
219 if (!lease -> agent_options)
220 goto nolease;
221
222 /* The client should not be unicasting a renewal if its lease
223 has expired, so make it go through the process of getting
224 its agent options legally. */
225 if (lease -> ends < cur_time)
226 goto nolease;
227
228 if (lease -> uid_len) {
229 oc = lookup_option (&dhcp_universe, packet -> options,
231 if (!oc)
233 packet -> options,
235 if (!oc)
236 goto nolease;
237
238 memset (&data, 0, sizeof data);
239 if (!evaluate_option_cache (&data,
240 packet, (struct lease *)0,
241 (struct client_state *)0,
242 packet -> options,
243 (struct option_state *)0,
244 &global_scope, oc, MDL))
245 goto nolease;
246 if (lease -> uid_len != data.len ||
247 memcmp (lease -> uid, data.data, data.len)) {
248 data_string_forget (&data, MDL);
249 goto nolease;
250 }
251 data_string_forget (&data, MDL);
252 } else
253 if ((lease -> hardware_addr.hbuf [0] !=
254 packet -> raw -> htype) ||
255 (lease -> hardware_addr.hlen - 1 !=
256 packet -> raw -> hlen) ||
257 memcmp (&lease -> hardware_addr.hbuf [1],
258 packet -> raw -> chaddr,
259 packet -> raw -> hlen))
260 goto nolease;
261
262 /* Okay, so we found a lease that matches the client. */
264 &(packet -> options -> universes
265 [agent_universe.index]),
267
270 agent_universe.index + 1;
271
273 }
274 nolease:
275
276 /* If a client null terminates options it sends, it probably
277 * expects the server to reciprocate.
278 */
279 if ((oc = lookup_option (&dhcp_universe, packet -> options,
280 DHO_HOST_NAME))) {
281 if (!oc -> expression)
282 ms_nulltp = oc->flags & OPTION_HAD_NULLS;
283 }
284
285 /* Classify the client. */
287
288 switch (packet -> packet_type) {
289 case DHCPDISCOVER:
290 dhcpdiscover (packet, ms_nulltp);
291 break;
292
293 case DHCPREQUEST:
294 dhcprequest (packet, ms_nulltp, lease);
295 break;
296
297 case DHCPRELEASE:
298 dhcprelease (packet, ms_nulltp);
299 break;
300
301 case DHCPDECLINE:
302 dhcpdecline (packet, ms_nulltp);
303 break;
304
305 case DHCPINFORM:
306 dhcpinform (packet, ms_nulltp);
307 break;
308
309 case DHCPLEASEQUERY:
310 dhcpleasequery(packet, ms_nulltp);
311 break;
312
313 case DHCPACK:
314 case DHCPOFFER:
315 case DHCPNAK:
317 case DHCPLEASEUNKNOWN:
318 case DHCPLEASEACTIVE:
319 break;
320
321 default:
322 errmsg = "unknown packet type";
323 goto bad_packet;
324 }
325 out:
326 if (lease)
327 lease_dereference (&lease, MDL);
328}
329
330void dhcpdiscover (packet, ms_nulltp)
331 struct packet *packet;
332 int ms_nulltp;
333{
334 struct lease *lease = (struct lease *)0;
335 char msgbuf [1024]; /* XXX */
336 TIME when;
337 const char *s;
338 int peer_has_leases = 0;
339#if defined (FAILOVER_PROTOCOL)
340 dhcp_failover_state_t *peer;
341#endif
342
344 0, &peer_has_leases, (struct lease *)0, MDL);
345
346 if (lease && lease -> client_hostname) {
347 if ((strlen (lease -> client_hostname) <= 64) &&
348 db_printable((unsigned char *)lease->client_hostname))
349 s = lease -> client_hostname;
350 else
351 s = "Hostname Unsuitable for Printing";
352 } else
353 s = (char *)0;
354
355 /* %Audit% This is log output. %2004.06.17,Safe%
356 * If we truncate we hope the user can get a hint from the log.
357 */
358#if defined(DHCPv6) && defined(DHCP4o6)
359 if (dhcpv4_over_dhcpv6 && (packet->dhcp4o6_response != NULL)) {
360 snprintf (msgbuf, sizeof msgbuf,
361 "DHCP4o6 DHCPDISCOVER from %s %s%s%svia %s",
362 (packet -> raw -> htype
363 ? print_hw_addr (packet -> raw -> htype,
364 packet -> raw -> hlen,
365 packet -> raw -> chaddr)
366 : (lease
368 : "<no identifier>")),
369 s ? "(" : "", s ? s : "", s ? ") " : "",
371 } else
372#endif
373 snprintf (msgbuf, sizeof msgbuf, "DHCPDISCOVER from %s %s%s%svia %s",
374 (packet -> raw -> htype
376 : (lease
378 : "<no identifier>")),
379 s ? "(" : "", s ? s : "", s ? ") " : "",
380 packet -> raw -> giaddr.s_addr
381 ? inet_ntoa (packet -> raw -> giaddr)
382 : packet -> interface -> name);
383
384 /* Sourceless packets don't make sense here. */
385 if (!packet -> shared_network) {
386#if defined(DHCPv6) && defined(DHCP4o6)
387 if (dhcpv4_over_dhcpv6 && (packet->dhcp4o6_response != NULL)) {
388 log_info ("DHCP4o6 packet from unknown subnet: %s",
390 } else
391#endif
392 log_info ("Packet from unknown subnet: %s",
393 inet_ntoa (packet -> raw -> giaddr));
394 goto out;
395 }
396
397#if defined (FAILOVER_PROTOCOL)
398 if (lease && lease -> pool && lease -> pool -> failover_peer) {
399 peer = lease -> pool -> failover_peer;
400
401 /*
402 * If the lease is ours to (re)allocate, then allocate it.
403 *
404 * If the lease is active, it belongs to the client. This
405 * is the right lease, if we are to offer one. We decide
406 * whether or not to offer later on.
407 *
408 * If the lease was last active, and we've reached this
409 * point, then it was last active with the same client. We
410 * can safely re-activate the lease with this client.
411 */
415 ; /* This space intentionally left blank. */
416
417 /* Otherwise, we can't let the client have this lease. */
418 } else {
419#if defined (DEBUG_FIND_LEASE)
420 log_debug ("discarding %s - %s",
421 piaddr (lease -> ip_addr),
423#endif
424 lease_dereference (&lease, MDL);
425 }
426 }
427#endif
428
429 /* If we didn't find a lease, try to allocate one... */
430 if (!lease) {
433 &peer_has_leases)) {
434 if (peer_has_leases)
435 log_error ("%s: peer holds all free leases",
436 msgbuf);
437 else
438 log_error ("%s: network %s: no free leases",
439 msgbuf,
440 packet -> shared_network -> name);
441 return;
442 }
443 }
444
445#if defined (FAILOVER_PROTOCOL)
446 if (lease && lease -> pool && lease -> pool -> failover_peer) {
447 peer = lease -> pool -> failover_peer;
448 if (peer -> service_state == not_responding ||
449 peer -> service_state == service_startup) {
450 log_info ("%s: not responding%s",
451 msgbuf, peer -> nrr);
452 goto out;
453 }
454 } else
455 peer = (dhcp_failover_state_t *)0;
456
457 /* Do load balancing if configured. */
458 if (peer && (peer -> service_state == cooperating) &&
459 !load_balance_mine (packet, peer)) {
460 if (peer_has_leases) {
461 log_debug ("%s: load balance to peer %s",
462 msgbuf, peer -> name);
463 goto out;
464 } else {
465 log_debug ("%s: cancel load balance to peer %s - %s",
466 msgbuf, peer -> name, "no free leases");
467 }
468 }
469#endif
470
471 /* If it's an expired lease, get rid of any bindings. */
474
475 /* Set the lease to really expire in 2 minutes, unless it has
476 not yet expired, in which case leave its expiry time alone. */
477 when = cur_time + 120;
478 if (when < lease -> ends)
479 when = lease -> ends;
480
481 ack_lease (packet, lease, DHCPOFFER, when, msgbuf, ms_nulltp,
482 (struct host_decl *)0);
483 out:
484 if (lease)
485 lease_dereference (&lease, MDL);
486}
487
488void dhcprequest (packet, ms_nulltp, ip_lease)
489 struct packet *packet;
490 int ms_nulltp;
491 struct lease *ip_lease;
492{
493 struct lease *lease;
494 struct iaddr cip;
495 struct iaddr sip;
496 struct subnet *subnet;
497 int ours = 0;
498 struct option_cache *oc;
499 struct data_string data;
500 char msgbuf [1024]; /* XXX */
501 const char *s;
502 char smbuf [19];
503#if defined (FAILOVER_PROTOCOL)
504 dhcp_failover_state_t *peer;
505#endif
506 int have_requested_addr = 0;
507
508 oc = lookup_option (&dhcp_universe, packet -> options,
510 memset (&data, 0, sizeof data);
511 if (oc &&
512 evaluate_option_cache (&data, packet, (struct lease *)0,
513 (struct client_state *)0,
514 packet -> options, (struct option_state *)0,
515 &global_scope, oc, MDL)) {
516 cip.len = 4;
517 memcpy (cip.iabuf, data.data, 4);
519 have_requested_addr = 1;
520 } else {
521 oc = (struct option_cache *)0;
522 cip.len = 4;
523 memcpy (cip.iabuf, &packet -> raw -> ciaddr.s_addr, 4);
524 }
525
526 /* Find the lease that matches the address requested by the
527 client. */
528
529 subnet = (struct subnet *)0;
530 lease = (struct lease *)0;
531 if (find_subnet (&subnet, cip, MDL))
533 subnet -> shared_network, &ours, 0, ip_lease, MDL);
534
535 if (lease && lease -> client_hostname) {
536 if ((strlen (lease -> client_hostname) <= 64) &&
537 db_printable((unsigned char *)lease->client_hostname))
538 s = lease -> client_hostname;
539 else
540 s = "Hostname Unsuitable for Printing";
541 } else
542 s = (char *)0;
543
544 oc = lookup_option (&dhcp_universe, packet -> options,
546 memset (&data, 0, sizeof data);
547 if (oc &&
548 evaluate_option_cache (&data, packet, (struct lease *)0,
549 (struct client_state *)0,
550 packet -> options, (struct option_state *)0,
551 &global_scope, oc, MDL)) {
552 sip.len = 4;
553 memcpy (sip.iabuf, data.data, 4);
554 data_string_forget (&data, MDL);
555 /* piaddr() should not return more than a 15 byte string.
556 * safe.
557 */
558 sprintf (smbuf, " (%s)", piaddr (sip));
559 } else {
560 smbuf [0] = 0;
561 sip.len = 0;
562 }
563
564 /* %Audit% This is log output. %2004.06.17,Safe%
565 * If we truncate we hope the user can get a hint from the log.
566 */
567#if defined(DHCPv6) && defined(DHCP4o6)
568 if (dhcpv4_over_dhcpv6 && (packet->dhcp4o6_response != NULL)) {
569 snprintf (msgbuf, sizeof msgbuf,
570 "DHCP4o6 DHCPREQUEST for %s%s from %s %s%s%svia %s",
571 piaddr (cip), smbuf,
572 (packet -> raw -> htype
573 ? print_hw_addr (packet -> raw -> htype,
574 packet -> raw -> hlen,
575 packet -> raw -> chaddr)
576 : (lease
578 : "<no identifier>")),
579 s ? "(" : "", s ? s : "", s ? ") " : "",
581 } else
582#endif
583 snprintf (msgbuf, sizeof msgbuf,
584 "DHCPREQUEST for %s%s from %s %s%s%svia %s",
585 piaddr (cip), smbuf,
586 (packet -> raw -> htype
588 : (lease
590 : "<no identifier>")),
591 s ? "(" : "", s ? s : "", s ? ") " : "",
592 packet -> raw -> giaddr.s_addr
593 ? inet_ntoa (packet -> raw -> giaddr)
594 : packet -> interface -> name);
595
596#if defined (FAILOVER_PROTOCOL)
597 if (lease && lease -> pool && lease -> pool -> failover_peer) {
598 peer = lease -> pool -> failover_peer;
599 if (peer -> service_state == not_responding ||
600 peer -> service_state == service_startup) {
601 log_info ("%s: not responding%s",
602 msgbuf, peer -> nrr);
603 goto out;
604 }
605
606 /* "load balance to peer" - is not done at all for request.
607 *
608 * If it's RENEWING, we are the only server to hear it, so
609 * we have to serve it. If it's REBINDING, it's out of
610 * communication with the other server, so there's no point
611 * in waiting to serve it. However, if the lease we're
612 * offering is not a free lease, then we may be the only
613 * server that can offer it, so we can't load balance if
614 * the lease isn't in the free or backup state. If it is
615 * in the free or backup state, then that state is what
616 * mandates one server or the other should perform the
617 * allocation, not the LBA...we know the peer cannot
618 * allocate a request for an address in our free state.
619 *
620 * So our only compass is lease_mine_to_reallocate(). This
621 * effects both load balancing, and a sanity-check that we
622 * are not going to try to allocate a lease that isn't ours.
623 */
624 if ((lease -> binding_state == FTS_FREE ||
627 log_debug ("%s: lease owned by peer", msgbuf);
628 goto out;
629 }
630
631 /*
632 * If the lease is in a transitional state, we can't
633 * renew it unless we can rewind it to a non-transitional
634 * state (active, free, or backup). lease_mine_to_reallocate()
635 * checks for free/backup, so we only need to check for active.
636 */
641 log_debug("%s: lease in transition state %s", msgbuf,
643 ? "released" : "expired");
644 goto out;
645 }
646
647 /* It's actually very unlikely that we'll ever get here,
648 but if we do, tell the client to stop using the lease,
649 because the administrator reset it. */
650 if (lease -> binding_state == FTS_RESET &&
652 log_debug ("%s: lease reset by administrator", msgbuf);
653 nak_lease (packet, &cip, lease->subnet->group);
654 goto out;
655 }
656
657 /* If server-id-check is enabled, verify that the client's
658 * server source address (sip from incoming packet) is ours.
659 * To avoid problems with confused clients we do some sanity
660 * checks to verify sip's length and that it isn't all zeros.
661 * We then get the server id we would likely use for this
662 * packet and compare them. If they don't match it we assume
663 * we didn't send the offer and so we don't process the
664 * request. */
665 if ((server_id_check == 1) && (sip.len == 4) &&
666 (memcmp(sip.iabuf, "\0\0\0\0", sip.len) != 0)) {
667 struct in_addr from;
668 struct option_state *eval_options = NULL;
669
670 eval_network_statements(&eval_options, packet, NULL);
671 get_server_source_address(&from, eval_options,
672 NULL, packet);
673 option_state_dereference (&eval_options, MDL);
674 if (memcmp(sip.iabuf, &from, sip.len) != 0) {
675 log_debug("%s: not our server id", msgbuf);
676 goto out;
677 }
678 }
679
680 /* At this point it's possible that we will get a broadcast
681 DHCPREQUEST for a lease that we didn't offer, because
682 both we and the peer are in a position to offer it.
683 In that case, we probably shouldn't answer. In order
684 to not answer, we would have to compare the server
685 identifier sent by the client with the list of possible
686 server identifiers we can send, and if the client's
687 identifier isn't on the list, drop the DHCPREQUEST.
688 We aren't currently doing that for two reasons - first,
689 it's not clear that all clients do the right thing
690 with respect to sending the client identifier, which
691 could mean that we might simply not respond to a client
692 that is depending on us to respond. Secondly, we allow
693 the user to specify the server identifier to send, and
694 we don't enforce that the server identifier should be
695 one of our IP addresses. This is probably not a big
696 deal, but it's theoretically an issue.
697
698 The reason we care about this is that if both servers
699 send a DHCPACK to the DHCPREQUEST, they are then going
700 to send dueling BNDUPD messages, which could cause
701 trouble. I think it causes no harm, but it seems
702 wrong. */
703 } else
704 peer = (dhcp_failover_state_t *)0;
705#endif
706
707 /* If a client on a given network REQUESTs a lease on an
708 address on a different network, NAK it. If the Requested
709 Address option was used, the protocol says that it must
710 have been broadcast, so we can trust the source network
711 information.
712
713 If ciaddr was specified and Requested Address was not, then
714 we really only know for sure what network a packet came from
715 if it came through a BOOTP gateway - if it came through an
716 IP router, we'll just have to assume that it's cool.
717
718 If we don't think we know where the packet came from, it
719 came through a gateway from an unknown network, so it's not
720 from a RENEWING client. If we recognize the network it
721 *thinks* it's on, we can NAK it even though we don't
722 recognize the network it's *actually* on; otherwise we just
723 have to ignore it.
724
725 We don't currently try to take advantage of access to the
726 raw packet, because it's not available on all platforms.
727 So a packet that was unicast to us through a router from a
728 RENEWING client is going to look exactly like a packet that
729 was broadcast to us from an INIT-REBOOT client.
730
731 Since we can't tell the difference between these two kinds
732 of packets, if the packet appears to have come in off the
733 local wire, we have to treat it as if it's a RENEWING
734 client. This means that we can't NAK a RENEWING client on
735 the local wire that has a bogus address. The good news is
736 that we won't ACK it either, so it should revert to INIT
737 state and send us a DHCPDISCOVER, which we *can* work with.
738
739 Because we can't detect that a RENEWING client is on the
740 wrong wire, it's going to sit there trying to renew until
741 it gets to the REBIND state, when we *can* NAK it because
742 the packet will get to us through a BOOTP gateway. We
743 shouldn't actually see DHCPREQUEST packets from RENEWING
744 clients on the wrong wire anyway, since their idea of their
745 local router will be wrong. In any case, the protocol
746 doesn't really allow us to NAK a DHCPREQUEST from a
747 RENEWING client, so we can punt on this issue. */
748
749 if (!packet -> shared_network ||
750 (packet -> raw -> ciaddr.s_addr &&
751 packet -> raw -> giaddr.s_addr) ||
752 (have_requested_addr && !packet -> raw -> ciaddr.s_addr)) {
753
754 /* If we don't know where it came from but we do know
755 where it claims to have come from, it didn't come
756 from there. */
757 if (!packet -> shared_network) {
758 if (subnet && subnet -> group -> authoritative) {
759 log_info ("%s: wrong network.", msgbuf);
760 nak_lease (packet, &cip, NULL);
761 goto out;
762 }
763 /* Otherwise, ignore it. */
764 log_info ("%s: ignored (%s).", msgbuf,
765 (subnet
766 ? "not authoritative" : "unknown subnet"));
767 goto out;
768 }
769
770 /* If we do know where it came from and it asked for an
771 address that is not on that shared network, nak it. */
772 if (subnet)
773 subnet_dereference (&subnet, MDL);
775 cip, MDL)) {
776 if (packet -> shared_network -> group -> authoritative)
777 {
778 log_info ("%s: wrong network.", msgbuf);
779 nak_lease (packet, &cip, NULL);
780 goto out;
781 }
782 log_info ("%s: ignored (not authoritative).", msgbuf);
783 return;
784 }
785 }
786
787 /* If the address the client asked for is ours, but it wasn't
788 available for the client, NAK it. */
789 if (!lease && ours) {
790 log_info ("%s: lease %s unavailable.", msgbuf, piaddr (cip));
791 nak_lease (packet, &cip, (subnet ? subnet->group : NULL));
792 goto out;
793 }
794
795 /* Otherwise, send the lease to the client if we found one. */
796 if (lease) {
797 ack_lease (packet, lease, DHCPACK, 0, msgbuf, ms_nulltp,
798 (struct host_decl *)0);
799 } else
800 log_info ("%s: unknown lease %s.", msgbuf, piaddr (cip));
801
802 out:
803 if (subnet)
804 subnet_dereference (&subnet, MDL);
805 if (lease)
806 lease_dereference (&lease, MDL);
807 return;
808}
809
810void dhcprelease (packet, ms_nulltp)
811 struct packet *packet;
812 int ms_nulltp;
813{
814 struct lease *lease = (struct lease *)0, *next = (struct lease *)0;
815 struct iaddr cip;
816 struct option_cache *oc;
817 struct data_string data;
818 const char *s;
819 char msgbuf [1024], cstr[16]; /* XXX */
820
821
822 /* DHCPRELEASE must not specify address in requested-address
823 option, but old protocol specs weren't explicit about this,
824 so let it go. */
825 if ((oc = lookup_option (&dhcp_universe, packet -> options,
827 log_info ("DHCPRELEASE from %s specified requested-address.",
829 }
830
831 oc = lookup_option (&dhcp_universe, packet -> options,
833 if (!oc)
834 oc = lookup_option (&dhcp_universe, packet -> options,
836 memset (&data, 0, sizeof data);
837 if (oc &&
838 evaluate_option_cache (&data, packet, (struct lease *)0,
839 (struct client_state *)0,
840 packet -> options, (struct option_state *)0,
841 &global_scope, oc, MDL)) {
842 find_lease_by_uid (&lease, data.data, data.len, MDL);
844
845 /* See if we can find a lease that matches the IP address
846 the client is claiming. */
847 while (lease) {
848 if (lease -> n_uid)
849 lease_reference (&next, lease -> n_uid, MDL);
850 if (!memcmp (&packet -> raw -> ciaddr,
851 lease -> ip_addr.iabuf, 4)) {
852 break;
853 }
854 lease_dereference (&lease, MDL);
855 if (next) {
856 lease_reference (&lease, next, MDL);
857 lease_dereference (&next, MDL);
858 }
859 }
860 if (next)
861 lease_dereference (&next, MDL);
862 }
863
864 /* The client is supposed to pass a valid client-identifier,
865 but the spec on this has changed historically, so try the
866 IP address in ciaddr if the client-identifier fails. */
867 if (!lease) {
868 cip.len = 4;
869 memcpy (cip.iabuf, &packet -> raw -> ciaddr, 4);
871 }
872
873
874 /* If the hardware address doesn't match, don't do the release. */
875 if (lease &&
876 (lease -> hardware_addr.hlen != packet -> raw -> hlen + 1 ||
877 lease -> hardware_addr.hbuf [0] != packet -> raw -> htype ||
878 memcmp (&lease -> hardware_addr.hbuf [1],
879 packet -> raw -> chaddr, packet -> raw -> hlen)))
880 lease_dereference (&lease, MDL);
881
882 if (lease && lease -> client_hostname) {
883 if ((strlen (lease -> client_hostname) <= 64) &&
884 db_printable((unsigned char *)lease->client_hostname))
885 s = lease -> client_hostname;
886 else
887 s = "Hostname Unsuitable for Printing";
888 } else
889 s = (char *)0;
890
891 /* %Audit% Cannot exceed 16 bytes. %2004.06.17,Safe%
892 * We copy this out to stack because we actually want to log two
893 * inet_ntoa()'s in this message.
894 */
895 strncpy(cstr, inet_ntoa (packet -> raw -> ciaddr), 15);
896 cstr[15] = '\0';
897
898 /* %Audit% This is log output. %2004.06.17,Safe%
899 * If we truncate we hope the user can get a hint from the log.
900 */
901#if defined(DHCPv6) && defined(DHCP4o6)
902 if (dhcpv4_over_dhcpv6 && (packet->dhcp4o6_response != NULL)) {
903 snprintf (msgbuf, sizeof msgbuf,
904 "DHCP4o6 DHCPRELEASE of %s from %s %s%s%svia "
905 "%s (%sfound)",
906 cstr,
907 (packet -> raw -> htype
908 ? print_hw_addr (packet -> raw -> htype,
909 packet -> raw -> hlen,
910 packet -> raw -> chaddr)
911 : (lease
913 : "<no identifier>")),
914 s ? "(" : "", s ? s : "", s ? ") " : "",
916 lease ? "" : "not ");
917 } else
918#endif
919 snprintf (msgbuf, sizeof msgbuf,
920 "DHCPRELEASE of %s from %s %s%s%svia %s (%sfound)",
921 cstr,
922 (packet -> raw -> htype
924 : (lease
926 : "<no identifier>")),
927 s ? "(" : "", s ? s : "", s ? ") " : "",
928 packet -> raw -> giaddr.s_addr
929 ? inet_ntoa (packet -> raw -> giaddr)
930 : packet -> interface -> name,
931 lease ? "" : "not ");
932
933#if defined (FAILOVER_PROTOCOL)
934 if (lease && lease -> pool && lease -> pool -> failover_peer) {
935 dhcp_failover_state_t *peer = lease -> pool -> failover_peer;
936 if (peer -> service_state == not_responding ||
937 peer -> service_state == service_startup) {
938 log_info ("%s: ignored%s",
939 peer -> name, peer -> nrr);
940 goto out;
941 }
942
943 /* DHCPRELEASE messages are unicast, so if the client
944 sent the DHCPRELEASE to us, it's not going to send it
945 to the peer. Not sure why this would happen, and
946 if it does happen I think we still have to change the
947 lease state, so that's what we're doing.
948 XXX See what it says in the draft about this. */
949 }
950#endif
951
952 /* If we found a lease, release it. */
953 if (lease && lease -> ends > cur_time) {
955 }
956 log_info ("%s", msgbuf);
957#if defined(FAILOVER_PROTOCOL)
958 out:
959#endif
960 if (lease)
961 lease_dereference (&lease, MDL);
962}
963
964void dhcpdecline (packet, ms_nulltp)
965 struct packet *packet;
966 int ms_nulltp;
967{
968 struct lease *lease = (struct lease *)0;
969 struct option_state *options = (struct option_state *)0;
970 int ignorep = 0;
971 int i;
972 const char *status;
973 const char *s;
974 char msgbuf [1024]; /* XXX */
975 struct iaddr cip;
976 struct option_cache *oc;
977 struct data_string data;
978
979 /* DHCPDECLINE must specify address. */
980 if (!(oc = lookup_option (&dhcp_universe, packet -> options,
982 return;
983 memset (&data, 0, sizeof data);
984 if (!evaluate_option_cache (&data, packet, (struct lease *)0,
985 (struct client_state *)0,
986 packet -> options,
987 (struct option_state *)0,
988 &global_scope, oc, MDL))
989 return;
990
991 cip.len = 4;
992 memcpy (cip.iabuf, data.data, 4);
995
996 if (lease && lease -> client_hostname) {
997 if ((strlen (lease -> client_hostname) <= 64) &&
998 db_printable((unsigned char *)lease->client_hostname))
999 s = lease -> client_hostname;
1000 else
1001 s = "Hostname Unsuitable for Printing";
1002 } else
1003 s = (char *)0;
1004
1005 /* %Audit% This is log output. %2004.06.17,Safe%
1006 * If we truncate we hope the user can get a hint from the log.
1007 */
1008#if defined(DHCPv6) && defined(DHCP4o6)
1009 if (dhcpv4_over_dhcpv6 && (packet->dhcp4o6_response != NULL)) {
1010 snprintf (msgbuf, sizeof msgbuf,
1011 "DHCP4o6 DHCPDECLINE of %s from %s %s%s%svia %s",
1012 piaddr (cip),
1013 (packet -> raw -> htype
1014 ? print_hw_addr (packet -> raw -> htype,
1015 packet -> raw -> hlen,
1016 packet -> raw -> chaddr)
1017 : (lease
1019 : "<no identifier>")),
1020 s ? "(" : "", s ? s : "", s ? ") " : "",
1022 } else
1023#endif
1024 snprintf (msgbuf, sizeof msgbuf,
1025 "DHCPDECLINE of %s from %s %s%s%svia %s",
1026 piaddr (cip),
1027 (packet -> raw -> htype
1029 : (lease
1031 : "<no identifier>")),
1032 s ? "(" : "", s ? s : "", s ? ") " : "",
1033 packet -> raw -> giaddr.s_addr
1034 ? inet_ntoa (packet -> raw -> giaddr)
1035 : packet -> interface -> name);
1036
1037 option_state_allocate (&options, MDL);
1038
1039 /* Execute statements in scope starting with the subnet scope. */
1040 if (lease)
1041 execute_statements_in_scope(NULL, packet, NULL, NULL,
1042 packet->options, options,
1043 &global_scope,
1044 lease->subnet->group,
1045 NULL, NULL);
1046
1047 /* Execute statements in the class scopes. */
1048 for (i = packet -> class_count; i > 0; i--) {
1050 (NULL, packet, NULL, NULL, packet->options, options,
1051 &global_scope, packet->classes[i - 1]->group,
1052 lease ? lease->subnet->group : NULL, NULL);
1053 }
1054
1055 /* Drop the request if dhcpdeclines are being ignored. */
1056 oc = lookup_option (&server_universe, options, SV_DECLINES);
1057 if (!oc ||
1059 (struct client_state *)0,
1060 packet -> options, options,
1061 &lease -> scope, oc, MDL)) {
1062 /* If we found a lease, mark it as unusable and complain. */
1063 if (lease) {
1064#if defined (FAILOVER_PROTOCOL)
1065 if (lease -> pool && lease -> pool -> failover_peer) {
1066 dhcp_failover_state_t *peer =
1067 lease -> pool -> failover_peer;
1068 if (peer -> service_state == not_responding ||
1069 peer -> service_state == service_startup) {
1070 if (!ignorep)
1071 log_info ("%s: ignored%s",
1072 peer -> name, peer -> nrr);
1073 goto out;
1074 }
1075
1076 /* DHCPDECLINE messages are broadcast, so we can safely
1077 ignore the DHCPDECLINE if the peer has the lease.
1078 XXX Of course, at this point that information has been
1079 lost. */
1080 }
1081#endif
1082
1083 abandon_lease (lease, "declined.");
1084 status = "abandoned";
1085 } else {
1086 status = "not found";
1087 }
1088 } else
1089 status = "ignored";
1090
1091 if (!ignorep)
1092 log_info ("%s: %s", msgbuf, status);
1093
1094#if defined(FAILOVER_PROTOCOL)
1095 out:
1096#endif
1097 if (options)
1098 option_state_dereference (&options, MDL);
1099 if (lease)
1100 lease_dereference (&lease, MDL);
1101}
1102
1103#if defined(RELAY_PORT)
1105 struct packet *packet;
1106{
1108 packet->options,
1109 RAI_RELAY_PORT) != NULL) {
1110 return (packet->client_port);
1111 }
1112
1113 return (0);
1114}
1115#endif
1116
1117void dhcpinform (packet, ms_nulltp)
1118 struct packet *packet;
1119 int ms_nulltp;
1120{
1121 char msgbuf[1024], *addr_type;
1122 struct data_string d1, prl, fixed_addr;
1123 struct option_cache *oc;
1124 struct option_state *options = NULL;
1125 struct dhcp_packet raw;
1126 struct packet outgoing;
1127 unsigned char dhcpack = DHCPACK;
1128 struct subnet *subnet = NULL;
1129 struct iaddr cip, gip, sip;
1130 unsigned i;
1131 int nulltp;
1132 struct sockaddr_in to;
1133 struct in_addr from;
1134 isc_boolean_t zeroed_ciaddr;
1135 struct interface_info *interface;
1136 int result, h_m_client_ip = 0;
1137 struct host_decl *host = NULL, *hp = NULL, *h;
1138#if defined(RELAY_PORT)
1139 u_int16_t relay_port = 0;
1140#endif
1141#if defined (DEBUG_INFORM_HOST)
1142 int h_w_fixed_addr = 0;
1143#endif
1144
1145 /* The client should set ciaddr to its IP address, but apparently
1146 it's common for clients not to do this, so we'll use their IP
1147 source address if they didn't set ciaddr. */
1148 if (!packet->raw->ciaddr.s_addr) {
1149 zeroed_ciaddr = ISC_TRUE;
1150 /* With DHCPv4-over-DHCPv6 it can be an IPv6 address
1151 so we check its length. */
1152 if (packet->client_addr.len == 4) {
1153 cip.len = 4;
1154 memcpy(cip.iabuf, &packet->client_addr.iabuf, 4);
1155 addr_type = "source";
1156 } else {
1157 cip.len = 0;
1158 memset(cip.iabuf, 0, 4);
1159 addr_type = "v4o6";
1160 }
1161 } else {
1162 zeroed_ciaddr = ISC_FALSE;
1163 cip.len = 4;
1164 memcpy(cip.iabuf, &packet->raw->ciaddr, 4);
1165 addr_type = "client";
1166 }
1167 sip.len = 4;
1168 memcpy(sip.iabuf, cip.iabuf, 4);
1169
1170 if (packet->raw->giaddr.s_addr) {
1171 gip.len = 4;
1172 memcpy(gip.iabuf, &packet->raw->giaddr, 4);
1173 if (zeroed_ciaddr == ISC_TRUE) {
1174 addr_type = "relay";
1175 memcpy(sip.iabuf, gip.iabuf, 4);
1176 }
1177 } else
1178 gip.len = 0;
1179
1180 /* %Audit% This is log output. %2004.06.17,Safe%
1181 * If we truncate we hope the user can get a hint from the log.
1182 */
1183#if defined(DHCPv6) && defined(DHCP4o6)
1184 if (dhcpv4_over_dhcpv6 && (packet->dhcp4o6_response != NULL)) {
1185 snprintf(msgbuf, sizeof(msgbuf),
1186 "DHCP4o6 DHCPINFORM from %s via %s",
1187 piaddr(cip),
1189 } else
1190#endif
1191 snprintf(msgbuf, sizeof(msgbuf), "DHCPINFORM from %s via %s",
1192 piaddr(cip),
1193 packet->raw->giaddr.s_addr ?
1194 inet_ntoa(packet->raw->giaddr) :
1196
1197 /* If the IP source address is zero, don't respond. */
1198 if (!memcmp(cip.iabuf, "\0\0\0", 4)) {
1199 log_info("%s: ignored (null source address).", msgbuf);
1200 return;
1201 }
1202
1203#if defined(RELAY_PORT)
1205#endif
1206
1207 /* Find the subnet that the client is on.
1208 * CC: Do the link selection / subnet selection
1209 */
1210
1211 option_state_allocate(&options, MDL);
1212
1214 RAI_LINK_SELECT)) == NULL)
1217
1218 memset(&d1, 0, sizeof d1);
1219 if (oc && evaluate_option_cache(&d1, packet, NULL, NULL,
1220 packet->options, NULL,
1221 &global_scope, oc, MDL)) {
1222 struct option_cache *noc = NULL;
1223
1224 if (d1.len != 4) {
1225 log_info("%s: ignored (invalid subnet selection option).", msgbuf);
1226 option_state_dereference(&options, MDL);
1227 data_string_forget(&d1, MDL);
1228 return;
1229 }
1230
1231 memcpy(sip.iabuf, d1.data, 4);
1232 data_string_forget(&d1, MDL);
1233
1234 /* Make a copy of the data. */
1235 if (option_cache_allocate(&noc, MDL)) {
1236 if (oc->data.len)
1237 data_string_copy(&noc->data, &oc->data, MDL);
1238 if (oc->expression)
1240 oc->expression, MDL);
1241 if (oc->option)
1242 option_reference(&(noc->option), oc->option,
1243 MDL);
1244 }
1245 save_option(&dhcp_universe, options, noc);
1247
1248 if ((zeroed_ciaddr == ISC_TRUE) && (gip.len != 0))
1249 addr_type = "relay link select";
1250 else
1251 addr_type = "selected";
1252 }
1253
1254 find_subnet(&subnet, sip, MDL);
1255
1256 if (subnet == NULL) {
1257 log_info("%s: unknown subnet for %s address %s",
1258 msgbuf, addr_type, piaddr(sip));
1259 option_state_dereference(&options, MDL);
1260 return;
1261 }
1262
1263 /* We don't respond to DHCPINFORM packets if we're not authoritative.
1264 It would be nice if a per-host value could override this, but
1265 there's overhead involved in checking this, so let's see how people
1266 react first. */
1267 if (!subnet->group->authoritative) {
1268 static int eso = 0;
1269 log_info("%s: not authoritative for subnet %s",
1270 msgbuf, piaddr (subnet -> net));
1271 if (!eso) {
1272 log_info("If this DHCP server is authoritative for%s",
1273 " that subnet,");
1274 log_info("please write an `authoritative;' directi%s",
1275 "ve either in the");
1276 log_info("subnet declaration or in some scope that%s",
1277 " encloses the");
1278 log_info("subnet declaration - for example, write %s",
1279 "it at the top");
1280 log_info("of the dhcpd.conf file.");
1281 }
1282 if (eso++ == 100)
1283 eso = 0;
1284 subnet_dereference(&subnet, MDL);
1285 option_state_dereference(&options, MDL);
1286 return;
1287 }
1288
1289 memset(&outgoing, 0, sizeof outgoing);
1290 memset(&raw, 0, sizeof raw);
1291 outgoing.raw = &raw;
1292
1293 maybe_return_agent_options(packet, options);
1294
1295 /* Execute statements network statements starting at the subnet level */
1296 execute_statements_in_scope(NULL, packet, NULL, NULL,
1297 packet->options, options,
1299 NULL, NULL);
1300
1301 /* If we have ciaddr, find its lease so we can find its pool. */
1302 if (zeroed_ciaddr == ISC_FALSE) {
1303 struct lease* cip_lease = NULL;
1304
1305 find_lease_by_ip_addr (&cip_lease, cip, MDL);
1306
1307 /* Overlay with pool options if ciaddr mapped to a lease. */
1308 if (cip_lease) {
1309 if (cip_lease->pool && cip_lease->pool->group) {
1311 NULL, packet, NULL, NULL,
1312 packet->options, options,
1313 &global_scope,
1314 cip_lease->pool->group,
1315 cip_lease->pool->shared_network->group,
1316 NULL);
1317 }
1318
1319 lease_dereference (&cip_lease, MDL);
1320 }
1321 }
1322
1323 /* Execute statements in the class scopes. */
1324 for (i = packet->class_count; i > 0; i--) {
1325 execute_statements_in_scope(NULL, packet, NULL, NULL,
1326 packet->options, options,
1327 &global_scope,
1328 packet->classes[i - 1]->group,
1329 subnet->group,
1330 NULL);
1331 }
1332
1333 /*
1334 * Process host declarations during DHCPINFORM,
1335 * Try to find a matching host declaration by cli ID or HW addr.
1336 *
1337 * Look through the host decls for one that matches the
1338 * client identifer or the hardware address. The preference
1339 * order is:
1340 * client id with matching ip address
1341 * hardware address with matching ip address
1342 * client id without a ip fixed address
1343 * hardware address without a fixed ip address
1344 * If found, set host to use its option definitions.
1345 */
1348 if (!oc)
1349 oc = lookup_option (&dhcp_universe, packet -> options,
1351 memset(&d1, 0, sizeof(d1));
1352 if (oc &&
1353 evaluate_option_cache(&d1, packet, NULL, NULL,
1354 packet->options, NULL,
1355 &global_scope, oc, MDL)) {
1356 find_hosts_by_uid(&hp, d1.data, d1.len, MDL);
1357 data_string_forget(&d1, MDL);
1358
1359#if defined (DEBUG_INFORM_HOST)
1360 if (hp)
1361 log_debug ("dhcpinform: found host by ID "
1362 "-- checking fixed-address match");
1363#endif
1364 /* check if we have one with fixed-address
1365 * matching the client ip first */
1366 for (h = hp; !h_m_client_ip && h; h = h->n_ipaddr) {
1367 if (!h->fixed_addr)
1368 continue;
1369
1370 memset(&fixed_addr, 0, sizeof(fixed_addr));
1371 if (!evaluate_option_cache (&fixed_addr, NULL,
1372 NULL, NULL, NULL, NULL,
1373 &global_scope,
1374 h->fixed_addr, MDL))
1375 continue;
1376
1377#if defined (DEBUG_INFORM_HOST)
1378 h_w_fixed_addr++;
1379#endif
1380 for (i = 0;
1381 (i + cip.len) <= fixed_addr.len;
1382 i += cip.len) {
1383 if (memcmp(fixed_addr.data + i,
1384 cip.iabuf, cip.len) == 0) {
1385#if defined (DEBUG_INFORM_HOST)
1386 log_debug ("dhcpinform: found "
1387 "host with matching "
1388 "fixed-address by ID");
1389#endif
1390 host_reference(&host, h, MDL);
1391 h_m_client_ip = 1;
1392 break;
1393 }
1394 }
1395 data_string_forget(&fixed_addr, MDL);
1396 }
1397
1398 /* fallback to a host without fixed-address */
1399 for (h = hp; !host && h; h = h->n_ipaddr) {
1400 if (h->fixed_addr)
1401 continue;
1402
1403#if defined (DEBUG_INFORM_HOST)
1404 log_debug ("dhcpinform: found host "
1405 "without fixed-address by ID");
1406#endif
1407 host_reference(&host, h, MDL);
1408 break;
1409 }
1410 if (hp)
1411 host_dereference (&hp, MDL);
1412 }
1413 if (!host || !h_m_client_ip) {
1415 packet->raw->chaddr,
1416 packet->raw->hlen, MDL);
1417
1418#if defined (DEBUG_INFORM_HOST)
1419 if (hp)
1420 log_debug ("dhcpinform: found host by HW "
1421 "-- checking fixed-address match");
1422#endif
1423
1424 /* check if we have one with fixed-address
1425 * matching the client ip first */
1426 for (h = hp; !h_m_client_ip && h; h = h->n_ipaddr) {
1427 if (!h->fixed_addr)
1428 continue;
1429
1430 memset (&fixed_addr, 0, sizeof(fixed_addr));
1431 if (!evaluate_option_cache (&fixed_addr, NULL,
1432 NULL, NULL, NULL, NULL,
1433 &global_scope,
1434 h->fixed_addr, MDL))
1435 continue;
1436
1437#if defined (DEBUG_INFORM_HOST)
1438 h_w_fixed_addr++;
1439#endif
1440 for (i = 0;
1441 (i + cip.len) <= fixed_addr.len;
1442 i += cip.len) {
1443 if (memcmp(fixed_addr.data + i,
1444 cip.iabuf, cip.len) == 0) {
1445#if defined (DEBUG_INFORM_HOST)
1446 log_debug ("dhcpinform: found "
1447 "host with matching "
1448 "fixed-address by HW");
1449#endif
1450 /*
1451 * Hmm.. we've found one
1452 * without IP by ID and now
1453 * (better) one with IP by HW.
1454 */
1455 if(host)
1456 host_dereference(&host, MDL);
1457 host_reference(&host, h, MDL);
1458 h_m_client_ip = 1;
1459 break;
1460 }
1461 }
1462 data_string_forget(&fixed_addr, MDL);
1463 }
1464 /* fallback to a host without fixed-address */
1465 for (h = hp; !host && h; h = h->n_ipaddr) {
1466 if (h->fixed_addr)
1467 continue;
1468
1469#if defined (DEBUG_INFORM_HOST)
1470 log_debug ("dhcpinform: found host without "
1471 "fixed-address by HW");
1472#endif
1473 host_reference (&host, h, MDL);
1474 break;
1475 }
1476
1477 if (hp)
1478 host_dereference (&hp, MDL);
1479 }
1480
1481#if defined (DEBUG_INFORM_HOST)
1482 /* Hmm..: what when there is a host with a fixed-address,
1483 * that matches by hw or id, but the fixed-addresses
1484 * didn't match client ip?
1485 */
1486 if (h_w_fixed_addr && !h_m_client_ip) {
1487 log_info ("dhcpinform: matching host with "
1488 "fixed-address different than "
1489 "client IP detected?!");
1490 }
1491#endif
1492
1493 /* If we have a host_decl structure, run the options
1494 * associated with its group. Whether the host decl
1495 * struct is old or not. */
1496 if (host) {
1497#if defined (DEBUG_INFORM_HOST)
1498 log_info ("dhcpinform: applying host (group) options");
1499#endif
1500 execute_statements_in_scope(NULL, packet, NULL, NULL,
1501 packet->options, options,
1503 subnet->group,
1504 NULL);
1505 host_dereference (&host, MDL);
1506 }
1507
1508 /* CC: end of host entry processing.... */
1509
1510 /* Figure out the filename. */
1511 memset (&d1, 0, sizeof d1);
1512 oc = lookup_option (&server_universe, options, SV_FILENAME);
1513 if (oc &&
1514 evaluate_option_cache (&d1, packet, (struct lease *)0,
1515 (struct client_state *)0,
1516 packet -> options, (struct option_state *)0,
1517 &global_scope, oc, MDL)) {
1518 i = d1.len;
1519 if (i >= sizeof(raw.file)) {
1520 log_info("file name longer than packet field "
1521 "truncated - field: %lu name: %d %.*s",
1522 (unsigned long)sizeof(raw.file), i,
1523 (int)i, d1.data);
1524 i = sizeof(raw.file);
1525 } else
1526 raw.file[i] = 0;
1527 memcpy (raw.file, d1.data, i);
1528 data_string_forget (&d1, MDL);
1529 }
1530
1531 /* Choose a server name as above. */
1533 if (oc &&
1534 evaluate_option_cache (&d1, packet, (struct lease *)0,
1535 (struct client_state *)0,
1536 packet -> options, (struct option_state *)0,
1537 &global_scope, oc, MDL)) {
1538 i = d1.len;
1539 if (i >= sizeof(raw.sname)) {
1540 log_info("server name longer than packet field "
1541 "truncated - field: %lu name: %d %.*s",
1542 (unsigned long)sizeof(raw.sname), i,
1543 (int)i, d1.data);
1544 i = sizeof(raw.sname);
1545 } else
1546 raw.sname[i] = 0;
1547 memcpy (raw.sname, d1.data, i);
1548 data_string_forget (&d1, MDL);
1549 }
1550
1551 /* Set a flag if this client is a lame Microsoft client that NUL
1552 terminates string options and expects us to do likewise. */
1553 nulltp = 0;
1554 if ((oc = lookup_option (&dhcp_universe, packet -> options,
1555 DHO_HOST_NAME))) {
1556 if (!oc->expression)
1557 nulltp = oc->flags & OPTION_HAD_NULLS;
1558 }
1559
1560 /* Put in DHCP-specific options. */
1562 oc = (struct option_cache *)0;
1563 if (option_cache_allocate (&oc, MDL)) {
1564 if (make_const_data (&oc -> expression,
1565 &dhcpack, 1, 0, 0, MDL)) {
1566 option_code_hash_lookup(&oc->option,
1567 dhcp_universe.code_hash,
1568 &i, 0, MDL);
1569 save_option (&dhcp_universe, options, oc);
1570 }
1572 }
1573
1574 get_server_source_address(&from, options, options, packet);
1575
1576 /* Use the subnet mask from the subnet declaration if no other
1577 mask has been provided. */
1578 i = DHO_SUBNET_MASK;
1579 if (subnet && !lookup_option (&dhcp_universe, options, i)) {
1580 oc = (struct option_cache *)0;
1581 if (option_cache_allocate (&oc, MDL)) {
1582 if (make_const_data (&oc -> expression,
1583 subnet -> netmask.iabuf,
1584 subnet -> netmask.len,
1585 0, 0, MDL)) {
1586 option_code_hash_lookup(&oc->option,
1587 dhcp_universe.code_hash,
1588 &i, 0, MDL);
1589 save_option (&dhcp_universe, options, oc);
1590 }
1592 }
1593 }
1594
1595 /* If a site option space has been specified, use that for
1596 site option codes. */
1598 if ((oc = lookup_option (&server_universe, options, i)) &&
1599 evaluate_option_cache (&d1, packet, (struct lease *)0,
1600 (struct client_state *)0,
1601 packet -> options, options,
1602 &global_scope, oc, MDL)) {
1603 struct universe *u = (struct universe *)0;
1604
1605 if (!universe_hash_lookup (&u, universe_hash,
1606 (const char *)d1.data, d1.len,
1607 MDL)) {
1608 log_error ("unknown option space %s.", d1.data);
1609 option_state_dereference (&options, MDL);
1610 if (subnet)
1611 subnet_dereference (&subnet, MDL);
1612 data_string_forget (&d1, MDL);
1613 return;
1614 }
1615
1616 options -> site_universe = u -> index;
1617 options->site_code_min = find_min_site_code(u);
1618 data_string_forget (&d1, MDL);
1619 } else {
1620 options -> site_universe = dhcp_universe.index;
1621 options -> site_code_min = 0; /* Trust me, it works. */
1622 }
1623
1624 memset (&prl, 0, sizeof prl);
1625
1626 /* Use the parameter list from the scope if there is one. */
1627 oc = lookup_option (&dhcp_universe, options,
1629
1630 /* Otherwise, if the client has provided a list of options
1631 that it wishes returned, use it to prioritize. Otherwise,
1632 prioritize based on the default priority list. */
1633
1634 if (!oc)
1635 oc = lookup_option (&dhcp_universe, packet -> options,
1637
1638 if (oc)
1639 evaluate_option_cache (&prl, packet, (struct lease *)0,
1640 (struct client_state *)0,
1641 packet -> options, options,
1642 &global_scope, oc, MDL);
1643
1644#ifdef DEBUG_PACKET
1646 dump_raw ((unsigned char *)packet -> raw, packet -> packet_length);
1647#endif
1648
1649 log_info ("%s", msgbuf);
1650
1651 /* Figure out the address of the boot file server. */
1652 if ((oc =
1654 if (evaluate_option_cache (&d1, packet, (struct lease *)0,
1655 (struct client_state *)0,
1656 packet -> options, options,
1657 &global_scope, oc, MDL)) {
1658 /* If there was more than one answer,
1659 take the first. */
1660 if (d1.len >= 4 && d1.data)
1661 memcpy (&raw.siaddr, d1.data, 4);
1662 data_string_forget (&d1, MDL);
1663 }
1664 }
1665
1666 /*
1667 * Remove any time options, per section 3.4 RFC 2131
1668 */
1672
1673 /* Set up the option buffer... */
1674 outgoing.packet_length =
1675 cons_options (packet, outgoing.raw, (struct lease *)0,
1676 (struct client_state *)0,
1677 0, packet -> options, options, &global_scope,
1678 0, nulltp, 0,
1679 prl.len ? &prl : (struct data_string *)0,
1680 (char *)0);
1681 option_state_dereference (&options, MDL);
1682 data_string_forget (&prl, MDL);
1683
1684 /* Make sure that the packet is at least as big as a BOOTP packet. */
1685 if (outgoing.packet_length < BOOTP_MIN_LEN)
1686 outgoing.packet_length = BOOTP_MIN_LEN;
1687
1688 raw.giaddr = packet -> raw -> giaddr;
1689 raw.ciaddr = packet -> raw -> ciaddr;
1690 memcpy (raw.chaddr, packet -> raw -> chaddr, sizeof raw.chaddr);
1691 raw.hlen = packet -> raw -> hlen;
1692 raw.htype = packet -> raw -> htype;
1693
1694 raw.xid = packet -> raw -> xid;
1695 raw.secs = packet -> raw -> secs;
1696 raw.flags = packet -> raw -> flags;
1697 raw.hops = packet -> raw -> hops;
1698 raw.op = BOOTREPLY;
1699
1700#ifdef DEBUG_PACKET
1701 dump_packet (&outgoing);
1702 dump_raw ((unsigned char *)&raw, outgoing.packet_length);
1703#endif
1704
1705#if defined(DHCPv6) && defined(DHCP4o6)
1706 if (dhcpv4_over_dhcpv6 && (packet->dhcp4o6_response != NULL)) {
1707 /* Report what we're sending. */
1708 snprintf(msgbuf, sizeof msgbuf,
1709 "DHCP4o6 DHCPACK to %s (%s) via", piaddr(cip),
1710 (packet->raw->htype && packet->raw->hlen) ?
1712 packet->raw->chaddr) :
1713 "<no client hardware address>");
1714 log_info("%s %s", msgbuf, piaddr(packet->client_addr));
1715
1716 /* fill dhcp4o6_response */
1720 outgoing.packet_length, MDL)) {
1721 log_fatal("No memory to store DHCP4o6 reply.");
1722 }
1726 outgoing.raw, outgoing.packet_length);
1727
1728 /* done */
1729 if (subnet)
1730 subnet_dereference (&subnet, MDL);
1731 return;
1732 }
1733#endif
1734
1735 /* Set up the common stuff... */
1736 to.sin_family = AF_INET;
1737#ifdef HAVE_SA_LEN
1738 to.sin_len = sizeof to;
1739#endif
1740 memset (to.sin_zero, 0, sizeof to.sin_zero);
1741
1742 /* RFC2131 states the server SHOULD unicast to ciaddr.
1743 * There are two wrinkles - relays, and when ciaddr is zero.
1744 * There's actually no mention of relays at all in rfc2131 in
1745 * regard to DHCPINFORM, except to say we might get packets from
1746 * clients via them. Note: relays unicast to clients to the
1747 * "yiaddr" address, which servers are forbidden to set when
1748 * answering an inform.
1749 *
1750 * The solution: If ciaddr is zero, and giaddr is set, go via the
1751 * relay with the broadcast flag set to help the relay (with no
1752 * yiaddr and very likely no chaddr, it will have no idea where to
1753 * send the packet).
1754 *
1755 * If the ciaddr is zero and giaddr is not set, go via the source
1756 * IP address (but you are permitted to barf on their shoes).
1757 *
1758 * If ciaddr is not zero, send the packet there always.
1759 */
1760 if (!raw.ciaddr.s_addr && gip.len) {
1761 memcpy(&to.sin_addr, gip.iabuf, 4);
1762#if defined(RELAY_PORT)
1763 to.sin_port = relay_port ? relay_port : local_port;
1764#else
1765 to.sin_port = local_port;
1766#endif
1767 raw.flags |= htons(BOOTP_BROADCAST);
1768 } else {
1769 gip.len = 0;
1770 memcpy(&to.sin_addr, cip.iabuf, 4);
1771 to.sin_port = remote_port;
1772 }
1773
1774 /* Report what we're sending. */
1775 snprintf(msgbuf, sizeof msgbuf, "DHCPACK to %s (%s) via", piaddr(cip),
1776 (packet->raw->htype && packet->raw->hlen) ?
1778 "<no client hardware address>");
1779 log_info("%s %s", msgbuf, gip.len ? piaddr(gip) :
1781
1782 errno = 0;
1784 : packet -> interface);
1785 result = send_packet(interface, &outgoing, &raw,
1786 outgoing.packet_length, from, &to, NULL);
1787 if (result < 0) {
1788 log_error ("%s:%d: Failed to send %d byte long packet over %s "
1789 "interface.", MDL, outgoing.packet_length,
1790 interface->name);
1791 }
1792
1793
1794 if (subnet)
1795 subnet_dereference (&subnet, MDL);
1796}
1797
1810void nak_lease (packet, cip, network_group)
1811 struct packet *packet;
1812 struct iaddr *cip;
1813 struct group *network_group; /* scope to use for options */
1814{
1815 struct sockaddr_in to;
1816 struct in_addr from;
1817 int result;
1818 struct dhcp_packet raw;
1819 unsigned char nak = DHCPNAK;
1820 struct packet outgoing;
1821 unsigned i;
1822#if defined(RELAY_PORT)
1823 u_int16_t relay_port = 0;
1824#endif
1825 struct option_state *options = (struct option_state *)0;
1826 struct option_cache *oc = (struct option_cache *)0;
1827 struct option_state *eval_options = NULL;
1828
1829 option_state_allocate (&options, MDL);
1830 memset (&outgoing, 0, sizeof outgoing);
1831 memset (&raw, 0, sizeof raw);
1832 outgoing.raw = &raw;
1833
1834 /* Set DHCP_MESSAGE_TYPE to DHCPNAK */
1835 if (!option_cache_allocate (&oc, MDL)) {
1836 log_error ("No memory for DHCPNAK message type.");
1837 option_state_dereference (&options, MDL);
1838 return;
1839 }
1840 if (!make_const_data (&oc -> expression, &nak, sizeof nak,
1841 0, 0, MDL)) {
1842 log_error ("No memory for expr_const expression.");
1844 option_state_dereference (&options, MDL);
1845 return;
1846 }
1848 option_code_hash_lookup(&oc->option, dhcp_universe.code_hash,
1849 &i, 0, MDL);
1850 save_option (&dhcp_universe, options, oc);
1852
1853#if defined(RELAY_PORT)
1855#endif
1856
1857 /* Set DHCP_MESSAGE to whatever the message is */
1858 if (!option_cache_allocate (&oc, MDL)) {
1859 log_error ("No memory for DHCPNAK message type.");
1860 option_state_dereference (&options, MDL);
1861 return;
1862 }
1863 if (!make_const_data (&oc -> expression,
1864 (unsigned char *)dhcp_message,
1865 strlen (dhcp_message), 1, 0, MDL)) {
1866 log_error ("No memory for expr_const expression.");
1868 option_state_dereference (&options, MDL);
1869 return;
1870 }
1871 i = DHO_DHCP_MESSAGE;
1872 option_code_hash_lookup(&oc->option, dhcp_universe.code_hash,
1873 &i, 0, MDL);
1874 save_option (&dhcp_universe, options, oc);
1876
1877 /* Setup the options at the global and subnet scopes. These
1878 * may be used to locate sever id option if enabled as well
1879 * for echo-client-id further on. (This allocates eval_options). */
1880 eval_network_statements(&eval_options, packet, network_group);
1881
1882#if defined(SERVER_ID_FOR_NAK)
1883 /* Pass in the evaluated options so they can be searched for
1884 * server-id, otherwise source address comes from the interface
1885 * address. */
1886 get_server_source_address(&from, eval_options, options, packet);
1887#else
1888 /* Get server source address from the interface address */
1889 get_server_source_address(&from, NULL, options, packet);
1890#endif /* if defined(SERVER_ID_FOR_NAK) */
1891
1892 /* If there were agent options in the incoming packet, return
1893 * them. We do not check giaddr to detect the presence of a
1894 * relay, as this excludes "l2" relay agents which have no
1895 * giaddr to set.
1896 */
1900 ((struct option_chain_head **)
1901 &(options -> universes [agent_universe.index]),
1902 (struct option_chain_head *)
1903 packet -> options -> universes [agent_universe.index],
1904 MDL);
1905 }
1906
1907 /* echo-client-id can specified at the class level so add class-scoped
1908 * options into eval_options. */
1909 for (i = packet->class_count; i > 0; i--) {
1910 execute_statements_in_scope(NULL, packet, NULL, NULL,
1911 packet->options, eval_options,
1912 &global_scope,
1913 packet->classes[i - 1]->group,
1914 NULL, NULL);
1915 }
1916
1917 /* Echo client id if we received and it's enabled */
1918 echo_client_id(packet, NULL, eval_options, options);
1919 option_state_dereference (&eval_options, MDL);
1920
1921 /* Do not use the client's requested parameter list. */
1922 delete_option (&dhcp_universe, packet -> options,
1924
1925 /* Set up the option buffer... */
1926 outgoing.packet_length =
1927 cons_options (packet, outgoing.raw, (struct lease *)0,
1928 (struct client_state *)0,
1929 0, packet -> options, options, &global_scope,
1930 0, 0, 0, (struct data_string *)0, (char *)0);
1931 option_state_dereference (&options, MDL);
1932
1933/* memset (&raw.ciaddr, 0, sizeof raw.ciaddr);*/
1934 raw.giaddr = packet -> raw -> giaddr;
1935 memcpy (raw.chaddr, packet -> raw -> chaddr, sizeof raw.chaddr);
1936 raw.hlen = packet -> raw -> hlen;
1937 raw.htype = packet -> raw -> htype;
1938
1939 raw.xid = packet -> raw -> xid;
1940 raw.secs = packet -> raw -> secs;
1941 raw.flags = packet -> raw -> flags | htons (BOOTP_BROADCAST);
1942 raw.hops = packet -> raw -> hops;
1943 raw.op = BOOTREPLY;
1944
1945 /* Make sure that the packet is at least as big as a BOOTP packet. */
1946 if (outgoing.packet_length < BOOTP_MIN_LEN)
1947 outgoing.packet_length = BOOTP_MIN_LEN;
1948
1949 /* Report what we're sending... */
1950#if defined(DHCPv6) && defined(DHCP4o6)
1951 if (dhcpv4_over_dhcpv6 && (packet->dhcp4o6_response != NULL)) {
1952 log_info ("DHCP4o6 DHCPNAK on %s to %s via %s",
1953 piaddr (*cip),
1954 print_hw_addr (packet -> raw -> htype,
1955 packet -> raw -> hlen,
1956 packet -> raw -> chaddr),
1958 } else
1959#endif
1960 log_info ("DHCPNAK on %s to %s via %s",
1961 piaddr (*cip),
1963 packet -> raw -> giaddr.s_addr
1964 ? inet_ntoa (packet -> raw -> giaddr)
1965 : packet -> interface -> name);
1966
1967#ifdef DEBUG_PACKET
1969 dump_raw ((unsigned char *)packet -> raw, packet -> packet_length);
1970 dump_packet (&outgoing);
1971 dump_raw ((unsigned char *)&raw, outgoing.packet_length);
1972#endif
1973
1974#if defined(DHCPv6) && defined(DHCP4o6)
1975 if (dhcpv4_over_dhcpv6 && (packet->dhcp4o6_response != NULL)) {
1976 /* fill dhcp4o6_response */
1980 outgoing.packet_length, MDL)) {
1981 log_fatal("No memory to store DHCP4o6 reply.");
1982 }
1986 outgoing.raw, outgoing.packet_length);
1987 return;
1988 }
1989#endif
1990
1991 /* Set up the common stuff... */
1992 to.sin_family = AF_INET;
1993#ifdef HAVE_SA_LEN
1994 to.sin_len = sizeof to;
1995#endif
1996 memset (to.sin_zero, 0, sizeof to.sin_zero);
1997
1998 /* If this was gatewayed, send it back to the gateway.
1999 Otherwise, broadcast it on the local network. */
2000 if (raw.giaddr.s_addr) {
2001 to.sin_addr = raw.giaddr;
2002 if (raw.giaddr.s_addr != htonl (INADDR_LOOPBACK))
2003#if defined(RELAY_PORT)
2004 to.sin_port = relay_port ? relay_port : local_port;
2005#else
2006 to.sin_port = local_port;
2007#endif
2008 else
2009 to.sin_port = remote_port; /* for testing. */
2010
2011 if (fallback_interface) {
2012 result = send_packet(fallback_interface, packet, &raw,
2013 outgoing.packet_length, from, &to,
2014 NULL);
2015 if (result < 0) {
2016 log_error ("%s:%d: Failed to send %d byte long "
2017 "packet over %s interface.", MDL,
2018 outgoing.packet_length,
2019 fallback_interface->name);
2020 }
2021
2022 return;
2023 }
2024 } else {
2025 to.sin_addr = limited_broadcast;
2026 to.sin_port = remote_port;
2027 }
2028
2029 errno = 0;
2030 result = send_packet(packet->interface, packet, &raw,
2031 outgoing.packet_length, from, &to, NULL);
2032 if (result < 0) {
2033 log_error ("%s:%d: Failed to send %d byte long packet over %s "
2034 "interface.", MDL, outgoing.packet_length,
2036 }
2037
2038}
2039
2058void echo_client_id(packet, lease, in_options, out_options)
2059 struct packet *packet;
2060 struct lease *lease;
2061 struct option_state *in_options;
2062 struct option_state *out_options;
2063{
2064 struct option_cache *oc;
2065 int ignorep;
2066
2067 /* Check if echo-client-id is enabled */
2069 if (oc && evaluate_boolean_option_cache(&ignorep, packet, lease,
2070 NULL, packet->options,
2071 in_options,
2072 (lease ? &lease->scope : NULL),
2073 oc, MDL)) {
2074 struct data_string client_id;
2075 unsigned int opcode = DHO_DHCP_CLIENT_IDENTIFIER;
2076
2077 /* Save knowledge that echo is enabled to the packet */
2079
2080 /* Now see if inbound packet contains client-id */
2081 oc = lookup_option(&dhcp_universe, packet->options, opcode);
2082 memset(&client_id, 0, sizeof client_id);
2083 if (oc && evaluate_option_cache(&client_id,
2084 packet, NULL, NULL,
2085 packet->options, NULL,
2086 (lease ? &lease->scope : NULL),
2087 oc, MDL)) {
2088 /* Packet contained client-id, add it to out_options. */
2089 oc = NULL;
2090 if (option_cache_allocate(&oc, MDL)) {
2091 if (make_const_data(&oc->expression,
2092 client_id.data,
2093 client_id.len,
2094 1, 0, MDL)) {
2095 option_code_hash_lookup(&oc->option,
2097 code_hash,
2098 &opcode,
2099 0, MDL);
2101 out_options, oc);
2102 }
2104 }
2105 }
2106 }
2107}
2108
2110 struct packet *packet;
2111 struct lease *lease;
2112 struct lease_state *state;
2113
2114{
2115
2116 struct pool *pool = lease->pool;
2117 int used, count, high_threshold, poolhigh = 0, poollow = 0;
2118 char *shared_name = "no name";
2119
2120 if (pool == NULL)
2121 return;
2122
2123 /* get a pointer to the name if we have one */
2124 if ((pool->shared_network != NULL) &&
2125 (pool->shared_network->name != NULL)) {
2126 shared_name = pool->shared_network->name;
2127 }
2128
2129 count = pool->lease_count;
2130 used = count - (pool->free_leases + pool->backup_leases);
2131
2132 /* The logged flag indicates if we have already crossed the high
2133 * threshold and emitted a log message. If it is set we check to
2134 * see if we have re-crossed the low threshold and need to reset
2135 * things. When we cross the high threshold we determine what
2136 * the low threshold is and save it into the low_threshold value.
2137 * When we cross that threshold we reset the logged flag and
2138 * the low_threshold to 0 which allows the high threshold message
2139 * to be emitted once again.
2140 * if we haven't recrossed the boundry we don't need to do anything.
2141 */
2142 if (pool->logged !=0) {
2143 if (used <= pool->low_threshold) {
2144 pool->low_threshold = 0;
2145 pool->logged = 0;
2146 log_error("Pool threshold reset - shared subnet: %s; "
2147 "address: %s; low threshold %d/%d.",
2148 shared_name, piaddr(lease->ip_addr),
2149 used, count);
2150 }
2151 return;
2152 }
2153
2154 /* find the high threshold */
2155 if (get_option_int(&poolhigh, &server_universe, packet, lease, NULL,
2156 packet->options, state->options, state->options,
2158 /* no threshold bail out */
2159 return;
2160 }
2161
2162 /* We do have a threshold for this pool, see if its valid */
2163 if ((poolhigh <= 0) || (poolhigh > 100)) {
2164 /* not valid */
2165 return;
2166 }
2167
2168 /* we have a valid value, have we exceeded it */
2169 high_threshold = FIND_PERCENT(count, poolhigh);
2170 if (used < high_threshold) {
2171 /* nope, no more to do */
2172 return;
2173 }
2174
2175 /* we've exceeded it, output a message */
2176 log_error("Pool threshold exceeded - shared subnet: %s; "
2177 "address: %s; high threshold %d%% %d/%d.",
2178 shared_name, piaddr(lease->ip_addr),
2179 poolhigh, used, count);
2180
2181 /* handle the low threshold now, if we don't
2182 * have a valid one we default to 0. */
2183 if ((get_option_int(&poollow, &server_universe, packet, lease, NULL,
2184 packet->options, state->options, state->options,
2185 &lease->scope, SV_LOG_THRESHOLD_LOW, MDL) == 0) ||
2186 (poollow > 100)) {
2187 poollow = 0;
2188 }
2189
2190 /*
2191 * If the low theshold is higher than the high threshold we continue to log
2192 * If it isn't then we set the flag saying we already logged and determine
2193 * what the reset threshold is.
2194 */
2195 if (poollow < poolhigh) {
2196 pool->logged = 1;
2197 pool->low_threshold = FIND_PERCENT(count, poollow);
2198 }
2199}
2200
2201void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
2202 struct packet *packet;
2203 struct lease *lease;
2204 unsigned int offer;
2205 TIME when;
2206 char *msg;
2207 int ms_nulltp;
2208 struct host_decl *hp;
2209{
2210 struct lease *lt;
2211 struct lease_state *state;
2212 struct lease *next;
2213 struct host_decl *host = (struct host_decl *)0;
2214 TIME lease_time;
2215 TIME offered_lease_time;
2216 struct data_string d1;
2217 TIME min_lease_time;
2220 struct option_cache *oc;
2221 isc_result_t result;
2222 TIME original_cltt;
2223 struct in_addr from;
2224 TIME remaining_time;
2225 struct iaddr cip;
2226#if defined(DELAYED_ACK)
2227 /* By default we don't do the enqueue */
2228 isc_boolean_t enqueue = ISC_FALSE;
2229#endif
2230 int use_old_lease = 0;
2231 int same_client = 0;
2232
2233 unsigned i, j;
2234 int s1;
2235 int ignorep;
2236
2237 /* If we're already acking this lease, don't do it again. */
2238 if (lease -> state)
2239 return;
2240
2241 /* Save original cltt for comparison later. */
2242 original_cltt = lease->cltt;
2243
2244 /* If the lease carries a host record, remember it. */
2245 if (hp)
2246 host_reference (&host, hp, MDL);
2247 else if (lease -> host)
2248 host_reference (&host, lease -> host, MDL);
2249
2250 /* Allocate a lease state structure... */
2251 state = new_lease_state (MDL);
2252 if (!state)
2253 log_fatal ("unable to allocate lease state!");
2254 state -> got_requested_address = packet -> got_requested_address;
2255 shared_network_reference (&state -> shared_network,
2256 packet -> interface -> shared_network, MDL);
2257
2258 /* See if we got a server identifier option. */
2261 state -> got_server_identifier = 1;
2262
2263 maybe_return_agent_options(packet, state->options);
2264
2265 /* If we are offering a lease that is still currently valid, preserve
2266 the events. We need to do this because if the client does not
2267 REQUEST our offer, it will expire in 2 minutes, overriding the
2268 expire time in the currently in force lease. We want the expire
2269 events to be executed at that point. */
2270 if (lease->ends <= cur_time && offer != DHCPOFFER) {
2271 /* Get rid of any old expiry or release statements - by
2272 executing the statements below, we will be inserting new
2273 ones if there are any to insert. */
2274 if (lease->on_star.on_expiry)
2277 if (lease->on_star.on_commit)
2283 }
2284
2285 /* Execute statements in scope starting with the subnet scope. */
2287 NULL, packet->options,
2288 state->options, &lease->scope,
2289 lease->subnet->group, NULL, NULL);
2290
2291 /* If the lease is from a pool, run the pool scope. */
2292 if (lease->pool)
2294 packet->options, state->options,
2295 &lease->scope, lease->pool->group,
2296 lease->pool->
2298 NULL));
2299
2300 /* Execute statements from class scopes. */
2301 for (i = packet -> class_count; i > 0; i--) {
2303 packet->options, state->options,
2304 &lease->scope,
2305 packet->classes[i - 1]->group,
2306 (lease->pool ? lease->pool->group
2307 : lease->subnet->group),
2308 NULL);
2309 }
2310
2311 /* See if the client is only supposed to have one lease at a time,
2312 and if so, find its other leases and release them. We can only
2313 do this on DHCPREQUEST. It's a little weird to do this before
2314 looking at permissions, because the client might not actually
2315 _get_ a lease after we've done the permission check, but the
2316 assumption for this option is that the client has exactly one
2317 network interface, and will only ever remember one lease. So
2318 if it sends a DHCPREQUEST, and doesn't get the lease, it's already
2319 forgotten about its old lease, so we can too. */
2320 if (packet -> packet_type == DHCPREQUEST &&
2321 (oc = lookup_option (&server_universe, state -> options,
2324 packet, lease,
2325 (struct client_state *)0,
2326 packet -> options,
2327 state -> options, &lease -> scope,
2328 oc, MDL)) {
2329 struct lease *seek;
2330 if (lease -> uid_len) {
2331 do {
2332 seek = (struct lease *)0;
2333 find_lease_by_uid (&seek, lease -> uid,
2334 lease -> uid_len, MDL);
2335 if (!seek)
2336 break;
2337 if (seek == lease && !seek -> n_uid) {
2338 lease_dereference (&seek, MDL);
2339 break;
2340 }
2341 next = (struct lease *)0;
2342
2343 /* Don't release expired leases, and don't
2344 release the lease we're going to assign. */
2345 next = (struct lease *)0;
2346 while (seek) {
2347 if (seek -> n_uid)
2348 lease_reference (&next, seek -> n_uid, MDL);
2349 if (seek != lease &&
2350 seek -> binding_state != FTS_RELEASED &&
2351 seek -> binding_state != FTS_EXPIRED &&
2352 seek -> binding_state != FTS_RESET &&
2353 seek -> binding_state != FTS_FREE &&
2354 seek -> binding_state != FTS_BACKUP)
2355 break;
2356 lease_dereference (&seek, MDL);
2357 if (next) {
2358 lease_reference (&seek, next, MDL);
2359 lease_dereference (&next, MDL);
2360 }
2361 }
2362 if (next)
2363 lease_dereference (&next, MDL);
2364 if (seek) {
2365 release_lease (seek, packet);
2366 lease_dereference (&seek, MDL);
2367 } else
2368 break;
2369 } while (1);
2370 }
2371 if (!lease -> uid_len ||
2372 (host &&
2373 !host -> client_identifier.len &&
2374 (oc = lookup_option (&server_universe, state -> options,
2375 SV_DUPLICATES)) &&
2377 (struct client_state *)0,
2378 packet -> options,
2379 state -> options,
2380 &lease -> scope,
2381 oc, MDL))) {
2382 do {
2383 seek = (struct lease *)0;
2385 (&seek, lease -> hardware_addr.hbuf,
2387 if (!seek)
2388 break;
2389 if (seek == lease && !seek -> n_hw) {
2390 lease_dereference (&seek, MDL);
2391 break;
2392 }
2393 next = (struct lease *)0;
2394 while (seek) {
2395 if (seek -> n_hw)
2396 lease_reference (&next, seek -> n_hw, MDL);
2397 if (seek != lease &&
2398 seek -> binding_state != FTS_RELEASED &&
2399 seek -> binding_state != FTS_EXPIRED &&
2400 seek -> binding_state != FTS_RESET &&
2401 seek -> binding_state != FTS_FREE &&
2402 seek -> binding_state != FTS_BACKUP)
2403 break;
2404 lease_dereference (&seek, MDL);
2405 if (next) {
2406 lease_reference (&seek, next, MDL);
2407 lease_dereference (&next, MDL);
2408 }
2409 }
2410 if (next)
2411 lease_dereference (&next, MDL);
2412 if (seek) {
2413 release_lease (seek, packet);
2414 lease_dereference (&seek, MDL);
2415 } else
2416 break;
2417 } while (1);
2418 }
2419 }
2420
2421
2422 /* Make sure this packet satisfies the configured minimum
2423 number of seconds. */
2424 memset (&d1, 0, sizeof d1);
2425 if (offer == DHCPOFFER &&
2426 (oc = lookup_option (&server_universe, state -> options,
2427 SV_MIN_SECS))) {
2429 (struct client_state *)0,
2430 packet -> options, state -> options,
2431 &lease -> scope, oc, MDL)) {
2432 if (d1.len &&
2433 ntohs (packet -> raw -> secs) < d1.data [0]) {
2434 log_info("%s: configured min-secs value (%d) "
2435 "is greater than secs field (%d). "
2436 "message dropped.", msg, d1.data[0],
2437 ntohs(packet->raw->secs));
2438 data_string_forget (&d1, MDL);
2440 if (host)
2441 host_dereference (&host, MDL);
2442 return;
2443 }
2444 data_string_forget (&d1, MDL);
2445 }
2446 }
2447
2448 /* Try to find a matching host declaration for this lease.
2449 */
2450 if (!host) {
2451 struct host_decl *hp = (struct host_decl *)0;
2452 struct host_decl *h;
2453
2454 /* Try to find a host_decl that matches the client
2455 identifier or hardware address on the packet, and
2456 has no fixed IP address. If there is one, hang
2457 it off the lease so that its option definitions
2458 can be used. */
2459 oc = lookup_option (&dhcp_universe, packet -> options,
2461 if (!oc)
2462 oc = lookup_option (&dhcp_universe, packet -> options,
2464 if (oc &&
2466 (struct client_state *)0,
2467 packet -> options, state -> options,
2468 &lease -> scope, oc, MDL)) {
2469 find_hosts_by_uid (&hp, d1.data, d1.len, MDL);
2470 data_string_forget (&d1, MDL);
2471 for (h = hp; h; h = h -> n_ipaddr) {
2472 if (!h -> fixed_addr)
2473 break;
2474 }
2475 if (h)
2476 host_reference (&host, h, MDL);
2477 if (hp != NULL)
2478 host_dereference(&hp, MDL);
2479 }
2480 if (!host) {
2482 packet -> raw -> htype,
2483 packet -> raw -> chaddr,
2484 packet -> raw -> hlen,
2485 MDL);
2486 for (h = hp; h; h = h -> n_ipaddr) {
2487 if (!h -> fixed_addr)
2488 break;
2489 }
2490 if (h)
2491 host_reference (&host, h, MDL);
2492 if (hp != NULL)
2493 host_dereference(&hp, MDL);
2494 }
2495 if (!host) {
2497 packet->options, MDL);
2498 for (h = hp; h; h = h -> n_ipaddr) {
2499 if (!h -> fixed_addr)
2500 break;
2501 }
2502 if (h)
2503 host_reference (&host, h, MDL);
2504 if (hp != NULL)
2505 host_dereference(&hp, MDL);
2506 }
2507 }
2508
2509 /* If we have a host_decl structure, run the options associated
2510 with its group. Whether the host decl struct is old or not. */
2511 if (host)
2513 packet->options, state->options,
2514 &lease->scope, host->group,
2515 (lease->pool
2516 ? lease->pool->group
2517 : lease->subnet->group),
2518 NULL);
2519
2520 /* Drop the request if it's not allowed for this client. By
2521 default, unknown clients are allowed. */
2522 if (!host &&
2523 (oc = lookup_option (&server_universe, state -> options,
2526 packet, lease,
2527 (struct client_state *)0,
2528 packet -> options,
2529 state -> options,
2530 &lease -> scope, oc, MDL)) {
2531 if (!ignorep)
2532 log_info ("%s: unknown client", msg);
2533 free_lease_state (state, MDL);
2534 if (host)
2535 host_dereference (&host, MDL);
2536 return;
2537 }
2538
2539 /* Drop the request if it's not allowed for this client. */
2540 if (!offer &&
2541 (oc = lookup_option (&server_universe, state -> options,
2542 SV_ALLOW_BOOTP)) &&
2544 packet, lease,
2545 (struct client_state *)0,
2546 packet -> options,
2547 state -> options,
2548 &lease -> scope, oc, MDL)) {
2549 if (!ignorep)
2550 log_info ("%s: bootp disallowed", msg);
2551 free_lease_state (state, MDL);
2552 if (host)
2553 host_dereference (&host, MDL);
2554 return;
2555 }
2556
2557 /* Drop the request if booting is specifically denied. */
2558 oc = lookup_option (&server_universe, state -> options,
2560 if (oc &&
2562 packet, lease,
2563 (struct client_state *)0,
2564 packet -> options,
2565 state -> options,
2566 &lease -> scope, oc, MDL)) {
2567 if (!ignorep)
2568 log_info ("%s: booting disallowed", msg);
2569 free_lease_state (state, MDL);
2570 if (host)
2571 host_dereference (&host, MDL);
2572 return;
2573 }
2574
2575 /* If we are configured to do per-class billing, do it. */
2577 /* See if the lease is currently being billed to a
2578 class, and if so, whether or not it can continue to
2579 be billed to that class. */
2580 if (lease -> billing_class) {
2581 for (i = 0; i < packet -> class_count; i++)
2582 if (packet -> classes [i] ==
2583 lease -> billing_class)
2584 break;
2585 if (i == packet -> class_count) {
2587 /* Active lease billing change negates reuse */
2588 if (lease->binding_state == FTS_ACTIVE) {
2589 lease->cannot_reuse = 1;
2590 }
2591 }
2592 }
2593
2594 /* If we don't have an active billing, see if we need
2595 one, and if we do, try to do so. */
2596 if (lease->billing_class == NULL) {
2597 char *cname = "";
2598 int bill = 0;
2599
2600 for (i = 0; i < packet->class_count; i++) {
2601 struct class *billclass, *superclass;
2602
2603 billclass = packet->classes[i];
2604 if (billclass->lease_limit) {
2605 bill++;
2606 if (bill_class(lease, billclass))
2607 break;
2608
2609 superclass = billclass->superclass;
2610 if (superclass != NULL)
2611 cname = superclass->name;
2612 else
2613 cname = billclass->name;
2614 }
2615 }
2616 if (bill != 0 && i == packet->class_count) {
2617 log_info("%s: no available billing: lease "
2618 "limit reached in all matching "
2619 "classes (last: '%s')", msg, cname);
2620 free_lease_state(state, MDL);
2621 if (host)
2622 host_dereference(&host, MDL);
2623 return;
2624 }
2625
2626 /*
2627 * If this is an offer, undo the billing. We go
2628 * through all the steps above to bill a class so
2629 * we can hit the 'no available billing' mark and
2630 * abort without offering. But it just doesn't make
2631 * sense to permanently bill a class for a non-active
2632 * lease. This means on REQUEST, we will bill this
2633 * lease again (if there is a REQUEST).
2634 */
2635 if (offer == DHCPOFFER &&
2636 lease->billing_class != NULL &&
2639
2640 /* Lease billing change negates reuse */
2641 if (lease->billing_class != NULL) {
2642 lease->cannot_reuse = 1;
2643 }
2644 }
2645 }
2646
2647 /* Figure out the filename. */
2648 oc = lookup_option (&server_universe, state -> options, SV_FILENAME);
2649 if (oc)
2650 evaluate_option_cache (&state -> filename, packet, lease,
2651 (struct client_state *)0,
2652 packet -> options, state -> options,
2653 &lease -> scope, oc, MDL);
2654
2655 /* Choose a server name as above. */
2656 oc = lookup_option (&server_universe, state -> options,
2658 if (oc)
2659 evaluate_option_cache (&state -> server_name, packet, lease,
2660 (struct client_state *)0,
2661 packet -> options, state -> options,
2662 &lease -> scope, oc, MDL);
2663
2664 /* At this point, we have a lease that we can offer the client.
2665 Now we construct a lease structure that contains what we want,
2666 and call supersede_lease to do the right thing with it. */
2667 lt = (struct lease *)0;
2668 result = lease_allocate (&lt, MDL);
2669 if (result != ISC_R_SUCCESS) {
2670 log_info ("%s: can't allocate temporary lease structure: %s",
2671 msg, isc_result_totext (result));
2673 if (host)
2674 host_dereference (&host, MDL);
2675 return;
2676 }
2677
2678 /* Use the ip address of the lease that we finally found in
2679 the database. */
2680 lt -> ip_addr = lease -> ip_addr;
2681
2682 /* Start now. */
2683 lt -> starts = cur_time;
2684
2685 /* Figure out how long a lease to assign. If this is a
2686 dynamic BOOTP lease, its duration must be infinite. */
2687 if (offer) {
2688 lt->flags &= ~BOOTP_LEASE;
2689
2691 if ((oc = lookup_option (&server_universe, state -> options,
2694 (struct client_state *)0,
2695 packet -> options,
2696 state -> options,
2697 &lease -> scope, oc, MDL)) {
2698 if (d1.len == sizeof (u_int32_t))
2700 getULong (d1.data);
2701 data_string_forget (&d1, MDL);
2702 }
2703 }
2704
2705 if ((oc = lookup_option (&dhcp_universe, packet -> options,
2708 (struct client_state *)0,
2709 packet -> options,
2710 state -> options,
2711 &lease -> scope, oc, MDL);
2712 else
2713 s1 = 0;
2714
2715 if (s1 && (d1.len == 4)) {
2716 u_int32_t ones = 0xffffffff;
2717
2718 /* One potential use of reserved leases is to allow
2719 * clients to signal reservation of their lease. They
2720 * can kinda sorta do this, if you squint hard enough,
2721 * by supplying an 'infinite' requested-lease-time
2722 * option. This is generally bad practice...you want
2723 * clients to return to the server on at least some
2724 * period (days, months, years) to get up-to-date
2725 * config state. So;
2726 *
2727 * 1) A client requests 0xffffffff lease-time.
2728 * 2) The server reserves the lease, and assigns a
2729 * <= max_lease_time lease-time to the client, which
2730 * we presume is much smaller than 0xffffffff.
2731 * 3) The client ultimately fails to renew its lease
2732 * (all clients go offline at some point).
2733 * 4) The server retains the reservation, although
2734 * the lease expires and passes through those states
2735 * as normal, it's placed in the 'reserved' queue,
2736 * and is under no circumstances allocated to any
2737 * clients.
2738 *
2739 * Whether the client knows its reserving its lease or
2740 * not, this can be a handy tool for a sysadmin.
2741 */
2742 if ((memcmp(d1.data, &ones, 4) == 0) &&
2744 state->options,
2747 lease, NULL, packet->options,
2749 oc, MDL)) {
2750 lt->flags |= RESERVED_LEASE;
2751 if (!ignorep)
2752 log_info("Infinite-leasetime "
2753 "reservation made on %s.",
2754 piaddr(lt->ip_addr));
2755 }
2756
2757 lease_time = getULong (d1.data);
2758 } else
2759 lease_time = default_lease_time;
2760
2761 if (s1)
2762 data_string_forget(&d1, MDL);
2763
2764 /* See if there's a maximum lease time. */
2766 if ((oc = lookup_option (&server_universe, state -> options,
2769 (struct client_state *)0,
2770 packet -> options,
2771 state -> options,
2772 &lease -> scope, oc, MDL)) {
2773 if (d1.len == sizeof (u_int32_t))
2775 getULong (d1.data);
2776 data_string_forget (&d1, MDL);
2777 }
2778 }
2779
2780 /* Enforce the maximum lease length. */
2781 if (lease_time < 0 /* XXX */
2782 || lease_time > max_lease_time)
2783 lease_time = max_lease_time;
2784
2785 min_lease_time = DEFAULT_MIN_LEASE_TIME;
2786 if (min_lease_time > max_lease_time)
2787 min_lease_time = max_lease_time;
2788
2789 if ((oc = lookup_option (&server_universe, state -> options,
2792 (struct client_state *)0,
2793 packet -> options,
2794 state -> options,
2795 &lease -> scope, oc, MDL)) {
2796 if (d1.len == sizeof (u_int32_t))
2797 min_lease_time = getULong (d1.data);
2798 data_string_forget (&d1, MDL);
2799 }
2800 }
2801
2802 /* CC: If there are less than
2803 adaptive-lease-time-threshold % free leases,
2804 hand out only short term leases */
2805
2806 memset(&d1, 0, sizeof(d1));
2807 if (lease->pool &&
2812 &lease->scope, oc, MDL)) {
2813 if (d1.len == 1 && d1.data[0] > 0 &&
2814 d1.data[0] < 100) {
2815 TIME adaptive_time;
2816 int poolfilled, total, count;
2817
2818 if (min_lease_time)
2819 adaptive_time = min_lease_time;
2820 else
2821 adaptive_time = DEFAULT_MIN_LEASE_TIME;
2822
2823 /* Allow the client to keep its lease. */
2824 if (lease->ends - cur_time > adaptive_time)
2825 adaptive_time = lease->ends - cur_time;
2826
2827 count = lease->pool->lease_count;
2828 total = count - (lease->pool->free_leases +
2830
2831 poolfilled = (total > (INT_MAX / 100)) ?
2832 total / (count / 100) :
2833 (total * 100) / count;
2834
2835 log_debug("Adap-lease: Total: %d, Free: %d, "
2836 "Ends: %d, Adaptive: %d, Fill: %d, "
2837 "Threshold: %d",
2840 (int)(lease->ends - cur_time),
2841 (int)adaptive_time, poolfilled,
2842 d1.data[0]);
2843
2844 if (poolfilled >= d1.data[0] &&
2845 lease_time > adaptive_time) {
2846 log_info("Pool over threshold, time "
2847 "for %s reduced from %d to "
2848 "%d.", piaddr(lease->ip_addr),
2849 (int)lease_time,
2850 (int)adaptive_time);
2851
2852 lease_time = adaptive_time;
2853 }
2854 }
2855 data_string_forget(&d1, MDL);
2856 }
2857
2858
2859 /*
2860 * If this is an ack check to see if we have used enough of
2861 * the pool to want to log a message
2862 */
2863 if (offer == DHCPACK)
2865
2866 /* a client requests an address which is not yet active*/
2867 if (lease->pool && lease->pool->valid_from &&
2869 /* NAK leases before pool activation date */
2870 cip.len = 4;
2871 memcpy (cip.iabuf, &lt->ip_addr.iabuf, 4);
2872 nak_lease(packet, &cip, lease->subnet->group);
2874 lease_dereference (&lt, MDL);
2875 if (host)
2876 host_dereference (&host, MDL);
2877 return;
2878
2879 }
2880
2881 /* CC:
2882 a) NAK current lease if past the expiration date
2883 b) extend lease only up to the expiration date, but not
2884 below min-lease-time
2885 Setting min-lease-time is essential for this to work!
2886 The value of min-lease-time determines the length
2887 of the transition window:
2888 A client renewing a second before the deadline will
2889 get a min-lease-time lease. Since the current ip might not
2890 be routable after the deadline, the client will
2891 be offline until it DISCOVERS again. Otherwise it will
2892 receive a NAK at T/2.
2893 A min-lease-time of 6 seconds effectively switches over
2894 all clients in this pool very quickly.
2895 */
2896
2897 if (lease->pool && lease->pool->valid_until) {
2898 if (cur_time >= lease->pool->valid_until) {
2899 /* NAK leases after pool expiration date */
2900 cip.len = 4;
2901 memcpy (cip.iabuf, &lt->ip_addr.iabuf, 4);
2902 nak_lease(packet, &cip, lease->subnet->group);
2904 lease_dereference (&lt, MDL);
2905 if (host)
2906 host_dereference (&host, MDL);
2907 return;
2908 }
2909 remaining_time = lease->pool->valid_until - cur_time;
2910 if (lease_time > remaining_time)
2911 lease_time = remaining_time;
2912 }
2913
2914 if (lease_time < min_lease_time) {
2915 if (min_lease_time)
2916 lease_time = min_lease_time;
2917 else
2918 lease_time = default_lease_time;
2919 }
2920
2921
2922#if defined (FAILOVER_PROTOCOL)
2923 /* Okay, we know the lease duration. Now check the
2924 failover state, if any. */
2925 if (lease -> pool && lease -> pool -> failover_peer) {
2926 TIME new_lease_time = lease_time;
2927 dhcp_failover_state_t *peer =
2928 lease -> pool -> failover_peer;
2929
2930 /* Copy previous lease failover ack-state. */
2931 lt->tsfp = lease->tsfp;
2932 lt->atsfp = lease->atsfp;
2933
2934 /* cltt set below */
2935
2936 /* Lease times less than MCLT are not a concern. */
2937 if (lease_time > peer->mclt) {
2938 /* Each server can only offer a lease time
2939 * that is either equal to MCLT (at least),
2940 * or up to TSFP+MCLT. Only if the desired
2941 * lease time falls within TSFP+MCLT, can
2942 * the server allow it.
2943 */
2944 if (lt->tsfp <= cur_time)
2945 new_lease_time = peer->mclt;
2946 else if ((cur_time + lease_time) >
2947 (lt->tsfp + peer->mclt))
2948 new_lease_time = (lt->tsfp - cur_time)
2949 + peer->mclt;
2950 }
2951
2952 /* Update potential expiry. Allow for the desired
2953 * lease time plus one half the actual (whether
2954 * modified downward or not) lease time, which is
2955 * actually an estimate of when the client will
2956 * renew. This way, the client will be able to get
2957 * the desired lease time upon renewal.
2958 */
2959 if (offer == DHCPACK) {
2960 if (lease_time == INFINITE_TIME) {
2961 lt->tstp = MAX_TIME;
2962 } else {
2963 lt->tstp =
2964 leaseTimeCheck(
2965 (cur_time + lease_time
2966 + (new_lease_time / 2)),
2967 MAX_TIME - 1);
2968 }
2969
2970 /* If we reduced the potential expiry time,
2971 * make sure we don't offer an old-expiry-time
2972 * lease for this lease before the change is
2973 * ack'd.
2974 */
2975 if (lt->tstp < lt->tsfp)
2976 lt->tsfp = lt->tstp;
2977 } else
2978 lt->tstp = lease->tstp;
2979
2980 /* Use failover-modified lease time. */
2981 lease_time = new_lease_time;
2982 }
2983#endif /* FAILOVER_PROTOCOL */
2984
2985 if (lease_time == INFINITE_TIME) {
2987 } else {
2988 /* If the lease duration causes the time value to wrap,
2989 use the maximum expiry time. */
2991 = leaseTimeCheck(cur_time + lease_time,
2992 MAX_TIME - 1);
2993 }
2994
2995 if (when)
2996 lt -> ends = when;
2997 else
2998 lt -> ends = state -> offered_expiry;
2999
3000 /* Don't make lease active until we actually get a
3001 DHCPREQUEST. */
3002 if (offer == DHCPACK)
3004 else
3006 } else {
3007 lt->flags |= BOOTP_LEASE;
3008
3009 lease_time = MAX_TIME - cur_time;
3010
3011 if ((oc = lookup_option (&server_universe, state -> options,
3014 (struct client_state *)0,
3015 packet -> options,
3016 state -> options,
3017 &lease -> scope, oc, MDL)) {
3018 if (d1.len == sizeof (u_int32_t))
3019 lease_time = getULong (d1.data);
3020 data_string_forget (&d1, MDL);
3021 }
3022 }
3023
3024 if ((oc = lookup_option (&server_universe, state -> options,
3027 (struct client_state *)0,
3028 packet -> options,
3029 state -> options,
3030 &lease -> scope, oc, MDL)) {
3031 if (d1.len == sizeof (u_int32_t))
3032 lease_time = (getULong (d1.data) -
3033 cur_time);
3034 data_string_forget (&d1, MDL);
3035 }
3036 }
3037
3038 lt -> ends = state -> offered_expiry = cur_time + lease_time;
3040 }
3041
3042 /* Update Client Last Transaction Time. */
3043 lt->cltt = cur_time;
3044
3045 /* See if we want to record the uid for this client */
3048 if ((oc == NULL) ||
3049 !evaluate_boolean_option_cache(&ignorep, packet, lease, NULL,
3051 &lease->scope, oc, MDL)) {
3052
3053 /* Record the uid, if given... */
3054 oc = lookup_option (&dhcp_universe, packet -> options,
3056 if (!oc)
3057 oc = lookup_option (&dhcp_universe, packet -> options,
3059 if (oc &&
3062 &lease->scope, oc, MDL)) {
3063 if (d1.len <= sizeof(lt->uid_buf)) {
3064 memcpy(lt->uid_buf, d1.data, d1.len);
3065 lt->uid = lt->uid_buf;
3066 lt->uid_max = sizeof(lt->uid_buf);
3067 lt->uid_len = d1.len;
3068 } else {
3069 unsigned char *tuid;
3070 lt->uid_max = d1.len;
3071 lt->uid_len = d1.len;
3072 tuid = (unsigned char *)dmalloc(lt->uid_max,
3073 MDL);
3074 /* XXX inelegant */
3075 if (!tuid)
3076 log_fatal ("no memory for large uid.");
3077 memcpy(tuid, d1.data, lt->uid_len);
3078 lt->uid = tuid;
3079 }
3080 data_string_forget (&d1, MDL);
3081 }
3082 }
3083
3084 if (host) {
3085 host_reference (&lt -> host, host, MDL);
3086 host_dereference (&host, MDL);
3087 }
3088 if (lease -> subnet)
3089 subnet_reference (&lt -> subnet, lease -> subnet, MDL);
3090 if (lease -> billing_class)
3091 class_reference (&lt -> billing_class,
3092 lease -> billing_class, MDL);
3093
3094 /* Set a flag if this client is a broken client that NUL
3095 terminates string options and expects us to do likewise. */
3096 if (ms_nulltp)
3098 else
3100
3101 /* Save any bindings. */
3102 if (lease -> scope) {
3105 }
3106 if (lease -> agent_options)
3108 lease -> agent_options, MDL);
3109
3110 /* Save the vendor-class-identifier for DHCPLEASEQUERY. */
3113 if (oc != NULL &&
3114 evaluate_option_cache(&d1, packet, NULL, NULL, packet->options,
3115 NULL, &lt->scope, oc, MDL)) {
3116 if (d1.len != 0) {
3117 bind_ds_value(&lt->scope, "vendor-class-identifier",
3118 &d1);
3119 }
3120
3121 data_string_forget(&d1, MDL);
3122 }
3123
3124 /* If we got relay agent information options from the packet, then
3125 * cache them for renewal in case the relay agent can't supply them
3126 * when the client unicasts. The options may be from an addressed
3127 * "l3" relay, or from an unaddressed "l2" relay which does not set
3128 * giaddr.
3129 */
3131 (packet->options != NULL) &&
3133 packet->options->universes[agent_universe.index] != NULL) {
3134 oc = lookup_option (&server_universe, state -> options,
3136 if (!oc ||
3138 (struct client_state *)0,
3139 packet -> options,
3140 state -> options,
3141 &lease -> scope, oc, MDL)) {
3142 if (lt -> agent_options)
3145 (&lt -> agent_options,
3146 (struct option_chain_head *)
3147 packet -> options -> universes [agent_universe.index],
3148 MDL);
3149 }
3150 }
3151
3152 /* Replace the old lease hostname with the new one, if it's changed. */
3153 oc = lookup_option (&dhcp_universe, packet -> options, DHO_HOST_NAME);
3154 if (oc)
3155 s1 = evaluate_option_cache (&d1, packet, (struct lease *)0,
3156 (struct client_state *)0,
3157 packet -> options,
3158 (struct option_state *)0,
3159 &global_scope, oc, MDL);
3160 else
3161 s1 = 0;
3162
3163 if (oc && s1 &&
3165 strlen (lease -> client_hostname) == d1.len &&
3166 !memcmp (lease -> client_hostname, d1.data, d1.len)) {
3167 /* Hasn't changed. */
3168 data_string_forget (&d1, MDL);
3170 lease -> client_hostname = (char *)0;
3171 } else if (oc && s1) {
3172 lt -> client_hostname = dmalloc (d1.len + 1, MDL);
3173 if (!lt -> client_hostname)
3174 log_error ("no memory for client hostname.");
3175 else {
3176 memcpy (lt -> client_hostname, d1.data, d1.len);
3177 lt -> client_hostname [d1.len] = 0;
3178 }
3179 data_string_forget (&d1, MDL);
3180 /* hostname changed, can't reuse lease */
3181 lease->cannot_reuse = 1;
3182 }
3183
3184 /* Record the hardware address, if given... */
3185 lt -> hardware_addr.hlen = packet -> raw -> hlen + 1;
3186 lt -> hardware_addr.hbuf [0] = packet -> raw -> htype;
3187 memcpy (&lt -> hardware_addr.hbuf [1], packet -> raw -> chaddr,
3188 sizeof packet -> raw -> chaddr);
3189
3190 /*
3191 * If client has requested the lease become infinite, then it
3192 * doens't qualify for reuse even if it's younger than the
3193 * dhcp-cache-threshold.
3194 */
3195 if ((lt->flags & RESERVED_LEASE) && !(lease->flags & RESERVED_LEASE)) {
3196 log_debug ("Cannot reuse: lease is changing to RESERVED");
3197 lease->cannot_reuse = 1;
3198 }
3199
3201
3202 /* If there are statements to execute when the lease is
3203 committed, execute them. */
3204 if (lease->on_star.on_commit && (!offer || offer == DHCPACK)) {
3205 execute_statements (NULL, packet, lt, NULL, packet->options,
3206 state->options, &lt->scope,
3207 lease->on_star.on_commit, NULL);
3208 if (lease->on_star.on_commit)
3211 }
3212
3213#ifdef NSUPDATE
3214 /* Perform DDNS updates, if configured to. */
3215 if ((!offer || offer == DHCPACK) &&
3216 (!(oc = lookup_option (&server_universe, state -> options,
3217 SV_DDNS_UPDATES)) ||
3219 (struct client_state *)0,
3220 packet -> options,
3221 state -> options,
3222 &lt -> scope, oc, MDL))) {
3223 ddns_updates(packet, lt, lease, NULL, NULL, state->options);
3224 }
3225#endif /* NSUPDATE */
3226
3227 /* Don't call supersede_lease on a mocked-up lease. */
3228 if (lease -> flags & STATIC_LEASE) {
3229 /* Copy the hardware address into the static lease
3230 structure. */
3231 lease -> hardware_addr.hlen = packet -> raw -> hlen + 1;
3232 lease -> hardware_addr.hbuf [0] = packet -> raw -> htype;
3233 memcpy (&lease -> hardware_addr.hbuf [1],
3234 packet -> raw -> chaddr,
3235 sizeof packet -> raw -> chaddr); /* XXX */
3236 } else {
3237 int commit = (!offer || (offer == DHCPACK));
3238
3239 /* If dhcp-cache-threshold is enabled, see if "lease" can
3240 * be reused. */
3241 use_old_lease = reuse_lease(packet, lt, lease, state, offer,
3242 &same_client);
3243 if (use_old_lease == 1) {
3244 commit = 0;
3245 }
3246
3247#if !defined(DELAYED_ACK)
3248 /* Install the new information on 'lt' onto the lease at
3249 * 'lease'. If this is a DHCPOFFER, it is a 'soft' promise,
3250 * if it is a DHCPACK, it is a 'hard' binding, so it needs
3251 * to be recorded and propogated immediately. If the update
3252 * fails, don't ACK it (or BOOTREPLY) either; we may give
3253 * the same lease to another client later, and that would be
3254 * a conflict.
3255 */
3256 if ((use_old_lease == 0) &&
3257 !supersede_lease(lease, lt, commit,
3258 offer == DHCPACK, offer == DHCPACK, 0)) {
3259#else /* defined(DELAYED_ACK) */
3260 /*
3261 * If there already isn't a need for a lease commit, and we
3262 * can just answer right away, set a flag to indicate this.
3263 */
3264 if (commit)
3265 enqueue = ISC_TRUE;
3266
3267 /* Install the new information on 'lt' onto the lease at
3268 * 'lease'. We will not 'commit' this information to disk
3269 * yet (fsync()), we will 'propogate' the information if
3270 * this is BOOTP or a DHCPACK, but we will not 'pimmediate'ly
3271 * transmit failover binding updates (this is delayed until
3272 * after the fsync()). If the update fails, don't ACK it (or
3273 * BOOTREPLY either); we may give the same lease out to a
3274 * different client, and that would be a conflict.
3275 */
3276 if ((use_old_lease == 0) &&
3277 !supersede_lease(lease, lt, 0,
3278 !offer || offer == DHCPACK, 0, 0)) {
3279#endif
3280 log_info ("%s: database update failed", msg);
3282 lease_dereference (&lt, MDL);
3283 return;
3284 }
3285 }
3286 lease_dereference (&lt, MDL);
3287
3288 /* Remember the interface on which the packet arrived. */
3289 state -> ip = packet -> interface;
3290
3291 /* Remember the giaddr, xid, secs, flags and hops. */
3292 state -> giaddr = packet -> raw -> giaddr;
3293 state -> ciaddr = packet -> raw -> ciaddr;
3294 state -> xid = packet -> raw -> xid;
3295 state -> secs = packet -> raw -> secs;
3296 state -> bootp_flags = packet -> raw -> flags;
3297 state -> hops = packet -> raw -> hops;
3298 state -> offer = offer;
3299
3300 /* If we're always supposed to broadcast to this client, set
3301 the broadcast bit in the bootp flags field. */
3302 if ((oc = lookup_option (&server_universe, state -> options,
3305 (struct client_state *)0,
3306 packet -> options, state -> options,
3307 &lease -> scope, oc, MDL))
3308 state -> bootp_flags |= htons (BOOTP_BROADCAST);
3309
3310 /* Get the Maximum Message Size option from the packet, if one
3311 was sent. */
3312 oc = lookup_option (&dhcp_universe, packet -> options,
3314 if (oc &&
3316 (struct client_state *)0,
3317 packet -> options, state -> options,
3318 &lease -> scope, oc, MDL)) {
3319 if (d1.len == sizeof (u_int16_t))
3320 state -> max_message_size = getUShort (d1.data);
3321 data_string_forget (&d1, MDL);
3322 } else {
3323 oc = lookup_option (&dhcp_universe, state -> options,
3325 if (oc &&
3327 (struct client_state *)0,
3328 packet -> options, state -> options,
3329 &lease -> scope, oc, MDL)) {
3330 if (d1.len == sizeof (u_int16_t))
3331 state -> max_message_size =
3332 getUShort (d1.data);
3333 data_string_forget (&d1, MDL);
3334 }
3335 }
3336
3337 /* Get the Subnet Selection option from the packet, if one
3338 was sent. */
3339 if ((oc = lookup_option (&dhcp_universe, packet -> options,
3341
3342 /* Make a copy of the data. */
3343 struct option_cache *noc = (struct option_cache *)0;
3344 if (option_cache_allocate (&noc, MDL)) {
3345 if (oc -> data.len)
3346 data_string_copy (&noc -> data,
3347 &oc -> data, MDL);
3348 if (oc -> expression)
3350 oc -> expression, MDL);
3351 if (oc -> option)
3352 option_reference(&(noc->option), oc->option,
3353 MDL);
3354
3355 save_option (&dhcp_universe, state -> options, noc);
3357 }
3358 }
3359
3360 /* Now, if appropriate, put in DHCP-specific options that
3361 override those. */
3362 if (state -> offer) {
3364 oc = (struct option_cache *)0;
3365 if (option_cache_allocate (&oc, MDL)) {
3366 if (make_const_data (&oc -> expression,
3367 &state -> offer, 1, 0, 0, MDL)) {
3368 option_code_hash_lookup(&oc->option,
3369 dhcp_universe.code_hash,
3370 &i, 0, MDL);
3372 state -> options, oc);
3373 }
3375 }
3376
3377 get_server_source_address(&from, state->options,
3378 state->options, packet);
3379 memcpy(state->from.iabuf, &from, sizeof(from));
3380 state->from.len = sizeof(from);
3381
3382 offered_lease_time =
3383 state -> offered_expiry - cur_time;
3384
3385 putULong(state->expiry, (u_int32_t)offered_lease_time);
3387 oc = (struct option_cache *)0;
3388 if (option_cache_allocate (&oc, MDL)) {
3389 if (make_const_data(&oc->expression, state->expiry,
3390 4, 0, 0, MDL)) {
3391 option_code_hash_lookup(&oc->option,
3392 dhcp_universe.code_hash,
3393 &i, 0, MDL);
3395 state -> options, oc);
3396 }
3398 }
3399
3400 /*
3401 * Validate any configured renew or rebinding times against
3402 * the determined lease time. Do rebinding first so that
3403 * the renew time can be validated against the rebind time.
3404 */
3405 if ((oc = lookup_option(&dhcp_universe, state->options,
3406 DHO_DHCP_REBINDING_TIME)) != NULL &&
3408 packet->options, state->options,
3409 &lease->scope, oc, MDL)) {
3410 TIME rebind_time = getULong(d1.data);
3411
3412 /* Drop the configured (invalid) rebinding time. */
3413 if (rebind_time >= offered_lease_time)
3416 else /* XXX: variable is reused. */
3417 offered_lease_time = rebind_time;
3418
3419 data_string_forget(&d1, MDL);
3420 }
3421
3422 if ((oc = lookup_option(&dhcp_universe, state->options,
3423 DHO_DHCP_RENEWAL_TIME)) != NULL &&
3425 packet->options, state->options,
3426 &lease->scope, oc, MDL)) {
3427 if (getULong(d1.data) >= offered_lease_time)
3430
3431 data_string_forget(&d1, MDL);
3432 }
3433 } else {
3434 /* XXXSK: should we use get_server_source_address() here? */
3435 if (state -> ip -> address_count) {
3436 state -> from.len =
3437 sizeof state -> ip -> addresses [0];
3438 memcpy (state -> from.iabuf,
3439 &state -> ip -> addresses [0],
3440 state -> from.len);
3441 }
3442 }
3443
3444 /* Figure out the address of the boot file server. */
3445 memset (&state -> siaddr, 0, sizeof state -> siaddr);
3446 if ((oc =
3448 state -> options, SV_NEXT_SERVER))) {
3450 (struct client_state *)0,
3451 packet -> options, state -> options,
3452 &lease -> scope, oc, MDL)) {
3453 /* If there was more than one answer,
3454 take the first. */
3455 if (d1.len >= 4 && d1.data)
3456 memcpy (&state -> siaddr, d1.data, 4);
3457 data_string_forget (&d1, MDL);
3458 }
3459 }
3460
3461 /* Use the subnet mask from the subnet declaration if no other
3462 mask has been provided. */
3463 i = DHO_SUBNET_MASK;
3464 if (!lookup_option (&dhcp_universe, state -> options, i)) {
3465 oc = (struct option_cache *)0;
3466 if (option_cache_allocate (&oc, MDL)) {
3467 if (make_const_data (&oc -> expression,
3468 lease -> subnet -> netmask.iabuf,
3469 lease -> subnet -> netmask.len,
3470 0, 0, MDL)) {
3471 option_code_hash_lookup(&oc->option,
3472 dhcp_universe.code_hash,
3473 &i, 0, MDL);
3475 state -> options, oc);
3476 }
3478 }
3479 }
3480
3481 /* Use the name of the host declaration if there is one
3482 and no hostname has otherwise been provided, and if the
3483 use-host-decl-name flag is set. */
3485
3486 /* Send client_id back if we received it and echo-client-id is on. */
3487 echo_client_id(packet, lease, state->options, state->options);
3488
3489 /* If we don't have a hostname yet, and we've been asked to do
3490 a reverse lookup to find the hostname, do it. */
3491 i = DHO_HOST_NAME;
3493 if (!lookup_option(&dhcp_universe, state->options, i) &&
3495 (&ignorep, packet, lease, NULL,
3496 packet->options, state->options, &lease->scope,
3497 lookup_option (&server_universe, state->options, j), MDL)) {
3498 struct in_addr ia;
3499 struct hostent *h;
3500
3501 memcpy (&ia, lease -> ip_addr.iabuf, 4);
3502
3503 h = gethostbyaddr ((char *)&ia, sizeof ia, AF_INET);
3504 if (!h)
3505 log_error ("No hostname for %s", inet_ntoa (ia));
3506 else {
3507 oc = (struct option_cache *)0;
3508 if (option_cache_allocate (&oc, MDL)) {
3509 if (make_const_data (&oc -> expression,
3510 ((unsigned char *)
3511 h -> h_name),
3512 strlen (h -> h_name) + 1,
3513 1, 1, MDL)) {
3514 option_code_hash_lookup(&oc->option,
3515 dhcp_universe.code_hash,
3516 &i, 0, MDL);
3518 state -> options, oc);
3519 }
3521 }
3522 }
3523 }
3524
3525 /* If so directed, use the leased IP address as the router address.
3526 This supposedly makes Win95 machines ARP for all IP addresses,
3527 so if the local router does proxy arp, you win. */
3528
3530 (&ignorep, packet, lease, (struct client_state *)0,
3531 packet -> options, state -> options, &lease -> scope,
3532 lookup_option (&server_universe, state -> options,
3534 i = DHO_ROUTERS;
3535 oc = lookup_option (&dhcp_universe, state -> options, i);
3536 if (!oc) {
3537 oc = (struct option_cache *)0;
3538 if (option_cache_allocate (&oc, MDL)) {
3539 if (make_const_data (&oc -> expression,
3540 lease -> ip_addr.iabuf,
3541 lease -> ip_addr.len,
3542 0, 0, MDL)) {
3543 option_code_hash_lookup(&oc->option,
3544 dhcp_universe.code_hash,
3545 &i, 0, MDL);
3547 state -> options, oc);
3548 }
3550 }
3551 }
3552 }
3553
3554 /* If a site option space has been specified, use that for
3555 site option codes. */
3557 if ((oc = lookup_option (&server_universe, state -> options, i)) &&
3559 (struct client_state *)0,
3560 packet -> options, state -> options,
3561 &lease -> scope, oc, MDL)) {
3562 struct universe *u = (struct universe *)0;
3563
3564 if (!universe_hash_lookup (&u, universe_hash,
3565 (const char *)d1.data, d1.len,
3566 MDL)) {
3567 log_error ("unknown option space %s.", d1.data);
3568 data_string_forget (&d1, MDL);
3569 return;
3570 }
3571
3572 state -> options -> site_universe = u -> index;
3573 state->options->site_code_min = find_min_site_code(u);
3574 data_string_forget (&d1, MDL);
3575 } else {
3576 state -> options -> site_code_min = 0;
3577 state -> options -> site_universe = dhcp_universe.index;
3578 }
3579
3580 /* If the client has provided a list of options that it wishes
3581 returned, use it to prioritize. If there's a parameter
3582 request list in scope, use that in preference. Otherwise
3583 use the default priority list. */
3584
3585 oc = lookup_option (&dhcp_universe, state -> options,
3587
3588 if (!oc)
3589 oc = lookup_option (&dhcp_universe, packet -> options,
3591 if (oc)
3592 evaluate_option_cache (&state -> parameter_request_list,
3593 packet, lease, (struct client_state *)0,
3594 packet -> options, state -> options,
3595 &lease -> scope, oc, MDL);
3596
3597#ifdef DEBUG_PACKET
3599 dump_raw ((unsigned char *)packet -> raw, packet -> packet_length);
3600#endif
3601
3602 lease -> state = state;
3603
3604 log_info ("%s", msg);
3605
3606 /* Hang the packet off the lease state. */
3607 packet_reference (&lease -> state -> packet, packet, MDL);
3608
3609 /* If this is a DHCPOFFER, send a ping (if appropriate) to the
3610 * lease address before actually we send the offer. */
3611 if ((offer == DHCPOFFER) &&
3612 do_ping_check(packet, state, lease, original_cltt, same_client)) {
3614 } else {
3615 lease->cltt = cur_time;
3616#if defined(DELAYED_ACK)
3617 if (enqueue)
3618 delayed_ack_enqueue(lease);
3619 else
3620#endif
3622 }
3623}
3624
3625/*
3626 * \brief Sends a ping to the lease ip_addr when appropriate
3627 *
3628 * A ping will be sent if all of the following are true:
3629 *
3630 * 1. Ping checks are enabled
3631 * 2. The lease is neither active nor static
3632 * 3. Any of the following is true:
3633 * a. The lease state is ABANDONED
3634 * b. This is the first offer of this lease (CLTT = 0)
3635 * c. The lease is being offered to a client other than its previous
3636 * owner
3637 * d. The lease is being offered to its previous owner and more than
3638 * cltt-secs have elapsed since CLTT of the original lease.
3639 *
3640 * \param packet inbound packet received from the client
3641 * \param state lease options state
3642 * \param lease lease to be offered (if one)
3643 * \param original_cltt CLTT of the original lease
3644 * \param same_client flag indicating if the client to be offered the
3645 * lease is its previous owner
3646 * \return Returns 1 if ping has been sent, 0 otherwise
3647 */
3648int do_ping_check(struct packet* packet, struct lease_state* state,
3649 struct lease* lease, TIME original_cltt,
3650 int same_client) {
3651 TIME ping_timeout = DEFAULT_PING_TIMEOUT;
3652 TIME ping_timeout_ms = DEFAULT_PING_TIMEOUT_MS;
3653 struct option_cache *oc = NULL;
3654 struct data_string ds;
3655 struct timeval tv;
3656 int ignorep;
3657 int timeout_secs;
3658 int timeout_ms;
3659
3660 // Don't go any further if lease is active or static.
3662 return (0);
3663 }
3664
3665 // If pings aren't enabled, punt.
3666 oc = lookup_option (&server_universe, state -> options, SV_PING_CHECKS);
3667 if (oc &&
3669 0, packet->options, state->options,
3670 &lease->scope, oc, MDL))) {
3671 return (0);
3672 }
3673
3674 // If it's not the first time for the same client and not an
3675 // abandoned lease, we need to check the cltt threshold
3676 if (same_client && original_cltt &&
3678 TIME cltt_secs = DEFAULT_PING_CLTT_SECS;
3679 memset(&ds, 0, sizeof(ds));
3680 oc = lookup_option (&server_universe, state->options,
3682 if (oc &&
3684 packet->options, state->options,
3685 &lease->scope, oc, MDL))) {
3686 if (ds.len == sizeof (u_int32_t)) {
3687 cltt_secs = getULong (ds.data);
3688 }
3689
3690 data_string_forget (&ds, MDL);
3691 }
3692
3693 // Punt if it is too soon.
3694 if (cur_time - original_cltt < cltt_secs) {
3695 return (0);
3696 }
3697 }
3698
3699 // Send the ping.
3701
3702 /* Determine whether to use configured or default ping timeout. */
3703 memset(&ds, 0, sizeof(ds));
3704
3706 if (oc &&
3708 packet->options, state->options,
3709 &lease->scope, oc, MDL))) {
3710 if (ds.len == sizeof (u_int32_t)) {
3711 ping_timeout = getULong (ds.data);
3712 }
3713
3714 data_string_forget (&ds, MDL);
3715 }
3716
3718 if (oc &&
3720 packet->options, state->options,
3721 &lease->scope, oc, MDL))) {
3722 if (ds.len == sizeof (u_int32_t)) {
3723 ping_timeout_ms = getULong (ds.data);
3724 }
3725
3726 data_string_forget (&ds, MDL);
3727 }
3728
3729 /*
3730 * Set the timeout for the ping to the current timeval plus
3731 * the configured time out. Use ping-timeout-ms if it is > 0.
3732 * This overrides ping-timeout allowing users to specify it in
3733 * milliseconds.
3734 */
3735 if (ping_timeout_ms > 0) {
3736 timeout_secs = ping_timeout_ms / 1000;
3737 timeout_ms = ping_timeout_ms % 1000;
3738 } else {
3739 timeout_secs = ping_timeout;
3740 timeout_ms = 0;
3741
3742 }
3743
3744 tv.tv_sec = cur_tv.tv_sec + timeout_secs;
3745 tv.tv_usec = cur_tv.tv_usec + (timeout_ms * 1000);
3746
3747#ifdef DEBUG
3748 log_debug ("Pinging:%s, state: %d, same client? %s, "
3749 " orig_cltt %s, elasped: %ld, timeout in: %d.%d secs" ,
3752 (same_client ? "y" : "n"),
3753 (original_cltt ? print_time(original_cltt) : "0"),
3754 (original_cltt ? (long)(cur_time - original_cltt) : 0),
3755 timeout_secs, timeout_ms);
3756
3757#endif
3758
3759 add_timeout (&tv, lease_ping_timeout, lease, (tvref_t)lease_reference,
3760 (tvunref_t)lease_dereference);
3761
3762 return (1);
3763}
3764
3765
3766#if defined(DELAYED_ACK)
3767
3768/*
3769 * CC: queue single ACK:
3770 * - write the lease (but do not fsync it yet)
3771 * - add to double linked list
3772 * - commit if more than xx ACKs pending
3773 * - if necessary set the max timer and bump the next timer
3774 * but only up to the max timer value.
3775 */
3776
3777static void
3778delayed_ack_enqueue(struct lease *lease)
3779{
3780 struct leasequeue *q;
3781
3782 if (!write_lease(lease))
3783 return;
3784 if (free_ackqueue) {
3785 q = free_ackqueue;
3786 free_ackqueue = q->next;
3787 } else {
3788 q = ((struct leasequeue *)
3789 dmalloc(sizeof(struct leasequeue), MDL));
3790 if (!q)
3791 log_fatal("delayed_ack_enqueue: no memory!");
3792 }
3793 memset(q, 0, sizeof *q);
3794 /* prepend to ackqueue*/
3795 lease_reference(&q->lease, lease, MDL);
3796 q->next = ackqueue_head;
3797 ackqueue_head = q;
3798 if (!ackqueue_tail)
3799 ackqueue_tail = q;
3800 else
3801 q->next->prev = q;
3802
3803 outstanding_acks++;
3804 if (outstanding_acks > max_outstanding_acks) {
3805 /* Cancel any pending timeout and call handler directly */
3806 cancel_timeout(delayed_acks_timer, NULL);
3807 delayed_acks_timer(NULL);
3808 } else {
3809 struct timeval next_fsync;
3810
3811 if (max_fsync.tv_sec == 0 && max_fsync.tv_usec == 0) {
3812 /* set the maximum time we'll wait */
3813 max_fsync.tv_sec = cur_tv.tv_sec + max_ack_delay_secs;
3814 max_fsync.tv_usec = cur_tv.tv_usec +
3816
3817 if (max_fsync.tv_usec >= 1000000) {
3818 max_fsync.tv_sec++;
3819 max_fsync.tv_usec -= 1000000;
3820 }
3821 }
3822
3823 /* Set the timeout */
3824 next_fsync.tv_sec = cur_tv.tv_sec;
3825 next_fsync.tv_usec = cur_tv.tv_usec + min_ack_delay_usecs;
3826 if (next_fsync.tv_usec >= 1000000) {
3827 next_fsync.tv_sec++;
3828 next_fsync.tv_usec -= 1000000;
3829 }
3830 /* but not more than the max */
3831 if ((next_fsync.tv_sec > max_fsync.tv_sec) ||
3832 ((next_fsync.tv_sec == max_fsync.tv_sec) &&
3833 (next_fsync.tv_usec > max_fsync.tv_usec))) {
3834 next_fsync.tv_sec = max_fsync.tv_sec;
3835 next_fsync.tv_usec = max_fsync.tv_usec;
3836 }
3837
3838 add_timeout(&next_fsync, delayed_acks_timer, NULL,
3839 (tvref_t) NULL, (tvunref_t) NULL);
3840 }
3841}
3842
3843/* Processes any delayed acks:
3844 * Commits the leases and then for each delayed ack:
3845 * - Update the failover peer if we're in failover
3846 * - Send the REPLY to the client
3847 */
3848static void
3849delayed_acks_timer(void *foo)
3850{
3851 struct leasequeue *ack, *p;
3852
3853 /* Reset max fsync */
3854 memset(&max_fsync, 0, sizeof(max_fsync));
3855
3856 if (!outstanding_acks) {
3857 /* Nothing to do, so punt, shouldn't happen? */
3858 return;
3859 }
3860
3861 /* Commit the leases first */
3862 commit_leases();
3863
3864 /* Now process the delayed ACKs
3865 - update failover peer
3866 - send out the ACK packets
3867 - move the queue slots to the free list
3868 */
3869
3870 /* process from bottom to retain packet order */
3871 for (ack = ackqueue_tail ; ack ; ack = p) {
3872 p = ack->prev;
3873
3874#if defined(FAILOVER_PROTOCOL)
3875 /* If we're in failover we need to send any deferred
3876 * bind updates as well as the replies */
3877 if (ack->lease->pool) {
3878 dhcp_failover_state_t *fpeer;
3879
3880 fpeer = ack->lease->pool->failover_peer;
3881 if (fpeer && fpeer->link_to_peer) {
3883 }
3884 }
3885#endif
3886
3887 /* dhcp_reply() requires that the reply state still be valid */
3888 if (ack->lease->state == NULL)
3889 log_error("delayed ack for %s has gone stale",
3890 piaddr(ack->lease->ip_addr));
3891 else {
3892 dhcp_reply(ack->lease);
3893 }
3894
3895 lease_dereference(&ack->lease, MDL);
3896 ack->next = free_ackqueue;
3897 free_ackqueue = ack;
3898 }
3899
3900 ackqueue_head = NULL;
3901 ackqueue_tail = NULL;
3902 outstanding_acks = 0;
3903}
3904
3905#if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
3906void
3907relinquish_ackqueue(void)
3908{
3909 struct leasequeue *q, *n;
3910
3911 for (q = ackqueue_head ; q ; q = n) {
3912 n = q->next;
3913 dfree(q, MDL);
3914 }
3915 for (q = free_ackqueue ; q ; q = n) {
3916 n = q->next;
3917 dfree(q, MDL);
3918 }
3919}
3920#endif
3921
3922#endif /* defined(DELAYED_ACK) */
3923
3925 struct lease *lease;
3926{
3927 int bufs = 0;
3928 unsigned packet_length;
3929 struct dhcp_packet raw;
3930 struct sockaddr_in to;
3931 struct in_addr from;
3932 struct hardware hto;
3933 int result;
3934 struct lease_state *state = lease -> state;
3935 int nulltp, bootpp, unicastp = 1;
3936#if defined(RELAY_PORT)
3937 u_int16_t relay_port = 0;
3938#endif
3939 struct data_string d1;
3940 const char *s;
3941
3942 if (!state)
3943 log_fatal ("dhcp_reply was supplied lease with no state!");
3944
3945 /* Compose a response for the client... */
3946 memset (&raw, 0, sizeof raw);
3947 memset (&d1, 0, sizeof d1);
3948
3949 /* Copy in the filename if given; otherwise, flag the filename
3950 buffer as available for options. */
3951 if (state -> filename.len && state -> filename.data) {
3952 memcpy (raw.file,
3953 state -> filename.data,
3954 state -> filename.len > sizeof raw.file
3955 ? sizeof raw.file : state -> filename.len);
3956 if (sizeof raw.file > state -> filename.len)
3957 memset (&raw.file [state -> filename.len], 0,
3958 (sizeof raw.file) - state -> filename.len);
3959 else
3960 log_info("file name longer than packet field "
3961 "truncated - field: %lu name: %d %.*s",
3962 (unsigned long)sizeof(raw.file),
3963 state->filename.len, (int)state->filename.len,
3964 state->filename.data);
3965 } else
3966 bufs |= 1;
3967
3968 /* Copy in the server name if given; otherwise, flag the
3969 server_name buffer as available for options. */
3970 if (state -> server_name.len && state -> server_name.data) {
3971 memcpy (raw.sname,
3972 state -> server_name.data,
3973 state -> server_name.len > sizeof raw.sname
3974 ? sizeof raw.sname : state -> server_name.len);
3975 if (sizeof raw.sname > state -> server_name.len)
3976 memset (&raw.sname [state -> server_name.len], 0,
3977 (sizeof raw.sname) - state -> server_name.len);
3978 else
3979 log_info("server name longer than packet field "
3980 "truncated - field: %lu name: %d %.*s",
3981 (unsigned long)sizeof(raw.sname),
3982 state->server_name.len,
3983 (int)state->server_name.len,
3984 state->server_name.data);
3985 } else
3986 bufs |= 2; /* XXX */
3987
3988 memcpy (raw.chaddr,
3989 &lease -> hardware_addr.hbuf [1], sizeof raw.chaddr);
3990 raw.hlen = lease -> hardware_addr.hlen - 1;
3991 raw.htype = lease -> hardware_addr.hbuf [0];
3992
3993 /* See if this is a Microsoft client that NUL-terminates its
3994 strings and expects us to do likewise... */
3995 if (lease -> flags & MS_NULL_TERMINATION)
3996 nulltp = 1;
3997 else
3998 nulltp = 0;
3999
4000 /* See if this is a bootp client... */
4001 if (state -> offer)
4002 bootpp = 0;
4003 else
4004 bootpp = 1;
4005
4006 /* Insert such options as will fit into the buffer. */
4007 packet_length = cons_options (state -> packet, &raw, lease,
4008 (struct client_state *)0,
4009 state -> max_message_size,
4010 state -> packet -> options,
4011 state -> options, &global_scope,
4012 bufs, nulltp, bootpp,
4013 &state -> parameter_request_list,
4014 (char *)0);
4015
4016 memcpy (&raw.ciaddr, &state -> ciaddr, sizeof raw.ciaddr);
4017 memcpy (&raw.yiaddr, lease -> ip_addr.iabuf, 4);
4018 raw.siaddr = state -> siaddr;
4019 raw.giaddr = state -> giaddr;
4020
4021 raw.xid = state -> xid;
4022 raw.secs = state -> secs;
4023 raw.flags = state -> bootp_flags;
4024 raw.hops = state -> hops;
4025 raw.op = BOOTREPLY;
4026
4027 if (lease -> client_hostname) {
4028 if ((strlen (lease -> client_hostname) <= 64) &&
4029 db_printable((unsigned char *)lease->client_hostname))
4030 s = lease -> client_hostname;
4031 else
4032 s = "Hostname Unsuitable for Printing";
4033 } else
4034 s = (char *)0;
4035
4036 /* Make sure outgoing packets are at least as big
4037 as a BOOTP packet. */
4038 if (packet_length < BOOTP_MIN_LEN)
4039 packet_length = BOOTP_MIN_LEN;
4040
4041#if defined(DHCPv6) && defined(DHCP4o6)
4042 if (dhcpv4_over_dhcpv6 && (state->packet->dhcp4o6_response != NULL)) {
4043 /* Say what we're doing... */
4044 log_info ("DHCP4o6 %s on %s to %s %s%s%svia %s",
4045 (state -> offer
4046 ? (state -> offer == DHCPACK
4047 ? "DHCPACK" : "DHCPOFFER")
4048 : "BOOTREPLY"),
4049 piaddr (lease -> ip_addr),
4050 (lease -> hardware_addr.hlen
4051 ? print_hw_addr (lease -> hardware_addr.hbuf [0],
4052 lease -> hardware_addr.hlen - 1,
4053 &lease -> hardware_addr.hbuf [1])
4054 : print_hex_1(lease->uid_len, lease->uid, 60)),
4055 s ? "(" : "", s ? s : "", s ? ") " : "",
4056 piaddr(state->packet->client_addr));
4057
4058 /* fill dhcp4o6_response */
4059 state->packet->dhcp4o6_response->len = packet_length;
4060 state->packet->dhcp4o6_response->buffer = NULL;
4062 packet_length, MDL)) {
4063 log_fatal("No memory to store DHCP4o6 reply.");
4064 }
4065 state->packet->dhcp4o6_response->data =
4067 memcpy(state->packet->dhcp4o6_response->buffer->data,
4068 &raw, packet_length);
4069
4070 /* done */
4071 free_lease_state (state, MDL);
4072 lease -> state = (struct lease_state *)0;
4073
4074 return;
4075 }
4076#endif
4077
4078 /* Say what we're doing... */
4079 log_info ("%s on %s to %s %s%s%svia %s",
4080 (state -> offer
4081 ? (state -> offer == DHCPACK ? "DHCPACK" : "DHCPOFFER")
4082 : "BOOTREPLY"),
4083 piaddr (lease -> ip_addr),
4084 (lease -> hardware_addr.hlen > 1
4085 ? print_hw_addr (lease -> hardware_addr.hbuf [0],
4086 lease -> hardware_addr.hlen - 1,
4087 &lease -> hardware_addr.hbuf [1])
4088 : print_hex_1(lease->uid_len, lease->uid, 60)),
4089 s ? "(" : "", s ? s : "", s ? ") " : "",
4090 (state -> giaddr.s_addr
4091 ? inet_ntoa (state -> giaddr)
4092 : state -> ip -> name));
4093
4094#ifdef DEBUG_PACKET
4095 dump_raw ((unsigned char *)&raw, packet_length);
4096#endif
4097
4098 /* Set up the hardware address... */
4099 hto.hlen = lease -> hardware_addr.hlen;
4100 memcpy (hto.hbuf, lease -> hardware_addr.hbuf, hto.hlen);
4101
4102 to.sin_family = AF_INET;
4103#ifdef HAVE_SA_LEN
4104 to.sin_len = sizeof to;
4105#endif
4106 memset (to.sin_zero, 0, sizeof to.sin_zero);
4107
4108#if defined(RELAY_PORT)
4110#endif
4111
4112 /* If this was gatewayed, send it back to the gateway... */
4113 if (raw.giaddr.s_addr) {
4114 to.sin_addr = raw.giaddr;
4115 if (raw.giaddr.s_addr != htonl (INADDR_LOOPBACK))
4116#if defined(RELAY_PORT)
4117 to.sin_port = relay_port ? relay_port : local_port;
4118#else
4119 to.sin_port = local_port;
4120#endif
4121 else
4122 to.sin_port = remote_port; /* For debugging. */
4123
4124 if (fallback_interface) {
4125 result = send_packet(fallback_interface, NULL, &raw,
4126 packet_length, raw.siaddr, &to,
4127 NULL);
4128 if (result < 0) {
4129 log_error ("%s:%d: Failed to send %d byte long "
4130 "packet over %s interface.", MDL,
4131 packet_length,
4132 fallback_interface->name);
4133 }
4134
4135
4136 free_lease_state (state, MDL);
4137 lease -> state = (struct lease_state *)0;
4138 return;
4139 }
4140
4141 /* If the client is RENEWING, unicast to the client using the
4142 regular IP stack. Some clients, particularly those that
4143 follow RFC1541, are buggy, and send both ciaddr and server
4144 identifier. We deal with this situation by assuming that
4145 if we got both dhcp-server-identifier and ciaddr, and
4146 giaddr was not set, then the client is on the local
4147 network, and we can therefore unicast or broadcast to it
4148 successfully. A client in REQUESTING state on another
4149 network that's making this mistake will have set giaddr,
4150 and will therefore get a relayed response from the above
4151 code. */
4152 } else if (raw.ciaddr.s_addr &&
4153 !((state -> got_server_identifier ||
4154 (raw.flags & htons (BOOTP_BROADCAST))) &&
4155 /* XXX This won't work if giaddr isn't zero, but it is: */
4156 (state -> shared_network ==
4157 lease -> subnet -> shared_network)) &&
4158 state -> offer == DHCPACK) {
4159 to.sin_addr = raw.ciaddr;
4160 to.sin_port = remote_port;
4161
4162 if (fallback_interface) {
4163 result = send_packet(fallback_interface, NULL, &raw,
4164 packet_length, raw.siaddr, &to,
4165 NULL);
4166 if (result < 0) {
4167 log_error("%s:%d: Failed to send %d byte long"
4168 " packet over %s interface.", MDL,
4169 packet_length,
4170 fallback_interface->name);
4171 }
4172
4173 free_lease_state (state, MDL);
4174 lease -> state = (struct lease_state *)0;
4175 return;
4176 }
4177
4178 /* If it comes from a client that already knows its address
4179 and is not requesting a broadcast response, and we can
4180 unicast to a client without using the ARP protocol, sent it
4181 directly to that client. */
4182 } else if (!(raw.flags & htons (BOOTP_BROADCAST)) &&
4183 can_unicast_without_arp (state -> ip)) {
4184 to.sin_addr = raw.yiaddr;
4185 to.sin_port = remote_port;
4186
4187 /* Otherwise, broadcast it on the local network. */
4188 } else {
4189 to.sin_addr = limited_broadcast;
4190 to.sin_port = remote_port;
4191 if (!(lease -> flags & UNICAST_BROADCAST_HACK))
4192 unicastp = 0;
4193 }
4194
4195 memcpy (&from, state -> from.iabuf, sizeof from);
4196
4197 result = send_packet(state->ip, NULL, &raw, packet_length,
4198 from, &to, unicastp ? &hto : NULL);
4199 if (result < 0) {
4200 log_error ("%s:%d: Failed to send %d byte long "
4201 "packet over %s interface.", MDL,
4202 packet_length, state->ip->name);
4203 }
4204
4205
4206 /* Free all of the entries in the option_state structure
4207 now that we're done with them. */
4208
4209 free_lease_state (state, MDL);
4210 lease -> state = (struct lease_state *)0;
4211}
4212
4213int find_lease (struct lease **lp,
4214 struct packet *packet, struct shared_network *share, int *ours,
4215 int *peer_has_leases, struct lease *ip_lease_in,
4216 const char *file, int line)
4217{
4218 struct lease *uid_lease = (struct lease *)0;
4219 struct lease *ip_lease = (struct lease *)0;
4220 struct lease *hw_lease = (struct lease *)0;
4221 struct lease *lease = (struct lease *)0;
4222 struct iaddr cip;
4223 struct host_decl *hp = (struct host_decl *)0;
4224 struct host_decl *host = (struct host_decl *)0;
4225 struct lease *fixed_lease = (struct lease *)0;
4226 struct lease *next = (struct lease *)0;
4227 struct option_cache *oc;
4228 struct data_string d1;
4229 int have_client_identifier = 0;
4230 struct data_string client_identifier;
4231 struct hardware h;
4232
4233#if defined(FAILOVER_PROTOCOL)
4234 /* Quick check to see if the peer has leases. */
4235 if (peer_has_leases) {
4236 struct pool *pool;
4237
4238 for (pool = share->pools ; pool ; pool = pool->next) {
4239 dhcp_failover_state_t *peer = pool->failover_peer;
4240
4241 if (peer &&
4242 ((peer->i_am == primary && pool->backup_leases) ||
4243 (peer->i_am == secondary && pool->free_leases))) {
4244 *peer_has_leases = 1;
4245 break;
4246 }
4247 }
4248 }
4249#endif /* FAILOVER_PROTOCOL */
4250
4251 if (packet -> raw -> ciaddr.s_addr) {
4252 cip.len = 4;
4253 memcpy (cip.iabuf, &packet -> raw -> ciaddr, 4);
4254 } else {
4255 /* Look up the requested address. */
4256 oc = lookup_option (&dhcp_universe, packet -> options,
4258 memset (&d1, 0, sizeof d1);
4259 if (oc &&
4260 evaluate_option_cache (&d1, packet, (struct lease *)0,
4261 (struct client_state *)0,
4262 packet -> options,
4263 (struct option_state *)0,
4264 &global_scope, oc, MDL)) {
4265 packet -> got_requested_address = 1;
4266 cip.len = 4;
4267 memcpy (cip.iabuf, d1.data, cip.len);
4268 data_string_forget (&d1, MDL);
4269 } else
4270 cip.len = 0;
4271 }
4272
4273 /* Try to find a host or lease that's been assigned to the
4274 specified unique client identifier. */
4275 oc = lookup_option (&dhcp_universe, packet -> options,
4277 if (!oc)
4278 oc = lookup_option (&dhcp_universe, packet -> options,
4280 memset (&client_identifier, 0, sizeof client_identifier);
4281 if (oc &&
4282 evaluate_option_cache (&client_identifier,
4283 packet, (struct lease *)0,
4284 (struct client_state *)0,
4285 packet -> options, (struct option_state *)0,
4286 &global_scope, oc, MDL)) {
4287 /* Remember this for later. */
4288 have_client_identifier = 1;
4289
4290 /* First, try to find a fixed host entry for the specified
4291 client identifier... */
4292 if (find_hosts_by_uid (&hp, client_identifier.data,
4293 client_identifier.len, MDL)) {
4294 /* Remember if we know of this client. */
4295 packet -> known = 1;
4296 mockup_lease (&fixed_lease, packet, share, hp);
4297 }
4298
4299#if defined (DEBUG_FIND_LEASE)
4300 if (fixed_lease) {
4301 log_info ("Found host for client identifier: %s.",
4302 piaddr (fixed_lease -> ip_addr));
4303 }
4304#endif
4305 if (hp) {
4306 if (!fixed_lease) /* Save the host if we found one. */
4307 host_reference (&host, hp, MDL);
4308 host_dereference (&hp, MDL);
4309 }
4310
4311 find_lease_by_uid (&uid_lease, client_identifier.data,
4312 client_identifier.len, MDL);
4313 }
4314
4315 /* If we didn't find a fixed lease using the uid, try doing
4316 it with the hardware address... */
4317 if (!fixed_lease && !host) {
4318 if (find_hosts_by_haddr (&hp, packet -> raw -> htype,
4319 packet -> raw -> chaddr,
4320 packet -> raw -> hlen, MDL)) {
4321 /* Remember if we know of this client. */
4322 packet -> known = 1;
4323 if (host)
4324 host_dereference (&host, MDL);
4325 host_reference (&host, hp, MDL);
4326 host_dereference (&hp, MDL);
4327 mockup_lease (&fixed_lease, packet, share, host);
4328#if defined (DEBUG_FIND_LEASE)
4329 if (fixed_lease) {
4330 log_info ("Found host for link address: %s.",
4331 piaddr (fixed_lease -> ip_addr));
4332 }
4333#endif
4334 }
4335 }
4336
4337 /* Finally, if we haven't found anything yet try again with the
4338 * host-identifier option ... */
4339 if (!fixed_lease && !host) {
4341 packet->options, MDL) == 1) {
4342 packet->known = 1;
4343 if (host)
4344 host_dereference(&host, MDL);
4345 host_reference(&host, hp, MDL);
4346 host_dereference(&hp, MDL);
4347 mockup_lease (&fixed_lease, packet, share, host);
4348#if defined (DEBUG_FIND_LEASE)
4349 if (fixed_lease) {
4350 log_info ("Found host via host-identifier");
4351 }
4352#endif
4353 }
4354 }
4355
4356 /* If fixed_lease is present but does not match the requested
4357 IP address, and this is a DHCPREQUEST, then we can't return
4358 any other lease, so we might as well return now. */
4359 if (packet -> packet_type == DHCPREQUEST && fixed_lease &&
4360 (fixed_lease -> ip_addr.len != cip.len ||
4361 memcmp (fixed_lease -> ip_addr.iabuf,
4362 cip.iabuf, cip.len))) {
4363 if (ours)
4364 *ours = 1;
4365 strcpy (dhcp_message, "requested address is incorrect");
4366#if defined (DEBUG_FIND_LEASE)
4367 log_info ("Client's fixed-address %s doesn't match %s%s",
4368 piaddr (fixed_lease -> ip_addr), "request ",
4369 print_dotted_quads (cip.len, cip.iabuf));
4370#endif
4371 goto out;
4372 }
4373
4374 /*
4375 * If we found leases matching the client identifier, loop through
4376 * the n_uid pointer looking for one that's actually valid. We
4377 * can't do this until we get here because we depend on
4378 * packet -> known, which may be set by either the uid host
4379 * lookup or the haddr host lookup.
4380 *
4381 * Note that the n_uid lease chain is sorted in order of
4382 * preference, so the first one is the best one.
4383 */
4384 while (uid_lease) {
4386#if defined (DEBUG_FIND_LEASE)
4387 log_info ("trying next lease matching client id: %s",
4388 piaddr (uid_lease -> ip_addr));
4389#endif
4390
4391#if defined (FAILOVER_PROTOCOL)
4392 /*
4393 * When we lookup a lease by uid, we know the client identifier
4394 * matches the lease's record. If it is active, or was last
4395 * active with the same client, we can trivially extend it.
4396 * If is not or was not active, we can allocate it to this
4397 * client if it matches the usual free/backup criteria (which
4398 * is contained in lease_mine_to_reallocate()).
4399 */
4400 if (uid_lease->binding_state != FTS_ACTIVE &&
4401 uid_lease->rewind_binding_state != FTS_ACTIVE &&
4402 !lease_mine_to_reallocate(uid_lease)) {
4403#if defined (DEBUG_FIND_LEASE)
4404 log_info("not active or not mine to allocate: %s",
4405 piaddr(uid_lease->ip_addr));
4406#endif
4407 goto n_uid;
4408 }
4409#endif
4410
4411 if (uid_lease -> subnet -> shared_network != share) {
4412#if defined (DEBUG_FIND_LEASE)
4413 log_info ("wrong network segment: %s",
4414 piaddr (uid_lease -> ip_addr));
4415#endif
4416 /* Allow multiple leases using the same UID
4417 on different subnetworks. */
4419 goto n_uid;
4420 }
4421
4422 if ((uid_lease -> pool -> prohibit_list &&
4423 permitted (packet, uid_lease -> pool -> prohibit_list)) ||
4424 (uid_lease -> pool -> permit_list &&
4425 !permitted (packet, uid_lease -> pool -> permit_list))) {
4426#if defined (DEBUG_FIND_LEASE)
4427 log_info ("not permitted: %s",
4428 piaddr (uid_lease -> ip_addr));
4429#endif
4430 n_uid:
4431 if (uid_lease -> n_uid)
4432 lease_reference (&next,
4433 uid_lease -> n_uid, MDL);
4434 if (do_release)
4435 release_lease (uid_lease, packet);
4436 lease_dereference (&uid_lease, MDL);
4437 if (next) {
4438 lease_reference (&uid_lease, next, MDL);
4439 lease_dereference (&next, MDL);
4440 }
4441 continue;
4442 }
4443 break;
4444 }
4445#if defined (DEBUG_FIND_LEASE)
4446 if (uid_lease)
4447 log_info ("Found lease for client id: %s.",
4448 piaddr (uid_lease -> ip_addr));
4449#endif
4450
4451 /* Find a lease whose hardware address matches, whose client
4452 * identifier matches (or equally doesn't have one), that's
4453 * permitted, and that's on the correct subnet.
4454 *
4455 * Note that the n_hw chain is sorted in order of preference, so
4456 * the first one found is the best one.
4457 */
4458 h.hlen = packet -> raw -> hlen + 1;
4459 h.hbuf [0] = packet -> raw -> htype;
4460 memcpy (&h.hbuf [1], packet -> raw -> chaddr, packet -> raw -> hlen);
4461 find_lease_by_hw_addr (&hw_lease, h.hbuf, h.hlen, MDL);
4462 while (hw_lease) {
4463#if defined (DEBUG_FIND_LEASE)
4464 log_info ("trying next lease matching hw addr: %s",
4465 piaddr (hw_lease -> ip_addr));
4466#endif
4467#if defined (FAILOVER_PROTOCOL)
4468 /*
4469 * When we lookup a lease by chaddr, we know the MAC address
4470 * matches the lease record (we will check if the lease has a
4471 * client-id the client does not next). If the lease is
4472 * currently active or was last active with this client, we can
4473 * trivially extend it. Otherwise, there are a set of rules
4474 * that govern if we can reallocate this lease to any client
4475 * ("lease_mine_to_reallocate()") including this one.
4476 */
4477 if (hw_lease->binding_state != FTS_ACTIVE &&
4478 hw_lease->rewind_binding_state != FTS_ACTIVE &&
4479 !lease_mine_to_reallocate(hw_lease)) {
4480#if defined (DEBUG_FIND_LEASE)
4481 log_info("not active or not mine to allocate: %s",
4482 piaddr(hw_lease->ip_addr));
4483#endif
4484 goto n_hw;
4485 }
4486#endif
4487
4488 /*
4489 * This conditional skips "potentially active" leases (leases
4490 * we think are expired may be extended by the peer, etc) that
4491 * may be assigned to a differently /client-identified/ client
4492 * with the same MAC address.
4493 */
4494 if (hw_lease -> binding_state != FTS_FREE &&
4495 hw_lease -> binding_state != FTS_BACKUP &&
4496 hw_lease -> uid &&
4497 (!have_client_identifier ||
4498 hw_lease -> uid_len != client_identifier.len ||
4499 memcmp (hw_lease -> uid, client_identifier.data,
4500 hw_lease -> uid_len))) {
4501#if defined (DEBUG_FIND_LEASE)
4502 log_info ("wrong client identifier: %s",
4503 piaddr (hw_lease -> ip_addr));
4504#endif
4505 goto n_hw;
4506 }
4507 if (hw_lease -> subnet -> shared_network != share) {
4508#if defined (DEBUG_FIND_LEASE)
4509 log_info ("wrong network segment: %s",
4510 piaddr (hw_lease -> ip_addr));
4511#endif
4512 goto n_hw;
4513 }
4514 if ((hw_lease -> pool -> prohibit_list &&
4515 permitted (packet, hw_lease -> pool -> prohibit_list)) ||
4516 (hw_lease -> pool -> permit_list &&
4517 !permitted (packet, hw_lease -> pool -> permit_list))) {
4518#if defined (DEBUG_FIND_LEASE)
4519 log_info ("not permitted: %s",
4520 piaddr (hw_lease -> ip_addr));
4521#endif
4522 if (!packet -> raw -> ciaddr.s_addr)
4523 release_lease (hw_lease, packet);
4524 n_hw:
4525 if (hw_lease -> n_hw)
4526 lease_reference (&next, hw_lease -> n_hw, MDL);
4527 lease_dereference (&hw_lease, MDL);
4528 if (next) {
4529 lease_reference (&hw_lease, next, MDL);
4530 lease_dereference (&next, MDL);
4531 }
4532 continue;
4533 }
4534 break;
4535 }
4536#if defined (DEBUG_FIND_LEASE)
4537 if (hw_lease)
4538 log_info ("Found lease for hardware address: %s.",
4539 piaddr (hw_lease -> ip_addr));
4540#endif
4541
4542 /* Try to find a lease that's been allocated to the client's
4543 IP address. */
4544 if (ip_lease_in)
4545 lease_reference (&ip_lease, ip_lease_in, MDL);
4546 else if (cip.len)
4547 find_lease_by_ip_addr (&ip_lease, cip, MDL);
4548
4549#if defined (DEBUG_FIND_LEASE)
4550 if (ip_lease)
4551 log_info ("Found lease for requested address: %s.",
4552 piaddr (ip_lease -> ip_addr));
4553#endif
4554
4555 /* If ip_lease is valid at this point, set ours to one, so that
4556 even if we choose a different lease, we know that the address
4557 the client was requesting was ours, and thus we can NAK it. */
4558 if (ip_lease && ours)
4559 *ours = 1;
4560
4561 /* If the requested IP address isn't on the network the packet
4562 came from, don't use it. Allow abandoned leases to be matched
4563 here - if the client is requesting it, there's a decent chance
4564 that it's because the lease database got trashed and a client
4565 that thought it had this lease answered an ARP or PING, causing the
4566 lease to be abandoned. If so, this request probably came from
4567 that client. */
4568 if (ip_lease && (ip_lease -> subnet -> shared_network != share)) {
4569 if (ours)
4570 *ours = 1;
4571#if defined (DEBUG_FIND_LEASE)
4572 log_info ("...but it was on the wrong shared network.");
4573#endif
4574 strcpy (dhcp_message, "requested address on bad subnet");
4575 lease_dereference (&ip_lease, MDL);
4576 }
4577
4578 /*
4579 * If the requested address is in use (or potentially in use) by
4580 * a different client, it can't be granted.
4581 *
4582 * This first conditional only detects if the lease is currently
4583 * identified to a different client (client-id and/or chaddr
4584 * mismatch). In this case we may not want to give the client the
4585 * lease, if doing so may potentially be an addressing conflict.
4586 */
4587 if (ip_lease &&
4588 (ip_lease -> uid ?
4589 (!have_client_identifier ||
4590 ip_lease -> uid_len != client_identifier.len ||
4591 memcmp (ip_lease -> uid, client_identifier.data,
4592 ip_lease -> uid_len)) :
4593 (ip_lease -> hardware_addr.hbuf [0] != packet -> raw -> htype ||
4594 ip_lease -> hardware_addr.hlen != packet -> raw -> hlen + 1 ||
4595 memcmp (&ip_lease -> hardware_addr.hbuf [1],
4596 packet -> raw -> chaddr,
4597 (unsigned)(ip_lease -> hardware_addr.hlen - 1))))) {
4598 /*
4599 * A lease is unavailable for allocation to a new client if
4600 * it is not in the FREE or BACKUP state. There may be
4601 * leases that are in the expired state with a rewinding
4602 * state that is free or backup, but these will be processed
4603 * into the free or backup states by expiration processes, so
4604 * checking for them here is superfluous.
4605 */
4606 if (ip_lease -> binding_state != FTS_FREE &&
4607 ip_lease -> binding_state != FTS_BACKUP) {
4608#if defined (DEBUG_FIND_LEASE)
4609 log_info ("rejecting lease for requested address.");
4610#endif
4611 /* If we're rejecting it because the peer has
4612 it, don't set "ours", because we shouldn't NAK. */
4613 if (ours && ip_lease -> binding_state != FTS_ACTIVE)
4614 *ours = 0;
4615 lease_dereference (&ip_lease, MDL);
4616 }
4617 }
4618
4619 /*
4620 * If we got an ip_lease and a uid_lease or hw_lease, and ip_lease
4621 * is/was not active, and is not ours to reallocate, forget about it.
4622 */
4623 if (ip_lease && (uid_lease || hw_lease) &&
4624 ip_lease->binding_state != FTS_ACTIVE &&
4625 ip_lease->rewind_binding_state != FTS_ACTIVE &&
4626#if defined(FAILOVER_PROTOCOL)
4627 !lease_mine_to_reallocate(ip_lease) &&
4628#endif
4630#if defined (DEBUG_FIND_LEASE)
4631 log_info("ip lease not active or not ours to offer.");
4632#endif
4633 lease_dereference(&ip_lease, MDL);
4634 }
4635
4636 /* If for some reason the client has more than one lease
4637 on the subnet that matches its uid, pick the one that
4638 it asked for and (if we can) free the other. */
4639 if (ip_lease && ip_lease->binding_state == FTS_ACTIVE &&
4640 ip_lease->uid && ip_lease != uid_lease) {
4641 if (have_client_identifier &&
4642 (ip_lease -> uid_len == client_identifier.len) &&
4643 !memcmp (client_identifier.data,
4644 ip_lease -> uid, ip_lease -> uid_len)) {
4645 if (uid_lease) {
4646 if (uid_lease->binding_state == FTS_ACTIVE) {
4647 log_error ("client %s has duplicate%s on %s",
4649 " leases",
4650 (ip_lease -> subnet ->
4651 shared_network -> name));
4652
4653 /* If the client is REQUESTing the lease,
4654 it shouldn't still be using the old
4655 one, so we can free it for allocation. */
4656 if (uid_lease &&
4657 uid_lease->binding_state == FTS_ACTIVE &&
4658 !packet -> raw -> ciaddr.s_addr &&
4659 (share ==
4660 uid_lease -> subnet -> shared_network) &&
4661 packet -> packet_type == DHCPREQUEST)
4662 release_lease (uid_lease, packet);
4663 }
4664 lease_dereference (&uid_lease, MDL);
4665 lease_reference (&uid_lease, ip_lease, MDL);
4666 }
4667 }
4668
4669 /* If we get to here and fixed_lease is not null, that means
4670 that there are both a dynamic lease and a fixed-address
4671 declaration for the same IP address. */
4672 if (packet -> packet_type == DHCPREQUEST && fixed_lease) {
4673 lease_dereference (&fixed_lease, MDL);
4674 db_conflict:
4675 log_error ("Dynamic and static leases present for %s.",
4676 piaddr (cip));
4677 log_error ("Remove host declaration %s or remove %s",
4678 (fixed_lease && fixed_lease -> host
4679 ? (fixed_lease -> host -> name
4680 ? fixed_lease -> host -> name
4681 : piaddr (cip))
4682 : piaddr (cip)),
4683 piaddr (cip));
4684 log_error ("from the dynamic address pool for %s",
4685 ip_lease -> subnet -> shared_network -> name
4686 );
4687 if (fixed_lease)
4688 lease_dereference (&ip_lease, MDL);
4689 strcpy (dhcp_message,
4690 "database conflict - call for help!");
4691 }
4692
4693 if (ip_lease && ip_lease != uid_lease) {
4694#if defined (DEBUG_FIND_LEASE)
4695 log_info ("requested address not available.");
4696#endif
4697 lease_dereference (&ip_lease, MDL);
4698 }
4699 }
4700
4701 /* If we get to here with both fixed_lease and ip_lease not
4702 null, then we have a configuration file bug. */
4703 if (packet -> packet_type == DHCPREQUEST && fixed_lease && ip_lease)
4704 goto db_conflict;
4705
4706 /* Toss extra pointers to the same lease... */
4707 if (hw_lease && hw_lease == uid_lease) {
4708#if defined (DEBUG_FIND_LEASE)
4709 log_info ("hardware lease and uid lease are identical.");
4710#endif
4711 lease_dereference (&hw_lease, MDL);
4712 }
4713 if (ip_lease && ip_lease == hw_lease) {
4714 lease_dereference (&hw_lease, MDL);
4715#if defined (DEBUG_FIND_LEASE)
4716 log_info ("hardware lease and ip lease are identical.");
4717#endif
4718 }
4719 if (ip_lease && ip_lease == uid_lease) {
4720 lease_dereference (&uid_lease, MDL);
4721#if defined (DEBUG_FIND_LEASE)
4722 log_info ("uid lease and ip lease are identical.");
4723#endif
4724 }
4725
4726 /* Make sure the client is permitted to use the requested lease. */
4727 if (ip_lease &&
4728 ((ip_lease -> pool -> prohibit_list &&
4729 permitted (packet, ip_lease -> pool -> prohibit_list)) ||
4730 (ip_lease -> pool -> permit_list &&
4731 !permitted (packet, ip_lease -> pool -> permit_list)))) {
4732 if (!packet->raw->ciaddr.s_addr &&
4733 (ip_lease->binding_state == FTS_ACTIVE))
4734 release_lease (ip_lease, packet);
4735
4736 lease_dereference (&ip_lease, MDL);
4737 }
4738
4739 if (uid_lease &&
4740 ((uid_lease -> pool -> prohibit_list &&
4741 permitted (packet, uid_lease -> pool -> prohibit_list)) ||
4742 (uid_lease -> pool -> permit_list &&
4743 !permitted (packet, uid_lease -> pool -> permit_list)))) {
4744 if (!packet -> raw -> ciaddr.s_addr)
4745 release_lease (uid_lease, packet);
4746 lease_dereference (&uid_lease, MDL);
4747 }
4748
4749 if (hw_lease &&
4750 ((hw_lease -> pool -> prohibit_list &&
4751 permitted (packet, hw_lease -> pool -> prohibit_list)) ||
4752 (hw_lease -> pool -> permit_list &&
4753 !permitted (packet, hw_lease -> pool -> permit_list)))) {
4754 if (!packet -> raw -> ciaddr.s_addr)
4755 release_lease (hw_lease, packet);
4756 lease_dereference (&hw_lease, MDL);
4757 }
4758
4759 /* If we've already eliminated the lease, it wasn't there to
4760 begin with. If we have come up with a matching lease,
4761 set the message to bad network in case we have to throw it out. */
4762 if (!ip_lease) {
4763 strcpy (dhcp_message, "requested address not available");
4764 }
4765
4766 /* If this is a DHCPREQUEST, make sure the lease we're going to return
4767 matches the requested IP address. If it doesn't, don't return a
4768 lease at all. */
4769 if (packet -> packet_type == DHCPREQUEST &&
4770 !ip_lease && !fixed_lease) {
4771#if defined (DEBUG_FIND_LEASE)
4772 log_info ("no applicable lease found for DHCPREQUEST.");
4773#endif
4774 goto out;
4775 }
4776
4777 /* At this point, if fixed_lease is nonzero, we can assign it to
4778 this client. */
4779 if (fixed_lease) {
4780 lease_reference (&lease, fixed_lease, MDL);
4781 lease_dereference (&fixed_lease, MDL);
4782#if defined (DEBUG_FIND_LEASE)
4783 log_info ("choosing fixed address.");
4784#endif
4785 }
4786
4787 /* If we got a lease that matched the ip address and don't have
4788 a better offer, use that; otherwise, release it. */
4789 if (ip_lease) {
4790 if (lease) {
4791 if (!packet -> raw -> ciaddr.s_addr)
4792 release_lease (ip_lease, packet);
4793#if defined (DEBUG_FIND_LEASE)
4794 log_info ("not choosing requested address (!).");
4795#endif
4796 lease_dereference (&ip_lease, MDL);
4797 } else {
4798#if defined (DEBUG_FIND_LEASE)
4799 log_info ("choosing lease on requested address.");
4800#endif
4801 lease_reference (&lease, ip_lease, MDL);
4802 if (lease -> host)
4803 host_dereference (&lease -> host, MDL);
4804 }
4805 }
4806
4807 /* If we got a lease that matched the client identifier, we may want
4808 to use it, but if we already have a lease we like, we must free
4809 the lease that matched the client identifier. */
4810 if (uid_lease) {
4811 if (lease) {
4812 log_error("uid lease %s for client %s is duplicate "
4813 "on %s",
4814 piaddr(uid_lease->ip_addr),
4816 uid_lease->subnet->shared_network->name);
4817
4818 if (!packet -> raw -> ciaddr.s_addr &&
4819 packet -> packet_type == DHCPREQUEST &&
4820 uid_lease -> binding_state == FTS_ACTIVE)
4821 release_lease(uid_lease, packet);
4822#if defined (DEBUG_FIND_LEASE)
4823 log_info ("not choosing uid lease.");
4824#endif
4825 } else {
4826 lease_reference (&lease, uid_lease, MDL);
4827 if (lease -> host)
4828 host_dereference (&lease -> host, MDL);
4829#if defined (DEBUG_FIND_LEASE)
4830 log_info ("choosing uid lease.");
4831#endif
4832 }
4833 lease_dereference (&uid_lease, MDL);
4834 }
4835
4836 /* The lease that matched the hardware address is treated likewise. */
4837 if (hw_lease) {
4838 if (lease) {
4839#if defined (DEBUG_FIND_LEASE)
4840 log_info ("not choosing hardware lease.");
4841#endif
4842 } else {
4843 /* We're a little lax here - if the client didn't
4844 send a client identifier and it's a bootp client,
4845 but the lease has a client identifier, we still
4846 let the client have a lease. */
4847 if (!hw_lease -> uid_len ||
4848 (have_client_identifier
4849 ? (hw_lease -> uid_len ==
4850 client_identifier.len &&
4851 !memcmp (hw_lease -> uid,
4852 client_identifier.data,
4853 client_identifier.len))
4854 : packet -> packet_type == 0)) {
4855 lease_reference (&lease, hw_lease, MDL);
4856 if (lease -> host)
4857 host_dereference (&lease -> host, MDL);
4858#if defined (DEBUG_FIND_LEASE)
4859 log_info ("choosing hardware lease.");
4860#endif
4861 } else {
4862#if defined (DEBUG_FIND_LEASE)
4863 log_info ("not choosing hardware lease: %s.",
4864 "uid mismatch");
4865#endif
4866 }
4867 }
4868 lease_dereference (&hw_lease, MDL);
4869 }
4870
4871 /*
4872 * If we found a host_decl but no matching address, try to
4873 * find a host_decl that has no address, and if there is one,
4874 * hang it off the lease so that we can use the supplied
4875 * options.
4876 */
4877 if (lease && host && !lease->host) {
4878 struct host_decl *p = NULL;
4879 struct host_decl *n = NULL;
4880
4881 host_reference(&p, host, MDL);
4882 while (p != NULL) {
4883 if (!p->fixed_addr) {
4884 /*
4885 * If the lease is currently active, then it
4886 * must be allocated to the present client.
4887 * We store a reference to the host record on
4888 * the lease to save a lookup later (in
4889 * ack_lease()). We mustn't refer to the host
4890 * record on non-active leases because the
4891 * client may be denied later.
4892 *
4893 * XXX: Not having this reference (such as in
4894 * DHCPDISCOVER/INIT) means ack_lease will have
4895 * to perform this lookup a second time. This
4896 * hopefully isn't a problem as DHCPREQUEST is
4897 * more common than DHCPDISCOVER.
4898 */
4900 host_reference(&lease->host, p, MDL);
4901
4902 host_dereference(&p, MDL);
4903 break;
4904 }
4905 if (p->n_ipaddr != NULL)
4906 host_reference(&n, p->n_ipaddr, MDL);
4907 host_dereference(&p, MDL);
4908 if (n != NULL) {
4909 host_reference(&p, n, MDL);
4910 host_dereference(&n, MDL);
4911 }
4912 }
4913 }
4914
4915 /* If we find an abandoned lease, but it's the one the client
4916 requested, we assume that previous bugginess on the part
4917 of the client, or a server database loss, caused the lease to
4918 be abandoned, so we reclaim it and let the client have it. */
4919 if (lease &&
4920 (lease -> binding_state == FTS_ABANDONED) &&
4921 lease == ip_lease &&
4922 packet -> packet_type == DHCPREQUEST) {
4923 log_error ("Reclaiming REQUESTed abandoned IP address %s.",
4924 piaddr (lease -> ip_addr));
4925 } else if (lease && (lease -> binding_state == FTS_ABANDONED)) {
4926 /* Otherwise, if it's not the one the client requested, we do not
4927 return it - instead, we claim it's ours, causing a DHCPNAK to be
4928 sent if this lookup is for a DHCPREQUEST, and force the client
4929 to go back through the allocation process. */
4930 if (ours)
4931 *ours = 1;
4932 lease_dereference (&lease, MDL);
4933 }
4934
4935 out:
4936 if (have_client_identifier)
4938
4939 if (fixed_lease)
4940 lease_dereference (&fixed_lease, MDL);
4941 if (hw_lease)
4942 lease_dereference (&hw_lease, MDL);
4943 if (uid_lease)
4944 lease_dereference (&uid_lease, MDL);
4945 if (ip_lease)
4946 lease_dereference (&ip_lease, MDL);
4947 if (host)
4948 host_dereference (&host, MDL);
4949
4950 if (lease) {
4951#if defined (DEBUG_FIND_LEASE)
4952 log_info ("Returning lease: %s.",
4953 piaddr (lease -> ip_addr));
4954#endif
4955 lease_reference (lp, lease, file, line);
4956 lease_dereference (&lease, MDL);
4957 return 1;
4958 }
4959#if defined (DEBUG_FIND_LEASE)
4960 log_info ("Not returning a lease.");
4961#endif
4962 return 0;
4963}
4964
4965/* Search the provided host_decl structure list for an address that's on
4966 the specified shared network. If one is found, mock up and return a
4967 lease structure for it; otherwise return the null pointer. */
4968
4969int mockup_lease (struct lease **lp, struct packet *packet,
4970 struct shared_network *share, struct host_decl *hp)
4971{
4972 struct lease *lease = (struct lease *)0;
4973 struct host_decl *rhp = (struct host_decl *)0;
4974
4975 if (lease_allocate (&lease, MDL) != ISC_R_SUCCESS)
4976 return 0;
4977 if (host_reference (&rhp, hp, MDL) != ISC_R_SUCCESS) {
4978 lease_dereference (&lease, MDL);
4979 return 0;
4980 }
4982 &rhp, &lease -> ip_addr, share)) {
4983 lease_dereference (&lease, MDL);
4984 host_dereference (&rhp, MDL);
4985 return 0;
4986 }
4987 host_reference (&lease -> host, rhp, MDL);
4988 if (rhp -> client_identifier.len > sizeof lease -> uid_buf)
4989 lease -> uid = dmalloc (rhp -> client_identifier.len, MDL);
4990 else
4991 lease -> uid = lease -> uid_buf;
4992 if (!lease -> uid) {
4993 lease_dereference (&lease, MDL);
4994 host_dereference (&rhp, MDL);
4995 return 0;
4996 }
4997 memcpy (lease -> uid, rhp -> client_identifier.data,
4998 rhp -> client_identifier.len);
4999 lease -> uid_len = rhp -> client_identifier.len;
5000 lease -> hardware_addr = rhp -> interface;
5001 lease -> starts = lease -> cltt = lease -> ends = MIN_TIME;
5003 lease -> binding_state = FTS_FREE;
5004
5005 lease_reference (lp, lease, MDL);
5006
5007 lease_dereference (&lease, MDL);
5008 host_dereference (&rhp, MDL);
5009 return 1;
5010}
5011
5012/* Look through all the pools in a list starting with the specified pool
5013 for a free lease. We try to find a virgin lease if we can. If we
5014 don't find a virgin lease, we try to find a non-virgin lease that's
5015 free. If we can't find one of those, we try to reclaim an abandoned
5016 lease. If all of these possibilities fail to pan out, we don't return
5017 a lease at all. */
5018
5019int allocate_lease (struct lease **lp, struct packet *packet,
5020 struct pool *pool, int *peer_has_leases)
5021{
5022 struct lease *lease = NULL;
5023 struct lease *candl = NULL;
5024
5025 for (; pool ; pool = pool -> next) {
5026 if ((pool -> prohibit_list &&
5027 permitted (packet, pool -> prohibit_list)) ||
5028 (pool -> permit_list &&
5029 !permitted (packet, pool -> permit_list)))
5030 continue;
5031
5032#if defined (FAILOVER_PROTOCOL)
5033 /* Peer_has_leases just says that we found at least one
5034 free lease. If no free lease is returned, the caller
5035 can deduce that this means the peer is hogging all the
5036 free leases, so we can print a better error message. */
5037 /* XXX Do we need code here to ignore PEER_IS_OWNER and
5038 * XXX just check tstp if we're in, e.g., PARTNER_DOWN?
5039 * XXX Where do we deal with CONFLICT_DETECTED, et al? */
5040 /* XXX This should be handled by the lease binding "state
5041 * XXX machine" - that is, when we get here, if a lease
5042 * XXX could be allocated, it will have the correct
5043 * XXX binding state so that the following code will
5044 * XXX result in its being allocated. */
5045 /* Skip to the most expired lease in the pool that is not
5046 * owned by a failover peer. */
5047 if (pool->failover_peer != NULL) {
5048 struct lease *peerl = NULL;
5049 if (pool->failover_peer->i_am == primary) {
5050 candl = LEASE_GET_FIRST(pool->free);
5051
5052 /*
5053 * In normal operation, we never want to touch
5054 * the peer's leases. In partner-down
5055 * operation, we need to be able to pick up
5056 * the peer's leases after STOS+MCLT.
5057 */
5058 peerl = LEASE_GET_FIRST(pool->backup);
5059 if (peerl != NULL) {
5060 if (((candl == NULL) ||
5061 (candl->ends > peerl->ends)) &&
5062 lease_mine_to_reallocate(peerl)) {
5063 candl = peerl;
5064 } else {
5065 *peer_has_leases = 1;
5066 }
5067 }
5068 } else {
5069 candl = LEASE_GET_FIRST(pool->backup);
5070
5071 peerl = LEASE_GET_FIRST(pool->free);
5072 if (peerl != NULL) {
5073 if (((candl == NULL) ||
5074 (candl->ends > peerl->ends)) &&
5075 lease_mine_to_reallocate(peerl)) {
5076 candl = peerl;
5077 } else {
5078 *peer_has_leases = 1;
5079 }
5080 }
5081 }
5082
5083 /* Try abandoned leases as a last resort. */
5084 peerl = LEASE_GET_FIRST(pool->abandoned);
5085 if ((candl == NULL) && (peerl != NULL) &&
5087 candl = peerl;
5088 } else
5089#endif
5090 {
5092 candl = LEASE_GET_FIRST(pool->free);
5093 else
5094 candl = LEASE_GET_FIRST(pool->abandoned);
5095 }
5096
5097 /*
5098 * XXX: This may not match with documented expectation.
5099 * It's expected that when we OFFER a lease, we set its
5100 * ends time forward 2 minutes so that it gets sorted to
5101 * the end of its free list (avoiding a similar allocation
5102 * to another client). It is not expected that we issue a
5103 * "no free leases" error when the last lease has been
5104 * offered, but it's not exactly broken either.
5105 */
5106 if (!candl ||
5107 (candl->binding_state != FTS_ABANDONED &&
5108 (candl->ends > cur_time))) {
5109 continue;
5110 }
5111
5112 if (!lease) {
5113 lease = candl;
5114 continue;
5115 }
5116
5117 /*
5118 * There are tiers of lease state preference, listed here in
5119 * reverse order (least to most preferential):
5120 *
5121 * ABANDONED
5122 * FREE/BACKUP
5123 *
5124 * If the selected lease and candidate are both of the same
5125 * state, select the oldest (longest ago) expiration time
5126 * between the two. If the candidate lease is of a higher
5127 * preferred grade over the selected lease, use it.
5128 */
5129 if ((lease -> binding_state == FTS_ABANDONED) &&
5130 ((candl -> binding_state != FTS_ABANDONED) ||
5131 (candl -> ends < lease -> ends))) {
5132 lease = candl;
5133 continue;
5134 } else if (candl -> binding_state == FTS_ABANDONED)
5135 continue;
5136
5137 if ((lease -> uid_len || lease -> hardware_addr.hlen) &&
5138 ((!candl -> uid_len && !candl -> hardware_addr.hlen) ||
5139 (candl -> ends < lease -> ends))) {
5140 lease = candl;
5141 continue;
5142 } else if (candl -> uid_len || candl -> hardware_addr.hlen)
5143 continue;
5144
5145 if (candl -> ends < lease -> ends)
5146 lease = candl;
5147 }
5148
5149 if (lease != NULL) {
5151 log_error("Reclaiming abandoned lease %s.",
5152 piaddr(lease->ip_addr));
5153
5154 /*
5155 * XXX: For reliability, we go ahead and remove the host
5156 * record and try to move on. For correctness, if there
5157 * are any other stale host vectors, we want to find them.
5158 */
5159 if (lease->host != NULL) {
5160 log_debug("soft impossible condition (%s:%d): stale "
5161 "host \"%s\" found on lease %s", MDL,
5162 lease->host->name,
5163 piaddr(lease->ip_addr));
5164 host_dereference(&lease->host, MDL);
5165 }
5166
5167 lease_reference (lp, lease, MDL);
5168 return 1;
5169 }
5170
5171 return 0;
5172}
5173
5174/* Determine whether or not a permit exists on a particular permit list
5175 that matches the specified packet, returning nonzero if so, zero if
5176 not. */
5177
5178int permitted (packet, permit_list)
5179 struct packet *packet;
5180 struct permit *permit_list;
5181{
5182 struct permit *p;
5183 int i;
5184
5185 for (p = permit_list; p; p = p -> next) {
5186 switch (p -> type) {
5188 if (!packet -> known)
5189 return 1;
5190 break;
5191
5193 if (packet -> known)
5194 return 1;
5195 break;
5196
5198 if (packet -> authenticated)
5199 return 1;
5200 break;
5201
5203 if (!packet -> authenticated)
5204 return 1;
5205 break;
5206
5207 case permit_all_clients:
5208 return 1;
5209
5211 if (!packet -> options_valid ||
5212 !packet -> packet_type)
5213 return 1;
5214 break;
5215
5216 case permit_class:
5217 for (i = 0; i < packet -> class_count; i++) {
5218 if (p -> class == packet -> classes [i])
5219 return 1;
5220 if (packet -> classes [i] &&
5221 packet -> classes [i] -> superclass &&
5222 (packet -> classes [i] -> superclass ==
5223 p -> class))
5224 return 1;
5225 }
5226 break;
5227
5228 case permit_after:
5229 if (cur_time > p->after)
5230 return 1;
5231 break;
5232 }
5233 }
5234 return 0;
5235}
5236
5237#if defined(DHCPv6) && defined(DHCP4o6)
5238static int locate_network6 (packet)
5239 struct packet *packet;
5240{
5241 const struct packet *chk_packet;
5242 const struct in6_addr *link_addr, *first_link_addr;
5243 struct iaddr ia;
5244 struct data_string data;
5245 struct subnet *subnet = NULL;
5246 struct option_cache *oc;
5247
5248 /* from locate_network() */
5249
5250 /* See if there's a Relay Agent Link Selection Option, or a
5251 * Subnet Selection Option. The Link-Select and Subnet-Select
5252 * are formatted and used precisely the same, but we must prefer
5253 * the link-select over the subnet-select.
5254 * BTW in DHCPv4 over DHCPv6 no cross version relay was specified
5255 * so it is unlikely to see a link-select.
5256 */
5258 RAI_LINK_SELECT)) == NULL)
5261
5262 /* If there's an option indicating link connection or subnet
5263 * selection, and it's valid, use it to figure out the subnet.
5264 * If it's not valid, fail.
5265 */
5266 if (oc) {
5267 memset(&data, 0, sizeof data);
5268 if (!evaluate_option_cache(&data, packet, NULL, NULL,
5269 packet->options, NULL,
5270 &global_scope, oc, MDL)) {
5271 return (0);
5272 }
5273 if (data.len == 0) {
5274 return (0);
5275 }
5276 if (data.len != 4) {
5278 return (0);
5279 }
5280 ia.len = 4;
5281 memcpy(ia.iabuf, data.data, 4);
5283
5284 if (find_subnet(&subnet, ia, MDL)) {
5285 shared_network_reference(&packet->shared_network,
5287 subnet_dereference(&subnet, MDL);
5288 return (1);
5289 }
5290 return (0);
5291 }
5292
5293 /* See if there is a giaddr (still unlikely), if there is one
5294 * use it to figure out the subnet. If it's not valid, fail.
5295 */
5296 if (packet->raw->giaddr.s_addr) {
5297 ia.len = 4;
5298 memcpy(ia.iabuf, &packet->raw->giaddr, 4);
5299
5300 if (find_subnet(&subnet, ia, MDL)) {
5301 shared_network_reference(&packet->shared_network,
5303 subnet_dereference(&subnet, MDL);
5304 return (1);
5305 }
5306 return (0);
5307 }
5308
5309 /* from shared_network_from_packet6() */
5310
5311 /* First, find the link address where the packet from the client
5312 * first appeared (if this packet was relayed).
5313 */
5314 first_link_addr = NULL;
5315 chk_packet = packet->dhcpv6_container_packet;
5316 while (chk_packet != NULL) {
5317 link_addr = &chk_packet->dhcpv6_link_address;
5318 if (!IN6_IS_ADDR_UNSPECIFIED(link_addr) &&
5319 !IN6_IS_ADDR_LINKLOCAL(link_addr)) {
5320 first_link_addr = link_addr;
5321 break;
5322 }
5323 chk_packet = chk_packet->dhcpv6_container_packet;
5324 }
5325
5326 /* If there is a relayed link address, find the subnet associated
5327 * with that, and use that to get the appropriate shared_network.
5328 */
5329 if (first_link_addr != NULL) {
5330 ia.len = sizeof(*first_link_addr);
5331 memcpy(ia.iabuf, first_link_addr, sizeof(*first_link_addr));
5332 if (find_subnet (&subnet, ia, MDL)) {
5333 shared_network_reference(&packet->shared_network,
5335 subnet_dereference(&subnet, MDL);
5336 return (1);
5337 }
5338 return (0);
5339 }
5340
5341 /* If there is no link address, we will use the interface
5342 * that this packet came in on to pick the shared_network.
5343 */
5344 if (packet->interface != NULL) {
5345 if (packet->interface->shared_network == NULL)
5346 return (0);
5347 shared_network_reference(&packet->shared_network,
5349 MDL);
5350 return (1);
5351 }
5352
5353 /* We shouldn't be able to get here but if there is no link
5354 * address and no interface we don't know where to get the
5355 * shared_network from, log an error and return an error.
5356 */
5357 log_error("No interface and no link address "
5358 "can't determine DHCP4o6 shared network");
5359 return (0);
5360}
5361#endif
5362
5364 struct packet *packet;
5365{
5366 struct iaddr ia;
5367 struct data_string data;
5368 struct subnet *subnet = (struct subnet *)0;
5369 struct option_cache *oc;
5370 int norelay = 0;
5371
5372#if defined(DHCPv6) && defined(DHCP4o6)
5373 if (dhcpv4_over_dhcpv6 && (packet->dhcp4o6_response != NULL)) {
5374 return (locate_network6 (packet));
5375 }
5376#endif
5377
5378 /* See if there's a Relay Agent Link Selection Option, or a
5379 * Subnet Selection Option. The Link-Select and Subnet-Select
5380 * are formatted and used precisely the same, but we must prefer
5381 * the link-select over the subnet-select.
5382 */
5384 RAI_LINK_SELECT)) == NULL)
5387
5388 /* If there's no SSO and no giaddr, then use the shared_network
5389 from the interface, if there is one. If not, fail. */
5390 if (!oc && !packet -> raw -> giaddr.s_addr) {
5391 if (packet -> interface -> shared_network) {
5392 struct in_addr any_addr;
5393 any_addr.s_addr = INADDR_ANY;
5394
5395 if (!packet -> packet_type && memcmp(&packet -> raw -> ciaddr, &any_addr, 4)) {
5396 struct iaddr cip;
5397 memcpy(cip.iabuf, &packet -> raw -> ciaddr, 4);
5398 cip.len = 4;
5400 norelay = 2;
5401 }
5402
5403 if (!norelay) {
5404 shared_network_reference(&packet -> shared_network, packet -> interface -> shared_network, MDL);
5405 return 1;
5406 }
5407 } else {
5408 return 0;
5409 }
5410 }
5411
5412 /* If there's an option indicating link connection, and it's valid,
5413 * use it to figure out the subnet. If it's not valid, fail.
5414 */
5415 if (oc) {
5416 memset (&data, 0, sizeof data);
5417 if (!evaluate_option_cache (&data, packet, (struct lease *)0,
5418 (struct client_state *)0,
5419 packet -> options,
5420 (struct option_state *)0,
5421 &global_scope, oc, MDL)) {
5422 return 0;
5423 }
5424
5425 if (data.len != 4) {
5426 data_string_forget (&data, MDL);
5427 return 0;
5428 }
5429
5430 ia.len = 4;
5431 memcpy (ia.iabuf, data.data, 4);
5432 data_string_forget (&data, MDL);
5433 } else {
5434 ia.len = 4;
5435 if (norelay)
5436 memcpy (ia.iabuf, &packet->raw->ciaddr, 4);
5437 else
5438 memcpy (ia.iabuf, &packet->raw->giaddr, 4);
5439 }
5440
5441 /* If we know the subnet on which the IP address lives, use it. */
5442 if (find_subnet (&subnet, ia, MDL)) {
5443 shared_network_reference (&packet -> shared_network,
5445 subnet_dereference (&subnet, MDL);
5446 if (norelay)
5447 return norelay;
5448 else
5449 return 1;
5450 }
5451
5452 /* Otherwise, fail. */
5453 return 0;
5454}
5455
5456/*
5457 * Try to figure out the source address to send packets from.
5458 *
5459 * from is the address structure we use to return any address
5460 * we find.
5461 *
5462 * options is the option cache to search. This may include
5463 * options from the incoming packet and configuration information.
5464 *
5465 * out_options is the outgoing option cache. This cache
5466 * may be the same as options. If out_options isn't NULL
5467 * we may save the server address option into it. We do so
5468 * if out_options is different than options or if the option
5469 * wasn't in options and we needed to find the address elsewhere.
5470 *
5471 * packet is the state structure for the incoming packet
5472 *
5473 * When finding the address we first check to see if it is
5474 * in the options list. If it isn't we use the first address
5475 * from the interface.
5476 *
5477 * While this is slightly more complicated than I'd like it allows
5478 * us to use the same code in several different places. ack,
5479 * inform and lease query use it to find the address and fill
5480 * in the options if we get the address from the interface.
5481 * nack uses it to find the address and copy it to the outgoing
5482 * cache. dhcprequest uses it to find the address for comparison
5483 * and doesn't need to add it to an outgoing list.
5484 */
5485
5486void
5487get_server_source_address(struct in_addr *from,
5488 struct option_state *options,
5489 struct option_state *out_options,
5490 struct packet *packet) {
5491 unsigned option_num;
5492 struct option_cache *oc = NULL;
5493 struct data_string d;
5494 struct in_addr *a = NULL;
5495 isc_boolean_t found = ISC_FALSE;
5496 int allocate = 0;
5497
5498 memset(&d, 0, sizeof(d));
5499 memset(from, 0, sizeof(*from));
5500
5501 option_num = DHO_DHCP_SERVER_IDENTIFIER;
5502 oc = lookup_option(&dhcp_universe, options, option_num);
5503 if (oc != NULL) {
5504 if (evaluate_option_cache(&d, packet, NULL, NULL,
5505 packet->options, options,
5506 &global_scope, oc, MDL)) {
5507 if (d.len == sizeof(*from)) {
5508 found = ISC_TRUE;
5509 memcpy(from, d.data, sizeof(*from));
5510
5511 /*
5512 * Arrange to save a copy of the data
5513 * to the outgoing list.
5514 */
5515 if ((out_options != NULL) &&
5516 (options != out_options)) {
5517 a = from;
5518 allocate = 1;
5519 }
5520 }
5522 }
5523 oc = NULL;
5524 }
5525
5526 if ((found == ISC_FALSE) &&
5527 (packet->interface->address_count > 0)) {
5528 *from = packet->interface->addresses[0];
5529
5530 if (out_options != NULL) {
5531 a = &packet->interface->addresses[0];
5532 }
5533 }
5534
5535 if ((a != NULL) &&
5536 (option_cache_allocate(&oc, MDL))) {
5537 if (make_const_data(&oc->expression,
5538 (unsigned char *)a, sizeof(*a),
5539 0, allocate, MDL)) {
5540 option_code_hash_lookup(&oc->option,
5541 dhcp_universe.code_hash,
5542 &option_num, 0, MDL);
5543 save_option(&dhcp_universe, out_options, oc);
5544 }
5546 }
5547
5548 return;
5549}
5550
5572void
5573eval_network_statements(struct option_state **network_options,
5574 struct packet *packet,
5575 struct group *network_group) {
5576
5577 if (*network_options == NULL) {
5578 option_state_allocate (network_options, MDL);
5579 }
5580
5581 /* Use the packet's shared_network if it has one. If not use
5582 * network_group and if it is null then use global scope. */
5583 if (packet->shared_network != NULL) {
5584 /*
5585 * If we have a subnet and group start with that else start
5586 * with the shared network group. The first will recurse and
5587 * include the second.
5588 */
5589 if ((packet->shared_network->subnets != NULL) &&
5590 (packet->shared_network->subnets->group != NULL)) {
5591 execute_statements_in_scope(NULL, packet, NULL, NULL,
5592 packet->options, *network_options,
5593 &global_scope,
5595 NULL, NULL);
5596 } else {
5597 execute_statements_in_scope(NULL, packet, NULL, NULL,
5598 packet->options, *network_options,
5599 &global_scope,
5601 NULL, NULL);
5602 }
5603
5604 /* do the pool if there is one */
5605 if (packet->shared_network->pools != NULL) {
5606 execute_statements_in_scope(NULL, packet, NULL, NULL,
5607 packet->options, *network_options,
5608 &global_scope,
5611 NULL);
5612 }
5613 } else if (network_group != NULL) {
5614 execute_statements_in_scope(NULL, packet, NULL, NULL,
5615 packet->options, *network_options,
5616 &global_scope, network_group,
5617 NULL, NULL);
5618 } else {
5619 execute_statements_in_scope(NULL, packet, NULL, NULL,
5620 packet->options, *network_options,
5622 NULL, NULL);
5623 }
5624}
5625
5626/*
5627 * Look for the lowest numbered site code number and
5628 * apply a log warning if it is less than 224. Do not
5629 * permit site codes less than 128 (old code never did).
5630 *
5631 * Note that we could search option codes 224 down to 128
5632 * on the hash table, but the table is (probably) smaller
5633 * than that if it was declared as a standalone table with
5634 * defaults. So we traverse the option code hash.
5635 */
5636static int
5637find_min_site_code(struct universe *u)
5638{
5639 if (u->site_code_min)
5640 return u->site_code_min;
5641
5642 /*
5643 * Note that site_code_min has to be global as we can't pass an
5644 * argument through hash_foreach(). The value 224 is taken from
5645 * RFC 3942.
5646 */
5647 site_code_min = 224;
5648 option_code_hash_foreach(u->code_hash, lowest_site_code);
5649
5650 if (site_code_min < 224) {
5651 log_error("WARNING: site-local option codes less than 224 have "
5652 "been deprecated by RFC3942. You have options "
5653 "listed in site local space %s that number as low as "
5654 "%d. Please investigate if these should be declared "
5655 "as regular options rather than site-local options, "
5656 "or migrated up past 224.",
5657 u->name, site_code_min);
5658 }
5659
5660 /*
5661 * don't even bother logging, this is just silly, and never worked
5662 * on any old version of software.
5663 */
5664 if (site_code_min < 128)
5665 site_code_min = 128;
5666
5667 /*
5668 * Cache the determined minimum site code on the universe structure.
5669 * Note that due to the < 128 check above, a value of zero is
5670 * impossible.
5671 */
5672 u->site_code_min = site_code_min;
5673
5674 return site_code_min;
5675}
5676
5677static isc_result_t
5678lowest_site_code(const void *key, unsigned len, void *object)
5679{
5680 struct option *option = object;
5681
5682 if (option->code < site_code_min)
5683 site_code_min = option->code;
5684
5685 return ISC_R_SUCCESS;
5686}
5687
5688static void
5689maybe_return_agent_options(struct packet *packet, struct option_state *options)
5690{
5691 /* If there were agent options in the incoming packet, return
5692 * them. Do not return the agent options if they were stashed
5693 * on the lease. We do not check giaddr to detect the presence of
5694 * a relay, as this excludes "l2" relay agents which have no giaddr
5695 * to set.
5696 *
5697 * XXX: If the user configures options for the relay agent information
5698 * (state->options->universes[agent_universe.index] is not NULL),
5699 * we're still required to duplicate other values provided by the
5700 * relay agent. So we need to merge the old values not configured
5701 * by the user into the new state, not just give up.
5702 */
5704 (packet->options != NULL) &&
5706 packet->options->universes[agent_universe.index] != NULL &&
5707 (options->universe_count <= agent_universe.index ||
5708 options->universes[agent_universe.index] == NULL)) {
5710 ((struct option_chain_head **)
5711 &(options->universes[agent_universe.index]),
5712 (struct option_chain_head *)
5714
5715 if (options->universe_count <= agent_universe.index)
5716 options->universe_count = agent_universe.index + 1;
5717 }
5718}
5719
5733 struct lease *lease,
5734 struct option_state *options) {
5735 unsigned int ocode = SV_USE_HOST_DECL_NAMES;
5736 if ((lease->host && lease->host->name) &&
5739 packet->options, options,
5740 &lease->scope,
5742 options, ocode),
5743 MDL))) {
5744 struct option_cache *oc = NULL;
5745 if (option_cache_allocate (&oc, MDL)) {
5746 if (make_const_data(&oc -> expression,
5747 ((unsigned char*)lease->host->name),
5748 strlen(lease->host->name),
5749 1, 0, MDL)) {
5750 ocode = DHO_HOST_NAME;
5751 option_code_hash_lookup(&oc->option,
5752 dhcp_universe.code_hash,
5753 &ocode, 0, MDL);
5754 save_option(&dhcp_universe, options, oc);
5755 }
5757 }
5758 }
5759}
5760
5799int
5800reuse_lease (struct packet* packet,
5801 struct lease* new_lease,
5802 struct lease* lease,
5803 struct lease_state *state,
5804 int offer,
5805 int *same_client) {
5806 int reusable = 0;
5807
5808 /* To even consider reuse all of the following must be true:
5809 * 1 - reuse hasn't already disqualified
5810 * 2 - current lease is active
5811 * 3 - DNS info hasn't changed
5812 * 4 - the host declaration hasn't changed
5813 * 5 - the uid hasn't changed
5814 * 6 - the hardware address hasn't changed */
5815
5816 /* Check client equality separately so we can pass the result out. */
5817 *same_client =
5818 (((lease->host == new_lease->host) &&
5819 (lease->uid_len == new_lease->uid_len) &&
5820 (memcmp(lease->uid, new_lease->uid, new_lease->uid_len) == 0) &&
5821 (lease->hardware_addr.hlen == new_lease->hardware_addr.hlen) &&
5822 (memcmp(&lease->hardware_addr.hbuf[0],
5823 &new_lease->hardware_addr.hbuf[0],
5824 lease->hardware_addr.hlen) == 0)) ? 1 : 0);
5825
5826 if ((lease->cannot_reuse == 0) &&
5828 (new_lease->ddns_cb == NULL) && *same_client) {
5829 int thresh = DEFAULT_CACHE_THRESHOLD;
5830 struct option_cache* oc = NULL;
5831 struct data_string d1;
5832
5833 /* Look up threshold value */
5834 memset(&d1, 0, sizeof(struct data_string));
5835 if ((oc = lookup_option(&server_universe, state->options,
5837 (evaluate_option_cache(&d1, packet, new_lease, NULL,
5838 packet->options, state->options,
5839 &new_lease->scope, oc, MDL))) {
5840 if (d1.len == 1 && (d1.data[0] < 100))
5841 thresh = d1.data[0];
5842
5843 data_string_forget(&d1, MDL);
5844 }
5845
5846 /* If threshold is enabled, check lease age */
5847 if (thresh > 0) {
5848 int limit = 0;
5849 int lease_length = 0;
5850 long lease_age = 0;
5851
5852 /* Calculate limit in seconds */
5853 lease_length = lease->ends - lease->starts;
5854 if (lease_length <= (INT_MAX / thresh))
5855 limit = lease_length * thresh / 100;
5856 else
5857 limit = lease_length / 100 * thresh;
5858
5859 /* Note new_lease->starts is really just cur_time */
5860 lease_age = new_lease->starts - lease->starts;
5861
5862 /* Is the lease young enough to reuse? */
5863 if (lease_age <= limit) {
5864 /* Restore expiry to its original value */
5865 state->offered_expiry = lease->ends;
5866
5867 /* Restore bindings. This fixes 37368. */
5868 if (new_lease->scope != NULL) {
5869 if (lease->scope != NULL) {
5871 &lease->scope,
5872 MDL);
5873 }
5874
5876 new_lease->scope, MDL);
5877 }
5878
5879 /* restore client hostname, fixes 42849. */
5880 if (new_lease->client_hostname) {
5882 new_lease->client_hostname;
5883 new_lease->client_hostname = NULL;
5884 }
5885
5886 /* We're cleared to reuse it */
5887 log_debug("reuse_lease: lease age %ld (secs)"
5888 " under %d%% threshold, reply with "
5889 "unaltered, existing lease for %s",
5890 lease_age, thresh, piaddr(lease->ip_addr));
5891
5892 reusable = 1;
5893 }
5894 }
5895 }
5896
5897 /* If we can't reuse it and this is an offer disqualify reuse for
5898 * ensuing REQUEST, otherwise clear the flag. */
5899 lease->cannot_reuse = (!reusable && offer == DHCPOFFER);
5900 return (reusable);
5901}
5902
5903/* \brief Validates a proposed value for use as a lease time
5904 *
5905 * Convenience function used for catching calculeated lease
5906 * times that overflow 4-byte times used in v4 protocol.
5907 *
5908 * We use variables of type TIME in lots of places, which on
5909 * 64-bit systems is 8 bytes while on 32-bit OSs it is int32_t,
5910 * so we have all sorts of fun places to mess things up.
5911 * This function checks a calculated lease time for and if it
5912 * is unsuitable for use as a lease time, the given alternate
5913 * value is returned.
5914 * \param calculated
5915 * \param alternate
5916 *
5917 * \returen either the calculated value if it is valid, or
5918 * the alternate value supplied
5919 */
5920TIME leaseTimeCheck(TIME calculated, TIME alternate) {
5921 if ((sizeof(TIME) > 4 && calculated >= INFINITE_TIME) ||
5922 (calculated < cur_time)) {
5923 return (alternate);
5924 }
5925
5926 return (calculated);
5927}
int buffer_allocate(struct buffer **ptr, unsigned len, const char *file, int line)
Definition alloc.c:679
int expression_reference(struct expression **ptr, struct expression *src, const char *file, int line)
Definition alloc.c:446
void data_string_forget(struct data_string *data, const char *file, int line)
Definition alloc.c:1339
int option_chain_head_reference(struct option_chain_head **ptr, struct option_chain_head *bp, const char *file, int line)
Definition alloc.c:67
int option_state_allocate(struct option_state **ptr, const char *file, int line)
Definition alloc.c:846
int option_state_dereference(struct option_state **ptr, const char *file, int line)
Definition alloc.c:911
int packet_reference(struct packet **ptr, struct packet *bp, const char *file, int line)
Definition alloc.c:1053
int binding_scope_reference(struct binding_scope **ptr, struct binding_scope *bp, const char *file, int line)
Definition alloc.c:1227
void data_string_copy(struct data_string *dest, const struct data_string *src, const char *file, int line)
Definition alloc.c:1323
int option_cache_allocate(struct option_cache **cptr, const char *file, int line)
Definition alloc.c:630
int option_chain_head_dereference(struct option_chain_head **ptr, const char *file, int line)
Definition alloc.c:95
void add_timeout(struct timeval *when, void *where, void *what, tvref_t ref, tvunref_t unref)
Definition dispatch.c:206
void cancel_timeout(void *where, void *what)
Definition dispatch.c:390
void save_option(struct universe *universe, struct option_state *options, struct option_cache *oc)
Definition options.c:2818
int option_cache_dereference(struct option_cache **ptr, const char *file, int line)
Definition options.c:2953
void delete_option(struct universe *universe, struct option_state *options, int code)
Definition options.c:2906
struct option_cache * lookup_option(struct universe *universe, struct option_state *options, unsigned code)
Definition options.c:2503
int get_option_int(int *result, struct universe *universe, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct option_state *options, struct binding_scope **scope, unsigned code, const char *file, int line)
Definition options.c:2358
int cons_options(struct packet *inpacket, struct dhcp_packet *outpacket, struct lease *lease, struct client_state *client_state, int mms, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, int overload_avail, int terminate, int bootpp, struct data_string *prl, const char *vuname)
Definition options.c:538
char * print_dotted_quads(unsigned len, const u_int8_t *data)
Definition print.c:493
char * print_hw_addr(int htype, const int hlen, const unsigned char *data) const
Definition print.c:171
const char * print_time(TIME t)
Definition print.c:1312
void dump_raw(unsigned char *buf, unsigned len) const
Definition print.c:293
#define FAILOVER_PROTOCOL
Definition config.h:33
u_int32_t getUShort(const unsigned char *)
u_int32_t getULong(const unsigned char *)
void putULong(unsigned char *, u_int32_t)
Definition convert.c:70
isc_boolean_t
Definition data.h:150
#define ISC_TRUE
Definition data.h:153
#define ISC_FALSE
Definition data.h:152
TIME default_lease_time
Definition dhclient.c:54
int commit_leases()
Definition dhclient.c:2234
u_int16_t remote_port
Definition discover.c:49
struct in_addr giaddr
Definition dhclient.c:77
void dhcpack(struct packet *packet)
Definition dhclient.c:1888
u_int16_t local_port
Definition discover.c:48
void do_release(struct client_state *client)
Definition dhclient.c:5337
int find_subnet(struct subnet **sp, struct iaddr addr, const char *file, int line)
Definition dhclient.c:1567
void unbill_class(struct lease *lease)
Definition dhclient.c:1562
int write_lease(struct lease *lease)
Definition dhclient.c:2239
TIME max_lease_time
Definition dhclient.c:55
int permitted(struct packet *packet, struct permit *permit_list)
Definition dhcp.c:5178
void ack_lease(struct packet *packet, struct lease *lease, unsigned int offer, TIME when, char *msg, int ms_nulltp, struct host_decl *hp)
Definition dhcp.c:2201
void dhcpinform(struct packet *packet, int ms_nulltp)
Definition dhcp.c:1117
void dhcp(struct packet *packet)
Definition dhcp.c:133
void dhcp_reply(struct lease *lease)
Definition dhcp.c:3924
void eval_network_statements(struct option_state **network_options, struct packet *packet, struct group *network_group)
Builds option set from statements at the global and network scope.
Definition dhcp.c:5573
char * print_hw_addr_or_client_id(struct packet *packet)
Definition dhcp.c:121
const int dhcp_type_name_max
Definition dhcp.c:88
char * print_client_identifier_from_packet(struct packet *packet)
Definition dhcp.c:96
int mockup_lease(struct lease **lp, struct packet *packet, struct shared_network *share, struct host_decl *hp)
Definition dhcp.c:4969
void dhcprelease(struct packet *packet, int ms_nulltp)
Definition dhcp.c:810
void dhcprequest(struct packet *packet, int ms_nulltp, struct lease *ip_lease)
Definition dhcp.c:488
void use_host_decl_name(struct packet *packet, struct lease *lease, struct option_state *options)
Adds hostname option when use-host-decl-names is enabled.
Definition dhcp.c:5732
int locate_network(struct packet *packet)
Definition dhcp.c:5363
void dhcpdiscover(struct packet *packet, int ms_nulltp)
Definition dhcp.c:330
int allocate_lease(struct lease **lp, struct packet *packet, struct pool *pool, int *peer_has_leases)
Definition dhcp.c:5019
void check_pool_threshold(struct packet *packet, struct lease *lease, struct lease_state *state)
Definition dhcp.c:2109
void nak_lease(struct packet *packet, struct iaddr *cip, struct group *network_group)
Constructs and sends a DHCP Nak.
Definition dhcp.c:1810
int find_lease(struct lease **lp, struct packet *packet, struct shared_network *share, int *ours, int *peer_has_leases, struct lease *ip_lease_in, const char *file, int line)
Definition dhcp.c:4213
void echo_client_id(struct packet *packet, struct lease *lease, struct option_state *in_options, struct option_state *out_options)
Adds a dhcp-client-id option to a set of options Given a set of input options, it searches for echo-c...
Definition dhcp.c:2058
void dhcpdecline(struct packet *packet, int ms_nulltp)
Definition dhcp.c:964
void get_server_source_address(struct in_addr *from, struct option_state *options, struct option_state *out_options, struct packet *packet)
Definition dhcp.c:5487
#define DHO_DHCP_MESSAGE
Definition dhcp.h:145
#define DHCPREQUEST
Definition dhcp.h:172
#define DHO_DHCP_MAX_MESSAGE_SIZE
Definition dhcp.h:146
#define RAI_LINK_SELECT
Definition dhcp.h:188
#define BOOTP_MIN_LEN
Definition dhcp.h:39
#define DHCPRELEASE
Definition dhcp.h:176
#define DHO_DHCP_PARAMETER_REQUEST_LIST
Definition dhcp.h:144
#define DHCPNAK
Definition dhcp.h:175
#define DHO_VENDOR_CLASS_IDENTIFIER
Definition dhcp.h:149
#define DHCPLEASEUNKNOWN
Definition dhcp.h:180
#define DHCPACK
Definition dhcp.h:174
#define RAI_RELAY_PORT
Definition dhcp.h:190
#define DHO_SUBNET_SELECTION
Definition dhcp.h:161
#define BOOTREPLY
Definition dhcp.h:69
#define DHO_HOST_NAME
Definition dhcp.h:101
#define DHCPLEASEQUERY
Definition dhcp.h:178
#define DHO_DHCP_CLIENT_IDENTIFIER
Definition dhcp.h:150
#define DHO_PXE_CLIENT_ID
Definition dhcp.h:159
#define DHO_DHCP_MESSAGE_TYPE
Definition dhcp.h:142
#define DHCPDISCOVER
Definition dhcp.h:170
#define DHCPLEASEUNASSIGNED
Definition dhcp.h:179
#define DHO_DHCP_RENEWAL_TIME
Definition dhcp.h:147
#define BOOTP_BROADCAST
Definition dhcp.h:72
#define DHCPOFFER
Definition dhcp.h:171
#define DHCPINFORM
Definition dhcp.h:177
#define DHO_DHCP_REBINDING_TIME
Definition dhcp.h:148
#define DHO_DHCP_SERVER_IDENTIFIER
Definition dhcp.h:143
#define DHO_ROUTERS
Definition dhcp.h:92
#define DHCPLEASEACTIVE
Definition dhcp.h:181
#define HTYPE_INFINIBAND
Definition dhcp.h:78
#define DHO_DHCP_REQUESTED_ADDRESS
Definition dhcp.h:139
#define DHO_DHCP_LEASE_TIME
Definition dhcp.h:140
#define DHO_SUBNET_MASK
Definition dhcp.h:90
#define DHCPDECLINE
Definition dhcp.h:173
void dump_raw(const unsigned char *, unsigned)
#define DEFAULT_DEFAULT_LEASE_TIME
Definition dhcpd.h:858
#define DEFAULT_PING_TIMEOUT_MS
Definition dhcpd.h:830
#define SV_ECHO_CLIENT_ID
Definition dhcpd.h:804
u_int16_t dhcp_check_relayport(struct packet *packet)
#define SV_MIN_LEASE_TIME
Definition dhcpd.h:713
void(* tvunref_t)(void *, const char *, int)
Definition dhcpd.h:1454
void execute_statements_in_scope(struct binding_value **result, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct group *, struct group *, struct on_star *)
Definition execute.c:570
int bill_class(struct lease *, struct class *)
Definition class.c:296
#define OPTION_HAD_NULLS
Definition dhcpd.h:392
#define DEFAULT_CACHE_THRESHOLD
Definition dhcpd.h:854
#define FTS_FREE
Definition dhcpd.h:537
int db_printable(const unsigned char *)
int option_chain_head_reference(struct option_chain_head **, struct option_chain_head *, const char *, int)
Definition alloc.c:67
#define SV_SERVER_NAME
Definition dhcpd.h:726
#define MIN_TIME
Definition dhcpd.h:1632
struct universe agent_universe
Definition stables.c:165
time_t TIME
Definition dhcpd.h:85
#define SV_LOG_THRESHOLD_LOW
Definition dhcpd.h:802
void free_lease_state(struct lease_state *, const char *, int)
Definition salloc.c:198
struct timeval cur_tv
Definition dispatch.c:35
int find_hosts_by_haddr(struct host_decl **, int, const unsigned char *, unsigned, const char *, int)
Definition mdb.c:632
#define LEASE_NOT_EMPTY(LQ)
Definition dhcpd.h:264
void(* tvref_t)(void *, void *, const char *, int)
Definition dhcpd.h:1453
#define SV_STASH_AGENT_OPTIONS
Definition dhcpd.h:747
void dump_packet(struct packet *)
#define SV_NEXT_SERVER
Definition dhcpd.h:727
#define MAX_TIME
Definition dhcpd.h:1631
int find_lease_by_uid(struct lease **, const unsigned char *, unsigned, const char *, int)
Definition mdb.c:2059
void abandon_lease(struct lease *, const char *)
Definition mdb.c:1830
struct ipv6_pool ** pools
void dhcpleasequery(struct packet *, int)
#define SV_USE_LEASE_ADDR_FOR_DEFAULT_ROUTE
Definition dhcpd.h:723
ssize_t send_packet(struct interface_info *, struct packet *, struct dhcp_packet *, size_t, struct in_addr, struct sockaddr_in *, struct hardware *)
#define FIND_PERCENT(count, percent)
Definition dhcpd.h:3919
int outstanding_pings
Definition dhcp.c:49
int max_ack_delay_secs
#define SV_ALLOW_BOOTING
Definition dhcpd.h:719
void nak_lease(struct packet *, struct iaddr *cip, struct group *)
Constructs and sends a DHCP Nak.
Definition dhcp.c:1810
#define SV_BOOT_UNKNOWN_CLIENTS
Definition dhcpd.h:716
#define PERSISTENT_FLAGS
Definition dhcpd.h:603
#define cur_time
Definition dhcpd.h:2126
#define STATIC_LEASE
Definition dhcpd.h:592
#define SV_IGNORE_CLIENT_UIDS
Definition dhcpd.h:801
#define FTS_BACKUP
Definition dhcpd.h:543
int allocate_lease(struct lease **, struct packet *, struct pool *, int *)
Definition dhcp.c:5019
int find_hosts_by_uid(struct host_decl **, const unsigned char *, unsigned, const char *, int)
Definition mdb.c:652
int supersede_lease(struct lease *, struct lease *, int, int, int, int)
Definition mdb.c:1155
void save_option(struct universe *, struct option_state *, struct option_cache *)
Definition options.c:2818
int find_grouped_subnet(struct subnet **, struct shared_network *, struct iaddr, const char *, int)
Definition mdb.c:953
void echo_client_id(struct packet *, struct lease *, struct option_state *, struct option_state *)
Adds a dhcp-client-id option to a set of options Given a set of input options, it searches for echo-c...
Definition dhcp.c:2058
#define DEFAULT_MIN_ACK_DELAY_USECS
Definition dhcpd.h:850
#define MS_NULL_TERMINATION
Definition dhcpd.h:595
int find_lease_by_hw_addr(struct lease **, const unsigned char *, unsigned, const char *, int)
Definition mdb.c:2067
#define SV_CACHE_THRESHOLD
Definition dhcpd.h:797
#define SV_PING_CLTT_SECS
Definition dhcpd.h:822
int ddns_updates(struct packet *, struct lease *, struct lease *, struct iasubopt *, struct iasubopt *, struct option_state *)
int server_id_check
Definition dhcpd.c:86
#define SV_MAX_LEASE_TIME
Definition dhcpd.h:712
#define SV_ONE_LEASE_PER_CLIENT
Definition dhcpd.h:720
int max_outstanding_acks
#define SV_GET_LEASE_HOSTNAMES
Definition dhcpd.h:721
struct universe server_universe
Definition stables.c:176
int have_billing_classes
Definition class.c:33
isc_result_t dhcp_failover_send_updates(dhcp_failover_state_t *)
int max_ack_delay_usecs
#define SV_DECLINES
Definition dhcpd.h:739
void eval_network_statements(struct option_state **options, struct packet *packet, struct group *network_group)
Builds option set from statements at the global and network scope.
Definition dhcp.c:5573
#define SV_MIN_SECS
Definition dhcpd.h:724
#define SV_PING_CHECKS
Definition dhcpd.h:752
#define SV_FILENAME
Definition dhcpd.h:725
struct universe dhcp_universe
#define SV_BOOTP_LEASE_CUTOFF
Definition dhcpd.h:714
int find_hosts_by_option(struct host_decl **, struct packet *, struct option_state *, const char *, int)
Definition mdb.c:660
#define DEFAULT_MIN_LEASE_TIME
Definition dhcpd.h:862
#define SV_USE_HOST_DECL_NAMES
Definition dhcpd.h:722
#define SV_LOG_THRESHOLD_HIGH
Definition dhcpd.h:803
#define SV_PING_TIMEOUT
Definition dhcpd.h:756
#define FTS_ACTIVE
Definition dhcpd.h:538
const char int line
Definition dhcpd.h:3802
#define SV_DUPLICATES
Definition dhcpd.h:738
int find_lease_by_ip_addr(struct lease **, struct iaddr, const char *, int)
Definition mdb.c:2052
#define DEFAULT_PING_CLTT_SECS
Definition dhcpd.h:834
#define DEFAULT_DELAYED_ACK
Definition dhcpd.h:838
const char * piaddr(struct iaddr)
Definition inet.c:579
#define FTS_RELEASED
Definition dhcpd.h:540
#define SV_ALLOW_BOOTP
Definition dhcpd.h:718
void classify_client(struct packet *)
Definition class.c:55
void release_lease(struct lease *, struct packet *)
Definition mdb.c:1755
int find_host_for_network(struct subnet **, struct host_decl **, struct iaddr *, struct shared_network *)
Definition mdb.c:736
#define FTS_RESET
Definition dhcpd.h:542
#define SV_SITE_OPTION_SPACE
Definition dhcpd.h:731
#define DEFAULT_PING_TIMEOUT
Definition dhcpd.h:826
int can_unicast_without_arp(struct interface_info *)
#define DEFAULT_MAX_LEASE_TIME
Definition dhcpd.h:866
#define INFINITE_TIME
Definition dhcpd.h:1630
#define RESERVED_LEASE
Definition dhcpd.h:594
int permitted(struct packet *, struct permit *)
Definition dhcp.c:5178
#define BOOTP_LEASE
Definition dhcpd.h:593
int buffer_allocate(struct buffer **, unsigned, const char *, int)
Definition alloc.c:679
#define SV_BOOTP_LEASE_LENGTH
Definition dhcpd.h:715
#define UNICAST_BROADCAST_HACK
Definition dhcpd.h:599
#define DEFAULT_ACK_DELAY_USECS
Definition dhcpd.h:846
#define SV_RESERVE_INFINITE
Definition dhcpd.h:757
void delete_option(struct universe *, struct option_state *, int)
Definition options.c:2906
void lease_ping_timeout(void *)
Definition dhcpd.c:1555
#define FTS_ABANDONED
Definition dhcpd.h:541
#define DEFAULT_ACK_DELAY_SECS
Definition dhcpd.h:842
#define SV_DDNS_UPDATES
Definition dhcpd.h:740
int lease_mine_to_reallocate(struct lease *)
int load_balance_mine(struct packet *, dhcp_failover_state_t *)
int option_state_dereference(struct option_state **, const char *, int)
Definition alloc.c:911
void get_server_source_address(struct in_addr *from, struct option_state *options, struct option_state *out_options, struct packet *packet)
Definition dhcp.c:5487
#define SV_ADAPTIVE_LEASE_TIME_THRESHOLD
Definition dhcpd.h:760
#define SV_DEFAULT_LEASE_TIME
Definition dhcpd.h:711
#define LEASE_GET_FIRST(LQ)
Definition dhcpd.h:258
int option_state_allocate(struct option_state **, const char *, int)
Definition alloc.c:846
const char * file
Definition dhcpd.h:3802
int cons_options(struct packet *, struct dhcp_packet *, struct lease *, struct client_state *, int, struct option_state *, struct option_state *, struct binding_scope **, int, int, int, struct data_string *, const char *)
Definition options.c:538
#define SV_PING_TIMEOUT_MS
Definition dhcpd.h:823
#define print_hex_1(len, data, limit)
Definition dhcpd.h:2638
struct lease_state * new_lease_state(const char *, int)
int option_cache_dereference(struct option_cache **, const char *, int)
Definition options.c:2953
#define SV_ALWAYS_BROADCAST
Definition dhcpd.h:732
#define FTS_EXPIRED
Definition dhcpd.h:539
u_int16_t relay_port
Definition discover.c:50
struct interface_info * fallback_interface
Definition discover.c:44
struct in_addr limited_broadcast
Definition discover.c:57
int dhcpv4_over_dhcpv6
Definition discover.c:51
int execute_statements(struct binding_value **result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *out_options, struct binding_scope **scope, struct executable_statement *statements, struct on_star *on_star)
Definition execute.c:35
void execute_statements_in_scope(struct binding_value **result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *out_options, struct binding_scope **scope, struct group *group, struct group *limiting_group, struct on_star *on_star)
Definition execute.c:570
int executable_statement_dereference(struct executable_statement **ptr, const char *file, int line)
Definition execute.c:630
const char * binding_state_print(enum failover_state state)
Definition failover.c:6505
service_state
Definition failover.h:315
@ service_startup
Definition failover.h:321
@ cooperating
Definition failover.h:317
@ not_responding
Definition failover.h:320
int icmp_echorequest(struct iaddr *addr)
Definition icmp.c:128
struct iaddr ip_addr(struct iaddr subnet, struct iaddr mask, u_int32_t host_address)
Definition inet.c:63
const char * piaddr(const struct iaddr addr)
Definition inet.c:579
#define ISC_R_SUCCESS
@ known
Definition keama.h:264
struct group * root_group
Definition memory.c:31
#define MDL
Definition omapip.h:567
void * dmalloc(size_t, const char *, int)
Definition alloc.c:57
void dfree(void *, const char *, int)
Definition alloc.c:145
int log_error(const char *,...) __attribute__((__format__(__printf__
int int int log_debug(const char *,...) __attribute__((__format__(__printf__
void log_fatal(const char *,...) __attribute__((__format__(__printf__
int int log_info(const char *,...) __attribute__((__format__(__printf__
unsigned char data[1]
Definition tree.h:62
struct group * group
Definition dhcpd.h:1129
struct class * superclass
Definition dhcpd.h:1105
char * name
Definition dhcpd.h:1106
int lease_limit
Definition dhcpd.h:1109
struct buffer * buffer
Definition tree.h:77
const unsigned char * data
Definition tree.h:78
unsigned len
Definition tree.h:79
struct in_addr siaddr
Definition dhcp.h:57
u_int16_t flags
Definition dhcp.h:54
u_int32_t xid
Definition dhcp.h:52
struct in_addr ciaddr
Definition dhcp.h:55
char file[DHCP_FILE_LEN]
Definition dhcp.h:61
u_int8_t op
Definition dhcp.h:48
struct in_addr giaddr
Definition dhcp.h:58
u_int8_t htype
Definition dhcp.h:49
struct in_addr yiaddr
Definition dhcp.h:56
u_int16_t secs
Definition dhcp.h:53
u_int8_t hlen
Definition dhcp.h:50
unsigned char chaddr[16]
Definition dhcp.h:59
char sname[DHCP_SNAME_LEN]
Definition dhcp.h:60
u_int8_t hops
Definition dhcp.h:51
Definition dhcpd.h:962
int authoritative
Definition dhcpd.h:969
u_int8_t hlen
Definition dhcpd.h:492
u_int8_t hbuf[HARDWARE_ADDR_LEN+1]
Definition dhcpd.h:493
char * name
Definition dhcpd.h:978
struct option_cache * fixed_addr
Definition dhcpd.h:986
struct data_string client_identifier
Definition dhcpd.h:980
int flags
Definition dhcpd.h:991
struct group * group
Definition dhcpd.h:988
struct host_decl * n_ipaddr
Definition dhcpd.h:976
struct hardware interface
Definition dhcpd.h:979
Definition inet.h:31
unsigned char iabuf[16]
Definition inet.h:33
unsigned len
Definition inet.h:32
char name[IFNAMSIZ]
Definition dhcpd.h:1408
int address_count
Definition dhcpd.h:1391
struct shared_network * shared_network
Definition dhcpd.h:1384
struct in_addr * addresses
Definition dhcpd.h:1388
Definition ip.h:47
struct interface_info * ip
Definition dhcpd.h:659
unsigned char expiry[4]
Definition dhcpd.h:668
struct packet * packet
Definition dhcpd.h:661
u_int8_t offer
Definition dhcpd.h:682
struct option_state * options
Definition dhcpd.h:665
struct iaddr from
Definition dhcpd.h:683
int got_server_identifier
Definition dhcpd.h:671
struct data_string filename server_name
Definition dhcpd.h:669
TIME offered_expiry
Definition dhcpd.h:663
Definition dhcpd.h:560
TIME atsfp
Definition dhcpd.h:639
TIME ends
Definition dhcpd.h:570
binding_state_t next_binding_state
Definition dhcpd.h:624
struct lease_state * state
Definition dhcpd.h:628
struct pool * pool
Definition dhcpd.h:578
u_int8_t flags
Definition dhcpd.h:591
struct lease * n_uid
Definition dhcpd.h:567
TIME starts
Definition dhcpd.h:570
struct dhcp_ddns_cb * ddns_cb
Definition dhcpd.h:650
struct binding_scope * scope
Definition dhcpd.h:575
char * client_hostname
Definition dhcpd.h:574
unsigned short cannot_reuse
Definition dhcpd.h:653
struct iaddr ip_addr
Definition dhcpd.h:569
struct hardware hardware_addr
Definition dhcpd.h:589
binding_state_t rewind_binding_state
Definition dhcpd.h:626
unsigned char * uid
Definition dhcpd.h:585
TIME tstp
Definition dhcpd.h:637
struct on_star on_star
Definition dhcpd.h:583
TIME tsfp
Definition dhcpd.h:638
struct lease * next
Definition dhcpd.h:562
struct subnet * subnet
Definition dhcpd.h:577
unsigned char uid_buf[7]
Definition dhcpd.h:588
struct class * billing_class
Definition dhcpd.h:579
struct host_decl * host
Definition dhcpd.h:576
unsigned short uid_max
Definition dhcpd.h:587
binding_state_t binding_state
Definition dhcpd.h:623
struct lease * n_hw
Definition dhcpd.h:567
unsigned short uid_len
Definition dhcpd.h:586
TIME cltt
Definition dhcpd.h:640
struct leasequeue * next
Definition dhcpd.h:1449
struct lease * lease
Definition dhcpd.h:1450
struct leasequeue * prev
Definition dhcpd.h:1448
struct executable_statement * on_commit
Definition dhcpd.h:555
struct executable_statement * on_expiry
Definition dhcpd.h:554
struct executable_statement * on_release
Definition dhcpd.h:556
struct data_string data
Definition dhcpd.h:390
struct option * option
Definition dhcpd.h:389
u_int32_t flags
Definition dhcpd.h:393
struct expression * expression
Definition dhcpd.h:388
int universe_count
Definition dhcpd.h:398
void * universes[1]
Definition dhcpd.h:401
int site_code_min
Definition dhcpd.h:400
Definition tree.h:345
unsigned code
Definition tree.h:349
isc_boolean_t agent_options_stashed
Definition dhcpd.h:464
struct in6_addr dhcpv6_link_address
Definition dhcpd.h:418
struct packet * dhcpv6_container_packet
Definition dhcpd.h:422
struct shared_network * shared_network
Definition dhcpd.h:448
int client_port
Definition dhcpd.h:431
struct dhcp_packet * raw
Definition dhcpd.h:406
int sv_echo_client_id
Definition dhcpd.h:474
struct interface_info * interface
Definition dhcpd.h:433
int known
Definition dhcpd.h:457
int class_count
Definition dhcpd.h:454
struct option_state * options
Definition dhcpd.h:449
unsigned packet_length
Definition dhcpd.h:408
struct data_string * dhcp4o6_response
Definition dhcpd.h:428
int packet_type
Definition dhcpd.h:409
struct class * classes[PACKET_MAX_CLASSES]
Definition dhcpd.h:455
struct iaddr client_addr
Definition dhcpd.h:432
TIME after
Definition dhcpd.h:1014
enum permit::@011051276256032144365216260061073130004016310224 type
struct permit * next
Definition dhcpd.h:1002
@ permit_known_clients
Definition dhcpd.h:1005
@ permit_dynamic_bootp_clients
Definition dhcpd.h:1009
@ permit_class
Definition dhcpd.h:1010
@ permit_after
Definition dhcpd.h:1011
@ permit_unknown_clients
Definition dhcpd.h:1004
@ permit_authenticated_clients
Definition dhcpd.h:1006
@ permit_all_clients
Definition dhcpd.h:1008
@ permit_unauthenticated_clients
Definition dhcpd.h:1007
Definition dhcpd.h:1029
struct permit * prohibit_list
Definition dhcpd.h:1035
struct group * group
Definition dhcpd.h:1032
struct permit * permit_list
Definition dhcpd.h:1034
int free_leases
Definition dhcpd.h:1044
int backup_leases
Definition dhcpd.h:1045
dhcp_failover_state_t * failover_peer
Definition dhcpd.h:1051
struct pool * next
Definition dhcpd.h:1031
int lease_count
Definition dhcpd.h:1043
LEASE_STRUCT free
Definition dhcpd.h:1038
int low_threshold
Definition dhcpd.h:1054
int logged
Definition dhcpd.h:1053
LEASE_STRUCT abandoned
Definition dhcpd.h:1040
TIME valid_from
Definition dhcpd.h:1047
TIME valid_until
Definition dhcpd.h:1048
LEASE_STRUCT backup
Definition dhcpd.h:1039
struct shared_network * shared_network
Definition dhcpd.h:1033
struct group * group
Definition dhcpd.h:1069
struct subnet * subnets
Definition dhcpd.h:1065
char * name
Definition dhcpd.h:1060
struct pool * pools
Definition dhcpd.h:1067
struct group * group
Definition dhcpd.h:1085
struct shared_network * shared_network
Definition dhcpd.h:1079
int index
Definition tree.h:339
unsigned site_code_min
Definition tree.h:335
option_code_hash_t * code_hash
Definition tree.h:337
const char * name
Definition tree.h:302
int option_reference(struct option **dest, struct option *src, const char *file, int line)
Definition tables.c:992
universe_hash_t * universe_hash
Definition tables.c:974
struct universe ** universes
Definition tables.c:975
int binding_scope_dereference(struct binding_scope **ptr, const char *file, int line)
Definition tree.c:3786
int evaluate_option_cache(struct data_string *result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct option_cache *oc, const char *file, int line)
Definition tree.c:2699
int evaluate_boolean_option_cache(int *ignorep, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct option_cache *oc, const char *file, int line)
Definition tree.c:2733
int make_const_data(struct expression **expr, const unsigned char *data, unsigned len, int terminated, int allocate, const char *file, int line)
Definition tree.c:219
int bind_ds_value(struct binding_scope **scope, const char *name, struct data_string *value)
Definition tree.c:4080
struct binding_scope * global_scope
Definition tree.c:38