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