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