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