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