xref: /minix3/external/bsd/dhcp/dist/server/dhcp.c (revision 83ee113ee0d94f3844d44065af2311604e9a30ad)
1 /*	$NetBSD: dhcp.c,v 1.1.1.3 2014/07/12 11:58:08 spz Exp $	*/
2 /* dhcp.c
3 
4    DHCP Protocol engine. */
5 
6 /*
7  * Copyright (c) 2004-2014 by Internet Systems Consortium, Inc. ("ISC")
8  * Copyright (c) 1995-2003 by Internet Software Consortium
9  *
10  * Permission to use, copy, modify, and distribute this software for any
11  * purpose with or without fee is hereby granted, provided that the above
12  * copyright notice and this permission notice appear in all copies.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
15  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
17  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
20  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  *
22  *   Internet Systems Consortium, Inc.
23  *   950 Charter Street
24  *   Redwood City, CA 94063
25  *   <info@isc.org>
26  *   https://www.isc.org/
27  *
28  */
29 
30 #include <sys/cdefs.h>
31 __RCSID("$NetBSD: dhcp.c,v 1.1.1.3 2014/07/12 11:58:08 spz Exp $");
32 
33 #include "dhcpd.h"
34 #include <errno.h>
35 #include <limits.h>
36 #include <sys/time.h>
37 
38 static void commit_leases_ackout(void *foo);
39 static void maybe_return_agent_options(struct packet *packet,
40 				       struct option_state *options);
41 
42 int outstanding_pings;
43 
44 struct leasequeue *ackqueue_head, *ackqueue_tail;
45 static struct leasequeue *free_ackqueue;
46 static struct timeval max_fsync;
47 
48 int outstanding_acks;
49 int max_outstanding_acks = DEFAULT_DELAYED_ACK;
50 int max_ack_delay_secs = DEFAULT_ACK_DELAY_SECS;
51 int max_ack_delay_usecs = DEFAULT_ACK_DELAY_USECS;
52 int min_ack_delay_usecs = DEFAULT_MIN_ACK_DELAY_USECS;
53 
54 static char dhcp_message [256];
55 static int site_code_min;
56 
57 static int find_min_site_code(struct universe *);
58 static isc_result_t lowest_site_code(const void *, unsigned, void *);
59 
60 static const char *dhcp_type_names [] = {
61 	"DHCPDISCOVER",
62 	"DHCPOFFER",
63 	"DHCPREQUEST",
64 	"DHCPDECLINE",
65 	"DHCPACK",
66 	"DHCPNAK",
67 	"DHCPRELEASE",
68 	"DHCPINFORM",
69 	"type 9",
70 	"DHCPLEASEQUERY",
71 	"DHCPLEASEUNASSIGNED",
72 	"DHCPLEASEUNKNOWN",
73 	"DHCPLEASEACTIVE"
74 };
75 const int dhcp_type_name_max = ((sizeof dhcp_type_names) / sizeof (char *));
76 
77 #if defined (TRACING)
78 # define send_packet trace_packet_send
79 #endif
80 
81 void
dhcp(struct packet * packet)82 dhcp (struct packet *packet) {
83 	int ms_nulltp = 0;
84 	struct option_cache *oc;
85 	struct lease *lease = NULL;
86 	const char *errmsg;
87 	struct data_string data;
88 
89 	if (!locate_network(packet) &&
90 	    packet->packet_type != DHCPREQUEST &&
91 	    packet->packet_type != DHCPINFORM &&
92 	    packet->packet_type != DHCPLEASEQUERY) {
93 		const char *s;
94 		char typebuf[32];
95 		errmsg = "unknown network segment";
96 	      bad_packet:
97 
98 		if (packet->packet_type > 0 &&
99 		    packet->packet_type <= dhcp_type_name_max) {
100 			s = dhcp_type_names[packet->packet_type - 1];
101 		} else {
102 			/* %Audit% Cannot exceed 28 bytes. %2004.06.17,Safe% */
103 			sprintf(typebuf, "type %d", packet->packet_type);
104 			s = typebuf;
105 		}
106 
107 		log_info("%s from %s via %s: %s", s,
108 			 (packet->raw->htype
109 			  ? print_hw_addr(packet->raw->htype,
110 					  packet->raw->hlen,
111 					  packet->raw->chaddr)
112 			  : "<no identifier>"),
113 			 packet->raw->giaddr.s_addr
114 			 ? inet_ntoa(packet->raw->giaddr)
115 			 : packet->interface->name, errmsg);
116 		goto out;
117 	}
118 
119 	/* There is a problem with the relay agent information option,
120 	 * which is that in order for a normal relay agent to append
121 	 * this option, the relay agent has to have been involved in
122 	 * getting the packet from the client to the server.  Note
123 	 * that this is the software entity known as the relay agent,
124 	 * _not_ the hardware entity known as a router in which the
125 	 * relay agent may be running, so the fact that a router has
126 	 * forwarded a packet does not mean that the relay agent in
127 	 * the router was involved.
128 	 *
129 	 * So when the client broadcasts (DHCPDISCOVER, or giaddr is set),
130 	 * we can be sure that there are either agent options in the
131 	 * packet, or there aren't supposed to be.  When the giaddr is not
132 	 * set, it's still possible that the client is on a directly
133 	 * attached subnet, and agent options are being appended by an l2
134 	 * device that has no address, and so sets no giaddr.
135 	 *
136 	 * But in either case it's possible that the packets we receive
137 	 * from the client in RENEW state may not include the agent options,
138 	 * so if they are not in the packet we must "pretend" the last values
139 	 * we observed were provided.
140 	 */
141 	if (packet->packet_type == DHCPREQUEST &&
142 	    packet->raw->ciaddr.s_addr && !packet->raw->giaddr.s_addr &&
143 	    (packet->options->universe_count <= agent_universe.index ||
144 	     packet->options->universes[agent_universe.index] == NULL))
145 	{
146 		struct iaddr cip;
147 
148 		cip.len = sizeof packet -> raw -> ciaddr;
149 		memcpy (cip.iabuf, &packet -> raw -> ciaddr,
150 			sizeof packet -> raw -> ciaddr);
151 		if (!find_lease_by_ip_addr (&lease, cip, MDL))
152 			goto nolease;
153 
154 		/* If there are no agent options on the lease, it's not
155 		   interesting. */
156 		if (!lease -> agent_options)
157 			goto nolease;
158 
159 		/* The client should not be unicasting a renewal if its lease
160 		   has expired, so make it go through the process of getting
161 		   its agent options legally. */
162 		if (lease -> ends < cur_time)
163 			goto nolease;
164 
165 		if (lease -> uid_len) {
166 			oc = lookup_option (&dhcp_universe, packet -> options,
167 					    DHO_DHCP_CLIENT_IDENTIFIER);
168 			if (!oc)
169 				goto nolease;
170 
171 			memset (&data, 0, sizeof data);
172 			if (!evaluate_option_cache (&data,
173 						    packet, (struct lease *)0,
174 						    (struct client_state *)0,
175 						    packet -> options,
176 						    (struct option_state *)0,
177 						    &global_scope, oc, MDL))
178 				goto nolease;
179 			if (lease -> uid_len != data.len ||
180 			    memcmp (lease -> uid, data.data, data.len)) {
181 				data_string_forget (&data, MDL);
182 				goto nolease;
183 			}
184 			data_string_forget (&data, MDL);
185 		} else
186 			if ((lease -> hardware_addr.hbuf [0] !=
187 			     packet -> raw -> htype) ||
188 			    (lease -> hardware_addr.hlen - 1 !=
189 			     packet -> raw -> hlen) ||
190 			    memcmp (&lease -> hardware_addr.hbuf [1],
191 				    packet -> raw -> chaddr,
192 				    packet -> raw -> hlen))
193 				goto nolease;
194 
195 		/* Okay, so we found a lease that matches the client. */
196 		option_chain_head_reference ((struct option_chain_head **)
197 					     &(packet -> options -> universes
198 					       [agent_universe.index]),
199 					     lease -> agent_options, MDL);
200 
201 		if (packet->options->universe_count <= agent_universe.index)
202 			packet->options->universe_count =
203 						agent_universe.index + 1;
204 
205 		packet->agent_options_stashed = ISC_TRUE;
206 	}
207       nolease:
208 
209 	/* If a client null terminates options it sends, it probably
210 	 * expects the server to reciprocate.
211 	 */
212 	if ((oc = lookup_option (&dhcp_universe, packet -> options,
213 				 DHO_HOST_NAME))) {
214 		if (!oc -> expression)
215 			ms_nulltp = oc->flags & OPTION_HAD_NULLS;
216 	}
217 
218 	/* Classify the client. */
219 	classify_client (packet);
220 
221 	switch (packet -> packet_type) {
222 	      case DHCPDISCOVER:
223 		dhcpdiscover (packet, ms_nulltp);
224 		break;
225 
226 	      case DHCPREQUEST:
227 		dhcprequest (packet, ms_nulltp, lease);
228 		break;
229 
230 	      case DHCPRELEASE:
231 		dhcprelease (packet, ms_nulltp);
232 		break;
233 
234 	      case DHCPDECLINE:
235 		dhcpdecline (packet, ms_nulltp);
236 		break;
237 
238 	      case DHCPINFORM:
239 		dhcpinform (packet, ms_nulltp);
240 		break;
241 
242 	      case DHCPLEASEQUERY:
243 		dhcpleasequery(packet, ms_nulltp);
244 		break;
245 
246 	      case DHCPACK:
247 	      case DHCPOFFER:
248 	      case DHCPNAK:
249 	      case DHCPLEASEUNASSIGNED:
250 	      case DHCPLEASEUNKNOWN:
251 	      case DHCPLEASEACTIVE:
252 		break;
253 
254 	      default:
255 		errmsg = "unknown packet type";
256 		goto bad_packet;
257 	}
258       out:
259 	if (lease)
260 		lease_dereference (&lease, MDL);
261 }
262 
dhcpdiscover(packet,ms_nulltp)263 void dhcpdiscover (packet, ms_nulltp)
264 	struct packet *packet;
265 	int ms_nulltp;
266 {
267 	struct lease *lease = (struct lease *)0;
268 	char msgbuf [1024]; /* XXX */
269 	TIME when;
270 	const char *s;
271 	int peer_has_leases = 0;
272 #if defined (FAILOVER_PROTOCOL)
273 	dhcp_failover_state_t *peer;
274 #endif
275 
276 	find_lease (&lease, packet, packet -> shared_network,
277 		    0, &peer_has_leases, (struct lease *)0, MDL);
278 
279 	if (lease && lease -> client_hostname) {
280 		if ((strlen (lease -> client_hostname) <= 64) &&
281 		    db_printable((unsigned char *)lease->client_hostname))
282 			s = lease -> client_hostname;
283 		else
284 			s = "Hostname Unsuitable for Printing";
285 	} else
286 		s = (char *)0;
287 
288 	/* %Audit% This is log output. %2004.06.17,Safe%
289 	 * If we truncate we hope the user can get a hint from the log.
290 	 */
291 	snprintf (msgbuf, sizeof msgbuf, "DHCPDISCOVER from %s %s%s%svia %s",
292 		 (packet -> raw -> htype
293 		  ? print_hw_addr (packet -> raw -> htype,
294 				   packet -> raw -> hlen,
295 				   packet -> raw -> chaddr)
296 		  : (lease
297 		     ? print_hex_1(lease->uid_len, lease->uid, 60)
298 		     : "<no identifier>")),
299 		  s ? "(" : "", s ? s : "", s ? ") " : "",
300 		  packet -> raw -> giaddr.s_addr
301 		  ? inet_ntoa (packet -> raw -> giaddr)
302 		  : packet -> interface -> name);
303 
304 	/* Sourceless packets don't make sense here. */
305 	if (!packet -> shared_network) {
306 		log_info ("Packet from unknown subnet: %s",
307 		      inet_ntoa (packet -> raw -> giaddr));
308 		goto out;
309 	}
310 
311 #if defined (FAILOVER_PROTOCOL)
312 	if (lease && lease -> pool && lease -> pool -> failover_peer) {
313 		peer = lease -> pool -> failover_peer;
314 
315 		/*
316 		 * If the lease is ours to (re)allocate, then allocate it.
317 		 *
318 		 * If the lease is active, it belongs to the client.  This
319 		 * is the right lease, if we are to offer one.  We decide
320 		 * whether or not to offer later on.
321 		 *
322 		 * If the lease was last active, and we've reached this
323 		 * point, then it was last active with the same client.  We
324 		 * can safely re-activate the lease with this client.
325 		 */
326 		if (lease->binding_state == FTS_ACTIVE ||
327 		    lease->rewind_binding_state == FTS_ACTIVE ||
328 		    lease_mine_to_reallocate(lease)) {
329 			; /* This space intentionally left blank. */
330 
331 		/* Otherwise, we can't let the client have this lease. */
332 		} else {
333 #if defined (DEBUG_FIND_LEASE)
334 		    log_debug ("discarding %s - %s",
335 			       piaddr (lease -> ip_addr),
336 			       binding_state_print (lease -> binding_state));
337 #endif
338 		    lease_dereference (&lease, MDL);
339 		}
340 	}
341 #endif
342 
343 	/* If we didn't find a lease, try to allocate one... */
344 	if (!lease) {
345 		if (!allocate_lease (&lease, packet,
346 				     packet -> shared_network -> pools,
347 				     &peer_has_leases)) {
348 			if (peer_has_leases)
349 				log_error ("%s: peer holds all free leases",
350 					   msgbuf);
351 			else
352 				log_error ("%s: network %s: no free leases",
353 					   msgbuf,
354 					   packet -> shared_network -> name);
355 			return;
356 		}
357 	}
358 
359 #if defined (FAILOVER_PROTOCOL)
360 	if (lease && lease -> pool && lease -> pool -> failover_peer) {
361 		peer = lease -> pool -> failover_peer;
362 		if (peer -> service_state == not_responding ||
363 		    peer -> service_state == service_startup) {
364 			log_info ("%s: not responding%s",
365 				  msgbuf, peer -> nrr);
366 			goto out;
367 		}
368 	} else
369 		peer = (dhcp_failover_state_t *)0;
370 
371 	/* Do load balancing if configured. */
372 	if (peer && (peer -> service_state == cooperating) &&
373 	    !load_balance_mine (packet, peer)) {
374 		if (peer_has_leases) {
375 			log_debug ("%s: load balance to peer %s",
376 				   msgbuf, peer -> name);
377 			goto out;
378 		} else {
379 			log_debug ("%s: cancel load balance to peer %s - %s",
380 				   msgbuf, peer -> name, "no free leases");
381 		}
382 	}
383 #endif
384 
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);
388 
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;
394 
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);
400 }
401 
dhcprequest(packet,ms_nulltp,ip_lease)402 void dhcprequest (packet, ms_nulltp, ip_lease)
403 	struct packet *packet;
404 	int ms_nulltp;
405 	struct lease *ip_lease;
406 {
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_requested_addr = 0;
421 
422 	oc = lookup_option (&dhcp_universe, packet -> options,
423 			    DHO_DHCP_REQUESTED_ADDRESS);
424 	memset (&data, 0, sizeof data);
425 	if (oc &&
426 	    evaluate_option_cache (&data, packet, (struct lease *)0,
427 				   (struct client_state *)0,
428 				   packet -> options, (struct option_state *)0,
429 				   &global_scope, oc, MDL)) {
430 		cip.len = 4;
431 		memcpy (cip.iabuf, data.data, 4);
432 		data_string_forget (&data, MDL);
433 		have_requested_addr = 1;
434 	} else {
435 		oc = (struct option_cache *)0;
436 		cip.len = 4;
437 		memcpy (cip.iabuf, &packet -> raw -> ciaddr.s_addr, 4);
438 	}
439 
440 	/* Find the lease that matches the address requested by the
441 	   client. */
442 
443 	subnet = (struct subnet *)0;
444 	lease = (struct lease *)0;
445 	if (find_subnet (&subnet, cip, MDL))
446 		find_lease (&lease, packet,
447 			    subnet -> shared_network, &ours, 0, ip_lease, MDL);
448 
449 	if (lease && lease -> client_hostname) {
450 		if ((strlen (lease -> client_hostname) <= 64) &&
451 		    db_printable((unsigned char *)lease->client_hostname))
452 			s = lease -> client_hostname;
453 		else
454 			s = "Hostname Unsuitable for Printing";
455 	} else
456 		s = (char *)0;
457 
458 	oc = lookup_option (&dhcp_universe, packet -> options,
459 			    DHO_DHCP_SERVER_IDENTIFIER);
460 	memset (&data, 0, sizeof data);
461 	if (oc &&
462 	    evaluate_option_cache (&data, packet, (struct lease *)0,
463 				   (struct client_state *)0,
464 				   packet -> options, (struct option_state *)0,
465 				   &global_scope, oc, MDL)) {
466 		sip.len = 4;
467 		memcpy (sip.iabuf, data.data, 4);
468 		data_string_forget (&data, MDL);
469 		/* piaddr() should not return more than a 15 byte string.
470 		 * safe.
471 		 */
472 		sprintf (smbuf, " (%s)", piaddr (sip));
473 	} else {
474 		smbuf [0] = 0;
475 		sip.len = 0;
476 	}
477 
478 	/* %Audit% This is log output. %2004.06.17,Safe%
479 	 * If we truncate we hope the user can get a hint from the log.
480 	 */
481 	snprintf (msgbuf, sizeof msgbuf,
482 		 "DHCPREQUEST for %s%s from %s %s%s%svia %s",
483 		 piaddr (cip), smbuf,
484 		 (packet -> raw -> htype
485 		  ? print_hw_addr (packet -> raw -> htype,
486 				   packet -> raw -> hlen,
487 				   packet -> raw -> chaddr)
488 		  : (lease
489 		     ? print_hex_1(lease->uid_len, lease->uid, 60)
490 		     : "<no identifier>")),
491 		 s ? "(" : "", s ? s : "", s ? ") " : "",
492 		  packet -> raw -> giaddr.s_addr
493 		  ? inet_ntoa (packet -> raw -> giaddr)
494 		  : packet -> interface -> name);
495 
496 #if defined (FAILOVER_PROTOCOL)
497 	if (lease && lease -> pool && lease -> pool -> failover_peer) {
498 		peer = lease -> pool -> failover_peer;
499 		if (peer -> service_state == not_responding ||
500 		    peer -> service_state == service_startup) {
501 			log_info ("%s: not responding%s",
502 				  msgbuf, peer -> nrr);
503 			goto out;
504 		}
505 
506 		/* "load balance to peer" - is not done at all for request.
507 		 *
508 		 * If it's RENEWING, we are the only server to hear it, so
509 		 * we have to serve it.   If it's REBINDING, it's out of
510 		 * communication with the other server, so there's no point
511 		 * in waiting to serve it.    However, if the lease we're
512 		 * offering is not a free lease, then we may be the only
513 		 * server that can offer it, so we can't load balance if
514 		 * the lease isn't in the free or backup state.  If it is
515 		 * in the free or backup state, then that state is what
516 		 * mandates one server or the other should perform the
517 		 * allocation, not the LBA...we know the peer cannot
518 		 * allocate a request for an address in our free state.
519 		 *
520 		 * So our only compass is lease_mine_to_reallocate().  This
521 		 * effects both load balancing, and a sanity-check that we
522 		 * are not going to try to allocate a lease that isn't ours.
523 		 */
524 		if ((lease -> binding_state == FTS_FREE ||
525 		     lease -> binding_state == FTS_BACKUP) &&
526 		    !lease_mine_to_reallocate (lease)) {
527 			log_debug ("%s: lease owned by peer", msgbuf);
528 			goto out;
529 		}
530 
531 		/*
532 		 * If the lease is in a transitional state, we can't
533 		 * renew it unless we can rewind it to a non-transitional
534 		 * state (active, free, or backup).  lease_mine_to_reallocate()
535 		 * checks for free/backup, so we only need to check for active.
536 		 */
537 		if ((lease->binding_state == FTS_RELEASED ||
538 		     lease->binding_state == FTS_EXPIRED) &&
539 		    lease->rewind_binding_state != FTS_ACTIVE &&
540 		    !lease_mine_to_reallocate(lease)) {
541 			log_debug("%s: lease in transition state %s", msgbuf,
542 				  (lease->binding_state == FTS_RELEASED)
543 				   ? "released" : "expired");
544 			goto out;
545 		}
546 
547 		/* It's actually very unlikely that we'll ever get here,
548 		   but if we do, tell the client to stop using the lease,
549 		   because the administrator reset it. */
550 		if (lease -> binding_state == FTS_RESET &&
551 		    !lease_mine_to_reallocate (lease)) {
552 			log_debug ("%s: lease reset by administrator", msgbuf);
553 			nak_lease (packet, &cip);
554 			goto out;
555 		}
556 
557 #if defined(SERVER_ID_CHECK)
558 		/* Do a quick check on the server source address to see if
559 		   it is ours.  sip is the incoming servrer id.  To avoid
560 		   problems with confused clients we do some sanity checks
561 		   to verify sip's length and that it isn't all zeros.
562 		   We then get the server id we would likely use for this
563 		   packet and compare them.  If they don't match it we assume
564 		   we didn't send the offer and so we don't process the request.
565 		*/
566 
567 		if ((sip.len == 4) &&
568 		    (memcmp(sip.iabuf, "\0\0\0\0", sip.len) != 0)) {
569 			struct in_addr from;
570 			setup_server_source_address(&from, NULL, packet);
571 			if (memcmp(sip.iabuf, &from, sip.len) != 0) {
572 				log_debug("%s: not our server id", msgbuf);
573 				goto out;
574 			}
575 		}
576 #endif /* if defined(SERVER_ID_CHECK) */
577 
578 		/* At this point it's possible that we will get a broadcast
579 		   DHCPREQUEST for a lease that we didn't offer, because
580 		   both we and the peer are in a position to offer it.
581 		   In that case, we probably shouldn't answer.   In order
582 		   to not answer, we would have to compare the server
583 		   identifier sent by the client with the list of possible
584 		   server identifiers we can send, and if the client's
585 		   identifier isn't on the list, drop the DHCPREQUEST.
586 		   We aren't currently doing that for two reasons - first,
587 		   it's not clear that all clients do the right thing
588 		   with respect to sending the client identifier, which
589 		   could mean that we might simply not respond to a client
590 		   that is depending on us to respond.   Secondly, we allow
591 		   the user to specify the server identifier to send, and
592 		   we don't enforce that the server identifier should be
593 		   one of our IP addresses.   This is probably not a big
594 		   deal, but it's theoretically an issue.
595 
596 		   The reason we care about this is that if both servers
597 		   send a DHCPACK to the DHCPREQUEST, they are then going
598 		   to send dueling BNDUPD messages, which could cause
599 		   trouble.   I think it causes no harm, but it seems
600 		   wrong. */
601 	} else
602 		peer = (dhcp_failover_state_t *)0;
603 #endif
604 
605 	/* If a client on a given network REQUESTs a lease on an
606 	   address on a different network, NAK it.  If the Requested
607 	   Address option was used, the protocol says that it must
608 	   have been broadcast, so we can trust the source network
609 	   information.
610 
611 	   If ciaddr was specified and Requested Address was not, then
612 	   we really only know for sure what network a packet came from
613 	   if it came through a BOOTP gateway - if it came through an
614 	   IP router, we'll just have to assume that it's cool.
615 
616 	   If we don't think we know where the packet came from, it
617 	   came through a gateway from an unknown network, so it's not
618 	   from a RENEWING client.  If we recognize the network it
619 	   *thinks* it's on, we can NAK it even though we don't
620 	   recognize the network it's *actually* on; otherwise we just
621 	   have to ignore it.
622 
623 	   We don't currently try to take advantage of access to the
624 	   raw packet, because it's not available on all platforms.
625 	   So a packet that was unicast to us through a router from a
626 	   RENEWING client is going to look exactly like a packet that
627 	   was broadcast to us from an INIT-REBOOT client.
628 
629 	   Since we can't tell the difference between these two kinds
630 	   of packets, if the packet appears to have come in off the
631 	   local wire, we have to treat it as if it's a RENEWING
632 	   client.  This means that we can't NAK a RENEWING client on
633 	   the local wire that has a bogus address.  The good news is
634 	   that we won't ACK it either, so it should revert to INIT
635 	   state and send us a DHCPDISCOVER, which we *can* work with.
636 
637 	   Because we can't detect that a RENEWING client is on the
638 	   wrong wire, it's going to sit there trying to renew until
639 	   it gets to the REBIND state, when we *can* NAK it because
640 	   the packet will get to us through a BOOTP gateway.  We
641 	   shouldn't actually see DHCPREQUEST packets from RENEWING
642 	   clients on the wrong wire anyway, since their idea of their
643 	   local router will be wrong.  In any case, the protocol
644 	   doesn't really allow us to NAK a DHCPREQUEST from a
645 	   RENEWING client, so we can punt on this issue. */
646 
647 	if (!packet -> shared_network ||
648 	    (packet -> raw -> ciaddr.s_addr &&
649 	     packet -> raw -> giaddr.s_addr) ||
650 	    (have_requested_addr && !packet -> raw -> ciaddr.s_addr)) {
651 
652 		/* If we don't know where it came from but we do know
653 		   where it claims to have come from, it didn't come
654 		   from there. */
655 		if (!packet -> shared_network) {
656 			if (subnet && subnet -> group -> authoritative) {
657 				log_info ("%s: wrong network.", msgbuf);
658 				nak_lease (packet, &cip);
659 				goto out;
660 			}
661 			/* Otherwise, ignore it. */
662 			log_info ("%s: ignored (%s).", msgbuf,
663 				  (subnet
664 				   ? "not authoritative" : "unknown subnet"));
665 			goto out;
666 		}
667 
668 		/* If we do know where it came from and it asked for an
669 		   address that is not on that shared network, nak it. */
670 		if (subnet)
671 			subnet_dereference (&subnet, MDL);
672 		if (!find_grouped_subnet (&subnet, packet -> shared_network,
673 					  cip, MDL)) {
674 			if (packet -> shared_network -> group -> authoritative)
675 			{
676 				log_info ("%s: wrong network.", msgbuf);
677 				nak_lease (packet, &cip);
678 				goto out;
679 			}
680 			log_info ("%s: ignored (not authoritative).", msgbuf);
681 			return;
682 		}
683 	}
684 
685 	/* If the address the client asked for is ours, but it wasn't
686 	   available for the client, NAK it. */
687 	if (!lease && ours) {
688 		log_info ("%s: lease %s unavailable.", msgbuf, piaddr (cip));
689 		nak_lease (packet, &cip);
690 		goto out;
691 	}
692 
693 	/* Otherwise, send the lease to the client if we found one. */
694 	if (lease) {
695 		ack_lease (packet, lease, DHCPACK, 0, msgbuf, ms_nulltp,
696 			   (struct host_decl *)0);
697 	} else
698 		log_info ("%s: unknown lease %s.", msgbuf, piaddr (cip));
699 
700       out:
701 	if (subnet)
702 		subnet_dereference (&subnet, MDL);
703 	if (lease)
704 		lease_dereference (&lease, MDL);
705 	return;
706 }
707 
dhcprelease(packet,ms_nulltp)708 void dhcprelease (packet, ms_nulltp)
709 	struct packet *packet;
710 	int ms_nulltp;
711 {
712 	struct lease *lease = (struct lease *)0, *next = (struct lease *)0;
713 	struct iaddr cip;
714 	struct option_cache *oc;
715 	struct data_string data;
716 	const char *s;
717 	char msgbuf [1024], cstr[16]; /* XXX */
718 
719 
720 	/* DHCPRELEASE must not specify address in requested-address
721 	   option, but old protocol specs weren't explicit about this,
722 	   so let it go. */
723 	if ((oc = lookup_option (&dhcp_universe, packet -> options,
724 				 DHO_DHCP_REQUESTED_ADDRESS))) {
725 		log_info ("DHCPRELEASE from %s specified requested-address.",
726 		      print_hw_addr (packet -> raw -> htype,
727 				     packet -> raw -> hlen,
728 				     packet -> raw -> chaddr));
729 	}
730 
731 	oc = lookup_option (&dhcp_universe, packet -> options,
732 			    DHO_DHCP_CLIENT_IDENTIFIER);
733 	memset (&data, 0, sizeof data);
734 	if (oc &&
735 	    evaluate_option_cache (&data, packet, (struct lease *)0,
736 				   (struct client_state *)0,
737 				   packet -> options, (struct option_state *)0,
738 				   &global_scope, oc, MDL)) {
739 		find_lease_by_uid (&lease, data.data, data.len, MDL);
740 		data_string_forget (&data, MDL);
741 
742 		/* See if we can find a lease that matches the IP address
743 		   the client is claiming. */
744 		while (lease) {
745 			if (lease -> n_uid)
746 				lease_reference (&next, lease -> n_uid, MDL);
747 			if (!memcmp (&packet -> raw -> ciaddr,
748 				     lease -> ip_addr.iabuf, 4)) {
749 				break;
750 			}
751 			lease_dereference (&lease, MDL);
752 			if (next) {
753 				lease_reference (&lease, next, MDL);
754 				lease_dereference (&next, MDL);
755 			}
756 		}
757 		if (next)
758 			lease_dereference (&next, MDL);
759 	}
760 
761 	/* The client is supposed to pass a valid client-identifier,
762 	   but the spec on this has changed historically, so try the
763 	   IP address in ciaddr if the client-identifier fails. */
764 	if (!lease) {
765 		cip.len = 4;
766 		memcpy (cip.iabuf, &packet -> raw -> ciaddr, 4);
767 		find_lease_by_ip_addr (&lease, cip, MDL);
768 	}
769 
770 
771 	/* If the hardware address doesn't match, don't do the release. */
772 	if (lease &&
773 	    (lease -> hardware_addr.hlen != packet -> raw -> hlen + 1 ||
774 	     lease -> hardware_addr.hbuf [0] != packet -> raw -> htype ||
775 	     memcmp (&lease -> hardware_addr.hbuf [1],
776 		     packet -> raw -> chaddr, packet -> raw -> hlen)))
777 		lease_dereference (&lease, MDL);
778 
779 	if (lease && lease -> client_hostname) {
780 		if ((strlen (lease -> client_hostname) <= 64) &&
781 		    db_printable((unsigned char *)lease->client_hostname))
782 			s = lease -> client_hostname;
783 		else
784 			s = "Hostname Unsuitable for Printing";
785 	} else
786 		s = (char *)0;
787 
788 	/* %Audit% Cannot exceed 16 bytes. %2004.06.17,Safe%
789 	 * We copy this out to stack because we actually want to log two
790 	 * inet_ntoa()'s in this message.
791 	 */
792 	strncpy(cstr, inet_ntoa (packet -> raw -> ciaddr), 15);
793 	cstr[15] = '\0';
794 
795 	/* %Audit% This is log output. %2004.06.17,Safe%
796 	 * If we truncate we hope the user can get a hint from the log.
797 	 */
798 	snprintf (msgbuf, sizeof msgbuf,
799 		 "DHCPRELEASE of %s from %s %s%s%svia %s (%sfound)",
800 		 cstr,
801 		 (packet -> raw -> htype
802 		  ? print_hw_addr (packet -> raw -> htype,
803 				   packet -> raw -> hlen,
804 				   packet -> raw -> chaddr)
805 		  : (lease
806 		     ? print_hex_1(lease->uid_len, lease->uid, 60)
807 		     : "<no identifier>")),
808 		 s ? "(" : "", s ? s : "", s ? ") " : "",
809 		 packet -> raw -> giaddr.s_addr
810 		 ? inet_ntoa (packet -> raw -> giaddr)
811 		 : packet -> interface -> name,
812 		 lease ? "" : "not ");
813 
814 #if defined (FAILOVER_PROTOCOL)
815 	if (lease && lease -> pool && lease -> pool -> failover_peer) {
816 		dhcp_failover_state_t *peer = lease -> pool -> failover_peer;
817 		if (peer -> service_state == not_responding ||
818 		    peer -> service_state == service_startup) {
819 			log_info ("%s: ignored%s",
820 				  peer -> name, peer -> nrr);
821 			goto out;
822 		}
823 
824 		/* DHCPRELEASE messages are unicast, so if the client
825 		   sent the DHCPRELEASE to us, it's not going to send it
826 		   to the peer.   Not sure why this would happen, and
827 		   if it does happen I think we still have to change the
828 		   lease state, so that's what we're doing.
829 		   XXX See what it says in the draft about this. */
830 	}
831 #endif
832 
833 	/* If we found a lease, release it. */
834 	if (lease && lease -> ends > cur_time) {
835 		release_lease (lease, packet);
836 	}
837 	log_info ("%s", msgbuf);
838 #if defined(FAILOVER_PROTOCOL)
839       out:
840 #endif
841 	if (lease)
842 		lease_dereference (&lease, MDL);
843 }
844 
dhcpdecline(packet,ms_nulltp)845 void dhcpdecline (packet, ms_nulltp)
846 	struct packet *packet;
847 	int ms_nulltp;
848 {
849 	struct lease *lease = (struct lease *)0;
850 	struct option_state *options = (struct option_state *)0;
851 	int ignorep = 0;
852 	int i;
853 	const char *status;
854 	const char *s;
855 	char msgbuf [1024]; /* XXX */
856 	struct iaddr cip;
857 	struct option_cache *oc;
858 	struct data_string data;
859 
860 	/* DHCPDECLINE must specify address. */
861 	if (!(oc = lookup_option (&dhcp_universe, packet -> options,
862 				  DHO_DHCP_REQUESTED_ADDRESS)))
863 		return;
864 	memset (&data, 0, sizeof data);
865 	if (!evaluate_option_cache (&data, packet, (struct lease *)0,
866 				    (struct client_state *)0,
867 				    packet -> options,
868 				    (struct option_state *)0,
869 				    &global_scope, oc, MDL))
870 		return;
871 
872 	cip.len = 4;
873 	memcpy (cip.iabuf, data.data, 4);
874 	data_string_forget (&data, MDL);
875 	find_lease_by_ip_addr (&lease, cip, MDL);
876 
877 	if (lease && lease -> client_hostname) {
878 		if ((strlen (lease -> client_hostname) <= 64) &&
879 		    db_printable((unsigned char *)lease->client_hostname))
880 			s = lease -> client_hostname;
881 		else
882 			s = "Hostname Unsuitable for Printing";
883 	} else
884 		s = (char *)0;
885 
886 	/* %Audit% This is log output. %2004.06.17,Safe%
887 	 * If we truncate we hope the user can get a hint from the log.
888 	 */
889 	snprintf (msgbuf, sizeof msgbuf,
890 		 "DHCPDECLINE of %s from %s %s%s%svia %s",
891 		 piaddr (cip),
892 		 (packet -> raw -> htype
893 		  ? print_hw_addr (packet -> raw -> htype,
894 				   packet -> raw -> hlen,
895 				   packet -> raw -> chaddr)
896 		  : (lease
897 		     ? print_hex_1(lease->uid_len, lease->uid, 60)
898 		     : "<no identifier>")),
899 		 s ? "(" : "", s ? s : "", s ? ") " : "",
900 		 packet -> raw -> giaddr.s_addr
901 		 ? inet_ntoa (packet -> raw -> giaddr)
902 		 : packet -> interface -> name);
903 
904 	option_state_allocate (&options, MDL);
905 
906 	/* Execute statements in scope starting with the subnet scope. */
907 	if (lease)
908 		execute_statements_in_scope(NULL, packet, NULL, NULL,
909 					    packet->options, options,
910 					    &global_scope,
911 					    lease->subnet->group,
912 					    NULL, NULL);
913 
914 	/* Execute statements in the class scopes. */
915 	for (i = packet -> class_count; i > 0; i--) {
916 		execute_statements_in_scope
917 			(NULL, packet, NULL, NULL, packet->options, options,
918 			 &global_scope, packet->classes[i - 1]->group,
919 			 lease ? lease->subnet->group : NULL, NULL);
920 	}
921 
922 	/* Drop the request if dhcpdeclines are being ignored. */
923 	oc = lookup_option (&server_universe, options, SV_DECLINES);
924 	if (!oc ||
925 	    evaluate_boolean_option_cache (&ignorep, packet, lease,
926 					   (struct client_state *)0,
927 					   packet -> options, options,
928 					   &lease -> scope, oc, MDL)) {
929 	    /* If we found a lease, mark it as unusable and complain. */
930 	    if (lease) {
931 #if defined (FAILOVER_PROTOCOL)
932 		if (lease -> pool && lease -> pool -> failover_peer) {
933 		    dhcp_failover_state_t *peer =
934 			    lease -> pool -> failover_peer;
935 		    if (peer -> service_state == not_responding ||
936 			peer -> service_state == service_startup) {
937 			if (!ignorep)
938 			    log_info ("%s: ignored%s",
939 				      peer -> name, peer -> nrr);
940 			goto out;
941 		    }
942 
943 		    /* DHCPDECLINE messages are broadcast, so we can safely
944 		       ignore the DHCPDECLINE if the peer has the lease.
945 		       XXX Of course, at this point that information has been
946 		       lost. */
947 		}
948 #endif
949 
950 		abandon_lease (lease, "declined.");
951 		status = "abandoned";
952 	    } else {
953 		status = "not found";
954 	    }
955 	} else
956 	    status = "ignored";
957 
958 	if (!ignorep)
959 		log_info ("%s: %s", msgbuf, status);
960 
961 #if defined(FAILOVER_PROTOCOL)
962       out:
963 #endif
964 	if (options)
965 		option_state_dereference (&options, MDL);
966 	if (lease)
967 		lease_dereference (&lease, MDL);
968 }
969 
dhcpinform(packet,ms_nulltp)970 void dhcpinform (packet, ms_nulltp)
971 	struct packet *packet;
972 	int ms_nulltp;
973 {
974 	char msgbuf[1024], *addr_type;
975 	struct data_string d1, prl, fixed_addr;
976 	struct option_cache *oc;
977 	struct option_state *options = NULL;
978 	struct dhcp_packet raw;
979 	struct packet outgoing;
980 	unsigned char dhcpack = DHCPACK;
981 	struct subnet *subnet = NULL;
982 	struct iaddr cip, gip, sip;
983 	unsigned i;
984 	int nulltp;
985 	struct sockaddr_in to;
986 	struct in_addr from;
987 	isc_boolean_t zeroed_ciaddr;
988 	struct interface_info *interface;
989 	int result, h_m_client_ip = 0;
990 	struct host_decl  *host = NULL, *hp = NULL, *h;
991 #if defined (DEBUG_INFORM_HOST)
992 	int h_w_fixed_addr = 0;
993 #endif
994 
995 	/* The client should set ciaddr to its IP address, but apparently
996 	   it's common for clients not to do this, so we'll use their IP
997 	   source address if they didn't set ciaddr. */
998 	if (!packet->raw->ciaddr.s_addr) {
999 		zeroed_ciaddr = ISC_TRUE;
1000 		cip.len = 4;
1001 		memcpy(cip.iabuf, &packet->client_addr.iabuf, 4);
1002 		addr_type = "source";
1003 	} else {
1004 		zeroed_ciaddr = ISC_FALSE;
1005 		cip.len = 4;
1006 		memcpy(cip.iabuf, &packet->raw->ciaddr, 4);
1007 		addr_type = "client";
1008 	}
1009 	sip.len = 4;
1010 	memcpy(sip.iabuf, cip.iabuf, 4);
1011 
1012 	if (packet->raw->giaddr.s_addr) {
1013 		gip.len = 4;
1014 		memcpy(gip.iabuf, &packet->raw->giaddr, 4);
1015 		if (zeroed_ciaddr == ISC_TRUE) {
1016 			addr_type = "relay";
1017 			memcpy(sip.iabuf, gip.iabuf, 4);
1018 		}
1019 	} else
1020 		gip.len = 0;
1021 
1022 	/* %Audit% This is log output. %2004.06.17,Safe%
1023 	 * If we truncate we hope the user can get a hint from the log.
1024 	 */
1025 	snprintf(msgbuf, sizeof(msgbuf), "DHCPINFORM from %s via %s",
1026 		 piaddr(cip),
1027 		 packet->raw->giaddr.s_addr ?
1028 		 inet_ntoa(packet->raw->giaddr) :
1029 		 packet->interface->name);
1030 
1031 	/* If the IP source address is zero, don't respond. */
1032 	if (!memcmp(cip.iabuf, "\0\0\0", 4)) {
1033 		log_info("%s: ignored (null source address).", msgbuf);
1034 		return;
1035 	}
1036 
1037 	/* Find the subnet that the client is on.
1038 	 * CC: Do the link selection / subnet selection
1039 	 */
1040 
1041 	option_state_allocate(&options, MDL);
1042 
1043 	if ((oc = lookup_option(&agent_universe, packet->options,
1044 				RAI_LINK_SELECT)) == NULL)
1045 		oc = lookup_option(&dhcp_universe, packet->options,
1046 				   DHO_SUBNET_SELECTION);
1047 
1048 	memset(&d1, 0, sizeof d1);
1049 	if (oc && evaluate_option_cache(&d1, packet, NULL, NULL,
1050 					packet->options, NULL,
1051 					&global_scope, oc, MDL)) {
1052 		struct option_cache *noc = NULL;
1053 
1054 		if (d1.len != 4) {
1055 			log_info("%s: ignored (invalid subnet selection option).", msgbuf);
1056 			option_state_dereference(&options, MDL);
1057 			return;
1058 		}
1059 
1060 		memcpy(sip.iabuf, d1.data, 4);
1061 		data_string_forget(&d1, MDL);
1062 
1063 		/* Make a copy of the data. */
1064 		if (option_cache_allocate(&noc, MDL)) {
1065 			if (oc->data.len)
1066 				data_string_copy(&noc->data, &oc->data, MDL);
1067 			if (oc->expression)
1068 				expression_reference(&noc->expression,
1069 						     oc->expression, MDL);
1070 			if (oc->option)
1071 				option_reference(&(noc->option), oc->option,
1072 						 MDL);
1073 		}
1074 		save_option(&dhcp_universe, options, noc);
1075 		option_cache_dereference(&noc, MDL);
1076 
1077 		if ((zeroed_ciaddr == ISC_TRUE) && (gip.len != 0))
1078 			addr_type = "relay link select";
1079 		else
1080 			addr_type = "selected";
1081 	}
1082 
1083 	find_subnet(&subnet, sip, MDL);
1084 
1085 	if (subnet == NULL) {
1086 		log_info("%s: unknown subnet for %s address %s",
1087 			 msgbuf, addr_type, piaddr(sip));
1088 		option_state_dereference (&options, MDL);
1089 		return;
1090 	}
1091 
1092 	/* We don't respond to DHCPINFORM packets if we're not authoritative.
1093 	   It would be nice if a per-host value could override this, but
1094 	   there's overhead involved in checking this, so let's see how people
1095 	   react first. */
1096 	if (subnet && !subnet -> group -> authoritative) {
1097 		static int eso = 0;
1098 		log_info ("%s: not authoritative for subnet %s",
1099 			  msgbuf, piaddr (subnet -> net));
1100 		if (!eso) {
1101 			log_info ("If this DHCP server is authoritative for%s",
1102 				  " that subnet,");
1103 			log_info ("please write an `authoritative;' directi%s",
1104 				  "ve either in the");
1105 			log_info ("subnet declaration or in some scope that%s",
1106 				  " encloses the");
1107 			log_info ("subnet declaration - for example, write %s",
1108 				  "it at the top");
1109 			log_info ("of the dhcpd.conf file.");
1110 		}
1111 		if (eso++ == 100)
1112 			eso = 0;
1113 		subnet_dereference (&subnet, MDL);
1114 		option_state_dereference (&options, MDL);
1115 		return;
1116 	}
1117 
1118 	memset (&outgoing, 0, sizeof outgoing);
1119 	memset (&raw, 0, sizeof raw);
1120 	outgoing.raw = &raw;
1121 
1122 	maybe_return_agent_options(packet, options);
1123 
1124 	/* Execute statements in scope starting with the subnet scope. */
1125 	if (subnet)
1126 		execute_statements_in_scope (NULL, packet, NULL, NULL,
1127 					     packet->options, options,
1128 					     &global_scope, subnet->group,
1129 					     NULL, NULL);
1130 
1131 	/* Execute statements in the class scopes. */
1132 	for (i = packet -> class_count; i > 0; i--) {
1133 		execute_statements_in_scope(NULL, packet, NULL, NULL,
1134 					    packet->options, options,
1135 					    &global_scope,
1136 					    packet->classes[i - 1]->group,
1137 					    subnet ? subnet->group : NULL,
1138 					    NULL);
1139 	}
1140 
1141 	/*
1142 	 * Process host declarations during DHCPINFORM,
1143 	 * Try to find a matching host declaration by cli ID or HW addr.
1144 	 *
1145 	 * Look through the host decls for one that matches the
1146 	 * client identifer or the hardware address.  The preference
1147 	 * order is:
1148 	 * client id with matching ip address
1149 	 * hardware address with matching ip address
1150 	 * client id without a ip fixed address
1151 	 * hardware address without a fixed ip address
1152 	 * If found, set host to use its option definitions.
1153          */
1154 	oc = lookup_option(&dhcp_universe, packet->options,
1155 			   DHO_DHCP_CLIENT_IDENTIFIER);
1156 	memset(&d1, 0, sizeof(d1));
1157 	if (oc &&
1158 	    evaluate_option_cache(&d1, packet, NULL, NULL,
1159 				  packet->options, NULL,
1160 				  &global_scope, oc, MDL)) {
1161 		find_hosts_by_uid(&hp, d1.data, d1.len, MDL);
1162 		data_string_forget(&d1, MDL);
1163 
1164 #if defined (DEBUG_INFORM_HOST)
1165 		if (hp)
1166 			log_debug ("dhcpinform: found host by ID "
1167 				   "-- checking fixed-address match");
1168 #endif
1169 		/* check if we have one with fixed-address
1170 		 * matching the client ip first */
1171 		for (h = hp; !h_m_client_ip && h; h = h->n_ipaddr) {
1172 			if (!h->fixed_addr)
1173 				continue;
1174 
1175 			memset(&fixed_addr, 0, sizeof(fixed_addr));
1176 			if (!evaluate_option_cache (&fixed_addr, NULL,
1177 						    NULL, NULL, NULL, NULL,
1178 						    &global_scope,
1179 						    h->fixed_addr, MDL))
1180 				continue;
1181 
1182 #if defined (DEBUG_INFORM_HOST)
1183 			h_w_fixed_addr++;
1184 #endif
1185 			for (i = 0;
1186 			     (i + cip.len) <= fixed_addr.len;
1187 			     i += cip.len) {
1188 				if (memcmp(fixed_addr.data + i,
1189 					   cip.iabuf, cip.len) == 0) {
1190 #if defined (DEBUG_INFORM_HOST)
1191 					log_debug ("dhcpinform: found "
1192 						   "host with matching "
1193 						   "fixed-address by ID");
1194 #endif
1195 					host_reference(&host, h, MDL);
1196 					h_m_client_ip = 1;
1197 					break;
1198 				}
1199 			}
1200 			data_string_forget(&fixed_addr, MDL);
1201 		}
1202 
1203 		/* fallback to a host without fixed-address */
1204 		for (h = hp; !host && h; h = h->n_ipaddr) {
1205 			if (h->fixed_addr)
1206 				continue;
1207 
1208 #if defined (DEBUG_INFORM_HOST)
1209 			log_debug ("dhcpinform: found host "
1210 				   "without fixed-address by ID");
1211 #endif
1212 			host_reference(&host, h, MDL);
1213 			break;
1214 		}
1215 		if (hp)
1216 			host_dereference (&hp, MDL);
1217 	}
1218 	if (!host || !h_m_client_ip) {
1219 		find_hosts_by_haddr(&hp, packet->raw->htype,
1220 				    packet->raw->chaddr,
1221 				    packet->raw->hlen, MDL);
1222 
1223 #if defined (DEBUG_INFORM_HOST)
1224 		if (hp)
1225 			log_debug ("dhcpinform: found host by HW "
1226 				   "-- checking fixed-address match");
1227 #endif
1228 
1229 		/* check if we have one with fixed-address
1230 		 * matching the client ip first */
1231 		for (h = hp; !h_m_client_ip && h; h = h->n_ipaddr) {
1232 			if (!h->fixed_addr)
1233 				continue;
1234 
1235 			memset (&fixed_addr, 0, sizeof(fixed_addr));
1236 			if (!evaluate_option_cache (&fixed_addr, NULL,
1237 						    NULL, NULL, NULL, NULL,
1238 						    &global_scope,
1239 						    h->fixed_addr, MDL))
1240 				continue;
1241 
1242 #if defined (DEBUG_INFORM_HOST)
1243 			h_w_fixed_addr++;
1244 #endif
1245 			for (i = 0;
1246 			     (i + cip.len) <= fixed_addr.len;
1247 			     i += cip.len) {
1248 				if (memcmp(fixed_addr.data + i,
1249 					   cip.iabuf, cip.len) == 0) {
1250 #if defined (DEBUG_INFORM_HOST)
1251 					log_debug ("dhcpinform: found "
1252 						   "host with matching "
1253 						   "fixed-address by HW");
1254 #endif
1255 					/*
1256 					 * Hmm.. we've found one
1257 					 * without IP by ID and now
1258 					 * (better) one with IP by HW.
1259 					 */
1260 					if(host)
1261 						host_dereference(&host, MDL);
1262 					host_reference(&host, h, MDL);
1263 					h_m_client_ip = 1;
1264 					break;
1265 				}
1266 			}
1267 			data_string_forget(&fixed_addr, MDL);
1268 		}
1269 		/* fallback to a host without fixed-address */
1270 		for (h = hp; !host && h; h = h->n_ipaddr) {
1271 			if (h->fixed_addr)
1272 				continue;
1273 
1274 #if defined (DEBUG_INFORM_HOST)
1275 			log_debug ("dhcpinform: found host without "
1276 				   "fixed-address by HW");
1277 #endif
1278 			host_reference (&host, h, MDL);
1279 			break;
1280 		}
1281 
1282 		if (hp)
1283 			host_dereference (&hp, MDL);
1284 	}
1285 
1286 #if defined (DEBUG_INFORM_HOST)
1287 	/* Hmm..: what when there is a host with a fixed-address,
1288 	 * that matches by hw or id, but the fixed-addresses
1289 	 * didn't match client ip?
1290 	 */
1291 	if (h_w_fixed_addr && !h_m_client_ip) {
1292 		log_info ("dhcpinform: matching host with "
1293 			  "fixed-address different than "
1294 			  "client IP detected?!");
1295 	}
1296 #endif
1297 
1298 	/* If we have a host_decl structure, run the options
1299 	 * associated with its group. Whether the host decl
1300 	 * struct is old or not. */
1301 	if (host) {
1302 #if defined (DEBUG_INFORM_HOST)
1303 		log_info ("dhcpinform: applying host (group) options");
1304 #endif
1305 		execute_statements_in_scope(NULL, packet, NULL, NULL,
1306 					    packet->options, options,
1307 					    &global_scope, host->group,
1308 					    host->group ?
1309 					      host->group->next : NULL,
1310 					    NULL);
1311 		host_dereference (&host, MDL);
1312 	}
1313 
1314  	/* CC: end of host entry processing.... */
1315 
1316 	/* Figure out the filename. */
1317 	memset (&d1, 0, sizeof d1);
1318 	oc = lookup_option (&server_universe, options, SV_FILENAME);
1319 	if (oc &&
1320 	    evaluate_option_cache (&d1, packet, (struct lease *)0,
1321 				   (struct client_state *)0,
1322 				   packet -> options, (struct option_state *)0,
1323 				   &global_scope, oc, MDL)) {
1324 		i = d1.len;
1325 		if (i >= sizeof(raw.file)) {
1326 			log_info("file name longer than packet field "
1327 				 "truncated - field: %lu name: %d %.*s",
1328 				 (unsigned long)sizeof(raw.file), i,
1329 				 (int)i, d1.data);
1330 			i = sizeof(raw.file);
1331 		} else
1332 			raw.file[i] = 0;
1333 		memcpy (raw.file, d1.data, i);
1334 		data_string_forget (&d1, MDL);
1335 	}
1336 
1337 	/* Choose a server name as above. */
1338 	oc = lookup_option (&server_universe, options, SV_SERVER_NAME);
1339 	if (oc &&
1340 	    evaluate_option_cache (&d1, packet, (struct lease *)0,
1341 				   (struct client_state *)0,
1342 				   packet -> options, (struct option_state *)0,
1343 				   &global_scope, oc, MDL)) {
1344 		i = d1.len;
1345 		if (i >= sizeof(raw.sname)) {
1346 			log_info("server name longer than packet field "
1347 				 "truncated - field: %lu name: %d %.*s",
1348 				 (unsigned long)sizeof(raw.sname), i,
1349 				 (int)i, d1.data);
1350 			i = sizeof(raw.sname);
1351 		} else
1352 			raw.sname[i] = 0;
1353 		memcpy (raw.sname, d1.data, i);
1354 		data_string_forget (&d1, MDL);
1355 	}
1356 
1357 	/* Set a flag if this client is a lame Microsoft client that NUL
1358 	   terminates string options and expects us to do likewise. */
1359 	nulltp = 0;
1360 	if ((oc = lookup_option (&dhcp_universe, packet -> options,
1361 				 DHO_HOST_NAME))) {
1362 		if (!oc->expression)
1363 			nulltp = oc->flags & OPTION_HAD_NULLS;
1364 	}
1365 
1366 	/* Put in DHCP-specific options. */
1367 	i = DHO_DHCP_MESSAGE_TYPE;
1368 	oc = (struct option_cache *)0;
1369 	if (option_cache_allocate (&oc, MDL)) {
1370 		if (make_const_data (&oc -> expression,
1371 				     &dhcpack, 1, 0, 0, MDL)) {
1372 			option_code_hash_lookup(&oc->option,
1373 						dhcp_universe.code_hash,
1374 						&i, 0, MDL);
1375 			save_option (&dhcp_universe, options, oc);
1376 		}
1377 		option_cache_dereference (&oc, MDL);
1378 	}
1379 
1380 	get_server_source_address(&from, options, options, packet);
1381 
1382 	/* Use the subnet mask from the subnet declaration if no other
1383 	   mask has been provided. */
1384 	i = DHO_SUBNET_MASK;
1385 	if (subnet && !lookup_option (&dhcp_universe, options, i)) {
1386 		oc = (struct option_cache *)0;
1387 		if (option_cache_allocate (&oc, MDL)) {
1388 			if (make_const_data (&oc -> expression,
1389 					     subnet -> netmask.iabuf,
1390 					     subnet -> netmask.len,
1391 					     0, 0, MDL)) {
1392 				option_code_hash_lookup(&oc->option,
1393 							dhcp_universe.code_hash,
1394 							&i, 0, MDL);
1395 				save_option (&dhcp_universe, options, oc);
1396 			}
1397 			option_cache_dereference (&oc, MDL);
1398 		}
1399 	}
1400 
1401 	/* If a site option space has been specified, use that for
1402 	   site option codes. */
1403 	i = SV_SITE_OPTION_SPACE;
1404 	if ((oc = lookup_option (&server_universe, options, i)) &&
1405 	    evaluate_option_cache (&d1, packet, (struct lease *)0,
1406 				   (struct client_state *)0,
1407 				   packet -> options, options,
1408 				   &global_scope, oc, MDL)) {
1409 		struct universe *u = (struct universe *)0;
1410 
1411 		if (!universe_hash_lookup (&u, universe_hash,
1412 					   (const char *)d1.data, d1.len,
1413 					   MDL)) {
1414 			log_error ("unknown option space %s.", d1.data);
1415 			option_state_dereference (&options, MDL);
1416 			if (subnet)
1417 				subnet_dereference (&subnet, MDL);
1418 			return;
1419 		}
1420 
1421 		options -> site_universe = u -> index;
1422 		options->site_code_min = find_min_site_code(u);
1423 		data_string_forget (&d1, MDL);
1424 	} else {
1425 		options -> site_universe = dhcp_universe.index;
1426 		options -> site_code_min = 0; /* Trust me, it works. */
1427 	}
1428 
1429 	memset (&prl, 0, sizeof prl);
1430 
1431 	/* Use the parameter list from the scope if there is one. */
1432 	oc = lookup_option (&dhcp_universe, options,
1433 			    DHO_DHCP_PARAMETER_REQUEST_LIST);
1434 
1435 	/* Otherwise, if the client has provided a list of options
1436 	   that it wishes returned, use it to prioritize.  Otherwise,
1437 	   prioritize based on the default priority list. */
1438 
1439 	if (!oc)
1440 		oc = lookup_option (&dhcp_universe, packet -> options,
1441 				    DHO_DHCP_PARAMETER_REQUEST_LIST);
1442 
1443 	if (oc)
1444 		evaluate_option_cache (&prl, packet, (struct lease *)0,
1445 				       (struct client_state *)0,
1446 				       packet -> options, options,
1447 				       &global_scope, oc, MDL);
1448 
1449 #ifdef DEBUG_PACKET
1450 	dump_packet (packet);
1451 	dump_raw ((unsigned char *)packet -> raw, packet -> packet_length);
1452 #endif
1453 
1454 	log_info ("%s", msgbuf);
1455 
1456 	/* Figure out the address of the boot file server. */
1457 	if ((oc =
1458 	     lookup_option (&server_universe, options, SV_NEXT_SERVER))) {
1459 		if (evaluate_option_cache (&d1, packet, (struct lease *)0,
1460 					   (struct client_state *)0,
1461 					   packet -> options, options,
1462 					   &global_scope, oc, MDL)) {
1463 			/* If there was more than one answer,
1464 			   take the first. */
1465 			if (d1.len >= 4 && d1.data)
1466 				memcpy (&raw.siaddr, d1.data, 4);
1467 			data_string_forget (&d1, MDL);
1468 		}
1469 	}
1470 
1471 	/*
1472 	 * Remove any time options, per section 3.4 RFC 2131
1473 	 */
1474 	delete_option(&dhcp_universe, options, DHO_DHCP_LEASE_TIME);
1475 	delete_option(&dhcp_universe, options, DHO_DHCP_RENEWAL_TIME);
1476 	delete_option(&dhcp_universe, options, DHO_DHCP_REBINDING_TIME);
1477 
1478 	/* Set up the option buffer... */
1479 	outgoing.packet_length =
1480 		cons_options (packet, outgoing.raw, (struct lease *)0,
1481 			      (struct client_state *)0,
1482 			      0, packet -> options, options, &global_scope,
1483 			      0, nulltp, 0,
1484 			      prl.len ? &prl : (struct data_string *)0,
1485 			      (char *)0);
1486 	option_state_dereference (&options, MDL);
1487 	data_string_forget (&prl, MDL);
1488 
1489 	/* Make sure that the packet is at least as big as a BOOTP packet. */
1490 	if (outgoing.packet_length < BOOTP_MIN_LEN)
1491 		outgoing.packet_length = BOOTP_MIN_LEN;
1492 
1493 	raw.giaddr = packet -> raw -> giaddr;
1494 	raw.ciaddr = packet -> raw -> ciaddr;
1495 	memcpy (raw.chaddr, packet -> raw -> chaddr, sizeof raw.chaddr);
1496 	raw.hlen = packet -> raw -> hlen;
1497 	raw.htype = packet -> raw -> htype;
1498 
1499 	raw.xid = packet -> raw -> xid;
1500 	raw.secs = packet -> raw -> secs;
1501 	raw.flags = packet -> raw -> flags;
1502 	raw.hops = packet -> raw -> hops;
1503 	raw.op = BOOTREPLY;
1504 
1505 #ifdef DEBUG_PACKET
1506 	dump_packet (&outgoing);
1507 	dump_raw ((unsigned char *)&raw, outgoing.packet_length);
1508 #endif
1509 
1510 	/* Set up the common stuff... */
1511 	to.sin_family = AF_INET;
1512 #ifdef HAVE_SA_LEN
1513 	to.sin_len = sizeof to;
1514 #endif
1515 	memset (to.sin_zero, 0, sizeof to.sin_zero);
1516 
1517 	/* RFC2131 states the server SHOULD unciast to ciaddr.
1518 	 * There are two wrinkles - relays, and when ciaddr is zero.
1519 	 * There's actually no mention of relays at all in rfc2131 in
1520 	 * regard to DHCPINFORM, except to say we might get packets from
1521 	 * clients via them.  Note: relays unicast to clients to the
1522 	 * "yiaddr" address, which servers are forbidden to set when
1523 	 * answering an inform.
1524 	 *
1525 	 * The solution: If ciaddr is zero, and giaddr is set, go via the
1526 	 * relay with the broadcast flag set to help the relay (with no
1527 	 * yiaddr and very likely no chaddr, it will have no idea where to
1528 	 * send the packet).
1529 	 *
1530 	 * If the ciaddr is zero and giaddr is not set, go via the source
1531 	 * IP address (but you are permitted to barf on their shoes).
1532 	 *
1533 	 * If ciaddr is not zero, send the packet there always.
1534 	 */
1535 	if (!raw.ciaddr.s_addr && gip.len) {
1536 		memcpy(&to.sin_addr, gip.iabuf, 4);
1537 		to.sin_port = local_port;
1538 		raw.flags |= htons(BOOTP_BROADCAST);
1539 	} else {
1540 		gip.len = 0;
1541 		memcpy(&to.sin_addr, cip.iabuf, 4);
1542 		to.sin_port = remote_port;
1543 	}
1544 
1545 	/* Report what we're sending. */
1546 	snprintf(msgbuf, sizeof msgbuf, "DHCPACK to %s (%s) via", piaddr(cip),
1547 		 (packet->raw->htype && packet->raw->hlen) ?
1548 			print_hw_addr(packet->raw->htype, packet->raw->hlen,
1549 				      packet->raw->chaddr) :
1550 			"<no client hardware address>");
1551 	log_info("%s %s", msgbuf, gip.len ? piaddr(gip) :
1552 					    packet->interface->name);
1553 
1554 	errno = 0;
1555 	interface = (fallback_interface ? fallback_interface
1556 		     : packet -> interface);
1557 	result = send_packet(interface, &outgoing, &raw,
1558 			     outgoing.packet_length, from, &to, NULL);
1559 	if (result < 0) {
1560 		log_error ("%s:%d: Failed to send %d byte long packet over %s "
1561 			   "interface.", MDL, outgoing.packet_length,
1562 			   interface->name);
1563 	}
1564 
1565 
1566 	if (subnet)
1567 		subnet_dereference (&subnet, MDL);
1568 }
1569 
nak_lease(packet,cip)1570 void nak_lease (packet, cip)
1571 	struct packet *packet;
1572 	struct iaddr *cip;
1573 {
1574 	struct sockaddr_in to;
1575 	struct in_addr from;
1576 	int result;
1577 	struct dhcp_packet raw;
1578 	unsigned char nak = DHCPNAK;
1579 	struct packet outgoing;
1580 	unsigned i;
1581 	struct option_state *options = (struct option_state *)0;
1582 	struct option_cache *oc = (struct option_cache *)0;
1583 
1584 	option_state_allocate (&options, MDL);
1585 	memset (&outgoing, 0, sizeof outgoing);
1586 	memset (&raw, 0, sizeof raw);
1587 	outgoing.raw = &raw;
1588 
1589 	/* Set DHCP_MESSAGE_TYPE to DHCPNAK */
1590 	if (!option_cache_allocate (&oc, MDL)) {
1591 		log_error ("No memory for DHCPNAK message type.");
1592 		option_state_dereference (&options, MDL);
1593 		return;
1594 	}
1595 	if (!make_const_data (&oc -> expression, &nak, sizeof nak,
1596 			      0, 0, MDL)) {
1597 		log_error ("No memory for expr_const expression.");
1598 		option_cache_dereference (&oc, MDL);
1599 		option_state_dereference (&options, MDL);
1600 		return;
1601 	}
1602 	i = DHO_DHCP_MESSAGE_TYPE;
1603 	option_code_hash_lookup(&oc->option, dhcp_universe.code_hash,
1604 				&i, 0, MDL);
1605 	save_option (&dhcp_universe, options, oc);
1606 	option_cache_dereference (&oc, MDL);
1607 
1608 	/* Set DHCP_MESSAGE to whatever the message is */
1609 	if (!option_cache_allocate (&oc, MDL)) {
1610 		log_error ("No memory for DHCPNAK message type.");
1611 		option_state_dereference (&options, MDL);
1612 		return;
1613 	}
1614 	if (!make_const_data (&oc -> expression,
1615 			      (unsigned char *)dhcp_message,
1616 			      strlen (dhcp_message), 1, 0, MDL)) {
1617 		log_error ("No memory for expr_const expression.");
1618 		option_cache_dereference (&oc, MDL);
1619 		option_state_dereference (&options, MDL);
1620 		return;
1621 	}
1622 	i = DHO_DHCP_MESSAGE;
1623 	option_code_hash_lookup(&oc->option, dhcp_universe.code_hash,
1624 				&i, 0, MDL);
1625 	save_option (&dhcp_universe, options, oc);
1626 	option_cache_dereference (&oc, MDL);
1627 
1628 	/*
1629 	 * If we are configured to do so we try to find a server id
1630 	 * option even for NAKS by calling setup_server_source_address().
1631 	 * This function will set up an options list from the global
1632 	 * and subnet scopes before trying to get the source address.
1633 	 *
1634 	 * Otherwise we simply call get_server_source_address()
1635 	 * directly, without a server options list, this means
1636 	 * we'll get the source address from the interface address.
1637 	 */
1638 #if defined(SERVER_ID_FOR_NAK)
1639 	setup_server_source_address(&from, options, packet);
1640 #else
1641 	get_server_source_address(&from, NULL, options, packet);
1642 #endif /* if defined(SERVER_ID_FOR_NAK) */
1643 
1644 
1645 	/* If there were agent options in the incoming packet, return
1646 	 * them.  We do not check giaddr to detect the presence of a
1647 	 * relay, as this excludes "l2" relay agents which have no
1648 	 * giaddr to set.
1649 	 */
1650 	if (packet->options->universe_count > agent_universe.index &&
1651 	    packet->options->universes [agent_universe.index]) {
1652 		option_chain_head_reference
1653 		    ((struct option_chain_head **)
1654 		     &(options -> universes [agent_universe.index]),
1655 		     (struct option_chain_head *)
1656 		     packet -> options -> universes [agent_universe.index],
1657 		     MDL);
1658 	}
1659 
1660 	/* Do not use the client's requested parameter list. */
1661 	delete_option (&dhcp_universe, packet -> options,
1662 		       DHO_DHCP_PARAMETER_REQUEST_LIST);
1663 
1664 	/* Set up the option buffer... */
1665 	outgoing.packet_length =
1666 		cons_options (packet, outgoing.raw, (struct lease *)0,
1667 			      (struct client_state *)0,
1668 			      0, packet -> options, options, &global_scope,
1669 			      0, 0, 0, (struct data_string *)0, (char *)0);
1670 	option_state_dereference (&options, MDL);
1671 
1672 /*	memset (&raw.ciaddr, 0, sizeof raw.ciaddr);*/
1673 	if (packet->interface->address_count)
1674 		raw.siaddr = packet->interface->addresses[0];
1675 	raw.giaddr = packet -> raw -> giaddr;
1676 	memcpy (raw.chaddr, packet -> raw -> chaddr, sizeof raw.chaddr);
1677 	raw.hlen = packet -> raw -> hlen;
1678 	raw.htype = packet -> raw -> htype;
1679 
1680 	raw.xid = packet -> raw -> xid;
1681 	raw.secs = packet -> raw -> secs;
1682 	raw.flags = packet -> raw -> flags | htons (BOOTP_BROADCAST);
1683 	raw.hops = packet -> raw -> hops;
1684 	raw.op = BOOTREPLY;
1685 
1686 	/* Report what we're sending... */
1687 	log_info ("DHCPNAK on %s to %s via %s",
1688 	      piaddr (*cip),
1689 	      print_hw_addr (packet -> raw -> htype,
1690 			     packet -> raw -> hlen,
1691 			     packet -> raw -> chaddr),
1692 	      packet -> raw -> giaddr.s_addr
1693 	      ? inet_ntoa (packet -> raw -> giaddr)
1694 	      : packet -> interface -> name);
1695 
1696 #ifdef DEBUG_PACKET
1697 	dump_packet (packet);
1698 	dump_raw ((unsigned char *)packet -> raw, packet -> packet_length);
1699 	dump_packet (&outgoing);
1700 	dump_raw ((unsigned char *)&raw, outgoing.packet_length);
1701 #endif
1702 
1703 	/* Set up the common stuff... */
1704 	to.sin_family = AF_INET;
1705 #ifdef HAVE_SA_LEN
1706 	to.sin_len = sizeof to;
1707 #endif
1708 	memset (to.sin_zero, 0, sizeof to.sin_zero);
1709 
1710 	/* Make sure that the packet is at least as big as a BOOTP packet. */
1711 	if (outgoing.packet_length < BOOTP_MIN_LEN)
1712 		outgoing.packet_length = BOOTP_MIN_LEN;
1713 
1714 	/* If this was gatewayed, send it back to the gateway.
1715 	   Otherwise, broadcast it on the local network. */
1716 	if (raw.giaddr.s_addr) {
1717 		to.sin_addr = raw.giaddr;
1718 		if (raw.giaddr.s_addr != htonl (INADDR_LOOPBACK))
1719 			to.sin_port = local_port;
1720 		else
1721 			to.sin_port = remote_port; /* for testing. */
1722 
1723 		if (fallback_interface) {
1724 			result = send_packet(fallback_interface, packet, &raw,
1725 					     outgoing.packet_length, from, &to,
1726 					     NULL);
1727 			if (result < 0) {
1728 				log_error ("%s:%d: Failed to send %d byte long "
1729 					   "packet over %s interface.", MDL,
1730 					   outgoing.packet_length,
1731 					   fallback_interface->name);
1732 			}
1733 
1734 			return;
1735 		}
1736 	} else {
1737 		to.sin_addr = limited_broadcast;
1738 		to.sin_port = remote_port;
1739 	}
1740 
1741 	errno = 0;
1742 	result = send_packet(packet->interface, packet, &raw,
1743 			     outgoing.packet_length, from, &to, NULL);
1744         if (result < 0) {
1745                 log_error ("%s:%d: Failed to send %d byte long packet over %s "
1746                            "interface.", MDL, outgoing.packet_length,
1747                            packet->interface->name);
1748         }
1749 
1750 }
1751 
ack_lease(packet,lease,offer,when,msg,ms_nulltp,hp)1752 void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
1753 	struct packet *packet;
1754 	struct lease *lease;
1755 	unsigned int offer;
1756 	TIME when;
1757 	char *msg;
1758 	int ms_nulltp;
1759 	struct host_decl *hp;
1760 {
1761 	struct lease *lt;
1762 	struct lease_state *state;
1763 	struct lease *next;
1764 	struct host_decl *host = (struct host_decl *)0;
1765 	TIME lease_time;
1766 	TIME offered_lease_time;
1767 	struct data_string d1;
1768 	TIME min_lease_time;
1769 	TIME max_lease_time;
1770 	TIME default_lease_time;
1771 	struct option_cache *oc;
1772 	isc_result_t result;
1773 	TIME ping_timeout;
1774 	TIME lease_cltt;
1775 	struct in_addr from;
1776 	TIME remaining_time;
1777 	struct iaddr cip;
1778 #if defined(DELAYED_ACK)
1779 	/* By default we don't do the enqueue */
1780 	isc_boolean_t enqueue = ISC_FALSE;
1781 #endif
1782 	int use_old_lease = 0;
1783 
1784 	unsigned i, j;
1785 	int s1;
1786 	int ignorep;
1787 	struct timeval tv;
1788 
1789 	/* If we're already acking this lease, don't do it again. */
1790 	if (lease -> state)
1791 		return;
1792 
1793 	/* Save original cltt for comparison later. */
1794 	lease_cltt = lease->cltt;
1795 
1796 	/* If the lease carries a host record, remember it. */
1797 	if (hp)
1798 		host_reference (&host, hp, MDL);
1799 	else if (lease -> host)
1800 		host_reference (&host, lease -> host, MDL);
1801 
1802 	/* Allocate a lease state structure... */
1803 	state = new_lease_state (MDL);
1804 	if (!state)
1805 		log_fatal ("unable to allocate lease state!");
1806 	state -> got_requested_address = packet -> got_requested_address;
1807 	shared_network_reference (&state -> shared_network,
1808 				  packet -> interface -> shared_network, MDL);
1809 
1810 	/* See if we got a server identifier option. */
1811 	if (lookup_option (&dhcp_universe,
1812 			   packet -> options, DHO_DHCP_SERVER_IDENTIFIER))
1813 		state -> got_server_identifier = 1;
1814 
1815 	maybe_return_agent_options(packet, state->options);
1816 
1817 	/* If we are offering a lease that is still currently valid, preserve
1818 	   the events.  We need to do this because if the client does not
1819 	   REQUEST our offer, it will expire in 2 minutes, overriding the
1820 	   expire time in the currently in force lease.  We want the expire
1821 	   events to be executed at that point. */
1822 	if (lease->ends <= cur_time && offer != DHCPOFFER) {
1823 		/* Get rid of any old expiry or release statements - by
1824 		   executing the statements below, we will be inserting new
1825 		   ones if there are any to insert. */
1826 		if (lease->on_star.on_expiry)
1827 			executable_statement_dereference
1828 				(&lease->on_star.on_expiry, MDL);
1829 		if (lease->on_star.on_commit)
1830 			executable_statement_dereference
1831 				(&lease->on_star.on_commit, MDL);
1832 		if (lease->on_star.on_release)
1833 			executable_statement_dereference
1834 				(&lease->on_star.on_release, MDL);
1835 	}
1836 
1837 	/* Execute statements in scope starting with the subnet scope. */
1838 	execute_statements_in_scope (NULL, packet, lease,
1839 				     NULL, packet->options,
1840 				     state->options, &lease->scope,
1841 				     lease->subnet->group, NULL, NULL);
1842 
1843 	/* If the lease is from a pool, run the pool scope. */
1844 	if (lease->pool)
1845 		(execute_statements_in_scope(NULL, packet, lease, NULL,
1846 					     packet->options, state->options,
1847 					     &lease->scope, lease->pool->group,
1848 					     lease->pool->
1849 						shared_network->group,
1850 					     NULL));
1851 
1852 	/* Execute statements from class scopes. */
1853 	for (i = packet -> class_count; i > 0; i--) {
1854 		execute_statements_in_scope(NULL, packet, lease, NULL,
1855 					    packet->options, state->options,
1856 					    &lease->scope,
1857 					    packet->classes[i - 1]->group,
1858 					    (lease->pool ? lease->pool->group
1859 					     : lease->subnet->group),
1860 					    NULL);
1861 	}
1862 
1863 	/* See if the client is only supposed to have one lease at a time,
1864 	   and if so, find its other leases and release them.    We can only
1865 	   do this on DHCPREQUEST.    It's a little weird to do this before
1866 	   looking at permissions, because the client might not actually
1867 	   _get_ a lease after we've done the permission check, but the
1868 	   assumption for this option is that the client has exactly one
1869 	   network interface, and will only ever remember one lease.   So
1870 	   if it sends a DHCPREQUEST, and doesn't get the lease, it's already
1871 	   forgotten about its old lease, so we can too. */
1872 	if (packet -> packet_type == DHCPREQUEST &&
1873 	    (oc = lookup_option (&server_universe, state -> options,
1874 				 SV_ONE_LEASE_PER_CLIENT)) &&
1875 	    evaluate_boolean_option_cache (&ignorep,
1876 					   packet, lease,
1877 					   (struct client_state *)0,
1878 					   packet -> options,
1879 					   state -> options, &lease -> scope,
1880 					   oc, MDL)) {
1881 	    struct lease *seek;
1882 	    if (lease -> uid_len) {
1883 		do {
1884 		    seek = (struct lease *)0;
1885 		    find_lease_by_uid (&seek, lease -> uid,
1886 				       lease -> uid_len, MDL);
1887 		    if (!seek)
1888 			break;
1889 		    if (seek == lease && !seek -> n_uid) {
1890 			lease_dereference (&seek, MDL);
1891 			break;
1892 		    }
1893 		    next = (struct lease *)0;
1894 
1895 		    /* Don't release expired leases, and don't
1896 		       release the lease we're going to assign. */
1897 		    next = (struct lease *)0;
1898 		    while (seek) {
1899 			if (seek -> n_uid)
1900 			    lease_reference (&next, seek -> n_uid, MDL);
1901 			if (seek != lease &&
1902 			    seek -> binding_state != FTS_RELEASED &&
1903 			    seek -> binding_state != FTS_EXPIRED &&
1904 			    seek -> binding_state != FTS_RESET &&
1905 			    seek -> binding_state != FTS_FREE &&
1906 			    seek -> binding_state != FTS_BACKUP)
1907 				break;
1908 			lease_dereference (&seek, MDL);
1909 			if (next) {
1910 			    lease_reference (&seek, next, MDL);
1911 			    lease_dereference (&next, MDL);
1912 			}
1913 		    }
1914 		    if (next)
1915 			lease_dereference (&next, MDL);
1916 		    if (seek) {
1917 			release_lease (seek, packet);
1918 			lease_dereference (&seek, MDL);
1919 		    } else
1920 			break;
1921 		} while (1);
1922 	    }
1923 	    if (!lease -> uid_len ||
1924 		(host &&
1925 		 !host -> client_identifier.len &&
1926 		 (oc = lookup_option (&server_universe, state -> options,
1927 				      SV_DUPLICATES)) &&
1928 		 !evaluate_boolean_option_cache (&ignorep, packet, lease,
1929 						 (struct client_state *)0,
1930 						 packet -> options,
1931 						 state -> options,
1932 						 &lease -> scope,
1933 						 oc, MDL))) {
1934 		do {
1935 		    seek = (struct lease *)0;
1936 		    find_lease_by_hw_addr
1937 			    (&seek, lease -> hardware_addr.hbuf,
1938 			     lease -> hardware_addr.hlen, MDL);
1939 		    if (!seek)
1940 			    break;
1941 		    if (seek == lease && !seek -> n_hw) {
1942 			    lease_dereference (&seek, MDL);
1943 			    break;
1944 		    }
1945 		    next = (struct lease *)0;
1946 		    while (seek) {
1947 			if (seek -> n_hw)
1948 			    lease_reference (&next, seek -> n_hw, MDL);
1949 			if (seek != lease &&
1950 			    seek -> binding_state != FTS_RELEASED &&
1951 			    seek -> binding_state != FTS_EXPIRED &&
1952 			    seek -> binding_state != FTS_RESET &&
1953 			    seek -> binding_state != FTS_FREE &&
1954 			    seek -> binding_state != FTS_BACKUP)
1955 				break;
1956 			lease_dereference (&seek, MDL);
1957 			if (next) {
1958 			    lease_reference (&seek, next, MDL);
1959 			    lease_dereference (&next, MDL);
1960 			}
1961 		    }
1962 		    if (next)
1963 			lease_dereference (&next, MDL);
1964 		    if (seek) {
1965 			release_lease (seek, packet);
1966 			lease_dereference (&seek, MDL);
1967 		    } else
1968 			break;
1969 		} while (1);
1970 	    }
1971 	}
1972 
1973 
1974 	/* Make sure this packet satisfies the configured minimum
1975 	   number of seconds. */
1976 	memset (&d1, 0, sizeof d1);
1977 	if (offer == DHCPOFFER &&
1978 	    (oc = lookup_option (&server_universe, state -> options,
1979 				 SV_MIN_SECS))) {
1980 		if (evaluate_option_cache (&d1, packet, lease,
1981 					   (struct client_state *)0,
1982 					   packet -> options, state -> options,
1983 					   &lease -> scope, oc, MDL)) {
1984 			if (d1.len &&
1985 			    ntohs (packet -> raw -> secs) < d1.data [0]) {
1986 				log_info("%s: configured min-secs value (%d) "
1987 					 "is greater than secs field (%d).  "
1988 					 "message dropped.", msg, d1.data[0],
1989 					 ntohs(packet->raw->secs));
1990 				data_string_forget (&d1, MDL);
1991 				free_lease_state (state, MDL);
1992 				if (host)
1993 					host_dereference (&host, MDL);
1994 				return;
1995 			}
1996 			data_string_forget (&d1, MDL);
1997 		}
1998 	}
1999 
2000 	/* Try to find a matching host declaration for this lease.
2001 	 */
2002 	if (!host) {
2003 		struct host_decl *hp = (struct host_decl *)0;
2004 		struct host_decl *h;
2005 
2006 		/* Try to find a host_decl that matches the client
2007 		   identifier or hardware address on the packet, and
2008 		   has no fixed IP address.   If there is one, hang
2009 		   it off the lease so that its option definitions
2010 		   can be used. */
2011 		oc = lookup_option (&dhcp_universe, packet -> options,
2012 				    DHO_DHCP_CLIENT_IDENTIFIER);
2013 		if (oc &&
2014 		    evaluate_option_cache (&d1, packet, lease,
2015 					   (struct client_state *)0,
2016 					   packet -> options, state -> options,
2017 					   &lease -> scope, oc, MDL)) {
2018 			find_hosts_by_uid (&hp, d1.data, d1.len, MDL);
2019 			data_string_forget (&d1, MDL);
2020 			for (h = hp; h; h = h -> n_ipaddr) {
2021 				if (!h -> fixed_addr)
2022 					break;
2023 			}
2024 			if (h)
2025 				host_reference (&host, h, MDL);
2026 			if (hp != NULL)
2027 				host_dereference(&hp, MDL);
2028 		}
2029 		if (!host) {
2030 			find_hosts_by_haddr (&hp,
2031 					     packet -> raw -> htype,
2032 					     packet -> raw -> chaddr,
2033 					     packet -> raw -> hlen,
2034 					     MDL);
2035 			for (h = hp; h; h = h -> n_ipaddr) {
2036 				if (!h -> fixed_addr)
2037 					break;
2038 			}
2039 			if (h)
2040 				host_reference (&host, h, MDL);
2041 			if (hp != NULL)
2042 				host_dereference(&hp, MDL);
2043 		}
2044 		if (!host) {
2045 			find_hosts_by_option(&hp, packet,
2046 					     packet->options, MDL);
2047 			for (h = hp; h; h = h -> n_ipaddr) {
2048 				if (!h -> fixed_addr)
2049 					break;
2050 			}
2051 			if (h)
2052 				host_reference (&host, h, MDL);
2053 			if (hp != NULL)
2054 				host_dereference(&hp, MDL);
2055 		}
2056 	}
2057 
2058 	/* If we have a host_decl structure, run the options associated
2059 	   with its group.  Whether the host decl struct is old or not. */
2060 	if (host)
2061 		execute_statements_in_scope (NULL, packet, lease, NULL,
2062 					     packet->options, state->options,
2063 					     &lease->scope, host->group,
2064 					     (lease->pool
2065 					      ? lease->pool->group
2066 					      : lease->subnet->group),
2067 					     NULL);
2068 
2069 	/* Drop the request if it's not allowed for this client.   By
2070 	   default, unknown clients are allowed. */
2071 	if (!host &&
2072 	    (oc = lookup_option (&server_universe, state -> options,
2073 				 SV_BOOT_UNKNOWN_CLIENTS)) &&
2074 	    !evaluate_boolean_option_cache (&ignorep,
2075 					    packet, lease,
2076 					    (struct client_state *)0,
2077 					    packet -> options,
2078 					    state -> options,
2079 					    &lease -> scope, oc, MDL)) {
2080 		if (!ignorep)
2081 			log_info ("%s: unknown client", msg);
2082 		free_lease_state (state, MDL);
2083 		if (host)
2084 			host_dereference (&host, MDL);
2085 		return;
2086 	}
2087 
2088 	/* Drop the request if it's not allowed for this client. */
2089 	if (!offer &&
2090 	    (oc = lookup_option (&server_universe, state -> options,
2091 				   SV_ALLOW_BOOTP)) &&
2092 	    !evaluate_boolean_option_cache (&ignorep,
2093 					    packet, lease,
2094 					    (struct client_state *)0,
2095 					    packet -> options,
2096 					    state -> options,
2097 					    &lease -> scope, oc, MDL)) {
2098 		if (!ignorep)
2099 			log_info ("%s: bootp disallowed", msg);
2100 		free_lease_state (state, MDL);
2101 		if (host)
2102 			host_dereference (&host, MDL);
2103 		return;
2104 	}
2105 
2106 	/* Drop the request if booting is specifically denied. */
2107 	oc = lookup_option (&server_universe, state -> options,
2108 			    SV_ALLOW_BOOTING);
2109 	if (oc &&
2110 	    !evaluate_boolean_option_cache (&ignorep,
2111 					    packet, lease,
2112 					    (struct client_state *)0,
2113 					    packet -> options,
2114 					    state -> options,
2115 					    &lease -> scope, oc, MDL)) {
2116 		if (!ignorep)
2117 			log_info ("%s: booting disallowed", msg);
2118 		free_lease_state (state, MDL);
2119 		if (host)
2120 			host_dereference (&host, MDL);
2121 		return;
2122 	}
2123 
2124 	/* If we are configured to do per-class billing, do it. */
2125 	if (have_billing_classes && !(lease -> flags & STATIC_LEASE)) {
2126 		/* See if the lease is currently being billed to a
2127 		   class, and if so, whether or not it can continue to
2128 		   be billed to that class. */
2129 		if (lease -> billing_class) {
2130 			for (i = 0; i < packet -> class_count; i++)
2131 				if (packet -> classes [i] ==
2132 				    lease -> billing_class)
2133 					break;
2134 			if (i == packet -> class_count)
2135 				unbill_class (lease, lease -> billing_class);
2136 		}
2137 
2138 		/* If we don't have an active billing, see if we need
2139 		   one, and if we do, try to do so. */
2140 		if (lease->billing_class == NULL) {
2141 			char *cname = "";
2142 			int bill = 0;
2143 
2144 			for (i = 0; i < packet->class_count; i++) {
2145 				struct class *billclass, *subclass;
2146 
2147 				billclass = packet->classes[i];
2148 				if (billclass->lease_limit) {
2149 					bill++;
2150 					if (bill_class(lease, billclass))
2151 						break;
2152 
2153 					subclass = billclass->superclass;
2154 					if (subclass == NULL)
2155 						cname = subclass->name;
2156 					else
2157 						cname = billclass->name;
2158 				}
2159 			}
2160 			if (bill != 0 && i == packet->class_count) {
2161 				log_info("%s: no available billing: lease "
2162 					 "limit reached in all matching "
2163 					 "classes (last: '%s')", msg, cname);
2164 				free_lease_state(state, MDL);
2165 				if (host)
2166 					host_dereference(&host, MDL);
2167 				return;
2168 			}
2169 
2170 			/*
2171 			 * If this is an offer, undo the billing.  We go
2172 			 * through all the steps above to bill a class so
2173 			 * we can hit the 'no available billing' mark and
2174 			 * abort without offering.  But it just doesn't make
2175 			 * sense to permanently bill a class for a non-active
2176 			 * lease.  This means on REQUEST, we will bill this
2177 			 * lease again (if there is a REQUEST).
2178 			 */
2179 			if (offer == DHCPOFFER &&
2180 			    lease->billing_class != NULL &&
2181 			    lease->binding_state != FTS_ACTIVE)
2182 				unbill_class(lease, lease->billing_class);
2183 		}
2184 	}
2185 
2186 	/* Figure out the filename. */
2187 	oc = lookup_option (&server_universe, state -> options, SV_FILENAME);
2188 	if (oc)
2189 		evaluate_option_cache (&state -> filename, packet, lease,
2190 				       (struct client_state *)0,
2191 				       packet -> options, state -> options,
2192 				       &lease -> scope, oc, MDL);
2193 
2194 	/* Choose a server name as above. */
2195 	oc = lookup_option (&server_universe, state -> options,
2196 			    SV_SERVER_NAME);
2197 	if (oc)
2198 		evaluate_option_cache (&state -> server_name, packet, lease,
2199 				       (struct client_state *)0,
2200 				       packet -> options, state -> options,
2201 				       &lease -> scope, oc, MDL);
2202 
2203 	/* At this point, we have a lease that we can offer the client.
2204 	   Now we construct a lease structure that contains what we want,
2205 	   and call supersede_lease to do the right thing with it. */
2206 	lt = (struct lease *)0;
2207 	result = lease_allocate (&lt, MDL);
2208 	if (result != ISC_R_SUCCESS) {
2209 		log_info ("%s: can't allocate temporary lease structure: %s",
2210 			  msg, isc_result_totext (result));
2211 		free_lease_state (state, MDL);
2212 		if (host)
2213 			host_dereference (&host, MDL);
2214 		return;
2215 	}
2216 
2217 	/* Use the ip address of the lease that we finally found in
2218 	   the database. */
2219 	lt -> ip_addr = lease -> ip_addr;
2220 
2221 	/* Start now. */
2222 	lt -> starts = cur_time;
2223 
2224 	/* Figure out how long a lease to assign.    If this is a
2225 	   dynamic BOOTP lease, its duration must be infinite. */
2226 	if (offer) {
2227 		lt->flags &= ~BOOTP_LEASE;
2228 
2229 		default_lease_time = DEFAULT_DEFAULT_LEASE_TIME;
2230 		if ((oc = lookup_option (&server_universe, state -> options,
2231 					 SV_DEFAULT_LEASE_TIME))) {
2232 			if (evaluate_option_cache (&d1, packet, lease,
2233 						   (struct client_state *)0,
2234 						   packet -> options,
2235 						   state -> options,
2236 						   &lease -> scope, oc, MDL)) {
2237 				if (d1.len == sizeof (u_int32_t))
2238 					default_lease_time =
2239 						getULong (d1.data);
2240 				data_string_forget (&d1, MDL);
2241 			}
2242 		}
2243 
2244 		if ((oc = lookup_option (&dhcp_universe, packet -> options,
2245 					 DHO_DHCP_LEASE_TIME)))
2246 			s1 = evaluate_option_cache (&d1, packet, lease,
2247 						    (struct client_state *)0,
2248 						    packet -> options,
2249 						    state -> options,
2250 						    &lease -> scope, oc, MDL);
2251 		else
2252 			s1 = 0;
2253 
2254 		if (s1 && (d1.len == 4)) {
2255 			u_int32_t ones = 0xffffffff;
2256 
2257 			/* One potential use of reserved leases is to allow
2258 			 * clients to signal reservation of their lease.  They
2259 			 * can kinda sorta do this, if you squint hard enough,
2260 			 * by supplying an 'infinite' requested-lease-time
2261 			 * option.  This is generally bad practice...you want
2262 			 * clients to return to the server on at least some
2263 			 * period (days, months, years) to get up-to-date
2264 			 * config state.  So;
2265 			 *
2266 			 * 1) A client requests 0xffffffff lease-time.
2267 			 * 2) The server reserves the lease, and assigns a
2268 			 *    <= max_lease_time lease-time to the client, which
2269 			 *    we presume is much smaller than 0xffffffff.
2270 			 * 3) The client ultimately fails to renew its lease
2271 			 *    (all clients go offline at some point).
2272 			 * 4) The server retains the reservation, although
2273 			 *    the lease expires and passes through those states
2274 			 *    as normal, it's placed in the 'reserved' queue,
2275 			 *    and is under no circumstances allocated to any
2276 			 *    clients.
2277 			 *
2278 			 * Whether the client knows its reserving its lease or
2279 			 * not, this can be a handy tool for a sysadmin.
2280 			 */
2281 			if ((memcmp(d1.data, &ones, 4) == 0) &&
2282 			    (oc = lookup_option(&server_universe,
2283 						state->options,
2284 						SV_RESERVE_INFINITE)) &&
2285 			    evaluate_boolean_option_cache(&ignorep, packet,
2286 						lease, NULL, packet->options,
2287 						state->options, &lease->scope,
2288 						oc, MDL)) {
2289 				lt->flags |= RESERVED_LEASE;
2290 				if (!ignorep)
2291 					log_info("Infinite-leasetime "
2292 						 "reservation made on %s.",
2293 						 piaddr(lt->ip_addr));
2294 			}
2295 
2296 			lease_time = getULong (d1.data);
2297 		} else
2298 			lease_time = default_lease_time;
2299 
2300 		if (s1)
2301 			data_string_forget(&d1, MDL);
2302 
2303 		/* See if there's a maximum lease time. */
2304 		max_lease_time = DEFAULT_MAX_LEASE_TIME;
2305 		if ((oc = lookup_option (&server_universe, state -> options,
2306 					 SV_MAX_LEASE_TIME))) {
2307 			if (evaluate_option_cache (&d1, packet, lease,
2308 						   (struct client_state *)0,
2309 						   packet -> options,
2310 						   state -> options,
2311 						   &lease -> scope, oc, MDL)) {
2312 				if (d1.len == sizeof (u_int32_t))
2313 					max_lease_time =
2314 						getULong (d1.data);
2315 				data_string_forget (&d1, MDL);
2316 			}
2317 		}
2318 
2319 		/* Enforce the maximum lease length. */
2320 		if (lease_time < 0 /* XXX */
2321 		    || lease_time > max_lease_time)
2322 			lease_time = max_lease_time;
2323 
2324 		min_lease_time = DEFAULT_MIN_LEASE_TIME;
2325 		if (min_lease_time > max_lease_time)
2326 			min_lease_time = max_lease_time;
2327 
2328 		if ((oc = lookup_option (&server_universe, state -> options,
2329 					 SV_MIN_LEASE_TIME))) {
2330 			if (evaluate_option_cache (&d1, packet, lease,
2331 						   (struct client_state *)0,
2332 						   packet -> options,
2333 						   state -> options,
2334 						   &lease -> scope, oc, MDL)) {
2335 				if (d1.len == sizeof (u_int32_t))
2336 					min_lease_time = getULong (d1.data);
2337 				data_string_forget (&d1, MDL);
2338 			}
2339 		}
2340 
2341 		/* CC: If there are less than
2342 		   adaptive-lease-time-threshold % free leases,
2343 		     hand out only short term leases */
2344 
2345 		memset(&d1, 0, sizeof(d1));
2346 		if (lease->pool &&
2347 		    (oc = lookup_option(&server_universe, state->options,
2348 					SV_ADAPTIVE_LEASE_TIME_THRESHOLD)) &&
2349 		    evaluate_option_cache(&d1, packet, lease, NULL,
2350 					  packet->options, state->options,
2351 					  &lease->scope, oc, MDL)) {
2352 			if (d1.len == 1 && d1.data[0] > 0 &&
2353 			    d1.data[0] < 100) {
2354 				TIME adaptive_time;
2355 				int poolfilled, total, count;
2356 
2357 				if (min_lease_time)
2358 					adaptive_time = min_lease_time;
2359 				else
2360 					adaptive_time = DEFAULT_MIN_LEASE_TIME;
2361 
2362 				/* Allow the client to keep its lease. */
2363 				if (lease->ends - cur_time > adaptive_time)
2364 					adaptive_time = lease->ends - cur_time;
2365 
2366 				count = lease->pool->lease_count;
2367 				total = count - (lease->pool->free_leases +
2368 						 lease->pool->backup_leases);
2369 
2370 				poolfilled = (total > (INT_MAX / 100)) ?
2371 					     total / (count / 100) :
2372 					     (total * 100) / count;
2373 
2374 				log_debug("Adap-lease: Total: %d, Free: %d, "
2375 					  "Ends: %d, Adaptive: %d, Fill: %d, "
2376 					  "Threshold: %d",
2377 					  lease->pool->lease_count,
2378 					  lease->pool->free_leases,
2379 					  (int)(lease->ends - cur_time),
2380 					  (int)adaptive_time, poolfilled,
2381 					  d1.data[0]);
2382 
2383 				if (poolfilled >= d1.data[0] &&
2384 				    lease_time > adaptive_time) {
2385 					log_info("Pool over threshold, time "
2386 						 "for %s reduced from %d to "
2387 						 "%d.", piaddr(lease->ip_addr),
2388 						 (int)lease_time,
2389 						 (int)adaptive_time);
2390 
2391 					lease_time = adaptive_time;
2392 				}
2393 			}
2394 			data_string_forget(&d1, MDL);
2395 		}
2396 
2397 		/* a client requests an address which is not yet active*/
2398 		if (lease->pool && lease->pool->valid_from &&
2399                     cur_time < lease->pool->valid_from) {
2400 			/* NAK leases before pool activation date */
2401 			cip.len = 4;
2402 			memcpy (cip.iabuf, &lt->ip_addr.iabuf, 4);
2403 			nak_lease(packet, &cip);
2404 			free_lease_state (state, MDL);
2405 			lease_dereference (&lt, MDL);
2406 			if (host)
2407 				host_dereference (&host, MDL);
2408 			return;
2409 
2410 		}
2411 
2412 		/* CC:
2413 		a) NAK current lease if past the expiration date
2414 		b) extend lease only up to the expiration date, but not
2415 		below min-lease-time
2416 		Setting min-lease-time is essential for this to work!
2417 		The value of min-lease-time determines the lenght
2418 		of the transition window:
2419 		A client renewing a second before the deadline will
2420 		get a min-lease-time lease. Since the current ip might not
2421 		be routable after the deadline, the client will
2422 		be offline until it DISCOVERS again. Otherwise it will
2423 		receive a NAK at T/2.
2424 		A min-lease-time of 6 seconds effectively switches over
2425 		all clients in this pool very quickly.
2426 			*/
2427 
2428 		if (lease->pool && lease->pool->valid_until) {
2429 			if (cur_time >= lease->pool->valid_until) {
2430 				/* NAK leases after pool expiration date */
2431 				cip.len = 4;
2432 				memcpy (cip.iabuf, &lt->ip_addr.iabuf, 4);
2433 				nak_lease(packet, &cip);
2434 				free_lease_state (state, MDL);
2435 				lease_dereference (&lt, MDL);
2436 				if (host)
2437 					host_dereference (&host, MDL);
2438 				return;
2439 			}
2440 			remaining_time = lease->pool->valid_until - cur_time;
2441 			if (lease_time > remaining_time)
2442 				lease_time = remaining_time;
2443 		}
2444 
2445 		if (lease_time < min_lease_time) {
2446 			if (min_lease_time)
2447 				lease_time = min_lease_time;
2448 			else
2449 				lease_time = default_lease_time;
2450 		}
2451 
2452 
2453 #if defined (FAILOVER_PROTOCOL)
2454 		/* Okay, we know the lease duration.   Now check the
2455 		   failover state, if any. */
2456 		if (lease -> pool && lease -> pool -> failover_peer) {
2457 			TIME new_lease_time = lease_time;
2458 			dhcp_failover_state_t *peer =
2459 			    lease -> pool -> failover_peer;
2460 
2461 			/* Copy previous lease failover ack-state. */
2462 			lt->tsfp = lease->tsfp;
2463 			lt->atsfp = lease->atsfp;
2464 
2465 			/* cltt set below */
2466 
2467 			/* Lease times less than MCLT are not a concern. */
2468 			if (lease_time > peer->mclt) {
2469 				/* Each server can only offer a lease time
2470 				 * that is either equal to MCLT (at least),
2471 				 * or up to TSFP+MCLT.  Only if the desired
2472 				 * lease time falls within TSFP+MCLT, can
2473 				 * the server allow it.
2474 				 */
2475 				if (lt->tsfp <= cur_time)
2476 					new_lease_time = peer->mclt;
2477 				else if ((cur_time + lease_time) >
2478 					 (lt->tsfp + peer->mclt))
2479 					new_lease_time = (lt->tsfp - cur_time)
2480 								+ peer->mclt;
2481 			}
2482 
2483 			/* Update potential expiry.  Allow for the desired
2484 			 * lease time plus one half the actual (whether
2485 			 * modified downward or not) lease time, which is
2486 			 * actually an estimate of when the client will
2487 			 * renew.  This way, the client will be able to get
2488 			 * the desired lease time upon renewal.
2489 			 */
2490 			if (offer == DHCPACK) {
2491 				lt->tstp = cur_time + lease_time +
2492 						(new_lease_time / 2);
2493 
2494 				/* If we reduced the potential expiry time,
2495 				 * make sure we don't offer an old-expiry-time
2496 				 * lease for this lease before the change is
2497 				 * ack'd.
2498 				 */
2499 				if (lt->tstp < lt->tsfp)
2500 					lt->tsfp = lt->tstp;
2501 			} else
2502 				lt->tstp = lease->tstp;
2503 
2504 			/* Use failover-modified lease time.  */
2505 			lease_time = new_lease_time;
2506 		}
2507 #endif /* FAILOVER_PROTOCOL */
2508 
2509 		/* If the lease duration causes the time value to wrap,
2510 		   use the maximum expiry time. */
2511 		if (cur_time + lease_time < cur_time)
2512 			state -> offered_expiry = MAX_TIME - 1;
2513 		else
2514 			state -> offered_expiry = cur_time + lease_time;
2515 		if (when)
2516 			lt -> ends = when;
2517 		else
2518 			lt -> ends = state -> offered_expiry;
2519 
2520 		/* Don't make lease active until we actually get a
2521 		   DHCPREQUEST. */
2522 		if (offer == DHCPACK)
2523 			lt -> next_binding_state = FTS_ACTIVE;
2524 		else
2525 			lt -> next_binding_state = lease -> binding_state;
2526 	} else {
2527 		lt->flags |= BOOTP_LEASE;
2528 
2529 		lease_time = MAX_TIME - cur_time;
2530 
2531 		if ((oc = lookup_option (&server_universe, state -> options,
2532 					 SV_BOOTP_LEASE_LENGTH))) {
2533 			if (evaluate_option_cache (&d1, packet, lease,
2534 						   (struct client_state *)0,
2535 						   packet -> options,
2536 						   state -> options,
2537 						   &lease -> scope, oc, MDL)) {
2538 				if (d1.len == sizeof (u_int32_t))
2539 					lease_time = getULong (d1.data);
2540 				data_string_forget (&d1, MDL);
2541 			}
2542 		}
2543 
2544 		if ((oc = lookup_option (&server_universe, state -> options,
2545 					 SV_BOOTP_LEASE_CUTOFF))) {
2546 			if (evaluate_option_cache (&d1, packet, lease,
2547 						   (struct client_state *)0,
2548 						   packet -> options,
2549 						   state -> options,
2550 						   &lease -> scope, oc, MDL)) {
2551 				if (d1.len == sizeof (u_int32_t))
2552 					lease_time = (getULong (d1.data) -
2553 						      cur_time);
2554 				data_string_forget (&d1, MDL);
2555 			}
2556 		}
2557 
2558 		lt -> ends = state -> offered_expiry = cur_time + lease_time;
2559 		lt -> next_binding_state = FTS_ACTIVE;
2560 	}
2561 
2562 	/* Update Client Last Transaction Time. */
2563 	lt->cltt = cur_time;
2564 
2565 	/* See if we want to record the uid for this client */
2566 	oc = lookup_option(&server_universe, state->options,
2567 			   SV_IGNORE_CLIENT_UIDS);
2568 	if ((oc == NULL) ||
2569 	    !evaluate_boolean_option_cache(&ignorep, packet, lease, NULL,
2570 					   packet->options, state->options,
2571 					   &lease->scope, oc, MDL)) {
2572 
2573 		/* Record the uid, if given... */
2574 		oc = lookup_option (&dhcp_universe, packet -> options,
2575 				    DHO_DHCP_CLIENT_IDENTIFIER);
2576 		if (oc &&
2577 		    evaluate_option_cache(&d1, packet, lease, NULL,
2578 					  packet->options, state->options,
2579 					  &lease->scope, oc, MDL)) {
2580 			if (d1.len <= sizeof(lt->uid_buf)) {
2581 				memcpy(lt->uid_buf, d1.data, d1.len);
2582 				lt->uid = lt->uid_buf;
2583 				lt->uid_max = sizeof(lt->uid_buf);
2584 				lt->uid_len = d1.len;
2585 			} else {
2586 				unsigned char *tuid;
2587 				lt->uid_max = d1.len;
2588 				lt->uid_len = d1.len;
2589 				tuid = (unsigned char *)dmalloc(lt->uid_max,
2590 								MDL);
2591 				/* XXX inelegant */
2592 				if (!tuid)
2593 					log_fatal ("no memory for large uid.");
2594 				memcpy(tuid, d1.data, lt->uid_len);
2595 				lt->uid = tuid;
2596 			}
2597 			data_string_forget (&d1, MDL);
2598 		}
2599 	}
2600 
2601 	if (host) {
2602 		host_reference (&lt -> host, host, MDL);
2603 		host_dereference (&host, MDL);
2604 	}
2605 	if (lease -> subnet)
2606 		subnet_reference (&lt -> subnet, lease -> subnet, MDL);
2607 	if (lease -> billing_class)
2608 		class_reference (&lt -> billing_class,
2609 				 lease -> billing_class, MDL);
2610 
2611 	/* Set a flag if this client is a broken client that NUL
2612 	   terminates string options and expects us to do likewise. */
2613 	if (ms_nulltp)
2614 		lease -> flags |= MS_NULL_TERMINATION;
2615 	else
2616 		lease -> flags &= ~MS_NULL_TERMINATION;
2617 
2618 	/* Save any bindings. */
2619 	if (lease -> scope) {
2620 		binding_scope_reference (&lt -> scope, lease -> scope, MDL);
2621 		binding_scope_dereference (&lease -> scope, MDL);
2622 	}
2623 	if (lease -> agent_options)
2624 		option_chain_head_reference (&lt -> agent_options,
2625 					     lease -> agent_options, MDL);
2626 
2627 	/* Save the vendor-class-identifier for DHCPLEASEQUERY. */
2628 	oc = lookup_option(&dhcp_universe, packet->options,
2629 			   DHO_VENDOR_CLASS_IDENTIFIER);
2630 	if (oc != NULL &&
2631 	    evaluate_option_cache(&d1, packet, NULL, NULL, packet->options,
2632 				  NULL, &lease->scope, oc, MDL)) {
2633 		if (d1.len != 0) {
2634 			bind_ds_value(&lease->scope, "vendor-class-identifier",
2635 				      &d1);
2636 		}
2637 
2638 		data_string_forget(&d1, MDL);
2639 	}
2640 
2641 	/* If we got relay agent information options from the packet, then
2642 	 * cache them for renewal in case the relay agent can't supply them
2643 	 * when the client unicasts.  The options may be from an addressed
2644 	 * "l3" relay, or from an unaddressed "l2" relay which does not set
2645 	 * giaddr.
2646 	 */
2647 	if (!packet->agent_options_stashed &&
2648 	    (packet->options != NULL) &&
2649 	    packet->options->universe_count > agent_universe.index &&
2650 	    packet->options->universes[agent_universe.index] != NULL) {
2651 	    oc = lookup_option (&server_universe, state -> options,
2652 				SV_STASH_AGENT_OPTIONS);
2653 	    if (!oc ||
2654 		evaluate_boolean_option_cache (&ignorep, packet, lease,
2655 					       (struct client_state *)0,
2656 					       packet -> options,
2657 					       state -> options,
2658 					       &lease -> scope, oc, MDL)) {
2659 		if (lt -> agent_options)
2660 		    option_chain_head_dereference (&lt -> agent_options, MDL);
2661 		option_chain_head_reference
2662 			(&lt -> agent_options,
2663 			 (struct option_chain_head *)
2664 			 packet -> options -> universes [agent_universe.index],
2665 			 MDL);
2666 	    }
2667 	}
2668 
2669 	/* Replace the old lease hostname with the new one, if it's changed. */
2670 	oc = lookup_option (&dhcp_universe, packet -> options, DHO_HOST_NAME);
2671 	if (oc)
2672 		s1 = evaluate_option_cache (&d1, packet, (struct lease *)0,
2673 					    (struct client_state *)0,
2674 					    packet -> options,
2675 					    (struct option_state *)0,
2676 					    &global_scope, oc, MDL);
2677 	else
2678 		s1 = 0;
2679 
2680 	if (oc && s1 &&
2681 	    lease -> client_hostname &&
2682 	    strlen (lease -> client_hostname) == d1.len &&
2683 	    !memcmp (lease -> client_hostname, d1.data, d1.len)) {
2684 		/* Hasn't changed. */
2685 		data_string_forget (&d1, MDL);
2686 		lt -> client_hostname = lease -> client_hostname;
2687 		lease -> client_hostname = (char *)0;
2688 	} else if (oc && s1) {
2689 		lt -> client_hostname = dmalloc (d1.len + 1, MDL);
2690 		if (!lt -> client_hostname)
2691 			log_error ("no memory for client hostname.");
2692 		else {
2693 			memcpy (lt -> client_hostname, d1.data, d1.len);
2694 			lt -> client_hostname [d1.len] = 0;
2695 		}
2696 		data_string_forget (&d1, MDL);
2697 	}
2698 
2699 	/* Record the hardware address, if given... */
2700 	lt -> hardware_addr.hlen = packet -> raw -> hlen + 1;
2701 	lt -> hardware_addr.hbuf [0] = packet -> raw -> htype;
2702 	memcpy (&lt -> hardware_addr.hbuf [1], packet -> raw -> chaddr,
2703 		sizeof packet -> raw -> chaddr);
2704 
2705 	lt -> flags = lease -> flags & ~PERSISTENT_FLAGS;
2706 
2707 	/* If there are statements to execute when the lease is
2708 	   committed, execute them. */
2709 	if (lease->on_star.on_commit && (!offer || offer == DHCPACK)) {
2710 		execute_statements (NULL, packet, lt, NULL, packet->options,
2711 				    state->options, &lt->scope,
2712 				    lease->on_star.on_commit, NULL);
2713 		if (lease->on_star.on_commit)
2714 			executable_statement_dereference
2715 				(&lease->on_star.on_commit, MDL);
2716 	}
2717 
2718 #ifdef NSUPDATE
2719 	/* Perform DDNS updates, if configured to. */
2720 	if ((!offer || offer == DHCPACK) &&
2721 	    (!(oc = lookup_option (&server_universe, state -> options,
2722 				   SV_DDNS_UPDATES)) ||
2723 	     evaluate_boolean_option_cache (&ignorep, packet, lt,
2724 					    (struct client_state *)0,
2725 					    packet -> options,
2726 					    state -> options,
2727 					    &lt -> scope, oc, MDL))) {
2728 		ddns_updates(packet, lt, lease, NULL, NULL, state->options);
2729 	}
2730 #endif /* NSUPDATE */
2731 
2732 	/* Don't call supersede_lease on a mocked-up lease. */
2733 	if (lease -> flags & STATIC_LEASE) {
2734 		/* Copy the hardware address into the static lease
2735 		   structure. */
2736 		lease -> hardware_addr.hlen = packet -> raw -> hlen + 1;
2737 		lease -> hardware_addr.hbuf [0] = packet -> raw -> htype;
2738 		memcpy (&lease -> hardware_addr.hbuf [1],
2739 			packet -> raw -> chaddr,
2740 			sizeof packet -> raw -> chaddr); /* XXX */
2741 	} else {
2742 		int commit = (!offer || (offer == DHCPACK));
2743 		int thresh = DEFAULT_CACHE_THRESHOLD;
2744 
2745 		/*
2746 		 * Check if the lease was issued recently, if so replay the
2747 		 * current lease and do not require a database sync event.
2748 		 * Recently is defined as being issued less than a given
2749 		 * percentage of the lease previously. The percentage can be
2750 		 * chosen either from a default value or via configuration.
2751 		 *
2752 		 */
2753 		if ((oc = lookup_option(&server_universe, state->options,
2754 					SV_CACHE_THRESHOLD)) &&
2755 		    evaluate_option_cache(&d1, packet, lt, NULL,
2756 					  packet->options, state->options,
2757 					  &lt->scope, oc, MDL)) {
2758 			if (d1.len == 1 && (d1.data[0] < 100))
2759 				thresh = d1.data[0];
2760 
2761 			data_string_forget(&d1, MDL);
2762 		}
2763 
2764 		/*
2765 		 * We check on ddns_cb to see if the ddns code has
2766 		 * updated the lt structure.  We could probably simply
2767 		 * copy the ddns_cb pointer in that case but lets be
2768 		 * simple and safe and update the entire lease.
2769 		 */
2770 		if ((lt->ddns_cb == NULL) &&
2771 		    (thresh > 0) && (offer == DHCPACK) &&
2772 		    (lease->binding_state == FTS_ACTIVE)) {
2773 			int limit;
2774 			int prev_lease = lease->ends - lease->starts;
2775 
2776 			/* it is better to avoid division by 0 */
2777 			if (prev_lease <= (INT_MAX / thresh))
2778 				limit = prev_lease * thresh / 100;
2779 			else
2780 				limit = prev_lease / 100 * thresh;
2781 
2782 			if ((lt->starts - lease->starts) <= limit) {
2783 				lt->starts = lease->starts;
2784 				state->offered_expiry = lt->ends = lease->ends;
2785 				commit = 0;
2786 				use_old_lease = 1;
2787 			}
2788 		}
2789 
2790 #if !defined(DELAYED_ACK)
2791 		/* Install the new information on 'lt' onto the lease at
2792 		 * 'lease'.  If this is a DHCPOFFER, it is a 'soft' promise,
2793 		 * if it is a DHCPACK, it is a 'hard' binding, so it needs
2794 		 * to be recorded and propogated immediately.  If the update
2795 		 * fails, don't ACK it (or BOOTREPLY) either; we may give
2796 		 * the same lease to another client later, and that would be
2797 		 * a conflict.
2798 		 */
2799 		if ((use_old_lease == 0) &&
2800 		    !supersede_lease(lease, lt, commit,
2801 				     offer == DHCPACK, offer == DHCPACK)) {
2802 #else /* defined(DELAYED_ACK) */
2803 		/*
2804 		 * If there already isn't a need for a lease commit, and we
2805 		 * can just answer right away, set a flag to indicate this.
2806 		 */
2807 		if (commit)
2808 			enqueue = ISC_TRUE;
2809 
2810 		/* Install the new information on 'lt' onto the lease at
2811 		 * 'lease'.  We will not 'commit' this information to disk
2812 		 * yet (fsync()), we will 'propogate' the information if
2813 		 * this is BOOTP or a DHCPACK, but we will not 'pimmediate'ly
2814 		 * transmit failover binding updates (this is delayed until
2815 		 * after the fsync()).  If the update fails, don't ACK it (or
2816 		 * BOOTREPLY either); we may give the same lease out to a
2817 		 * different client, and that would be a conflict.
2818 		 */
2819 		if ((use_old_lease == 0) &&
2820 		    !supersede_lease(lease, lt, 0,
2821 				     !offer || offer == DHCPACK, 0)) {
2822 #endif
2823 			log_info ("%s: database update failed", msg);
2824 			free_lease_state (state, MDL);
2825 			lease_dereference (&lt, MDL);
2826 			return;
2827 		}
2828 	}
2829 	lease_dereference (&lt, MDL);
2830 
2831 	/* Remember the interface on which the packet arrived. */
2832 	state -> ip = packet -> interface;
2833 
2834 	/* Remember the giaddr, xid, secs, flags and hops. */
2835 	state -> giaddr = packet -> raw -> giaddr;
2836 	state -> ciaddr = packet -> raw -> ciaddr;
2837 	state -> xid = packet -> raw -> xid;
2838 	state -> secs = packet -> raw -> secs;
2839 	state -> bootp_flags = packet -> raw -> flags;
2840 	state -> hops = packet -> raw -> hops;
2841 	state -> offer = offer;
2842 
2843 	/* If we're always supposed to broadcast to this client, set
2844 	   the broadcast bit in the bootp flags field. */
2845 	if ((oc = lookup_option (&server_universe, state -> options,
2846 				SV_ALWAYS_BROADCAST)) &&
2847 	    evaluate_boolean_option_cache (&ignorep, packet, lease,
2848 					   (struct client_state *)0,
2849 					   packet -> options, state -> options,
2850 					   &lease -> scope, oc, MDL))
2851 		state -> bootp_flags |= htons (BOOTP_BROADCAST);
2852 
2853 	/* Get the Maximum Message Size option from the packet, if one
2854 	   was sent. */
2855 	oc = lookup_option (&dhcp_universe, packet -> options,
2856 			    DHO_DHCP_MAX_MESSAGE_SIZE);
2857 	if (oc &&
2858 	    evaluate_option_cache (&d1, packet, lease,
2859 				   (struct client_state *)0,
2860 				   packet -> options, state -> options,
2861 				   &lease -> scope, oc, MDL)) {
2862 		if (d1.len == sizeof (u_int16_t))
2863 			state -> max_message_size = getUShort (d1.data);
2864 		data_string_forget (&d1, MDL);
2865 	} else {
2866 		oc = lookup_option (&dhcp_universe, state -> options,
2867 				    DHO_DHCP_MAX_MESSAGE_SIZE);
2868 		if (oc &&
2869 		    evaluate_option_cache (&d1, packet, lease,
2870 					   (struct client_state *)0,
2871 					   packet -> options, state -> options,
2872 					   &lease -> scope, oc, MDL)) {
2873 			if (d1.len == sizeof (u_int16_t))
2874 				state -> max_message_size =
2875 					getUShort (d1.data);
2876 			data_string_forget (&d1, MDL);
2877 		}
2878 	}
2879 
2880 	/* Get the Subnet Selection option from the packet, if one
2881 	   was sent. */
2882 	if ((oc = lookup_option (&dhcp_universe, packet -> options,
2883 				 DHO_SUBNET_SELECTION))) {
2884 
2885 		/* Make a copy of the data. */
2886 		struct option_cache *noc = (struct option_cache *)0;
2887 		if (option_cache_allocate (&noc, MDL)) {
2888 			if (oc -> data.len)
2889 				data_string_copy (&noc -> data,
2890 						  &oc -> data, MDL);
2891 			if (oc -> expression)
2892 				expression_reference (&noc -> expression,
2893 						      oc -> expression, MDL);
2894 			if (oc -> option)
2895 				option_reference(&(noc->option), oc->option,
2896 						 MDL);
2897 
2898 			save_option (&dhcp_universe, state -> options, noc);
2899 			option_cache_dereference (&noc, MDL);
2900 		}
2901 	}
2902 
2903 	/* Now, if appropriate, put in DHCP-specific options that
2904 	   override those. */
2905 	if (state -> offer) {
2906 		i = DHO_DHCP_MESSAGE_TYPE;
2907 		oc = (struct option_cache *)0;
2908 		if (option_cache_allocate (&oc, MDL)) {
2909 			if (make_const_data (&oc -> expression,
2910 					     &state -> offer, 1, 0, 0, MDL)) {
2911 				option_code_hash_lookup(&oc->option,
2912 							dhcp_universe.code_hash,
2913 							&i, 0, MDL);
2914 				save_option (&dhcp_universe,
2915 					     state -> options, oc);
2916 			}
2917 			option_cache_dereference (&oc, MDL);
2918 		}
2919 
2920 		get_server_source_address(&from, state->options,
2921 					  state->options, packet);
2922 		memcpy(state->from.iabuf, &from, sizeof(from));
2923 		state->from.len = sizeof(from);
2924 
2925 		offered_lease_time =
2926 			state -> offered_expiry - cur_time;
2927 
2928 		putULong(state->expiry, (u_int32_t)offered_lease_time);
2929 		i = DHO_DHCP_LEASE_TIME;
2930 		oc = (struct option_cache *)0;
2931 		if (option_cache_allocate (&oc, MDL)) {
2932 			if (make_const_data(&oc->expression, state->expiry,
2933 					    4, 0, 0, MDL)) {
2934 				option_code_hash_lookup(&oc->option,
2935 							dhcp_universe.code_hash,
2936 							&i, 0, MDL);
2937 				save_option (&dhcp_universe,
2938 					     state -> options, oc);
2939 			}
2940 			option_cache_dereference (&oc, MDL);
2941 		}
2942 
2943 		/*
2944 		 * Validate any configured renew or rebinding times against
2945 		 * the determined lease time.  Do rebinding first so that
2946 		 * the renew time can be validated against the rebind time.
2947 		 */
2948 		if ((oc = lookup_option(&dhcp_universe, state->options,
2949 					DHO_DHCP_REBINDING_TIME)) != NULL &&
2950 		    evaluate_option_cache(&d1, packet, lease, NULL,
2951 					  packet->options, state->options,
2952 					  &lease->scope, oc, MDL)) {
2953 			TIME rebind_time = getULong(d1.data);
2954 
2955 			/* Drop the configured (invalid) rebinding time. */
2956 			if (rebind_time >= offered_lease_time)
2957 				delete_option(&dhcp_universe, state->options,
2958 					      DHO_DHCP_REBINDING_TIME);
2959 			else /* XXX: variable is reused. */
2960 				offered_lease_time = rebind_time;
2961 
2962 			data_string_forget(&d1, MDL);
2963 		}
2964 
2965 		if ((oc = lookup_option(&dhcp_universe, state->options,
2966 					DHO_DHCP_RENEWAL_TIME)) != NULL &&
2967 		    evaluate_option_cache(&d1, packet, lease, NULL,
2968 					  packet->options, state->options,
2969 					  &lease->scope, oc, MDL)) {
2970 			if (getULong(d1.data) >= offered_lease_time)
2971 				delete_option(&dhcp_universe, state->options,
2972 					      DHO_DHCP_RENEWAL_TIME);
2973 
2974 			data_string_forget(&d1, MDL);
2975 		}
2976 	} else {
2977 		/* XXXSK: should we use get_server_source_address() here? */
2978 		if (state -> ip -> address_count) {
2979 			state -> from.len =
2980 				sizeof state -> ip -> addresses [0];
2981 			memcpy (state -> from.iabuf,
2982 				&state -> ip -> addresses [0],
2983 				state -> from.len);
2984 		}
2985 	}
2986 
2987 	/* Figure out the address of the boot file server. */
2988 	memset (&state -> siaddr, 0, sizeof state -> siaddr);
2989 	if ((oc =
2990 	     lookup_option (&server_universe,
2991 			    state -> options, SV_NEXT_SERVER))) {
2992 		if (evaluate_option_cache (&d1, packet, lease,
2993 					   (struct client_state *)0,
2994 					   packet -> options, state -> options,
2995 					   &lease -> scope, oc, MDL)) {
2996 			/* If there was more than one answer,
2997 			   take the first. */
2998 			if (d1.len >= 4 && d1.data)
2999 				memcpy (&state -> siaddr, d1.data, 4);
3000 			data_string_forget (&d1, MDL);
3001 		}
3002 	}
3003 
3004 	/* Use the subnet mask from the subnet declaration if no other
3005 	   mask has been provided. */
3006 	i = DHO_SUBNET_MASK;
3007 	if (!lookup_option (&dhcp_universe, state -> options, i)) {
3008 		oc = (struct option_cache *)0;
3009 		if (option_cache_allocate (&oc, MDL)) {
3010 			if (make_const_data (&oc -> expression,
3011 					     lease -> subnet -> netmask.iabuf,
3012 					     lease -> subnet -> netmask.len,
3013 					     0, 0, MDL)) {
3014 				option_code_hash_lookup(&oc->option,
3015 							dhcp_universe.code_hash,
3016 							&i, 0, MDL);
3017 				save_option (&dhcp_universe,
3018 					     state -> options, oc);
3019 			}
3020 			option_cache_dereference (&oc, MDL);
3021 		}
3022 	}
3023 
3024 	/* Use the hostname from the host declaration if there is one
3025 	   and no hostname has otherwise been provided, and if the
3026 	   use-host-decl-name flag is set. */
3027 	i = DHO_HOST_NAME;
3028 	j = SV_USE_HOST_DECL_NAMES;
3029 	if (!lookup_option (&dhcp_universe, state -> options, i) &&
3030 	    lease -> host && lease -> host -> name &&
3031 	    (evaluate_boolean_option_cache
3032 	     (&ignorep, packet, lease, (struct client_state *)0,
3033 	      packet -> options, state -> options, &lease -> scope,
3034 	      lookup_option (&server_universe, state -> options, j), MDL))) {
3035 		oc = (struct option_cache *)0;
3036 		if (option_cache_allocate (&oc, MDL)) {
3037 			if (make_const_data (&oc -> expression,
3038 					     ((unsigned char *)
3039 					      lease -> host -> name),
3040 					     strlen (lease -> host -> name),
3041 					     1, 0, MDL)) {
3042 				option_code_hash_lookup(&oc->option,
3043 							dhcp_universe.code_hash,
3044 							&i, 0, MDL);
3045 				save_option (&dhcp_universe,
3046 					     state -> options, oc);
3047 			}
3048 			option_cache_dereference (&oc, MDL);
3049 		}
3050 	}
3051 
3052 	/* If we don't have a hostname yet, and we've been asked to do
3053 	   a reverse lookup to find the hostname, do it. */
3054 	i = DHO_HOST_NAME;
3055 	j = SV_GET_LEASE_HOSTNAMES;
3056 	if (!lookup_option(&dhcp_universe, state->options, i) &&
3057 	    evaluate_boolean_option_cache
3058 	     (&ignorep, packet, lease, NULL,
3059 	      packet->options, state->options, &lease->scope,
3060 	      lookup_option (&server_universe, state->options, j), MDL)) {
3061 		struct in_addr ia;
3062 		struct hostent *h;
3063 
3064 		memcpy (&ia, lease -> ip_addr.iabuf, 4);
3065 
3066 		h = gethostbyaddr ((char *)&ia, sizeof ia, AF_INET);
3067 		if (!h)
3068 			log_error ("No hostname for %s", inet_ntoa (ia));
3069 		else {
3070 			oc = (struct option_cache *)0;
3071 			if (option_cache_allocate (&oc, MDL)) {
3072 				if (make_const_data (&oc -> expression,
3073 						     ((unsigned char *)
3074 						      h -> h_name),
3075 						     strlen (h -> h_name) + 1,
3076 						     1, 1, MDL)) {
3077 					option_code_hash_lookup(&oc->option,
3078 							dhcp_universe.code_hash,
3079 								&i, 0, MDL);
3080 					save_option (&dhcp_universe,
3081 						     state -> options, oc);
3082 				}
3083 				option_cache_dereference (&oc, MDL);
3084 			}
3085 		}
3086 	}
3087 
3088 	/* If so directed, use the leased IP address as the router address.
3089 	   This supposedly makes Win95 machines ARP for all IP addresses,
3090 	   so if the local router does proxy arp, you win. */
3091 
3092 	if (evaluate_boolean_option_cache
3093 	    (&ignorep, packet, lease, (struct client_state *)0,
3094 	     packet -> options, state -> options, &lease -> scope,
3095 	     lookup_option (&server_universe, state -> options,
3096 			    SV_USE_LEASE_ADDR_FOR_DEFAULT_ROUTE), MDL)) {
3097 		i = DHO_ROUTERS;
3098 		oc = lookup_option (&dhcp_universe, state -> options, i);
3099 		if (!oc) {
3100 			oc = (struct option_cache *)0;
3101 			if (option_cache_allocate (&oc, MDL)) {
3102 				if (make_const_data (&oc -> expression,
3103 						     lease -> ip_addr.iabuf,
3104 						     lease -> ip_addr.len,
3105 						     0, 0, MDL)) {
3106 					option_code_hash_lookup(&oc->option,
3107 							dhcp_universe.code_hash,
3108 								&i, 0, MDL);
3109 					save_option (&dhcp_universe,
3110 						     state -> options, oc);
3111 				}
3112 				option_cache_dereference (&oc, MDL);
3113 			}
3114 		}
3115 	}
3116 
3117 	/* If a site option space has been specified, use that for
3118 	   site option codes. */
3119 	i = SV_SITE_OPTION_SPACE;
3120 	if ((oc = lookup_option (&server_universe, state -> options, i)) &&
3121 	    evaluate_option_cache (&d1, packet, lease,
3122 				   (struct client_state *)0,
3123 				   packet -> options, state -> options,
3124 				   &lease -> scope, oc, MDL)) {
3125 		struct universe *u = (struct universe *)0;
3126 
3127 		if (!universe_hash_lookup (&u, universe_hash,
3128 					   (const char *)d1.data, d1.len,
3129 					   MDL)) {
3130 			log_error ("unknown option space %s.", d1.data);
3131 			return;
3132 		}
3133 
3134 		state -> options -> site_universe = u -> index;
3135 		state->options->site_code_min = find_min_site_code(u);
3136 		data_string_forget (&d1, MDL);
3137 	} else {
3138 		state -> options -> site_code_min = 0;
3139 		state -> options -> site_universe = dhcp_universe.index;
3140 	}
3141 
3142 	/* If the client has provided a list of options that it wishes
3143 	   returned, use it to prioritize.  If there's a parameter
3144 	   request list in scope, use that in preference.  Otherwise
3145 	   use the default priority list. */
3146 
3147 	oc = lookup_option (&dhcp_universe, state -> options,
3148 			    DHO_DHCP_PARAMETER_REQUEST_LIST);
3149 
3150 	if (!oc)
3151 		oc = lookup_option (&dhcp_universe, packet -> options,
3152 				    DHO_DHCP_PARAMETER_REQUEST_LIST);
3153 	if (oc)
3154 		evaluate_option_cache (&state -> parameter_request_list,
3155 				       packet, lease, (struct client_state *)0,
3156 				       packet -> options, state -> options,
3157 				       &lease -> scope, oc, MDL);
3158 
3159 #ifdef DEBUG_PACKET
3160 	dump_packet (packet);
3161 	dump_raw ((unsigned char *)packet -> raw, packet -> packet_length);
3162 #endif
3163 
3164 	lease -> state = state;
3165 
3166 	log_info ("%s", msg);
3167 
3168 	/* Hang the packet off the lease state. */
3169 	packet_reference (&lease -> state -> packet, packet, MDL);
3170 
3171 	/* If this is a DHCPOFFER, ping the lease address before actually
3172 	   sending the offer. */
3173 	if (offer == DHCPOFFER && !(lease -> flags & STATIC_LEASE) &&
3174 	    ((cur_time - lease_cltt) > 60) &&
3175 	    (!(oc = lookup_option (&server_universe, state -> options,
3176 				   SV_PING_CHECKS)) ||
3177 	     evaluate_boolean_option_cache (&ignorep, packet, lease,
3178 					    (struct client_state *)0,
3179 					    packet -> options,
3180 					    state -> options,
3181 					    &lease -> scope, oc, MDL))) {
3182 		icmp_echorequest (&lease -> ip_addr);
3183 
3184 		/* Determine whether to use configured or default ping timeout.
3185 		 */
3186 		if ((oc = lookup_option (&server_universe, state -> options,
3187 						SV_PING_TIMEOUT)) &&
3188 		    evaluate_option_cache (&d1, packet, lease, NULL,
3189 						packet -> options,
3190 						state -> options,
3191 						&lease -> scope, oc, MDL)) {
3192 			if (d1.len == sizeof (u_int32_t))
3193 				ping_timeout = getULong (d1.data);
3194 			else
3195 				ping_timeout = DEFAULT_PING_TIMEOUT;
3196 
3197 			data_string_forget (&d1, MDL);
3198 		} else
3199 			ping_timeout = DEFAULT_PING_TIMEOUT;
3200 
3201 #ifdef DEBUG
3202 		log_debug ("Ping timeout: %ld", (long)ping_timeout);
3203 #endif
3204 
3205 		/*
3206 		 * Set a timeout for 'ping-timeout' seconds from NOW, including
3207 		 * current microseconds.  As ping-timeout defaults to 1, the
3208 		 * exclusion of current microseconds causes a value somewhere
3209 		 * /between/ zero and one.
3210 		 */
3211 		tv.tv_sec = cur_tv.tv_sec + ping_timeout;
3212 		tv.tv_usec = cur_tv.tv_usec;
3213 		add_timeout (&tv, lease_ping_timeout, lease,
3214 			     (tvref_t)lease_reference,
3215 			     (tvunref_t)lease_dereference);
3216 		++outstanding_pings;
3217 	} else {
3218   		lease->cltt = cur_time;
3219 #if defined(DELAYED_ACK)
3220 		if (enqueue)
3221 			delayed_ack_enqueue(lease);
3222 		else
3223 #endif
3224 			dhcp_reply(lease);
3225 	}
3226 }
3227 
3228 /*
3229  * CC: queue single ACK:
3230  * - write the lease (but do not fsync it yet)
3231  * - add to double linked list
3232  * - commit if more than xx ACKs pending
3233  * - if necessary set the max timer and bump the next timer
3234  *   but only up to the max timer value.
3235  */
3236 
3237 void
delayed_ack_enqueue(struct lease * lease)3238 delayed_ack_enqueue(struct lease *lease)
3239 {
3240 	struct leasequeue *q;
3241 
3242 	if (!write_lease(lease))
3243 		return;
3244 	if (free_ackqueue) {
3245 	   	q = free_ackqueue;
3246 		free_ackqueue = q->next;
3247 	} else {
3248 		q = ((struct leasequeue *)
3249 			     dmalloc(sizeof(struct leasequeue), MDL));
3250 		if (!q)
3251 			log_fatal("delayed_ack_enqueue: no memory!");
3252 	}
3253 	memset(q, 0, sizeof *q);
3254 	/* prepend to ackqueue*/
3255 	lease_reference(&q->lease, lease, MDL);
3256 	q->next = ackqueue_head;
3257 	ackqueue_head = q;
3258 	if (!ackqueue_tail)
3259 		ackqueue_tail = q;
3260 	else
3261 		q->next->prev = q;
3262 
3263 	outstanding_acks++;
3264 	if (outstanding_acks > max_outstanding_acks) {
3265 		commit_leases();
3266 
3267 		/* Reset max_fsync and cancel any pending timeout. */
3268 		memset(&max_fsync, 0, sizeof(max_fsync));
3269 		cancel_timeout(commit_leases_ackout, NULL);
3270 	} else {
3271 		struct timeval next_fsync;
3272 
3273 		if (max_fsync.tv_sec == 0 && max_fsync.tv_usec == 0) {
3274 			/* set the maximum time we'll wait */
3275 			max_fsync.tv_sec = cur_tv.tv_sec + max_ack_delay_secs;
3276 			max_fsync.tv_usec = cur_tv.tv_usec +
3277 				max_ack_delay_usecs;
3278 
3279 			if (max_fsync.tv_usec >= 1000000) {
3280 				max_fsync.tv_sec++;
3281 				max_fsync.tv_usec -= 1000000;
3282 			}
3283 		}
3284 
3285 		/* Set the timeout */
3286 		next_fsync.tv_sec = cur_tv.tv_sec;
3287 		next_fsync.tv_usec = cur_tv.tv_usec + min_ack_delay_usecs;
3288 		if (next_fsync.tv_usec >= 1000000) {
3289 			next_fsync.tv_sec++;
3290 			next_fsync.tv_usec -= 1000000;
3291 		}
3292 		/* but not more than the max */
3293 		if ((next_fsync.tv_sec > max_fsync.tv_sec) ||
3294 		    ((next_fsync.tv_sec == max_fsync.tv_sec) &&
3295 		     (next_fsync.tv_usec > max_fsync.tv_usec))) {
3296 			next_fsync.tv_sec = max_fsync.tv_sec;
3297 			next_fsync.tv_usec = max_fsync.tv_usec;
3298 		}
3299 
3300 		add_timeout(&next_fsync, commit_leases_ackout, NULL,
3301 			    (tvref_t) NULL, (tvunref_t) NULL);
3302 	}
3303 }
3304 
3305 static void
commit_leases_ackout(void * foo)3306 commit_leases_ackout(void *foo)
3307 {
3308 	if (outstanding_acks) {
3309 		commit_leases();
3310 
3311 		memset(&max_fsync, 0, sizeof(max_fsync));
3312 	}
3313 }
3314 
3315 /* CC: process the delayed ACK responses:
3316    - send out the ACK packets
3317    - move the queue slots to the free list
3318  */
3319 void
flush_ackqueue(void * foo)3320 flush_ackqueue(void *foo)
3321 {
3322 	struct leasequeue *ack, *p;
3323 	/*  process from bottom to retain packet order */
3324 	for (ack = ackqueue_tail ; ack ; ack = p) {
3325 		p = ack->prev;
3326 
3327 		/* dhcp_reply() requires that the reply state still be valid */
3328 		if (ack->lease->state == NULL)
3329 			log_error("delayed ack for %s has gone stale",
3330 				  piaddr(ack->lease->ip_addr));
3331 		else
3332 			dhcp_reply(ack->lease);
3333 
3334 		lease_dereference(&ack->lease, MDL);
3335 		ack->next = free_ackqueue;
3336 		free_ackqueue = ack;
3337 	}
3338 	ackqueue_head = NULL;
3339 	ackqueue_tail = NULL;
3340 	outstanding_acks = 0;
3341 }
3342 
3343 #if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
3344 void
relinquish_ackqueue(void)3345 relinquish_ackqueue(void)
3346 {
3347 	struct leasequeue *q, *n;
3348 
3349 	for (q = ackqueue_head ; q ; q = n) {
3350 		n = q->next;
3351 		dfree(q, MDL);
3352 	}
3353 	for (q = free_ackqueue ; q ; q = n) {
3354 		n = q->next;
3355 		dfree(q, MDL);
3356 	}
3357 }
3358 #endif
3359 
dhcp_reply(lease)3360 void dhcp_reply (lease)
3361 	struct lease *lease;
3362 {
3363 	int bufs = 0;
3364 	unsigned packet_length;
3365 	struct dhcp_packet raw;
3366 	struct sockaddr_in to;
3367 	struct in_addr from;
3368 	struct hardware hto;
3369 	int result;
3370 	struct lease_state *state = lease -> state;
3371 	int nulltp, bootpp, unicastp = 1;
3372 	struct data_string d1;
3373 	const char *s;
3374 
3375 	if (!state)
3376 		log_fatal ("dhcp_reply was supplied lease with no state!");
3377 
3378 	/* Compose a response for the client... */
3379 	memset (&raw, 0, sizeof raw);
3380 	memset (&d1, 0, sizeof d1);
3381 
3382 	/* Copy in the filename if given; otherwise, flag the filename
3383 	   buffer as available for options. */
3384 	if (state -> filename.len && state -> filename.data) {
3385 		memcpy (raw.file,
3386 			state -> filename.data,
3387 			state -> filename.len > sizeof raw.file
3388 			? sizeof raw.file : state -> filename.len);
3389 		if (sizeof raw.file > state -> filename.len)
3390 			memset (&raw.file [state -> filename.len], 0,
3391 				(sizeof raw.file) - state -> filename.len);
3392 		else
3393 			log_info("file name longer than packet field "
3394 				 "truncated - field: %lu name: %d %.*s",
3395 				 (unsigned long)sizeof(raw.file),
3396 				 state->filename.len, (int)state->filename.len,
3397 				 state->filename.data);
3398 	} else
3399 		bufs |= 1;
3400 
3401 	/* Copy in the server name if given; otherwise, flag the
3402 	   server_name buffer as available for options. */
3403 	if (state -> server_name.len && state -> server_name.data) {
3404 		memcpy (raw.sname,
3405 			state -> server_name.data,
3406 			state -> server_name.len > sizeof raw.sname
3407 			? sizeof raw.sname : state -> server_name.len);
3408 		if (sizeof raw.sname > state -> server_name.len)
3409 			memset (&raw.sname [state -> server_name.len], 0,
3410 				(sizeof raw.sname) - state -> server_name.len);
3411 		else
3412 			log_info("server name longer than packet field "
3413 				 "truncated - field: %lu name: %d %.*s",
3414 				 (unsigned long)sizeof(raw.sname),
3415 				 state->server_name.len,
3416 				 (int)state->server_name.len,
3417 				 state->server_name.data);
3418 	} else
3419 		bufs |= 2; /* XXX */
3420 
3421 	memcpy (raw.chaddr,
3422 		&lease -> hardware_addr.hbuf [1], sizeof raw.chaddr);
3423 	raw.hlen = lease -> hardware_addr.hlen - 1;
3424 	raw.htype = lease -> hardware_addr.hbuf [0];
3425 
3426 	/* See if this is a Microsoft client that NUL-terminates its
3427 	   strings and expects us to do likewise... */
3428 	if (lease -> flags & MS_NULL_TERMINATION)
3429 		nulltp = 1;
3430 	else
3431 		nulltp = 0;
3432 
3433 	/* See if this is a bootp client... */
3434 	if (state -> offer)
3435 		bootpp = 0;
3436 	else
3437 		bootpp = 1;
3438 
3439 	/* Insert such options as will fit into the buffer. */
3440 	packet_length = cons_options (state -> packet, &raw, lease,
3441 				      (struct client_state *)0,
3442 				      state -> max_message_size,
3443 				      state -> packet -> options,
3444 				      state -> options, &global_scope,
3445 				      bufs, nulltp, bootpp,
3446 				      &state -> parameter_request_list,
3447 				      (char *)0);
3448 
3449 	memcpy (&raw.ciaddr, &state -> ciaddr, sizeof raw.ciaddr);
3450 	memcpy (&raw.yiaddr, lease -> ip_addr.iabuf, 4);
3451 	raw.siaddr = state -> siaddr;
3452 	raw.giaddr = state -> giaddr;
3453 
3454 	raw.xid = state -> xid;
3455 	raw.secs = state -> secs;
3456 	raw.flags = state -> bootp_flags;
3457 	raw.hops = state -> hops;
3458 	raw.op = BOOTREPLY;
3459 
3460 	if (lease -> client_hostname) {
3461 		if ((strlen (lease -> client_hostname) <= 64) &&
3462 		    db_printable((unsigned char *)lease->client_hostname))
3463 			s = lease -> client_hostname;
3464 		else
3465 			s = "Hostname Unsuitable for Printing";
3466 	} else
3467 		s = (char *)0;
3468 
3469 	/* Say what we're doing... */
3470 	log_info ("%s on %s to %s %s%s%svia %s",
3471 		  (state -> offer
3472 		   ? (state -> offer == DHCPACK ? "DHCPACK" : "DHCPOFFER")
3473 		   : "BOOTREPLY"),
3474 		  piaddr (lease -> ip_addr),
3475 		  (lease -> hardware_addr.hlen
3476 		   ? print_hw_addr (lease -> hardware_addr.hbuf [0],
3477 				    lease -> hardware_addr.hlen - 1,
3478 				    &lease -> hardware_addr.hbuf [1])
3479 		   : print_hex_1(lease->uid_len, lease->uid, 60)),
3480 		  s ? "(" : "", s ? s : "", s ? ") " : "",
3481 		  (state -> giaddr.s_addr
3482 		   ? inet_ntoa (state -> giaddr)
3483 		   : state -> ip -> name));
3484 
3485 	/* Set up the hardware address... */
3486 	hto.hlen = lease -> hardware_addr.hlen;
3487 	memcpy (hto.hbuf, lease -> hardware_addr.hbuf, hto.hlen);
3488 
3489 	to.sin_family = AF_INET;
3490 #ifdef HAVE_SA_LEN
3491 	to.sin_len = sizeof to;
3492 #endif
3493 	memset (to.sin_zero, 0, sizeof to.sin_zero);
3494 
3495 #ifdef DEBUG_PACKET
3496 	dump_raw ((unsigned char *)&raw, packet_length);
3497 #endif
3498 
3499 	/* Make sure outgoing packets are at least as big
3500 	   as a BOOTP packet. */
3501 	if (packet_length < BOOTP_MIN_LEN)
3502 		packet_length = BOOTP_MIN_LEN;
3503 
3504 	/* If this was gatewayed, send it back to the gateway... */
3505 	if (raw.giaddr.s_addr) {
3506 		to.sin_addr = raw.giaddr;
3507 		if (raw.giaddr.s_addr != htonl (INADDR_LOOPBACK))
3508 			to.sin_port = local_port;
3509 		else
3510 			to.sin_port = remote_port; /* For debugging. */
3511 
3512 		if (fallback_interface) {
3513 			result = send_packet(fallback_interface, NULL, &raw,
3514 					     packet_length, raw.siaddr, &to,
3515 					     NULL);
3516 			if (result < 0) {
3517 				log_error ("%s:%d: Failed to send %d byte long "
3518 					   "packet over %s interface.", MDL,
3519 					   packet_length,
3520 					   fallback_interface->name);
3521 			}
3522 
3523 
3524 			free_lease_state (state, MDL);
3525 			lease -> state = (struct lease_state *)0;
3526 			return;
3527 		}
3528 
3529 	/* If the client is RENEWING, unicast to the client using the
3530 	   regular IP stack.  Some clients, particularly those that
3531 	   follow RFC1541, are buggy, and send both ciaddr and server
3532 	   identifier.  We deal with this situation by assuming that
3533 	   if we got both dhcp-server-identifier and ciaddr, and
3534 	   giaddr was not set, then the client is on the local
3535 	   network, and we can therefore unicast or broadcast to it
3536 	   successfully.  A client in REQUESTING state on another
3537 	   network that's making this mistake will have set giaddr,
3538 	   and will therefore get a relayed response from the above
3539 	   code. */
3540 	} else if (raw.ciaddr.s_addr &&
3541 		   !((state -> got_server_identifier ||
3542 		      (raw.flags & htons (BOOTP_BROADCAST))) &&
3543 		     /* XXX This won't work if giaddr isn't zero, but it is: */
3544 		     (state -> shared_network ==
3545 		      lease -> subnet -> shared_network)) &&
3546 		   state -> offer == DHCPACK) {
3547 		to.sin_addr = raw.ciaddr;
3548 		to.sin_port = remote_port;
3549 
3550 		if (fallback_interface) {
3551 			result = send_packet(fallback_interface, NULL, &raw,
3552 					     packet_length, raw.siaddr, &to,
3553 					     NULL);
3554 			if (result < 0) {
3555 				log_error("%s:%d: Failed to send %d byte long"
3556 					  " packet over %s interface.", MDL,
3557 					   packet_length,
3558 					   fallback_interface->name);
3559 			}
3560 
3561 			free_lease_state (state, MDL);
3562 			lease -> state = (struct lease_state *)0;
3563 			return;
3564 		}
3565 
3566 	/* If it comes from a client that already knows its address
3567 	   and is not requesting a broadcast response, and we can
3568 	   unicast to a client without using the ARP protocol, sent it
3569 	   directly to that client. */
3570 	} else if (!(raw.flags & htons (BOOTP_BROADCAST)) &&
3571 		   can_unicast_without_arp (state -> ip)) {
3572 		to.sin_addr = raw.yiaddr;
3573 		to.sin_port = remote_port;
3574 
3575 	/* Otherwise, broadcast it on the local network. */
3576 	} else {
3577 		to.sin_addr = limited_broadcast;
3578 		to.sin_port = remote_port;
3579 		if (!(lease -> flags & UNICAST_BROADCAST_HACK))
3580 			unicastp = 0;
3581 	}
3582 
3583 	memcpy (&from, state -> from.iabuf, sizeof from);
3584 
3585 	result = send_packet(state->ip, NULL, &raw, packet_length,
3586 			      from, &to, unicastp ? &hto : NULL);
3587 	if (result < 0) {
3588 	    log_error ("%s:%d: Failed to send %d byte long "
3589 		       "packet over %s interface.", MDL,
3590 		       packet_length, state->ip->name);
3591 	}
3592 
3593 
3594 	/* Free all of the entries in the option_state structure
3595 	   now that we're done with them. */
3596 
3597 	free_lease_state (state, MDL);
3598 	lease -> state = (struct lease_state *)0;
3599 }
3600 
find_lease(struct lease ** lp,struct packet * packet,struct shared_network * share,int * ours,int * peer_has_leases,struct lease * ip_lease_in,const char * file,int line)3601 int find_lease (struct lease **lp,
3602 		struct packet *packet, struct shared_network *share, int *ours,
3603 		int *peer_has_leases, struct lease *ip_lease_in,
3604 		const char *file, int line)
3605 {
3606 	struct lease *uid_lease = (struct lease *)0;
3607 	struct lease *ip_lease = (struct lease *)0;
3608 	struct lease *hw_lease = (struct lease *)0;
3609 	struct lease *lease = (struct lease *)0;
3610 	struct iaddr cip;
3611 	struct host_decl *hp = (struct host_decl *)0;
3612 	struct host_decl *host = (struct host_decl *)0;
3613 	struct lease *fixed_lease = (struct lease *)0;
3614 	struct lease *next = (struct lease *)0;
3615 	struct option_cache *oc;
3616 	struct data_string d1;
3617 	int have_client_identifier = 0;
3618 	struct data_string client_identifier;
3619 	struct hardware h;
3620 
3621 #if defined(FAILOVER_PROTOCOL)
3622 	/* Quick check to see if the peer has leases. */
3623 	if (peer_has_leases) {
3624 		struct pool *pool;
3625 
3626 		for (pool = share->pools ; pool ; pool = pool->next) {
3627 			dhcp_failover_state_t *peer = pool->failover_peer;
3628 
3629 			if (peer &&
3630 			    ((peer->i_am == primary && pool->backup_leases) ||
3631 			     (peer->i_am == secondary && pool->free_leases))) {
3632 				*peer_has_leases = 1;
3633 				break;
3634 			}
3635 		}
3636 	}
3637 #endif /* FAILOVER_PROTOCOL */
3638 
3639 	if (packet -> raw -> ciaddr.s_addr) {
3640 		cip.len = 4;
3641 		memcpy (cip.iabuf, &packet -> raw -> ciaddr, 4);
3642 	} else {
3643 		/* Look up the requested address. */
3644 		oc = lookup_option (&dhcp_universe, packet -> options,
3645 				    DHO_DHCP_REQUESTED_ADDRESS);
3646 		memset (&d1, 0, sizeof d1);
3647 		if (oc &&
3648 		    evaluate_option_cache (&d1, packet, (struct lease *)0,
3649 					   (struct client_state *)0,
3650 					   packet -> options,
3651 					   (struct option_state *)0,
3652 					   &global_scope, oc, MDL)) {
3653 			packet -> got_requested_address = 1;
3654 			cip.len = 4;
3655 			memcpy (cip.iabuf, d1.data, cip.len);
3656 			data_string_forget (&d1, MDL);
3657 		} else
3658 			cip.len = 0;
3659 	}
3660 
3661 	/* Try to find a host or lease that's been assigned to the
3662 	   specified unique client identifier. */
3663 	oc = lookup_option (&dhcp_universe, packet -> options,
3664 			    DHO_DHCP_CLIENT_IDENTIFIER);
3665 	memset (&client_identifier, 0, sizeof client_identifier);
3666 	if (oc &&
3667 	    evaluate_option_cache (&client_identifier,
3668 				   packet, (struct lease *)0,
3669 				   (struct client_state *)0,
3670 				   packet -> options, (struct option_state *)0,
3671 				   &global_scope, oc, MDL)) {
3672 		/* Remember this for later. */
3673 		have_client_identifier = 1;
3674 
3675 		/* First, try to find a fixed host entry for the specified
3676 		   client identifier... */
3677 		if (find_hosts_by_uid (&hp, client_identifier.data,
3678 				       client_identifier.len, MDL)) {
3679 			/* Remember if we know of this client. */
3680 			packet -> known = 1;
3681 			mockup_lease (&fixed_lease, packet, share, hp);
3682 		}
3683 
3684 #if defined (DEBUG_FIND_LEASE)
3685 		if (fixed_lease) {
3686 			log_info ("Found host for client identifier: %s.",
3687 			      piaddr (fixed_lease -> ip_addr));
3688 		}
3689 #endif
3690 		if (hp) {
3691 			if (!fixed_lease) /* Save the host if we found one. */
3692 				host_reference (&host, hp, MDL);
3693 			host_dereference (&hp, MDL);
3694 		}
3695 
3696 		find_lease_by_uid (&uid_lease, client_identifier.data,
3697 				   client_identifier.len, MDL);
3698 	}
3699 
3700 	/* If we didn't find a fixed lease using the uid, try doing
3701 	   it with the hardware address... */
3702 	if (!fixed_lease && !host) {
3703 		if (find_hosts_by_haddr (&hp, packet -> raw -> htype,
3704 					 packet -> raw -> chaddr,
3705 					 packet -> raw -> hlen, MDL)) {
3706 			/* Remember if we know of this client. */
3707 			packet -> known = 1;
3708 			if (host)
3709 				host_dereference (&host, MDL);
3710 			host_reference (&host, hp, MDL);
3711 			host_dereference (&hp, MDL);
3712 			mockup_lease (&fixed_lease, packet, share, host);
3713 #if defined (DEBUG_FIND_LEASE)
3714 			if (fixed_lease) {
3715 				log_info ("Found host for link address: %s.",
3716 				      piaddr (fixed_lease -> ip_addr));
3717 			}
3718 #endif
3719 		}
3720 	}
3721 
3722 	/* Finally, if we haven't found anything yet try again with the
3723 	 * host-identifier option ... */
3724 	if (!fixed_lease && !host) {
3725 		if (find_hosts_by_option(&hp, packet,
3726 					 packet->options, MDL) == 1) {
3727 			packet->known = 1;
3728 			if (host)
3729 				host_dereference(&host, MDL);
3730 			host_reference(&host, hp, MDL);
3731 			host_dereference(&hp, MDL);
3732 			mockup_lease (&fixed_lease, packet, share, host);
3733 #if defined (DEBUG_FIND_LEASE)
3734 			if (fixed_lease) {
3735 				log_info ("Found host via host-identifier");
3736 			}
3737 #endif
3738 		}
3739 	}
3740 
3741 	/* If fixed_lease is present but does not match the requested
3742 	   IP address, and this is a DHCPREQUEST, then we can't return
3743 	   any other lease, so we might as well return now. */
3744 	if (packet -> packet_type == DHCPREQUEST && fixed_lease &&
3745 	    (fixed_lease -> ip_addr.len != cip.len ||
3746 	     memcmp (fixed_lease -> ip_addr.iabuf,
3747 		     cip.iabuf, cip.len))) {
3748 		if (ours)
3749 			*ours = 1;
3750 		strcpy (dhcp_message, "requested address is incorrect");
3751 #if defined (DEBUG_FIND_LEASE)
3752 		log_info ("Client's fixed-address %s doesn't match %s%s",
3753 			  piaddr (fixed_lease -> ip_addr), "request ",
3754 			  print_dotted_quads (cip.len, cip.iabuf));
3755 #endif
3756 		goto out;
3757 	}
3758 
3759 	/*
3760 	 * If we found leases matching the client identifier, loop through
3761 	 * the n_uid pointer looking for one that's actually valid.   We
3762 	 * can't do this until we get here because we depend on
3763 	 * packet -> known, which may be set by either the uid host
3764 	 * lookup or the haddr host lookup.
3765 	 *
3766 	 * Note that the n_uid lease chain is sorted in order of
3767 	 * preference, so the first one is the best one.
3768 	 */
3769 	while (uid_lease) {
3770 #if defined (DEBUG_FIND_LEASE)
3771 		log_info ("trying next lease matching client id: %s",
3772 			  piaddr (uid_lease -> ip_addr));
3773 #endif
3774 
3775 #if defined (FAILOVER_PROTOCOL)
3776 		/*
3777 		 * When we lookup a lease by uid, we know the client identifier
3778 		 * matches the lease's record.  If it is active, or was last
3779 		 * active with the same client, we can trivially extend it.
3780 		 * If is not or was not active, we can allocate it to this
3781 		 * client if it matches the usual free/backup criteria (which
3782 		 * is contained in lease_mine_to_reallocate()).
3783 		 */
3784 		if (uid_lease->binding_state != FTS_ACTIVE &&
3785 		    uid_lease->rewind_binding_state != FTS_ACTIVE &&
3786 		    !lease_mine_to_reallocate(uid_lease)) {
3787 #if defined (DEBUG_FIND_LEASE)
3788 			log_info("not active or not mine to allocate: %s",
3789 				 piaddr(uid_lease->ip_addr));
3790 #endif
3791 			goto n_uid;
3792 		}
3793 #endif
3794 
3795 		if (uid_lease -> subnet -> shared_network != share) {
3796 #if defined (DEBUG_FIND_LEASE)
3797 			log_info ("wrong network segment: %s",
3798 				  piaddr (uid_lease -> ip_addr));
3799 #endif
3800 			goto n_uid;
3801 		}
3802 
3803 		if ((uid_lease -> pool -> prohibit_list &&
3804 		     permitted (packet, uid_lease -> pool -> prohibit_list)) ||
3805 		    (uid_lease -> pool -> permit_list &&
3806 		     !permitted (packet, uid_lease -> pool -> permit_list))) {
3807 #if defined (DEBUG_FIND_LEASE)
3808 			log_info ("not permitted: %s",
3809 				  piaddr (uid_lease -> ip_addr));
3810 #endif
3811 		       n_uid:
3812 			if (uid_lease -> n_uid)
3813 				lease_reference (&next,
3814 						 uid_lease -> n_uid, MDL);
3815 			if (!packet -> raw -> ciaddr.s_addr)
3816 				release_lease (uid_lease, packet);
3817 			lease_dereference (&uid_lease, MDL);
3818 			if (next) {
3819 				lease_reference (&uid_lease, next, MDL);
3820 				lease_dereference (&next, MDL);
3821 			}
3822 			continue;
3823 		}
3824 		break;
3825 	}
3826 #if defined (DEBUG_FIND_LEASE)
3827 	if (uid_lease)
3828 		log_info ("Found lease for client id: %s.",
3829 		      piaddr (uid_lease -> ip_addr));
3830 #endif
3831 
3832 	/* Find a lease whose hardware address matches, whose client
3833 	 * identifier matches (or equally doesn't have one), that's
3834 	 * permitted, and that's on the correct subnet.
3835 	 *
3836 	 * Note that the n_hw chain is sorted in order of preference, so
3837 	 * the first one found is the best one.
3838 	 */
3839 	h.hlen = packet -> raw -> hlen + 1;
3840 	h.hbuf [0] = packet -> raw -> htype;
3841 	memcpy (&h.hbuf [1], packet -> raw -> chaddr, packet -> raw -> hlen);
3842 	find_lease_by_hw_addr (&hw_lease, h.hbuf, h.hlen, MDL);
3843 	while (hw_lease) {
3844 #if defined (DEBUG_FIND_LEASE)
3845 		log_info ("trying next lease matching hw addr: %s",
3846 			  piaddr (hw_lease -> ip_addr));
3847 #endif
3848 #if defined (FAILOVER_PROTOCOL)
3849 		/*
3850 		 * When we lookup a lease by chaddr, we know the MAC address
3851 		 * matches the lease record (we will check if the lease has a
3852 		 * client-id the client does not next).  If the lease is
3853 		 * currently active or was last active with this client, we can
3854 		 * trivially extend it.  Otherwise, there are a set of rules
3855 		 * that govern if we can reallocate this lease to any client
3856 		 * ("lease_mine_to_reallocate()") including this one.
3857 		 */
3858 		if (hw_lease->binding_state != FTS_ACTIVE &&
3859 		    hw_lease->rewind_binding_state != FTS_ACTIVE &&
3860 		    !lease_mine_to_reallocate(hw_lease)) {
3861 #if defined (DEBUG_FIND_LEASE)
3862 			log_info("not active or not mine to allocate: %s",
3863 				 piaddr(hw_lease->ip_addr));
3864 #endif
3865 			goto n_hw;
3866 		}
3867 #endif
3868 
3869 		/*
3870 		 * This conditional skips "potentially active" leases (leases
3871 		 * we think are expired may be extended by the peer, etc) that
3872 		 * may be assigned to a differently /client-identified/ client
3873 		 * with the same MAC address.
3874 		 */
3875 		if (hw_lease -> binding_state != FTS_FREE &&
3876 		    hw_lease -> binding_state != FTS_BACKUP &&
3877 		    hw_lease -> uid &&
3878 		    (!have_client_identifier ||
3879 		     hw_lease -> uid_len != client_identifier.len ||
3880 		     memcmp (hw_lease -> uid, client_identifier.data,
3881 			     hw_lease -> uid_len))) {
3882 #if defined (DEBUG_FIND_LEASE)
3883 			log_info ("wrong client identifier: %s",
3884 				  piaddr (hw_lease -> ip_addr));
3885 #endif
3886 			goto n_hw;
3887 		}
3888 		if (hw_lease -> subnet -> shared_network != share) {
3889 #if defined (DEBUG_FIND_LEASE)
3890 			log_info ("wrong network segment: %s",
3891 				  piaddr (hw_lease -> ip_addr));
3892 #endif
3893 			goto n_hw;
3894 		}
3895 		if ((hw_lease -> pool -> prohibit_list &&
3896 		      permitted (packet, hw_lease -> pool -> prohibit_list)) ||
3897 		    (hw_lease -> pool -> permit_list &&
3898 		     !permitted (packet, hw_lease -> pool -> permit_list))) {
3899 #if defined (DEBUG_FIND_LEASE)
3900 			log_info ("not permitted: %s",
3901 				  piaddr (hw_lease -> ip_addr));
3902 #endif
3903 			if (!packet -> raw -> ciaddr.s_addr)
3904 				release_lease (hw_lease, packet);
3905 		       n_hw:
3906 			if (hw_lease -> n_hw)
3907 				lease_reference (&next, hw_lease -> n_hw, MDL);
3908 			lease_dereference (&hw_lease, MDL);
3909 			if (next) {
3910 				lease_reference (&hw_lease, next, MDL);
3911 				lease_dereference (&next, MDL);
3912 			}
3913 			continue;
3914 		}
3915 		break;
3916 	}
3917 #if defined (DEBUG_FIND_LEASE)
3918 	if (hw_lease)
3919 		log_info ("Found lease for hardware address: %s.",
3920 		      piaddr (hw_lease -> ip_addr));
3921 #endif
3922 
3923 	/* Try to find a lease that's been allocated to the client's
3924 	   IP address. */
3925 	if (ip_lease_in)
3926 		lease_reference (&ip_lease, ip_lease_in, MDL);
3927 	else if (cip.len)
3928 		find_lease_by_ip_addr (&ip_lease, cip, MDL);
3929 
3930 #if defined (DEBUG_FIND_LEASE)
3931 	if (ip_lease)
3932 		log_info ("Found lease for requested address: %s.",
3933 		      piaddr (ip_lease -> ip_addr));
3934 #endif
3935 
3936 	/* If ip_lease is valid at this point, set ours to one, so that
3937 	   even if we choose a different lease, we know that the address
3938 	   the client was requesting was ours, and thus we can NAK it. */
3939 	if (ip_lease && ours)
3940 		*ours = 1;
3941 
3942 	/* If the requested IP address isn't on the network the packet
3943 	   came from, don't use it.  Allow abandoned leases to be matched
3944 	   here - if the client is requesting it, there's a decent chance
3945 	   that it's because the lease database got trashed and a client
3946 	   that thought it had this lease answered an ARP or PING, causing the
3947 	   lease to be abandoned.   If so, this request probably came from
3948 	   that client. */
3949 	if (ip_lease && (ip_lease -> subnet -> shared_network != share)) {
3950 		if (ours)
3951 			*ours = 1;
3952 #if defined (DEBUG_FIND_LEASE)
3953 		log_info ("...but it was on the wrong shared network.");
3954 #endif
3955 		strcpy (dhcp_message, "requested address on bad subnet");
3956 		lease_dereference (&ip_lease, MDL);
3957 	}
3958 
3959 	/*
3960 	 * If the requested address is in use (or potentially in use) by
3961 	 * a different client, it can't be granted.
3962 	 *
3963 	 * This first conditional only detects if the lease is currently
3964 	 * identified to a different client (client-id and/or chaddr
3965 	 * mismatch).  In this case we may not want to give the client the
3966 	 * lease, if doing so may potentially be an addressing conflict.
3967 	 */
3968 	if (ip_lease &&
3969 	    (ip_lease -> uid ?
3970 	     (!have_client_identifier ||
3971 	      ip_lease -> uid_len != client_identifier.len ||
3972 	      memcmp (ip_lease -> uid, client_identifier.data,
3973 		      ip_lease -> uid_len)) :
3974 	     (ip_lease -> hardware_addr.hbuf [0] != packet -> raw -> htype ||
3975 	      ip_lease -> hardware_addr.hlen != packet -> raw -> hlen + 1 ||
3976 	      memcmp (&ip_lease -> hardware_addr.hbuf [1],
3977 		      packet -> raw -> chaddr,
3978 		      (unsigned)(ip_lease -> hardware_addr.hlen - 1))))) {
3979 		/*
3980 		 * A lease is unavailable for allocation to a new client if
3981 		 * it is not in the FREE or BACKUP state.  There may be
3982 		 * leases that are in the expired state with a rewinding
3983 		 * state that is free or backup, but these will be processed
3984 		 * into the free or backup states by expiration processes, so
3985 		 * checking for them here is superfluous.
3986 		 */
3987 		if (ip_lease -> binding_state != FTS_FREE &&
3988 		    ip_lease -> binding_state != FTS_BACKUP) {
3989 #if defined (DEBUG_FIND_LEASE)
3990 			log_info ("rejecting lease for requested address.");
3991 #endif
3992 			/* If we're rejecting it because the peer has
3993 			   it, don't set "ours", because we shouldn't NAK. */
3994 			if (ours && ip_lease -> binding_state != FTS_ACTIVE)
3995 				*ours = 0;
3996 			lease_dereference (&ip_lease, MDL);
3997 		}
3998 	}
3999 
4000 	/*
4001 	 * If we got an ip_lease and a uid_lease or hw_lease, and ip_lease
4002 	 * is/was not active, and is not ours to reallocate, forget about it.
4003 	 */
4004 	if (ip_lease && (uid_lease || hw_lease) &&
4005 	    ip_lease->binding_state != FTS_ACTIVE &&
4006 	    ip_lease->rewind_binding_state != FTS_ACTIVE &&
4007 #if defined(FAILOVER_PROTOCOL)
4008 	    !lease_mine_to_reallocate(ip_lease) &&
4009 #endif
4010 	    packet->packet_type == DHCPDISCOVER) {
4011 #if defined (DEBUG_FIND_LEASE)
4012 		log_info("ip lease not active or not ours to offer.");
4013 #endif
4014 		lease_dereference(&ip_lease, MDL);
4015 	}
4016 
4017 	/* If for some reason the client has more than one lease
4018 	   on the subnet that matches its uid, pick the one that
4019 	   it asked for and (if we can) free the other. */
4020 	if (ip_lease && ip_lease->binding_state == FTS_ACTIVE &&
4021 	    ip_lease->uid && ip_lease != uid_lease) {
4022 		if (have_client_identifier &&
4023 		    (ip_lease -> uid_len == client_identifier.len) &&
4024 		    !memcmp (client_identifier.data,
4025 			     ip_lease -> uid, ip_lease -> uid_len)) {
4026 			if (uid_lease) {
4027 			    if (uid_lease->binding_state == FTS_ACTIVE) {
4028 				log_error ("client %s has duplicate%s on %s",
4029 					   (print_hw_addr
4030 					    (packet -> raw -> htype,
4031 					     packet -> raw -> hlen,
4032 					     packet -> raw -> chaddr)),
4033 					   " leases",
4034 					   (ip_lease -> subnet ->
4035 					    shared_network -> name));
4036 
4037 				/* If the client is REQUESTing the lease,
4038 				   it shouldn't still be using the old
4039 				   one, so we can free it for allocation. */
4040 				if (uid_lease &&
4041 				    uid_lease->binding_state == FTS_ACTIVE &&
4042 				    !packet -> raw -> ciaddr.s_addr &&
4043 				    (share ==
4044 				     uid_lease -> subnet -> shared_network) &&
4045 				    packet -> packet_type == DHCPREQUEST)
4046 					release_lease (uid_lease, packet);
4047 			    }
4048 			    lease_dereference (&uid_lease, MDL);
4049 			    lease_reference (&uid_lease, ip_lease, MDL);
4050 			}
4051 		}
4052 
4053 		/* If we get to here and fixed_lease is not null, that means
4054 		   that there are both a dynamic lease and a fixed-address
4055 		   declaration for the same IP address. */
4056 		if (packet -> packet_type == DHCPREQUEST && fixed_lease) {
4057 			lease_dereference (&fixed_lease, MDL);
4058 		      db_conflict:
4059 			log_error ("Dynamic and static leases present for %s.",
4060 				   piaddr (cip));
4061 			log_error ("Remove host declaration %s or remove %s",
4062 				   (fixed_lease && fixed_lease -> host
4063 				    ? (fixed_lease -> host -> name
4064 				       ? fixed_lease -> host -> name
4065 				       : piaddr (cip))
4066 				    : piaddr (cip)),
4067 				    piaddr (cip));
4068 			log_error ("from the dynamic address pool for %s",
4069 				   ip_lease -> subnet -> shared_network -> name
4070 				  );
4071 			if (fixed_lease)
4072 				lease_dereference (&ip_lease, MDL);
4073 			strcpy (dhcp_message,
4074 				"database conflict - call for help!");
4075 		}
4076 
4077 		if (ip_lease && ip_lease != uid_lease) {
4078 #if defined (DEBUG_FIND_LEASE)
4079 			log_info ("requested address not available.");
4080 #endif
4081 			lease_dereference (&ip_lease, MDL);
4082 		}
4083 	}
4084 
4085 	/* If we get to here with both fixed_lease and ip_lease not
4086 	   null, then we have a configuration file bug. */
4087 	if (packet -> packet_type == DHCPREQUEST && fixed_lease && ip_lease)
4088 		goto db_conflict;
4089 
4090 	/* Toss extra pointers to the same lease... */
4091 	if (hw_lease && hw_lease == uid_lease) {
4092 #if defined (DEBUG_FIND_LEASE)
4093 		log_info ("hardware lease and uid lease are identical.");
4094 #endif
4095 		lease_dereference (&hw_lease, MDL);
4096 	}
4097 	if (ip_lease && ip_lease == hw_lease) {
4098 		lease_dereference (&hw_lease, MDL);
4099 #if defined (DEBUG_FIND_LEASE)
4100 		log_info ("hardware lease and ip lease are identical.");
4101 #endif
4102 	}
4103 	if (ip_lease && ip_lease == uid_lease) {
4104 		lease_dereference (&uid_lease, MDL);
4105 #if defined (DEBUG_FIND_LEASE)
4106 		log_info ("uid lease and ip lease are identical.");
4107 #endif
4108 	}
4109 
4110 	/* Make sure the client is permitted to use the requested lease. */
4111 	if (ip_lease &&
4112 	    ((ip_lease -> pool -> prohibit_list &&
4113 	      permitted (packet, ip_lease -> pool -> prohibit_list)) ||
4114 	     (ip_lease -> pool -> permit_list &&
4115 	      !permitted (packet, ip_lease -> pool -> permit_list)))) {
4116 		if (!packet->raw->ciaddr.s_addr &&
4117 		    (ip_lease->binding_state == FTS_ACTIVE))
4118 			release_lease (ip_lease, packet);
4119 
4120 		lease_dereference (&ip_lease, MDL);
4121 	}
4122 
4123 	if (uid_lease &&
4124 	    ((uid_lease -> pool -> prohibit_list &&
4125 	      permitted (packet, uid_lease -> pool -> prohibit_list)) ||
4126 	     (uid_lease -> pool -> permit_list &&
4127 	      !permitted (packet, uid_lease -> pool -> permit_list)))) {
4128 		if (!packet -> raw -> ciaddr.s_addr)
4129 			release_lease (uid_lease, packet);
4130 		lease_dereference (&uid_lease, MDL);
4131 	}
4132 
4133 	if (hw_lease &&
4134 	    ((hw_lease -> pool -> prohibit_list &&
4135 	      permitted (packet, hw_lease -> pool -> prohibit_list)) ||
4136 	     (hw_lease -> pool -> permit_list &&
4137 	      !permitted (packet, hw_lease -> pool -> permit_list)))) {
4138 		if (!packet -> raw -> ciaddr.s_addr)
4139 			release_lease (hw_lease, packet);
4140 		lease_dereference (&hw_lease, MDL);
4141 	}
4142 
4143 	/* If we've already eliminated the lease, it wasn't there to
4144 	   begin with.   If we have come up with a matching lease,
4145 	   set the message to bad network in case we have to throw it out. */
4146 	if (!ip_lease) {
4147 		strcpy (dhcp_message, "requested address not available");
4148 	}
4149 
4150 	/* If this is a DHCPREQUEST, make sure the lease we're going to return
4151 	   matches the requested IP address.   If it doesn't, don't return a
4152 	   lease at all. */
4153 	if (packet -> packet_type == DHCPREQUEST &&
4154 	    !ip_lease && !fixed_lease) {
4155 #if defined (DEBUG_FIND_LEASE)
4156 		log_info ("no applicable lease found for DHCPREQUEST.");
4157 #endif
4158 		goto out;
4159 	}
4160 
4161 	/* At this point, if fixed_lease is nonzero, we can assign it to
4162 	   this client. */
4163 	if (fixed_lease) {
4164 		lease_reference (&lease, fixed_lease, MDL);
4165 		lease_dereference (&fixed_lease, MDL);
4166 #if defined (DEBUG_FIND_LEASE)
4167 		log_info ("choosing fixed address.");
4168 #endif
4169 	}
4170 
4171 	/* If we got a lease that matched the ip address and don't have
4172 	   a better offer, use that; otherwise, release it. */
4173 	if (ip_lease) {
4174 		if (lease) {
4175 			if (!packet -> raw -> ciaddr.s_addr)
4176 				release_lease (ip_lease, packet);
4177 #if defined (DEBUG_FIND_LEASE)
4178 			log_info ("not choosing requested address (!).");
4179 #endif
4180 		} else {
4181 #if defined (DEBUG_FIND_LEASE)
4182 			log_info ("choosing lease on requested address.");
4183 #endif
4184 			lease_reference (&lease, ip_lease, MDL);
4185 			if (lease -> host)
4186 				host_dereference (&lease -> host, MDL);
4187 		}
4188 		lease_dereference (&ip_lease, MDL);
4189 	}
4190 
4191 	/* If we got a lease that matched the client identifier, we may want
4192 	   to use it, but if we already have a lease we like, we must free
4193 	   the lease that matched the client identifier. */
4194 	if (uid_lease) {
4195 		if (lease) {
4196 			log_error("uid lease %s for client %s is duplicate "
4197 				  "on %s",
4198 				  piaddr(uid_lease->ip_addr),
4199 				  print_hw_addr(packet->raw->htype,
4200 						packet->raw->hlen,
4201 						packet->raw->chaddr),
4202 				  uid_lease->subnet->shared_network->name);
4203 
4204 			if (!packet -> raw -> ciaddr.s_addr &&
4205 			    packet -> packet_type == DHCPREQUEST &&
4206 			    uid_lease -> binding_state == FTS_ACTIVE)
4207 				release_lease(uid_lease, packet);
4208 #if defined (DEBUG_FIND_LEASE)
4209 			log_info ("not choosing uid lease.");
4210 #endif
4211 		} else {
4212 			lease_reference (&lease, uid_lease, MDL);
4213 			if (lease -> host)
4214 				host_dereference (&lease -> host, MDL);
4215 #if defined (DEBUG_FIND_LEASE)
4216 			log_info ("choosing uid lease.");
4217 #endif
4218 		}
4219 		lease_dereference (&uid_lease, MDL);
4220 	}
4221 
4222 	/* The lease that matched the hardware address is treated likewise. */
4223 	if (hw_lease) {
4224 		if (lease) {
4225 #if defined (DEBUG_FIND_LEASE)
4226 			log_info ("not choosing hardware lease.");
4227 #endif
4228 		} else {
4229 			/* We're a little lax here - if the client didn't
4230 			   send a client identifier and it's a bootp client,
4231 			   but the lease has a client identifier, we still
4232 			   let the client have a lease. */
4233 			if (!hw_lease -> uid_len ||
4234 			    (have_client_identifier
4235 			     ? (hw_lease -> uid_len ==
4236 				client_identifier.len &&
4237 				!memcmp (hw_lease -> uid,
4238 					 client_identifier.data,
4239 					 client_identifier.len))
4240 			     : packet -> packet_type == 0)) {
4241 				lease_reference (&lease, hw_lease, MDL);
4242 				if (lease -> host)
4243 					host_dereference (&lease -> host, MDL);
4244 #if defined (DEBUG_FIND_LEASE)
4245 				log_info ("choosing hardware lease.");
4246 #endif
4247 			} else {
4248 #if defined (DEBUG_FIND_LEASE)
4249 				log_info ("not choosing hardware lease: %s.",
4250 					  "uid mismatch");
4251 #endif
4252 			}
4253 		}
4254 		lease_dereference (&hw_lease, MDL);
4255 	}
4256 
4257 	/*
4258 	 * If we found a host_decl but no matching address, try to
4259 	 * find a host_decl that has no address, and if there is one,
4260 	 * hang it off the lease so that we can use the supplied
4261 	 * options.
4262 	 */
4263 	if (lease && host && !lease->host) {
4264 		struct host_decl *p = NULL;
4265 		struct host_decl *n = NULL;
4266 
4267 		host_reference(&p, host, MDL);
4268 		while (p != NULL) {
4269 			if (!p->fixed_addr) {
4270 				/*
4271 				 * If the lease is currently active, then it
4272 				 * must be allocated to the present client.
4273 				 * We store a reference to the host record on
4274 				 * the lease to save a lookup later (in
4275 				 * ack_lease()).  We mustn't refer to the host
4276 				 * record on non-active leases because the
4277 				 * client may be denied later.
4278 				 *
4279 				 * XXX: Not having this reference (such as in
4280 				 * DHCPDISCOVER/INIT) means ack_lease will have
4281 				 * to perform this lookup a second time.  This
4282 				 * hopefully isn't a problem as DHCPREQUEST is
4283 				 * more common than DHCPDISCOVER.
4284 				 */
4285 				if (lease->binding_state == FTS_ACTIVE)
4286 					host_reference(&lease->host, p, MDL);
4287 
4288 				host_dereference(&p, MDL);
4289 				break;
4290 			}
4291 			if (p->n_ipaddr != NULL)
4292 				host_reference(&n, p->n_ipaddr, MDL);
4293 			host_dereference(&p, MDL);
4294 			if (n != NULL) {
4295 				host_reference(&p, n, MDL);
4296 				host_dereference(&n, MDL);
4297 			}
4298 		}
4299 	}
4300 
4301 	/* If we find an abandoned lease, but it's the one the client
4302 	   requested, we assume that previous bugginess on the part
4303 	   of the client, or a server database loss, caused the lease to
4304 	   be abandoned, so we reclaim it and let the client have it. */
4305 	if (lease &&
4306 	    (lease -> binding_state == FTS_ABANDONED) &&
4307 	    lease == ip_lease &&
4308 	    packet -> packet_type == DHCPREQUEST) {
4309 		log_error ("Reclaiming REQUESTed abandoned IP address %s.",
4310 		      piaddr (lease -> ip_addr));
4311 	} else if (lease && (lease -> binding_state == FTS_ABANDONED)) {
4312 	/* Otherwise, if it's not the one the client requested, we do not
4313 	   return it - instead, we claim it's ours, causing a DHCPNAK to be
4314 	   sent if this lookup is for a DHCPREQUEST, and force the client
4315 	   to go back through the allocation process. */
4316 		if (ours)
4317 			*ours = 1;
4318 		lease_dereference (&lease, MDL);
4319 	}
4320 
4321       out:
4322 	if (have_client_identifier)
4323 		data_string_forget (&client_identifier, MDL);
4324 
4325 	if (fixed_lease)
4326 		lease_dereference (&fixed_lease, MDL);
4327 	if (hw_lease)
4328 		lease_dereference (&hw_lease, MDL);
4329 	if (uid_lease)
4330 		lease_dereference (&uid_lease, MDL);
4331 	if (ip_lease)
4332 		lease_dereference (&ip_lease, MDL);
4333 	if (host)
4334 		host_dereference (&host, MDL);
4335 
4336 	if (lease) {
4337 #if defined (DEBUG_FIND_LEASE)
4338 		log_info ("Returning lease: %s.",
4339 		      piaddr (lease -> ip_addr));
4340 #endif
4341 		lease_reference (lp, lease, file, line);
4342 		lease_dereference (&lease, MDL);
4343 		return 1;
4344 	}
4345 #if defined (DEBUG_FIND_LEASE)
4346 	log_info ("Not returning a lease.");
4347 #endif
4348 	return 0;
4349 }
4350 
4351 /* Search the provided host_decl structure list for an address that's on
4352    the specified shared network.  If one is found, mock up and return a
4353    lease structure for it; otherwise return the null pointer. */
4354 
mockup_lease(struct lease ** lp,struct packet * packet,struct shared_network * share,struct host_decl * hp)4355 int mockup_lease (struct lease **lp, struct packet *packet,
4356 		  struct shared_network *share, struct host_decl *hp)
4357 {
4358 	struct lease *lease = (struct lease *)0;
4359 	struct host_decl *rhp = (struct host_decl *)0;
4360 
4361 	if (lease_allocate (&lease, MDL) != ISC_R_SUCCESS)
4362 		return 0;
4363 	if (host_reference (&rhp, hp, MDL) != ISC_R_SUCCESS) {
4364 		lease_dereference (&lease, MDL);
4365 		return 0;
4366 	}
4367 	if (!find_host_for_network (&lease -> subnet,
4368 				    &rhp, &lease -> ip_addr, share)) {
4369 		lease_dereference (&lease, MDL);
4370 		host_dereference (&rhp, MDL);
4371 		return 0;
4372 	}
4373 	host_reference (&lease -> host, rhp, MDL);
4374 	if (rhp -> client_identifier.len > sizeof lease -> uid_buf)
4375 		lease -> uid = dmalloc (rhp -> client_identifier.len, MDL);
4376 	else
4377 		lease -> uid = lease -> uid_buf;
4378 	if (!lease -> uid) {
4379 		lease_dereference (&lease, MDL);
4380 		host_dereference (&rhp, MDL);
4381 		return 0;
4382 	}
4383 	memcpy (lease -> uid, rhp -> client_identifier.data,
4384 		rhp -> client_identifier.len);
4385 	lease -> uid_len = rhp -> client_identifier.len;
4386 	lease -> hardware_addr = rhp -> interface;
4387 	lease -> starts = lease -> cltt = lease -> ends = MIN_TIME;
4388 	lease -> flags = STATIC_LEASE;
4389 	lease -> binding_state = FTS_FREE;
4390 
4391 	lease_reference (lp, lease, MDL);
4392 
4393 	lease_dereference (&lease, MDL);
4394 	host_dereference (&rhp, MDL);
4395 	return 1;
4396 }
4397 
4398 /* Look through all the pools in a list starting with the specified pool
4399    for a free lease.   We try to find a virgin lease if we can.   If we
4400    don't find a virgin lease, we try to find a non-virgin lease that's
4401    free.   If we can't find one of those, we try to reclaim an abandoned
4402    lease.   If all of these possibilities fail to pan out, we don't return
4403    a lease at all. */
4404 
allocate_lease(struct lease ** lp,struct packet * packet,struct pool * pool,int * peer_has_leases)4405 int allocate_lease (struct lease **lp, struct packet *packet,
4406 		    struct pool *pool, int *peer_has_leases)
4407 {
4408 	struct lease *lease = (struct lease *)0;
4409 	struct lease *candl = (struct lease *)0;
4410 
4411 	for (; pool ; pool = pool -> next) {
4412 		if ((pool -> prohibit_list &&
4413 		     permitted (packet, pool -> prohibit_list)) ||
4414 		    (pool -> permit_list &&
4415 		     !permitted (packet, pool -> permit_list)))
4416 			continue;
4417 
4418 #if defined (FAILOVER_PROTOCOL)
4419 		/* Peer_has_leases just says that we found at least one
4420 		   free lease.  If no free lease is returned, the caller
4421 		   can deduce that this means the peer is hogging all the
4422 		   free leases, so we can print a better error message. */
4423 		/* XXX Do we need code here to ignore PEER_IS_OWNER and
4424 		 * XXX just check tstp if we're in, e.g., PARTNER_DOWN?
4425 		 * XXX Where do we deal with CONFLICT_DETECTED, et al? */
4426 		/* XXX This should be handled by the lease binding "state
4427 		 * XXX machine" - that is, when we get here, if a lease
4428 		 * XXX could be allocated, it will have the correct
4429 		 * XXX binding state so that the following code will
4430 		 * XXX result in its being allocated. */
4431 		/* Skip to the most expired lease in the pool that is not
4432 		 * owned by a failover peer. */
4433 		if (pool->failover_peer != NULL) {
4434 			if (pool->failover_peer->i_am == primary) {
4435 				candl = pool->free;
4436 
4437 				/*
4438 				 * In normal operation, we never want to touch
4439 				 * the peer's leases.  In partner-down
4440 				 * operation, we need to be able to pick up
4441 				 * the peer's leases after STOS+MCLT.
4442 				 */
4443 				if (pool->backup != NULL) {
4444 					if (((candl == NULL) ||
4445 					     (candl->ends >
4446 					      pool->backup->ends)) &&
4447 					    lease_mine_to_reallocate(
4448 							    pool->backup)) {
4449 						candl = pool->backup;
4450 					} else {
4451 						*peer_has_leases = 1;
4452 					}
4453 				}
4454 			} else {
4455 				candl = pool->backup;
4456 
4457 				if (pool->free != NULL) {
4458 					if (((candl == NULL) ||
4459 					     (candl->ends >
4460 					      pool->free->ends)) &&
4461 					    lease_mine_to_reallocate(
4462 							    pool->free)) {
4463 						candl = pool->free;
4464 					} else {
4465 						*peer_has_leases = 1;
4466 					}
4467 				}
4468 			}
4469 
4470 			/* Try abandoned leases as a last resort. */
4471 			if ((candl == NULL) &&
4472 			    (pool->abandoned != NULL) &&
4473 			    lease_mine_to_reallocate(pool->abandoned))
4474 				candl = pool->abandoned;
4475 		} else
4476 #endif
4477 		{
4478 			if (pool -> free)
4479 				candl = pool -> free;
4480 			else
4481 				candl = pool -> abandoned;
4482 		}
4483 
4484 		/*
4485 		 * XXX: This may not match with documented expectation.
4486 		 * It's expected that when we OFFER a lease, we set its
4487 		 * ends time forward 2 minutes so that it gets sorted to
4488 		 * the end of its free list (avoiding a similar allocation
4489 		 * to another client).  It is not expected that we issue a
4490 		 * "no free leases" error when the last lease has been
4491 		 * offered, but it's not exactly broken either.
4492 		 */
4493 		if (!candl || (candl -> ends > cur_time))
4494 			continue;
4495 
4496 		if (!lease) {
4497 			lease = candl;
4498 			continue;
4499 		}
4500 
4501 		/*
4502 		 * There are tiers of lease state preference, listed here in
4503 		 * reverse order (least to most preferential):
4504 		 *
4505 		 *    ABANDONED
4506 		 *    FREE/BACKUP
4507 		 *
4508 		 * If the selected lease and candidate are both of the same
4509 		 * state, select the oldest (longest ago) expiration time
4510 		 * between the two.  If the candidate lease is of a higher
4511 		 * preferred grade over the selected lease, use it.
4512 		 */
4513 		if ((lease -> binding_state == FTS_ABANDONED) &&
4514 		    ((candl -> binding_state != FTS_ABANDONED) ||
4515 		     (candl -> ends < lease -> ends))) {
4516 			lease = candl;
4517 			continue;
4518 		} else if (candl -> binding_state == FTS_ABANDONED)
4519 			continue;
4520 
4521 		if ((lease -> uid_len || lease -> hardware_addr.hlen) &&
4522 		    ((!candl -> uid_len && !candl -> hardware_addr.hlen) ||
4523 		     (candl -> ends < lease -> ends))) {
4524 			lease = candl;
4525 			continue;
4526 		} else if (candl -> uid_len || candl -> hardware_addr.hlen)
4527 			continue;
4528 
4529 		if (candl -> ends < lease -> ends)
4530 			lease = candl;
4531 	}
4532 
4533 	if (lease != NULL) {
4534 		if (lease->binding_state == FTS_ABANDONED)
4535 			log_error("Reclaiming abandoned lease %s.",
4536 				  piaddr(lease->ip_addr));
4537 
4538 		/*
4539 		 * XXX: For reliability, we go ahead and remove the host
4540 		 * record and try to move on.  For correctness, if there
4541 		 * are any other stale host vectors, we want to find them.
4542 		 */
4543 		if (lease->host != NULL) {
4544 			log_debug("soft impossible condition (%s:%d): stale "
4545 				  "host \"%s\" found on lease %s", MDL,
4546 				  lease->host->name,
4547 				  piaddr(lease->ip_addr));
4548 			host_dereference(&lease->host, MDL);
4549 		}
4550 
4551 		lease_reference (lp, lease, MDL);
4552 		return 1;
4553 	}
4554 
4555 	return 0;
4556 }
4557 
4558 /* Determine whether or not a permit exists on a particular permit list
4559    that matches the specified packet, returning nonzero if so, zero if
4560    not. */
4561 
permitted(packet,permit_list)4562 int permitted (packet, permit_list)
4563 	struct packet *packet;
4564 	struct permit *permit_list;
4565 {
4566 	struct permit *p;
4567 	int i;
4568 
4569 	for (p = permit_list; p; p = p -> next) {
4570 		switch (p -> type) {
4571 		      case permit_unknown_clients:
4572 			if (!packet -> known)
4573 				return 1;
4574 			break;
4575 
4576 		      case permit_known_clients:
4577 			if (packet -> known)
4578 				return 1;
4579 			break;
4580 
4581 		      case permit_authenticated_clients:
4582 			if (packet -> authenticated)
4583 				return 1;
4584 			break;
4585 
4586 		      case permit_unauthenticated_clients:
4587 			if (!packet -> authenticated)
4588 				return 1;
4589 			break;
4590 
4591 		      case permit_all_clients:
4592 			return 1;
4593 
4594 		      case permit_dynamic_bootp_clients:
4595 			if (!packet -> options_valid ||
4596 			    !packet -> packet_type)
4597 				return 1;
4598 			break;
4599 
4600 		      case permit_class:
4601 			for (i = 0; i < packet -> class_count; i++) {
4602 				if (p -> class == packet -> classes [i])
4603 					return 1;
4604 				if (packet -> classes [i] &&
4605 				    packet -> classes [i] -> superclass &&
4606 				    (packet -> classes [i] -> superclass ==
4607 				     p -> class))
4608 					return 1;
4609 			}
4610 			break;
4611 
4612 		      case permit_after:
4613 			if (cur_time > p->after)
4614 				return 1;
4615 			break;
4616 		}
4617 	}
4618 	return 0;
4619 }
4620 
locate_network(packet)4621 int locate_network (packet)
4622 	struct packet *packet;
4623 {
4624 	struct iaddr ia;
4625 	struct data_string data;
4626 	struct subnet *subnet = (struct subnet *)0;
4627 	struct option_cache *oc;
4628 
4629 	/* See if there's a Relay Agent Link Selection Option, or a
4630 	 * Subnet Selection Option.  The Link-Select and Subnet-Select
4631 	 * are formatted and used precisely the same, but we must prefer
4632 	 * the link-select over the subnet-select.
4633 	 */
4634 	if ((oc = lookup_option(&agent_universe, packet->options,
4635 				RAI_LINK_SELECT)) == NULL)
4636 		oc = lookup_option(&dhcp_universe, packet->options,
4637 				   DHO_SUBNET_SELECTION);
4638 
4639 	/* If there's no SSO and no giaddr, then use the shared_network
4640 	   from the interface, if there is one.   If not, fail. */
4641 	if (!oc && !packet -> raw -> giaddr.s_addr) {
4642 		if (packet -> interface -> shared_network) {
4643 			shared_network_reference
4644 				(&packet -> shared_network,
4645 				 packet -> interface -> shared_network, MDL);
4646 			return 1;
4647 		}
4648 		return 0;
4649 	}
4650 
4651 	/* If there's an option indicating link connection, and it's valid,
4652 	 * use it to figure out the subnet.  If it's not valid, fail.
4653 	 */
4654 	if (oc) {
4655 		memset (&data, 0, sizeof data);
4656 		if (!evaluate_option_cache (&data, packet, (struct lease *)0,
4657 					    (struct client_state *)0,
4658 					    packet -> options,
4659 					    (struct option_state *)0,
4660 					    &global_scope, oc, MDL)) {
4661 			return 0;
4662 		}
4663 		if (data.len != 4) {
4664 			return 0;
4665 		}
4666 		ia.len = 4;
4667 		memcpy (ia.iabuf, data.data, 4);
4668 		data_string_forget (&data, MDL);
4669 	} else {
4670 		ia.len = 4;
4671 		memcpy (ia.iabuf, &packet -> raw -> giaddr, 4);
4672 	}
4673 
4674 	/* If we know the subnet on which the IP address lives, use it. */
4675 	if (find_subnet (&subnet, ia, MDL)) {
4676 		shared_network_reference (&packet -> shared_network,
4677 					  subnet -> shared_network, MDL);
4678 		subnet_dereference (&subnet, MDL);
4679 		return 1;
4680 	}
4681 
4682 	/* Otherwise, fail. */
4683 	return 0;
4684 }
4685 
4686 /*
4687  * Try to figure out the source address to send packets from.
4688  *
4689  * from is the address structure we use to return any address
4690  * we find.
4691  *
4692  * options is the option cache to search.  This may include
4693  * options from the incoming packet and configuration information.
4694  *
4695  * out_options is the outgoing option cache.  This cache
4696  * may be the same as options.  If send_options isn't NULL
4697  * we may save the server address option into it.  We do so
4698  * if send_options is different than options or if the option
4699  * wasn't in options and we needed to find the address elsewhere.
4700  *
4701  * packet is the state structure for the incoming packet
4702  *
4703  * When finding the address we first check to see if it is
4704  * in the options list.  If it isn't we use the first address
4705  * from the interface.
4706  *
4707  * While this is slightly more complicated than I'd like it allows
4708  * us to use the same code in several different places.  ack,
4709  * inform and lease query use it to find the address and fill
4710  * in the options if we get the address from the interface.
4711  * nack uses it to find the address and copy it to the outgoing
4712  * cache.  dhcprequest uses it to find the address for comparison
4713  * and doesn't need to add it to an outgoing list.
4714  */
4715 
4716 void
get_server_source_address(struct in_addr * from,struct option_state * options,struct option_state * out_options,struct packet * packet)4717 get_server_source_address(struct in_addr *from,
4718 			  struct option_state *options,
4719 			  struct option_state *out_options,
4720 			  struct packet *packet) {
4721 	unsigned option_num;
4722 	struct option_cache *oc = NULL;
4723 	struct data_string d;
4724 	struct in_addr *a = NULL;
4725 	isc_boolean_t found = ISC_FALSE;
4726 	int allocate = 0;
4727 
4728 	memset(&d, 0, sizeof(d));
4729 	memset(from, 0, sizeof(*from));
4730 
4731        	option_num = DHO_DHCP_SERVER_IDENTIFIER;
4732        	oc = lookup_option(&dhcp_universe, options, option_num);
4733        	if (oc != NULL)  {
4734 		if (evaluate_option_cache(&d, packet, NULL, NULL,
4735 					  packet->options, options,
4736 					  &global_scope, oc, MDL)) {
4737 			if (d.len == sizeof(*from)) {
4738 				found = ISC_TRUE;
4739 				memcpy(from, d.data, sizeof(*from));
4740 
4741 				/*
4742 				 * Arrange to save a copy of the data
4743 				 * to the outgoing list.
4744 				 */
4745 				if ((out_options != NULL) &&
4746 				    (options != out_options)) {
4747 					a = from;
4748 					allocate = 1;
4749 				}
4750 			}
4751 			data_string_forget(&d, MDL);
4752 		}
4753 		oc = NULL;
4754 	}
4755 
4756 	if ((found == ISC_FALSE) &&
4757 	    (packet->interface->address_count > 0)) {
4758 		*from = packet->interface->addresses[0];
4759 
4760 		if (out_options != NULL) {
4761 			a = &packet->interface->addresses[0];
4762 		}
4763 	}
4764 
4765 	if ((a != NULL) &&
4766 	    (option_cache_allocate(&oc, MDL))) {
4767 		if (make_const_data(&oc->expression,
4768 				    (unsigned char *)a, sizeof(*a),
4769 				    0, allocate, MDL)) {
4770 			option_code_hash_lookup(&oc->option,
4771 						dhcp_universe.code_hash,
4772 						&option_num, 0, MDL);
4773 			save_option(&dhcp_universe, out_options, oc);
4774 		}
4775 		option_cache_dereference(&oc, MDL);
4776 	}
4777 
4778 	return;
4779 }
4780 
4781 /*
4782  * Set up an option state list to try and find a server option.
4783  * We don't go through all possible options - in particualr we
4784  * skip the hosts and we don't include the lease to avoid
4785  * making changes to it.  This means that we won't get the
4786  * correct server id if the admin puts them on hosts or
4787  * builds the server id with information from the lease.
4788  *
4789  * As this is a fallback function (used to handle NAKs or
4790  * sort out server id mismatch in failover) and requires
4791  * configuration by the admin, it should be okay.
4792  */
4793 
4794 void
setup_server_source_address(struct in_addr * from,struct option_state * options,struct packet * packet)4795 setup_server_source_address(struct in_addr *from,
4796 			    struct option_state *options,
4797 			    struct packet *packet) {
4798 
4799 	struct option_state *sid_options = NULL;
4800 
4801 	if (packet->shared_network != NULL) {
4802 		option_state_allocate (&sid_options, MDL);
4803 
4804 		/*
4805 		 * If we have a subnet and group start with that else start
4806 		 * with the shared network group.  The first will recurse and
4807 		 * include the second.
4808 		 */
4809 		if ((packet->shared_network->subnets != NULL) &&
4810 		    (packet->shared_network->subnets->group != NULL)) {
4811 			execute_statements_in_scope(NULL, packet, NULL, NULL,
4812 					packet->options, sid_options,
4813 					&global_scope,
4814 					packet->shared_network->subnets->group,
4815 					NULL, NULL);
4816 		} else {
4817 			execute_statements_in_scope(NULL, packet, NULL, NULL,
4818 					packet->options, sid_options,
4819 					&global_scope,
4820 					packet->shared_network->group,
4821 					NULL, NULL);
4822 		}
4823 
4824 		/* do the pool if there is one */
4825 		if (packet->shared_network->pools != NULL) {
4826 			execute_statements_in_scope(NULL, packet, NULL, NULL,
4827 					packet->options, sid_options,
4828 					&global_scope,
4829 					packet->shared_network->pools->group,
4830 					packet->shared_network->group,
4831 					NULL);
4832 		}
4833 
4834 		/* currently we don't bother with classes or hosts as
4835 		 * neither seems to be useful in this case */
4836 	}
4837 
4838 	/* Make the call to get the server address */
4839 	get_server_source_address(from, sid_options, options, packet);
4840 
4841 	/* get rid of the option cache */
4842 	if (sid_options != NULL)
4843 		option_state_dereference(&sid_options, MDL);
4844 }
4845 
4846 /*
4847  * Look for the lowest numbered site code number and
4848  * apply a log warning if it is less than 224.  Do not
4849  * permit site codes less than 128 (old code never did).
4850  *
4851  * Note that we could search option codes 224 down to 128
4852  * on the hash table, but the table is (probably) smaller
4853  * than that if it was declared as a standalone table with
4854  * defaults.  So we traverse the option code hash.
4855  */
4856 static int
find_min_site_code(struct universe * u)4857 find_min_site_code(struct universe *u)
4858 {
4859 	if (u->site_code_min)
4860 		return u->site_code_min;
4861 
4862 	/*
4863 	 * Note that site_code_min has to be global as we can't pass an
4864 	 * argument through hash_foreach().  The value 224 is taken from
4865 	 * RFC 3942.
4866 	 */
4867 	site_code_min = 224;
4868 	option_code_hash_foreach(u->code_hash, lowest_site_code);
4869 
4870 	if (site_code_min < 224) {
4871 		log_error("WARNING: site-local option codes less than 224 have "
4872 			  "been deprecated by RFC3942.  You have options "
4873 			  "listed in site local space %s that number as low as "
4874 			  "%d.  Please investigate if these should be declared "
4875 			  "as regular options rather than site-local options, "
4876 			  "or migrated up past 224.",
4877 			  u->name, site_code_min);
4878 	}
4879 
4880 	/*
4881 	 * don't even bother logging, this is just silly, and never worked
4882 	 * on any old version of software.
4883 	 */
4884 	if (site_code_min < 128)
4885 		site_code_min = 128;
4886 
4887 	/*
4888 	 * Cache the determined minimum site code on the universe structure.
4889 	 * Note that due to the < 128 check above, a value of zero is
4890 	 * impossible.
4891 	 */
4892 	u->site_code_min = site_code_min;
4893 
4894 	return site_code_min;
4895 }
4896 
4897 static isc_result_t
lowest_site_code(const void * key,unsigned len,void * object)4898 lowest_site_code(const void *key, unsigned len, void *object)
4899 {
4900 	struct option *option = object;
4901 
4902 	if (option->code < site_code_min)
4903 		site_code_min = option->code;
4904 
4905 	return ISC_R_SUCCESS;
4906 }
4907 
4908 static void
maybe_return_agent_options(struct packet * packet,struct option_state * options)4909 maybe_return_agent_options(struct packet *packet, struct option_state *options)
4910 {
4911 	/* If there were agent options in the incoming packet, return
4912 	 * them.  Do not return the agent options if they were stashed
4913 	 * on the lease.  We do not check giaddr to detect the presence of
4914 	 * a relay, as this excludes "l2" relay agents which have no giaddr
4915 	 * to set.
4916 	 *
4917 	 * XXX: If the user configures options for the relay agent information
4918 	 * (state->options->universes[agent_universe.index] is not NULL),
4919 	 * we're still required to duplicate other values provided by the
4920 	 * relay agent.  So we need to merge the old values not configured
4921 	 * by the user into the new state, not just give up.
4922 	 */
4923 	if (!packet->agent_options_stashed &&
4924 	    (packet->options != NULL) &&
4925 	    packet->options->universe_count > agent_universe.index &&
4926 	    packet->options->universes[agent_universe.index] != NULL &&
4927 	    (options->universe_count <= agent_universe.index ||
4928 	     options->universes[agent_universe.index] == NULL)) {
4929 		option_chain_head_reference
4930 		    ((struct option_chain_head **)
4931 		     &(options->universes[agent_universe.index]),
4932 		     (struct option_chain_head *)
4933 		     packet->options->universes[agent_universe.index], MDL);
4934 
4935 		if (options->universe_count <= agent_universe.index)
4936 			options->universe_count = agent_universe.index + 1;
4937 	}
4938 }
4939