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