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