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