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