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