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