xref: /openbsd/usr.sbin/dhcpd/dhcp.c (revision 8415e52b)
1 /*	$OpenBSD: dhcp.c,v 1.57 2017/07/11 10:28:24 reyk Exp $ */
2 
3 /*
4  * Copyright (c) 1995, 1996, 1997, 1998, 1999
5  * The Internet Software Consortium.   All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of The Internet Software Consortium nor the names
17  *    of its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
21  * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
22  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24  * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
25  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  * This software has been written for the Internet Software Consortium
35  * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
36  * Enterprises.  To learn more about the Internet Software Consortium,
37  * see ``http://www.vix.com/isc''.  To learn more about Vixie
38  * Enterprises, see ``http://www.vix.com''.
39  */
40 
41 #include <sys/types.h>
42 #include <sys/socket.h>
43 
44 #include <arpa/inet.h>
45 
46 #include <net/if.h>
47 
48 #include <netinet/in.h>
49 
50 #include <errno.h>
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <string.h>
54 
55 #include "dhcp.h"
56 #include "tree.h"
57 #include "dhcpd.h"
58 #include "log.h"
59 #include "sync.h"
60 
61 int outstanding_pings;
62 
63 static char dhcp_message[256];
64 
65 void
dhcp(struct packet * packet,int is_udpsock)66 dhcp(struct packet *packet, int is_udpsock)
67 {
68 	if (!locate_network(packet) && packet->packet_type != DHCPREQUEST)
69 		return;
70 
71 	if (is_udpsock && packet->packet_type != DHCPINFORM) {
72 		log_info("Unable to handle a DHCP message type=%d on UDP "
73 		    "socket", packet->packet_type);
74 		return;
75 	}
76 
77 	switch (packet->packet_type) {
78 	case DHCPDISCOVER:
79 		dhcpdiscover(packet);
80 		break;
81 
82 	case DHCPREQUEST:
83 		dhcprequest(packet);
84 		break;
85 
86 	case DHCPRELEASE:
87 		dhcprelease(packet);
88 		break;
89 
90 	case DHCPDECLINE:
91 		dhcpdecline(packet);
92 		break;
93 
94 	case DHCPINFORM:
95 		dhcpinform(packet);
96 		break;
97 
98 	default:
99 		break;
100 	}
101 }
102 
103 void
dhcpdiscover(struct packet * packet)104 dhcpdiscover(struct packet *packet)
105 {
106 	struct lease *lease = find_lease(packet, packet->shared_network, 0);
107 	struct host_decl *hp;
108 
109 	log_info("DHCPDISCOVER from %s via %s",
110 	    print_hw_addr(packet->raw->htype, packet->raw->hlen,
111 	    packet->raw->chaddr),
112 	    packet->raw->giaddr.s_addr ? inet_ntoa(packet->raw->giaddr) :
113 	    packet->interface->name);
114 
115 	/* Sourceless packets don't make sense here. */
116 	if (!packet->shared_network) {
117 		log_info("Packet from unknown subnet: %s",
118 		    inet_ntoa(packet->raw->giaddr));
119 		return;
120 	}
121 
122 	/* If we didn't find a lease, try to allocate one... */
123 	if (!lease) {
124 		lease = packet->shared_network->last_lease;
125 
126 		/*
127 		 * If there are no leases in that subnet that have
128 		 * expired, we have nothing to offer this client.
129 		 */
130 		if (!lease || lease->ends > cur_time) {
131 			log_info("no free leases on subnet %s",
132 			    packet->shared_network->name);
133 			return;
134 		}
135 
136 		/*
137 		 * If we find an abandoned lease, take it, but print a
138 		 * warning message, so that if it continues to lose,
139 		 * the administrator will eventually investigate.
140 		 */
141 		if ((lease->flags & ABANDONED_LEASE)) {
142 			struct lease *lp;
143 
144 			/* See if we can find an unabandoned lease first. */
145 			for (lp = lease; lp; lp = lp->prev) {
146 				if (lp->ends > cur_time)
147 					break;
148 				if (!(lp->flags & ABANDONED_LEASE)) {
149 					lease = lp;
150 					break;
151 				}
152 			}
153 
154 			/*
155 			 * If we can't find an unabandoned lease,
156 			 * reclaim the abandoned lease.
157 			 */
158 			if ((lease->flags & ABANDONED_LEASE)) {
159 				log_warnx("Reclaiming abandoned IP address %s.",
160 				    piaddr(lease->ip_addr));
161 				lease->flags &= ~ABANDONED_LEASE;
162 
163 				pfmsg('L', lease); /* unabandon address */
164 			}
165 		}
166 
167 		/* Try to find a host_decl that matches the client
168 		   identifier or hardware address on the packet, and
169 		   has no fixed IP address.   If there is one, hang
170 		   it off the lease so that its option definitions
171 		   can be used. */
172 		if (((packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len != 0) &&
173 		    ((hp = find_hosts_by_uid(
174 		    packet->options[DHO_DHCP_CLIENT_IDENTIFIER].data,
175 		    packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len)) !=
176 		    NULL)) ||
177 		    ((hp = find_hosts_by_haddr(packet->raw->htype,
178 		    packet->raw->chaddr, packet->raw->hlen)) != NULL)) {
179 			for (; hp; hp = hp->n_ipaddr) {
180 				if (!hp->fixed_addr) {
181 					lease->host = hp;
182 					break;
183 				}
184 			}
185 		} else
186 			lease->host = NULL;
187 	}
188 
189 	/* If this subnet won't boot unknown clients, ignore the
190 	   request. */
191 	if (!lease->host &&
192 	    !lease->subnet->group->boot_unknown_clients) {
193 		log_info("Ignoring unknown client %s",
194 		    print_hw_addr(packet->raw->htype, packet->raw->hlen,
195 		    packet->raw->chaddr));
196 	} else if (lease->host && !lease->host->group->allow_booting) {
197 		log_info("Declining to boot client %s",
198 		    lease->host->name ? lease->host->name :
199 		    print_hw_addr(packet->raw->htype, packet->raw->hlen,
200 		    packet->raw->chaddr));
201 	} else
202 		ack_lease(packet, lease, DHCPOFFER, cur_time + 120);
203 }
204 
205 void
dhcprequest(struct packet * packet)206 dhcprequest(struct packet *packet)
207 {
208 	struct lease *lease;
209 	struct iaddr cip;
210 	struct subnet *subnet;
211 	int ours = 0;
212 
213 	cip.len = 4;
214 	if (packet->options[DHO_DHCP_REQUESTED_ADDRESS].len == 4)
215 		memcpy(cip.iabuf,
216 		    packet->options[DHO_DHCP_REQUESTED_ADDRESS].data, 4);
217 	else
218 		memcpy(cip.iabuf, &packet->raw->ciaddr.s_addr, 4);
219 	subnet = find_subnet(cip);
220 
221 	/* Find the lease that matches the address requested by the client. */
222 
223 	if (subnet)
224 		lease = find_lease(packet, subnet->shared_network, &ours);
225 	else
226 		lease = NULL;
227 
228 	log_info("DHCPREQUEST for %s from %s via %s", piaddr(cip),
229 	    print_hw_addr(packet->raw->htype, packet->raw->hlen,
230 	    packet->raw->chaddr),
231 	    packet->raw->giaddr.s_addr ? inet_ntoa(packet->raw->giaddr) :
232 	    packet->interface->name);
233 
234 	/* If a client on a given network REQUESTs a lease on an
235 	 * address on a different network, NAK it.  If the Requested
236 	 * Address option was used, the protocol says that it must
237 	 * have been broadcast, so we can trust the source network
238 	 * information.
239 	 *
240 	 * If ciaddr was specified and Requested Address was not, then
241 	 * we really only know for sure what network a packet came from
242 	 * if it came through a BOOTP gateway - if it came through an
243 	 * IP router, we'll just have to assume that it's cool.
244 	 *
245 	 * If we don't think we know where the packet came from, it
246 	 * came through a gateway from an unknown network, so it's not
247 	 * from a RENEWING client.  If we recognize the network it
248 	 * *thinks* it's on, we can NAK it even though we don't
249 	 * recognize the network it's *actually* on; otherwise we just
250 	 * have to ignore it.
251 	 *
252 	 * We don't currently try to take advantage of access to the
253 	 * raw packet, because it's not available on all platforms.
254 	 * So a packet that was unicast to us through a router from a
255 	 * RENEWING client is going to look exactly like a packet that
256 	 * was broadcast to us from an INIT-REBOOT client.
257 	 *
258 	 * Since we can't tell the difference between these two kinds
259 	 * of packets, if the packet appears to have come in off the
260 	 * local wire, we have to treat it as if it's a RENEWING
261 	 * client.  This means that we can't NAK a RENEWING client on
262 	 * the local wire that has a bogus address.  The good news is
263 	 * that we won't ACK it either, so it should revert to INIT
264 	 * state and send us a DHCPDISCOVER, which we *can* work with.
265 	 *
266 	 * Because we can't detect that a RENEWING client is on the
267 	 * wrong wire, it's going to sit there trying to renew until
268 	 * it gets to the REBIND state, when we *can* NAK it because
269 	 * the packet will get to us through a BOOTP gateway.  We
270 	 * shouldn't actually see DHCPREQUEST packets from RENEWING
271 	 * clients on the wrong wire anyway, since their idea of their
272 	 * local router will be wrong.  In any case, the protocol
273 	 * doesn't really allow us to NAK a DHCPREQUEST from a
274 	 * RENEWING client, so we can punt on this issue.
275 	 */
276 	if (!packet->shared_network ||
277 	    (packet->raw->ciaddr.s_addr && packet->raw->giaddr.s_addr) ||
278 	    (packet->options[DHO_DHCP_REQUESTED_ADDRESS].len == 4 &&
279 	    !packet->raw->ciaddr.s_addr)) {
280 
281 		/*
282 		 * If we don't know where it came from but we do know
283 		 * where it claims to have come from, it didn't come
284 		 * from there.   Fry it.
285 		 */
286 		if (!packet->shared_network) {
287 			if (subnet &&
288 			    subnet->shared_network->group->authoritative) {
289 				nak_lease(packet, &cip);
290 				return;
291 			}
292 			/* Otherwise, ignore it. */
293 			return;
294 		}
295 
296 		/*
297 		 * If we do know where it came from and it asked for an
298 		 * address that is not on that shared network, nak it.
299 		 */
300 		subnet = find_grouped_subnet(packet->shared_network, cip);
301 		if (!subnet) {
302 			if (packet->shared_network->group->authoritative)
303 				nak_lease(packet, &cip);
304 			return;
305 		}
306 	}
307 
308 	/*
309 	 * If we found a lease for the client but it's not the one the
310 	 * client asked for, don't send it - some other server probably
311 	 * made the cut.
312 	 */
313 	if (lease && !addr_eq(lease->ip_addr, cip)) {
314 		/*
315 		 * If we found the address the client asked for, but
316 		 * it wasn't what got picked, the lease belongs to us,
317 		 * so we should NAK it.
318 		 */
319 		if (ours)
320 			nak_lease(packet, &cip);
321 		return;
322 	}
323 
324 	/*
325 	 * If the address the client asked for is ours, but it wasn't
326 	 * available for the client, NAK it.
327 	 */
328 	if (!lease && ours) {
329 		nak_lease(packet, &cip);
330 		return;
331 	}
332 
333 	/* If we're not allowed to serve this client anymore, don't. */
334 	if (lease && !lease->host &&
335 	    !lease->subnet->group->boot_unknown_clients) {
336 		log_info("Ignoring unknown client %s",
337 		    print_hw_addr(packet->raw->htype, packet->raw->hlen,
338 		    packet->raw->chaddr));
339 		return;
340 	} else if (lease && lease->host && !lease->host->group->allow_booting)
341 		{
342 		log_info("Declining to renew client %s",
343 		    lease->host->name ? lease->host->name :
344 		    print_hw_addr(packet->raw->htype, packet->raw->hlen,
345 		    packet->raw->chaddr));
346 		return;
347 	}
348 
349 	/*
350 	 * If we own the lease that the client is asking for,
351 	 * and it's already been assigned to the client, ack it.
352 	 */
353 	if (lease &&
354 	    ((lease->uid_len && lease->uid_len ==
355 	    packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len &&
356 	    !memcmp(packet->options[DHO_DHCP_CLIENT_IDENTIFIER].data,
357 	    lease->uid, lease->uid_len)) ||
358 	    (lease->hardware_addr.hlen == packet->raw->hlen &&
359 	    lease->hardware_addr.htype == packet->raw->htype &&
360 	    !memcmp(lease->hardware_addr.haddr, packet->raw->chaddr,
361 	    packet->raw->hlen)))) {
362 		ack_lease(packet, lease, DHCPACK, 0);
363 		sync_lease(lease);
364 		return;
365 	}
366 
367 	/*
368 	 * At this point, the client has requested a lease, and it's
369 	 * available, but it wasn't assigned to the client, which
370 	 * means that the client probably hasn't gone through the
371 	 * DHCPDISCOVER part of the protocol.  We are within our
372 	 * rights to send a DHCPNAK.   We can also send a DHCPACK.
373 	 * The thing we probably should not do is to remain silent.
374 	 * For now, we'll just assign the lease to the client anyway.
375 	 */
376 	if (lease) {
377 		ack_lease(packet, lease, DHCPACK, 0);
378 		sync_lease(lease);
379 	}
380 }
381 
382 void
dhcprelease(struct packet * packet)383 dhcprelease(struct packet *packet)
384 {
385 	char ciaddrbuf[INET_ADDRSTRLEN];
386 	struct lease *lease;
387 	struct iaddr cip;
388 	int i;
389 
390 	/*
391 	 * DHCPRELEASE must not specify address in requested-address
392 	 * option, but old protocol specs weren't explicit about this,
393 	 * so let it go.
394 	 */
395 	if (packet->options[DHO_DHCP_REQUESTED_ADDRESS].len) {
396 		log_info("DHCPRELEASE from %s specified requested-address.",
397 		    print_hw_addr(packet->raw->htype, packet->raw->hlen,
398 		    packet->raw->chaddr));
399 	}
400 
401 	i = DHO_DHCP_CLIENT_IDENTIFIER;
402 	if (packet->options[i].len) {
403 		lease = find_lease_by_uid(packet->options[i].data,
404 		    packet->options[i].len);
405 
406 		/*
407 		 * See if we can find a lease that matches the
408 		 * IP address the client is claiming.
409 		 */
410 		for (; lease; lease = lease->n_uid) {
411 			if (!memcmp(&packet->raw->ciaddr,
412 			    lease->ip_addr.iabuf, 4)) {
413 				break;
414 			}
415 		}
416 	} else {
417 		/*
418 		* The client is supposed to pass a valid client-identifier,
419 		 * but the spec on this has changed historically, so try the
420 		 * IP address in ciaddr if the client-identifier fails.
421 		 */
422 		cip.len = 4;
423 		memcpy(cip.iabuf, &packet->raw->ciaddr, 4);
424 		lease = find_lease_by_ip_addr(cip);
425 	}
426 
427 	/* Can't do >1 inet_ntoa() in a printf()! */
428 	strlcpy(ciaddrbuf, inet_ntoa(packet->raw->ciaddr), sizeof(ciaddrbuf));
429 
430 	log_info("DHCPRELEASE of %s from %s via %s (%sfound)",
431 	    ciaddrbuf,
432 	    print_hw_addr(packet->raw->htype, packet->raw->hlen,
433 	    packet->raw->chaddr),
434 	    packet->raw->giaddr.s_addr ? inet_ntoa(packet->raw->giaddr) :
435 	    packet->interface->name,
436 	    lease ? "" : "not ");
437 
438 	/* If we're already acking this lease, don't do it again. */
439 	if (lease && lease->state) {
440 		log_info("DHCPRELEASE already acking lease %s",
441 		    piaddr(lease->ip_addr));
442 		return;
443 	}
444 
445 	/* If we found a lease, release it. */
446 	if (lease && lease->ends > cur_time) {
447 		/*
448 		 * First, we ping this lease to see if it's still
449 		 * there. if it is, we don't release it. This avoids
450 		 * the problem of spoofed releases being used to liberate
451 		 * addresses from the server.
452 		 */
453 		if (!lease->releasing) {
454 			log_info("DHCPRELEASE of %s from %s via %s (found)",
455 			    ciaddrbuf,
456 			    print_hw_addr(packet->raw->htype,
457 			    packet->raw->hlen, packet->raw->chaddr),
458 			    packet->raw->giaddr.s_addr ?
459 			    inet_ntoa(packet->raw->giaddr) :
460 			    packet->interface->name);
461 
462 			lease->releasing = 1;
463 			add_timeout(cur_time + 1, lease_ping_timeout, lease);
464 			icmp_echorequest(&(lease->ip_addr));
465 			++outstanding_pings;
466 		} else {
467 			log_info("DHCPRELEASE of %s from %s via %s ignored "
468 			    "(release already pending)",
469 			    ciaddrbuf,
470 			    print_hw_addr(packet->raw->htype,
471 			    packet->raw->hlen, packet->raw->chaddr),
472 			    packet->raw->giaddr.s_addr ?
473 			    inet_ntoa(packet->raw->giaddr) :
474 			    packet->interface->name);
475 		}
476 	} else {
477 		log_info("DHCPRELEASE of %s from %s via %s for nonexistent "
478 		    "lease", ciaddrbuf, print_hw_addr(packet->raw->htype,
479 		    packet->raw->hlen, packet->raw->chaddr),
480 		    packet->raw->giaddr.s_addr ?
481 		    inet_ntoa(packet->raw->giaddr) : packet->interface->name);
482 	}
483 }
484 
485 void
dhcpdecline(struct packet * packet)486 dhcpdecline(struct packet *packet)
487 {
488 	struct lease *lease;
489 	struct iaddr cip;
490 
491 	/* DHCPDECLINE must specify address. */
492 	if (packet->options[DHO_DHCP_REQUESTED_ADDRESS].len != 4)
493 		return;
494 
495 	cip.len = 4;
496 	memcpy(cip.iabuf,
497 	    packet->options[DHO_DHCP_REQUESTED_ADDRESS].data, 4);
498 	lease = find_lease_by_ip_addr(cip);
499 
500 	log_info("DHCPDECLINE on %s from %s via %s",
501 	    piaddr(cip), print_hw_addr(packet->raw->htype,
502 	    packet->raw->hlen, packet->raw->chaddr),
503 	    packet->raw->giaddr.s_addr ? inet_ntoa(packet->raw->giaddr) :
504 	    packet->interface->name);
505 
506 	/* If we're already acking this lease, don't do it again. */
507 	if (lease && lease->state) {
508 		log_info("DHCPDECLINE already acking lease %s",
509 		    piaddr(lease->ip_addr));
510 		return;
511 	}
512 
513 	/* If we found a lease, mark it as unusable and complain. */
514 	if (lease)
515 		abandon_lease(lease, "declined.");
516 }
517 
518 void
dhcpinform(struct packet * packet)519 dhcpinform(struct packet *packet)
520 {
521 	struct lease lease;
522 	struct iaddr cip;
523 	struct subnet *subnet;
524 
525 	/*
526 	 * ciaddr should be set to client's IP address but
527 	 * not all clients are standards compliant.
528 	 */
529 	cip.len = 4;
530 	if (packet->raw->ciaddr.s_addr && !packet->raw->giaddr.s_addr) {
531 		if (memcmp(&packet->raw->ciaddr.s_addr,
532 		    packet->client_addr.iabuf, 4) != 0) {
533 			log_info("DHCPINFORM from %s but ciaddr %s is not "
534 			    "consistent with actual address",
535 			    piaddr(packet->client_addr),
536 			    inet_ntoa(packet->raw->ciaddr));
537 			return;
538 		}
539 		memcpy(cip.iabuf, &packet->raw->ciaddr.s_addr, 4);
540 	} else
541 		memcpy(cip.iabuf, &packet->client_addr.iabuf, 4);
542 
543 	log_info("DHCPINFORM from %s", piaddr(cip));
544 
545 	/* Find the lease that matches the address requested by the client. */
546 	subnet = find_subnet(cip);
547 	if (!subnet)
548 		return;
549 
550 	/* Sourceless packets don't make sense here. */
551 	if (!subnet->shared_network) {
552 		log_info("Packet from unknown subnet: %s",
553 		    inet_ntoa(packet->raw->giaddr));
554 		return;
555 	}
556 
557 	/* Use a fake lease entry */
558 	memset(&lease, 0, sizeof(lease));
559 	lease.subnet = subnet;
560 	lease.shared_network = subnet->shared_network;
561 
562 	if (packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len)
563 		lease.host = find_hosts_by_uid(
564 		    packet->options[DHO_DHCP_CLIENT_IDENTIFIER].data,
565 		    packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len);
566 
567 	lease.starts = lease.timestamp = lease.ends = MIN_TIME;
568 	lease.flags = INFORM_NOLEASE;
569 	ack_lease(packet, &lease, DHCPACK, 0);
570 	if (lease.state != NULL)
571 		free_lease_state(lease.state, "ack_lease");
572 }
573 
574 void
nak_lease(struct packet * packet,struct iaddr * cip)575 nak_lease(struct packet *packet, struct iaddr *cip)
576 {
577 	struct sockaddr_in to;
578 	struct in_addr from;
579 	ssize_t result;
580 	int i;
581 	struct dhcp_packet raw;
582 	unsigned char nak = DHCPNAK;
583 	struct packet outgoing;
584 	struct tree_cache *options[256];
585 	struct tree_cache dhcpnak_tree, dhcpmsg_tree;
586 	struct tree_cache client_tree, server_tree;
587 
588 	memset(options, 0, sizeof options);
589 	memset(&outgoing, 0, sizeof outgoing);
590 	memset(&raw, 0, sizeof raw);
591 	outgoing.raw = &raw;
592 
593 	/* Set DHCP_MESSAGE_TYPE to DHCPNAK */
594 	i = DHO_DHCP_MESSAGE_TYPE;
595 	options[i] = &dhcpnak_tree;
596 	options[i]->value = &nak;
597 	options[i]->len = sizeof nak;
598 	options[i]->buf_size = sizeof nak;
599 	options[i]->timeout = -1;
600 	options[i]->tree = NULL;
601 	options[i]->flags = 0;
602 
603 	/* Set DHCP_MESSAGE to whatever the message is */
604 	i = DHO_DHCP_MESSAGE;
605 	options[i] = &dhcpmsg_tree;
606 	options[i]->value = (unsigned char *)dhcp_message;
607 	options[i]->len = strlen(dhcp_message);
608 	options[i]->buf_size = strlen(dhcp_message);
609 	options[i]->timeout = -1;
610 	options[i]->tree = NULL;
611 	options[i]->flags = 0;
612 
613 	/* Include server identifier in the NAK. At least one
614 	 * router vendor depends on it when using dhcp relay proxy mode.
615 	 */
616 	i = DHO_DHCP_SERVER_IDENTIFIER;
617 	if (packet->options[i].len) {
618 		options[i] = &server_tree;
619 		options[i]->value = packet->options[i].data,
620 		options[i]->len = packet->options[i].len;
621 		options[i]->buf_size = packet->options[i].len;
622 		options[i]->timeout = -1;
623 		options[i]->tree = NULL;
624 		options[i]->flags = 0;
625 	}
626 
627 	/* Echo back the client-identifier as RFC 6842 mandates. */
628 	i = DHO_DHCP_CLIENT_IDENTIFIER;
629 	if (packet->options[i].len) {
630 		options[i] = &client_tree;
631 		options[i]->value = packet->options[i].data,
632 		options[i]->len = packet->options[i].len;
633 		options[i]->buf_size = packet->options[i].len;
634 		options[i]->timeout = -1;
635 		options[i]->tree = NULL;
636 		options[i]->flags = 0;
637 	}
638 
639 	/* Do not use the client's requested parameter list. */
640 	i = DHO_DHCP_PARAMETER_REQUEST_LIST;
641 	if (packet->options[i].data) {
642 		packet->options[i].len = 0;
643 		free(packet->options[i].data);
644 		packet->options[i].data = NULL;
645 	}
646 
647 	/* Set up the option buffer... */
648 	outgoing.packet_length = cons_options(packet, outgoing.raw,
649 	    0, options, 0, 0, 0, NULL, 0);
650 
651 /*	memset(&raw.ciaddr, 0, sizeof raw.ciaddr);*/
652 	raw.siaddr = packet->interface->primary_address;
653 	raw.giaddr = packet->raw->giaddr;
654 	memcpy(raw.chaddr, packet->raw->chaddr, sizeof raw.chaddr);
655 	raw.hlen = packet->raw->hlen;
656 	raw.htype = packet->raw->htype;
657 	raw.xid = packet->raw->xid;
658 	raw.secs = packet->raw->secs;
659 	raw.flags = packet->raw->flags | htons(BOOTP_BROADCAST);
660 	raw.hops = packet->raw->hops;
661 	raw.op = BOOTREPLY;
662 
663 	/* Report what we're sending... */
664 	log_info("DHCPNAK on %s to %s via %s", piaddr(*cip),
665 	    print_hw_addr(packet->raw->htype, packet->raw->hlen,
666 	    packet->raw->chaddr), packet->raw->giaddr.s_addr ?
667 	    inet_ntoa(packet->raw->giaddr) : packet->interface->name);
668 
669 	/* Set up the common stuff... */
670 	memset(&to, 0, sizeof to);
671 	to.sin_family = AF_INET;
672 	to.sin_len = sizeof to;
673 
674 	from = packet->interface->primary_address;
675 
676 	/* Make sure that the packet is at least as big as a BOOTP packet. */
677 	if (outgoing.packet_length < BOOTP_MIN_LEN)
678 		outgoing.packet_length = BOOTP_MIN_LEN;
679 
680 	/*
681 	 * If this was gatewayed, send it back to the gateway.
682 	 * Otherwise, broadcast it on the local network.
683 	 */
684 	if (raw.giaddr.s_addr) {
685 		to.sin_addr = raw.giaddr;
686 		to.sin_port = server_port;
687 
688 		result = packet->interface->send_packet(packet->interface, &raw,
689 		    outgoing.packet_length, from, &to, packet->haddr);
690 		if (result == -1)
691 			log_warn("send_fallback");
692 		return;
693 	} else {
694 		to.sin_addr.s_addr = htonl(INADDR_BROADCAST);
695 		to.sin_port = client_port;
696 	}
697 
698 	errno = 0;
699 	result = packet->interface->send_packet(packet->interface, &raw,
700 	    outgoing.packet_length, from, &to, NULL);
701 }
702 
703 void
ack_lease(struct packet * packet,struct lease * lease,unsigned int offer,time_t when)704 ack_lease(struct packet *packet, struct lease *lease, unsigned int offer,
705     time_t when)
706 {
707 	struct lease lt;
708 	struct lease_state *state;
709 	time_t lease_time, offered_lease_time, max_lease_time, default_lease_time;
710 	struct class *vendor_class, *user_class;
711 	int ulafdr, echo_client_id, i;
712 
713 	/* If we're already acking this lease, don't do it again. */
714 	if (lease->state) {
715 		if ((lease->flags & STATIC_LEASE) ||
716 		    cur_time - lease->timestamp < 60) {
717 			log_info("already acking lease %s",
718 			    piaddr(lease->ip_addr));
719 			return;
720 		}
721 		free_lease_state(lease->state, "ACK timed out");
722 		lease->state = NULL;
723 	}
724 
725 	i = DHO_DHCP_CLASS_IDENTIFIER;
726 	if (packet->options[i].len) {
727 		vendor_class = find_class(0, packet->options[i].data,
728 		    packet->options[i].len);
729 	} else
730 		vendor_class = NULL;
731 
732 	i = DHO_DHCP_USER_CLASS_ID;
733 	if (packet->options[i].len) {
734 		user_class = find_class(1, packet->options[i].data,
735 		    packet->options[i].len);
736 	} else
737 		user_class = NULL;
738 
739 	/*
740 	 * If there is not a specific host entry, and either the
741 	 * vendor class or user class (if they exist) deny booting,
742 	 * then bug out.
743 	 */
744 	if (!lease->host) {
745 		if (vendor_class && !vendor_class->group->allow_booting) {
746 			log_debug("Booting denied by vendor class");
747 			return;
748 		}
749 
750 		if (user_class && !user_class->group->allow_booting) {
751 			log_debug("Booting denied by user class");
752 			return;
753 		}
754 	}
755 
756 	/* Allocate a lease state structure... */
757 	state = new_lease_state("ack_lease");
758 	if (!state)
759 		fatalx("unable to allocate lease state!");
760 	memset(state, 0, sizeof *state);
761 	state->got_requested_address = packet->got_requested_address;
762 	state->shared_network = packet->interface->shared_network;
763 
764 	/* Remember if we got a server identifier option. */
765 	i = DHO_DHCP_SERVER_IDENTIFIER;
766 	if (packet->options[i].len)
767 		state->got_server_identifier = 1;
768 
769 	/* Replace the old lease hostname with the new one, if it's changed. */
770 	i = DHO_HOST_NAME;
771 	if (packet->options[i].len && lease->client_hostname &&
772 	    (strlen(lease->client_hostname) == packet->options[i].len) &&
773 	    !memcmp(lease->client_hostname, packet->options[i].data,
774 	    packet->options[i].len)) {
775 	} else if (packet->options[i].len) {
776 		free(lease->client_hostname);
777 		lease->client_hostname = malloc( packet->options[i].len + 1);
778 		if (!lease->client_hostname)
779 			fatalx("no memory for client hostname.\n");
780 		memcpy(lease->client_hostname, packet->options[i].data,
781 		    packet->options[i].len);
782 		lease->client_hostname[packet->options[i].len] = 0;
783 	} else if (lease->client_hostname) {
784 		free(lease->client_hostname);
785 		lease->client_hostname = 0;
786 	}
787 
788 	/* Replace the lease client identifier with a new one. */
789 	i = DHO_DHCP_CLIENT_IDENTIFIER;
790 	if (packet->options[i].len && lease->client_identifier &&
791 	    lease->client_identifier_len == packet->options[i].len &&
792 	    !memcmp(lease->client_identifier, packet->options[i].data,
793 	    packet->options[i].len)) {
794 		/* Same client identifier. */
795 	} else if (packet->options[i].len) {
796 		free(lease->client_identifier);
797 		lease->client_identifier = malloc(packet->options[i].len);
798 		if (!lease->client_identifier)
799 			fatalx("no memory for client identifier.\n");
800 		lease->client_identifier_len = packet->options[i].len;
801 		memcpy(lease->client_identifier, packet->options[i].data,
802 		    packet->options[i].len);
803 	} else if (lease->client_identifier) {
804 		free(lease->client_identifier);
805 		lease->client_identifier = NULL;
806 		lease->client_identifier_len = 0;
807 	}
808 
809 	/*
810 	 * Choose a filename; first from the host_decl, if any, then from
811 	 * the user class, then from the vendor class.
812 	 */
813 	if (lease->host && lease->host->group->filename)
814 		strlcpy(state->filename, lease->host->group->filename,
815 		    sizeof state->filename);
816 	else if (user_class && user_class->group->filename)
817 		strlcpy(state->filename, user_class->group->filename,
818 		    sizeof state->filename);
819 	else if (vendor_class && vendor_class->group->filename)
820 		strlcpy(state->filename, vendor_class->group->filename,
821 		    sizeof state->filename);
822 	else if (packet->raw->file[0])
823 		strlcpy(state->filename, packet->raw->file,
824 		    sizeof state->filename);
825 	else if (lease->subnet->group->filename)
826 		strlcpy(state->filename, lease->subnet->group->filename,
827 		    sizeof state->filename);
828 	else
829 		strlcpy(state->filename, "", sizeof state->filename);
830 
831 	/* Choose a server name as above. */
832 	if (lease->host && lease->host->group->server_name)
833 		state->server_name = lease->host->group->server_name;
834 	else if (user_class && user_class->group->server_name)
835 		state->server_name = user_class->group->server_name;
836 	else if (vendor_class && vendor_class->group->server_name)
837 		state->server_name = vendor_class->group->server_name;
838 	else if (lease->subnet->group->server_name)
839 		state->server_name = lease->subnet->group->server_name;
840 	else state->server_name = NULL;
841 
842 	/*
843 	 * At this point, we have a lease that we can offer the client.
844 	 * Now we construct a lease structure that contains what we want,
845 	 * and call supersede_lease to do the right thing with it.
846 	 */
847 	memset(&lt, 0, sizeof lt);
848 
849 	/*
850 	 * Use the ip address of the lease that we finally found in
851 	 * the database.
852 	 */
853 	lt.ip_addr = lease->ip_addr;
854 
855 	/* Start now. */
856 	lt.starts = cur_time;
857 
858 	/* Figure out maximum lease time. */
859 	if (lease->host && lease->host->group->max_lease_time)
860 		max_lease_time = lease->host->group->max_lease_time;
861 	else
862 		max_lease_time = lease->subnet->group->max_lease_time;
863 
864 	/* Figure out default lease time. */
865 	if (lease->host && lease->host->group->default_lease_time)
866 		default_lease_time = lease->host->group->default_lease_time;
867 	else
868 		default_lease_time = lease->subnet->group->default_lease_time;
869 
870 	/*
871 	 * Figure out how long a lease to assign.    If this is a
872 	 * dynamic BOOTP lease, its duration must be infinite.
873 	 */
874 	if (offer) {
875 		i = DHO_DHCP_LEASE_TIME;
876 		if (packet->options[i].len == 4) {
877 			lease_time = getULong( packet->options[i].data);
878 
879 			/*
880 			 * Don't let the client ask for a longer lease than
881 			 * is supported for this subnet or host.
882 			 *
883 			 * time_t is signed, so really large numbers come
884 			 * back as negative.  Don't allow lease_time of 0,
885 			 * either.
886 			 */
887 			if (lease_time < 1 || lease_time > max_lease_time)
888 				lease_time = max_lease_time;
889 		} else
890 			lease_time = default_lease_time;
891 
892 		state->offered_expiry = cur_time + lease_time;
893 		if (when)
894 			lt.ends = when;
895 		else
896 			lt.ends = state->offered_expiry;
897 	} else {
898 		if (lease->host &&
899 		    lease->host->group->bootp_lease_length)
900 			lt.ends = (cur_time +
901 			    lease->host->group->bootp_lease_length);
902 		else if (lease->subnet->group->bootp_lease_length)
903 			lt.ends = (cur_time +
904 			    lease->subnet->group->bootp_lease_length);
905 		else if (lease->host &&
906 		    lease->host->group->bootp_lease_cutoff)
907 			lt.ends = lease->host->group->bootp_lease_cutoff;
908 		else
909 			lt.ends = lease->subnet->group->bootp_lease_cutoff;
910 		state->offered_expiry = lt.ends;
911 		lt.flags = BOOTP_LEASE;
912 	}
913 
914 	/* Record the uid, if given... */
915 	i = DHO_DHCP_CLIENT_IDENTIFIER;
916 	if (packet->options[i].len) {
917 		if (packet->options[i].len <= sizeof lt.uid_buf) {
918 			memcpy(lt.uid_buf, packet->options[i].data,
919 			    packet->options[i].len);
920 			lt.uid = lt.uid_buf;
921 			lt.uid_max = sizeof lt.uid_buf;
922 			lt.uid_len = packet->options[i].len;
923 		} else {
924 			lt.uid_max = lt.uid_len = packet->options[i].len;
925 			lt.uid = malloc(lt.uid_max);
926 			if (!lt.uid)
927 				fatalx("can't allocate memory for large uid.");
928 			memcpy(lt.uid, packet->options[i].data, lt.uid_len);
929 		}
930 	}
931 
932 	lt.host = lease->host;
933 	lt.subnet = lease->subnet;
934 	lt.shared_network = lease->shared_network;
935 
936 	/* Don't call supersede_lease on a mocked-up lease. */
937 	if (lease->flags & (STATIC_LEASE | INFORM_NOLEASE)) {
938 		/* Copy the hardware address into the static lease
939 		   structure. */
940 		lease->hardware_addr.hlen = packet->raw->hlen;
941 		lease->hardware_addr.htype = packet->raw->htype;
942 		memcpy(lease->hardware_addr.haddr, packet->raw->chaddr,
943 		    sizeof packet->raw->chaddr); /* XXX */
944 	} else {
945 		/* Record the hardware address, if given... */
946 		lt.hardware_addr.hlen = packet->raw->hlen;
947 		lt.hardware_addr.htype = packet->raw->htype;
948 		memcpy(lt.hardware_addr.haddr, packet->raw->chaddr,
949 		    sizeof packet->raw->chaddr);
950 
951 		/* Install the new information about this lease in the
952 		   database.  If this is a DHCPACK or a dynamic BOOTREPLY
953 		   and we can't write the lease, don't ACK it (or BOOTREPLY
954 		   it) either. */
955 
956 		if (!(supersede_lease(lease, &lt, !offer ||
957 		    offer == DHCPACK) || (offer && offer != DHCPACK))) {
958 			free_lease_state(state, "ack_lease: !supersede_lease");
959 			return;
960 		}
961 	}
962 
963 	/* Remember the interface on which the packet arrived. */
964 	state->ip = packet->interface;
965 
966 	/* Set a flag if this client is a lame Microsoft client that NUL
967 	   terminates string options and expects us to do likewise. */
968 	i = DHO_HOST_NAME;
969 	if (packet->options[i].len &&
970 	    packet->options[i].data[packet->options[i].len - 1] == '\0')
971 		lease->flags |= MS_NULL_TERMINATION;
972 	else
973 		lease->flags &= ~MS_NULL_TERMINATION;
974 
975 	/* Remember the giaddr, xid, secs, flags and hops. */
976 	state->giaddr = packet->raw->giaddr;
977 	state->ciaddr = packet->raw->ciaddr;
978 	state->xid = packet->raw->xid;
979 	state->secs = packet->raw->secs;
980 	state->bootp_flags = packet->raw->flags;
981 	state->hops = packet->raw->hops;
982 	state->offer = offer;
983 	memcpy(&state->haddr, packet->haddr, sizeof state->haddr);
984 
985 	/* Figure out what options to send to the client: */
986 
987 	/* Start out with the subnet options... */
988 	memcpy(state->options, lease->subnet->group->options,
989 	    sizeof state->options);
990 
991 	/* Vendor and user classes are only supported for DHCP clients. */
992 	if (state->offer) {
993 		/* If we have a vendor class, install those options,
994 		   superseding any subnet options. */
995 		if (vendor_class) {
996 			for (i = 0; i < 256; i++)
997 				if (vendor_class->group->options[i])
998 					state->options[i] =
999 					    vendor_class->group->options[i];
1000 		}
1001 
1002 		/* If we have a user class, install those options,
1003 		   superseding any subnet and vendor class options. */
1004 		if (user_class) {
1005 			for (i = 0; i < 256; i++)
1006 				if (user_class->group->options[i])
1007 					state->options[i] =
1008 					    user_class->group->options[i];
1009 		}
1010 
1011 	}
1012 
1013 	/* If we have a host_decl structure, install the associated
1014 	   options, superseding anything that's in the way. */
1015 	if (lease->host) {
1016 		for (i = 0; i < 256; i++)
1017 			if (lease->host->group->options[i])
1018 				state->options[i] =
1019 				    lease->host->group->options[i];
1020 	}
1021 
1022 	/* Get the Maximum Message Size option from the packet, if one
1023 	   was sent. */
1024 	i = DHO_DHCP_MAX_MESSAGE_SIZE;
1025 	if (packet->options[i].data &&
1026 	    packet->options[i].len == sizeof(u_int16_t))
1027 		state->max_message_size = getUShort(packet->options[i].data);
1028 	/* Otherwise, if a maximum message size was specified, use that. */
1029 	else if (state->options[i] && state->options[i]->value)
1030 		state->max_message_size = getUShort(state->options[i]->value);
1031 
1032 	/* Save the parameter request list if there is one. */
1033 	i = DHO_DHCP_PARAMETER_REQUEST_LIST;
1034 	if (packet->options[i].data) {
1035 		state->prl = calloc(1, packet->options[i].len);
1036 		if (!state->prl)
1037 			log_warnx("no memory for parameter request list");
1038 		else {
1039 			memcpy(state->prl, packet->options[i].data,
1040 			    packet->options[i].len);
1041 			state->prl_len = packet->options[i].len;
1042 		}
1043 	}
1044 
1045 	/* If we didn't get a hostname from an option somewhere, see if
1046 	   we can get one from the lease. */
1047 	i = DHO_HOST_NAME;
1048 	if (!state->options[i] && lease->hostname) {
1049 		state->options[i] = new_tree_cache("hostname");
1050 		state->options[i]->flags = TC_TEMPORARY;
1051 		state->options[i]->value = (unsigned char *)lease->hostname;
1052 		state->options[i]->len = strlen(lease->hostname);
1053 		state->options[i]->buf_size = state->options[i]->len;
1054 		state->options[i]->timeout = -1;
1055 		state->options[i]->tree = NULL;
1056 	}
1057 
1058 	/*
1059 	 * Now, if appropriate, put in DHCP-specific options that
1060 	 * override those.
1061 	 */
1062 	if (state->offer) {
1063 		i = DHO_DHCP_MESSAGE_TYPE;
1064 		state->options[i] = new_tree_cache("message-type");
1065 		state->options[i]->flags = TC_TEMPORARY;
1066 		state->options[i]->value = &state->offer;
1067 		state->options[i]->len = sizeof state->offer;
1068 		state->options[i]->buf_size = sizeof state->offer;
1069 		state->options[i]->timeout = -1;
1070 		state->options[i]->tree = NULL;
1071 
1072 		i = DHO_DHCP_SERVER_IDENTIFIER;
1073 		if (!state->options[i]) {
1074 		 use_primary:
1075 			state->options[i] = new_tree_cache("server-id");
1076 			state->options[i]->value =
1077 			    (unsigned char *)&state->ip->primary_address;
1078 			state->options[i]->len =
1079 			    sizeof state->ip->primary_address;
1080 			state->options[i]->buf_size = state->options[i]->len;
1081 			state->options[i]->timeout = -1;
1082 			state->options[i]->tree = NULL;
1083 			state->from.len = sizeof state->ip->primary_address;
1084 			memcpy(state->from.iabuf, &state->ip->primary_address,
1085 			    state->from.len);
1086 		} else {
1087 			/* Find the value of the server identifier... */
1088 			if (!tree_evaluate(state->options[i]))
1089 				goto use_primary;
1090 			if (!state->options[i]->value ||
1091 			    (state->options[i]->len >
1092 			    sizeof state->from.iabuf))
1093 				goto use_primary;
1094 
1095 			state->from.len = state->options[i]->len;
1096 			memcpy(state->from.iabuf, state->options[i]->value,
1097 			    state->from.len);
1098 		}
1099 		/*
1100 		 * Do not ACK a REQUEST intended for another server.
1101 		 */
1102 		if (packet->options[i].len == 4) {
1103 			if (state->options[i]->len != 4 ||
1104 			    memcmp(packet->options[i].data,
1105 			    state->options[i]->value, 4) != 0) {
1106 				free_lease_state(state, "ack_lease: "
1107 				    "server identifier");
1108 				return;
1109 			}
1110 		}
1111 
1112 		/* If we used the vendor class the client specified, we
1113 		   have to return it. */
1114 		if (vendor_class) {
1115 			i = DHO_DHCP_CLASS_IDENTIFIER;
1116 			state->options[i] = new_tree_cache("class-identifier");
1117 			state->options[i]->flags = TC_TEMPORARY;
1118 			state->options[i]->value =
1119 				(unsigned char *)vendor_class->name;
1120 			state->options[i]->len = strlen(vendor_class->name);
1121 			state->options[i]->buf_size = state->options[i]->len;
1122 			state->options[i]->timeout = -1;
1123 			state->options[i]->tree = NULL;
1124 		}
1125 
1126 		/* If we used the user class the client specified, we
1127 		   have to return it. */
1128 		if (user_class) {
1129 			i = DHO_DHCP_USER_CLASS_ID;
1130 			state->options[i] = new_tree_cache("user-class");
1131 			state->options[i]->flags = TC_TEMPORARY;
1132 			state->options[i]->value =
1133 				(unsigned char *)user_class->name;
1134 			state->options[i]->len = strlen(user_class->name);
1135 			state->options[i]->buf_size = state->options[i]->len;
1136 			state->options[i]->timeout = -1;
1137 			state->options[i]->tree = NULL;
1138 		}
1139 	}
1140 
1141 	/* for DHCPINFORM, don't include lease time parameters */
1142 	if (state->offer && (lease->flags & INFORM_NOLEASE) == 0) {
1143 
1144 		/* Sanity check the lease time. */
1145 		if ((state->offered_expiry - cur_time) < 15)
1146 			offered_lease_time = default_lease_time;
1147 		else if (state->offered_expiry - cur_time > max_lease_time)
1148 			offered_lease_time = max_lease_time;
1149 		else
1150 			offered_lease_time =
1151 			    state->offered_expiry - cur_time;
1152 
1153 		putULong((unsigned char *)&state->expiry, offered_lease_time);
1154 		i = DHO_DHCP_LEASE_TIME;
1155 		state->options[i] = new_tree_cache("lease-expiry");
1156 		state->options[i]->flags = TC_TEMPORARY;
1157 		state->options[i]->value = (unsigned char *)&state->expiry;
1158 		state->options[i]->len = sizeof state->expiry;
1159 		state->options[i]->buf_size = sizeof state->expiry;
1160 		state->options[i]->timeout = -1;
1161 		state->options[i]->tree = NULL;
1162 
1163 		/* Renewal time is lease time * 0.5. */
1164 		offered_lease_time /= 2;
1165 		putULong((unsigned char *)&state->renewal, offered_lease_time);
1166 		i = DHO_DHCP_RENEWAL_TIME;
1167 		state->options[i] = new_tree_cache("renewal-time");
1168 		state->options[i]->flags = TC_TEMPORARY;
1169 		state->options[i]->value =
1170 			(unsigned char *)&state->renewal;
1171 		state->options[i]->len = sizeof state->renewal;
1172 		state->options[i]->buf_size = sizeof state->renewal;
1173 		state->options[i]->timeout = -1;
1174 		state->options[i]->tree = NULL;
1175 
1176 
1177 		/* Rebinding time is lease time * 0.875. */
1178 		offered_lease_time += (offered_lease_time / 2 +
1179 		    offered_lease_time / 4);
1180 		putULong((unsigned char *)&state->rebind, offered_lease_time);
1181 		i = DHO_DHCP_REBINDING_TIME;
1182 		state->options[i] = new_tree_cache("rebind-time");
1183 		state->options[i]->flags = TC_TEMPORARY;
1184 		state->options[i]->value = (unsigned char *)&state->rebind;
1185 		state->options[i]->len = sizeof state->rebind;
1186 		state->options[i]->buf_size = sizeof state->rebind;
1187 		state->options[i]->timeout = -1;
1188 		state->options[i]->tree = NULL;
1189 	}
1190 
1191 	/* Use the subnet mask from the subnet declaration if no other
1192 	   mask has been provided. */
1193 	i = DHO_SUBNET_MASK;
1194 	if (!state->options[i]) {
1195 		state->options[i] = new_tree_cache("subnet-mask");
1196 		state->options[i]->flags = TC_TEMPORARY;
1197 		state->options[i]->value = lease->subnet->netmask.iabuf;
1198 		state->options[i]->len = lease->subnet->netmask.len;
1199 		state->options[i]->buf_size = lease->subnet->netmask.len;
1200 		state->options[i]->timeout = -1;
1201 		state->options[i]->tree = NULL;
1202 	}
1203 
1204 	/* If so directed, use the leased IP address as the router address.
1205 	   This supposedly makes Win95 machines ARP for all IP addresses,
1206 	   so if the local router does proxy arp, you win. */
1207 
1208 	ulafdr = 0;
1209 	if (lease->host) {
1210 		if (lease->host->group->use_lease_addr_for_default_route)
1211 			ulafdr = 1;
1212 	} else if (user_class) {
1213 		if (user_class->group->use_lease_addr_for_default_route)
1214 			ulafdr = 1;
1215 	} else if (vendor_class) {
1216 		if (vendor_class->group->use_lease_addr_for_default_route)
1217 			ulafdr = 1;
1218 	} else if (lease->subnet->group->use_lease_addr_for_default_route)
1219 		ulafdr = 1;
1220 	else
1221 		ulafdr = 0;
1222 
1223 	i = DHO_ROUTERS;
1224 	if (ulafdr && !state->options[i]) {
1225 		state->options[i] = new_tree_cache("routers");
1226 		state->options[i]->flags = TC_TEMPORARY;
1227 		state->options[i]->value = lease->ip_addr.iabuf;
1228 		state->options[i]->len = lease->ip_addr.len;
1229 		state->options[i]->buf_size = lease->ip_addr.len;
1230 		state->options[i]->timeout = -1;
1231 		state->options[i]->tree = NULL;
1232 	}
1233 
1234 	/*
1235 	 * RFC 3046: MUST NOT echo relay agent information if the server
1236 	 * does not understand/use the data. We don't.
1237 	 */
1238 	i = DHO_RELAY_AGENT_INFORMATION;
1239 	memset(&state->options[i], 0, sizeof(state->options[i]));
1240 
1241 	/* Echo back the client-identifier as RFC 6842 mandates. */
1242 	if (lease->host)
1243 		echo_client_id = lease->host->group->echo_client_id;
1244 	else if (user_class)
1245 		echo_client_id = user_class->group->echo_client_id;
1246 	else if (vendor_class)
1247 		echo_client_id = vendor_class->group->echo_client_id;
1248 	else
1249 		echo_client_id = lease->subnet->group->echo_client_id;
1250 	i = DHO_DHCP_CLIENT_IDENTIFIER;
1251 	if (lease->client_identifier && echo_client_id) {
1252 		state->options[i] = new_tree_cache("dhcp-client-identifier");
1253 		state->options[i]->flags = TC_TEMPORARY;
1254 		state->options[i]->value = lease->client_identifier;
1255 		state->options[i]->len = lease->client_identifier_len;
1256 		state->options[i]->buf_size = lease->client_identifier_len;
1257 		state->options[i]->timeout = -1;
1258 		state->options[i]->tree = NULL;
1259 	} else
1260 		memset(&state->options[i], 0, sizeof(state->options[i]));
1261 
1262 	lease->state = state;
1263 
1264 	/* If this is a DHCPOFFER, ping the lease address before actually
1265 	   sending the offer. */
1266 	if (offer == DHCPOFFER && !(lease->flags & STATIC_LEASE) &&
1267 	    cur_time - lease->timestamp > 60) {
1268 		lease->timestamp = cur_time;
1269 		icmp_echorequest(&lease->ip_addr);
1270 		add_timeout(cur_time + 1, lease_ping_timeout, lease);
1271 		++outstanding_pings;
1272 	} else {
1273 		lease->timestamp = cur_time;
1274 		dhcp_reply(lease);
1275 	}
1276 }
1277 
1278 void
dhcp_reply(struct lease * lease)1279 dhcp_reply(struct lease *lease)
1280 {
1281 	char ciaddrbuf[INET_ADDRSTRLEN];
1282 	int bufs = 0, packet_length, i;
1283 	struct dhcp_packet raw;
1284 	struct sockaddr_in to;
1285 	struct in_addr from;
1286 	struct lease_state *state = lease->state;
1287 	int nulltp, bootpp;
1288 	u_int8_t *prl;
1289 	int prl_len;
1290 
1291 	if (!state)
1292 		fatalx("dhcp_reply was supplied lease with no state!");
1293 
1294 	/* Compose a response for the client... */
1295 	memset(&raw, 0, sizeof raw);
1296 
1297 	/* Copy in the filename if given; otherwise, flag the filename
1298 	   buffer as available for options. */
1299 	if (state->filename[0])
1300 		strlcpy(raw.file, state->filename, sizeof raw.file);
1301 	else
1302 		bufs |= 1;
1303 
1304 	/* Copy in the server name if given; otherwise, flag the
1305 	   server_name buffer as available for options. */
1306 	if (state->server_name)
1307 		strlcpy(raw.sname, state->server_name, sizeof raw.sname);
1308 	else
1309 		bufs |= 2; /* XXX */
1310 
1311 	memcpy(raw.chaddr, lease->hardware_addr.haddr, sizeof raw.chaddr);
1312 	raw.hlen = lease->hardware_addr.hlen;
1313 	raw.htype = lease->hardware_addr.htype;
1314 
1315 	/* See if this is a Microsoft client that NUL-terminates its
1316 	   strings and expects us to do likewise... */
1317 	if (lease->flags & MS_NULL_TERMINATION)
1318 		nulltp = 1;
1319 	else
1320 		nulltp = 0;
1321 
1322 	/* See if this is a bootp client... */
1323 	if (state->offer)
1324 		bootpp = 0;
1325 	else
1326 		bootpp = 1;
1327 
1328 	if (state->options[DHO_DHCP_PARAMETER_REQUEST_LIST] &&
1329 	    state->options[DHO_DHCP_PARAMETER_REQUEST_LIST]->value) {
1330 		prl = state->options[DHO_DHCP_PARAMETER_REQUEST_LIST]->value;
1331 		prl_len = state->options[DHO_DHCP_PARAMETER_REQUEST_LIST]->len;
1332 	} else if (state->prl) {
1333 		prl = state->prl;
1334 		prl_len = state->prl_len;
1335 	} else {
1336 		prl = NULL;
1337 		prl_len = 0;
1338 	}
1339 
1340 	/* Insert such options as will fit into the buffer. */
1341 	packet_length = cons_options(NULL, &raw, state->max_message_size,
1342 	    state->options, bufs, nulltp, bootpp, prl, prl_len);
1343 
1344 	/* Having done the cons_options(), we can release the tree_cache
1345 	   entries. */
1346 	for (i = 0; i < 256; i++) {
1347 		if (state->options[i] &&
1348 		    state->options[i]->flags & TC_TEMPORARY)
1349 			free_tree_cache(state->options[i]);
1350 	}
1351 
1352 	memcpy(&raw.ciaddr, &state->ciaddr, sizeof raw.ciaddr);
1353 	if ((lease->flags & INFORM_NOLEASE) == 0)
1354 		memcpy(&raw.yiaddr, lease->ip_addr.iabuf, 4);
1355 
1356 	/* Figure out the address of the next server. */
1357 	if (lease->host && lease->host->group->next_server.len)
1358 		memcpy(&raw.siaddr, lease->host->group->next_server.iabuf, 4);
1359 	else if (lease->subnet->group->next_server.len)
1360 		memcpy(&raw.siaddr, lease->subnet->group->next_server.iabuf,
1361 		    4);
1362 	else if (lease->subnet->interface_address.len)
1363 		memcpy(&raw.siaddr, lease->subnet->interface_address.iabuf, 4);
1364 	else
1365 		raw.siaddr = state->ip->primary_address;
1366 
1367 	raw.giaddr = state->giaddr;
1368 
1369 	raw.xid = state->xid;
1370 	raw.secs = state->secs;
1371 	raw.flags = state->bootp_flags;
1372 	raw.hops = state->hops;
1373 	raw.op = BOOTREPLY;
1374 
1375 	/* Can't do >1 inet_ntoa() in a printf()! */
1376 	strlcpy(ciaddrbuf, inet_ntoa(state->ciaddr), sizeof(ciaddrbuf));
1377 
1378 	/* Say what we're doing... */
1379 	if ((state->offer == DHCPACK) && (lease->flags & INFORM_NOLEASE))
1380 		log_info("DHCPACK to %s (%s) via %s",
1381 		    ciaddrbuf,
1382 		    print_hw_addr(lease->hardware_addr.htype,
1383 		        lease->hardware_addr.hlen, lease->hardware_addr.haddr),
1384 		    state->giaddr.s_addr ? inet_ntoa(state->giaddr) :
1385 		        state->ip->name);
1386 	else
1387 		log_info("%s on %s to %s via %s",
1388 		    (state->offer ? (state->offer == DHCPACK ? "DHCPACK" :
1389 			"DHCPOFFER") : "BOOTREPLY"),
1390 		    piaddr(lease->ip_addr),
1391 		    print_hw_addr(lease->hardware_addr.htype,
1392 		        lease->hardware_addr.hlen, lease->hardware_addr.haddr),
1393 		    state->giaddr.s_addr ? inet_ntoa(state->giaddr) :
1394 		        state->ip->name);
1395 
1396 	memset(&to, 0, sizeof to);
1397 	to.sin_family = AF_INET;
1398 #ifdef HAVE_SA_LEN
1399 	to.sin_len = sizeof to;
1400 #endif
1401 
1402 	/* Make sure outgoing packets are at least as big
1403 	   as a BOOTP packet. */
1404 	if (packet_length < BOOTP_MIN_LEN)
1405 		packet_length = BOOTP_MIN_LEN;
1406 
1407 	/* If this was gatewayed, send it back to the gateway... */
1408 	if (raw.giaddr.s_addr) {
1409 		to.sin_addr = raw.giaddr;
1410 		to.sin_port = server_port;
1411 
1412 		memcpy(&from, state->from.iabuf, sizeof from);
1413 
1414 		(void) state->ip->send_packet(state->ip, &raw,
1415 		    packet_length, from, &to, &state->haddr);
1416 
1417 		free_lease_state(state, "dhcp_reply gateway");
1418 		lease->state = NULL;
1419 		return;
1420 
1421 	/* If the client is RENEWING, unicast to the client using the
1422 	   regular IP stack.  Some clients, particularly those that
1423 	   follow RFC1541, are buggy, and send both ciaddr and
1424 	   server-identifier.  We deal with this situation by assuming
1425 	   that if we got both dhcp-server-identifier and ciaddr, and
1426 	   giaddr was not set, then the client is on the local
1427 	   network, and we can therefore unicast or broadcast to it
1428 	   successfully.  A client in REQUESTING state on another
1429 	   network that's making this mistake will have set giaddr,
1430 	   and will therefore get a relayed response from the above
1431 	   code. */
1432 	} else if (raw.ciaddr.s_addr &&
1433 	    !((state->got_server_identifier ||
1434 	    (raw.flags & htons(BOOTP_BROADCAST))) &&
1435 	    /* XXX This won't work if giaddr isn't zero, but it is: */
1436 	    (state->shared_network == lease->shared_network)) &&
1437 	    state->offer == DHCPACK) {
1438 		to.sin_addr = raw.ciaddr;
1439 		to.sin_port = client_port;
1440 
1441 	/* If it comes from a client that already knows its address
1442 	   and is not requesting a broadcast response, and we can
1443 	   unicast to a client without using the ARP protocol, sent it
1444 	   directly to that client. */
1445 	} else if (!(raw.flags & htons(BOOTP_BROADCAST))) {
1446 		to.sin_addr = raw.yiaddr;
1447 		to.sin_port = client_port;
1448 
1449 	/* Otherwise, broadcast it on the local network. */
1450 	} else {
1451 		to.sin_addr.s_addr = htonl(INADDR_BROADCAST);
1452 		to.sin_port = client_port;
1453 		memset(&state->haddr, 0xff, sizeof state->haddr);
1454 	}
1455 
1456 	memcpy(&from, state->from.iabuf, sizeof from);
1457 
1458 	(void) state->ip->send_packet(state->ip, &raw, packet_length,
1459 	    from, &to, &state->haddr);
1460 
1461 	free_lease_state(state, "dhcp_reply");
1462 	lease->state = NULL;
1463 }
1464 
1465 struct lease *
find_lease(struct packet * packet,struct shared_network * share,int * ours)1466 find_lease(struct packet *packet, struct shared_network *share,
1467     int *ours)
1468 {
1469 	struct lease *uid_lease, *ip_lease, *hw_lease;
1470 	struct lease *lease = NULL;
1471 	struct iaddr cip;
1472 	struct host_decl *hp, *host = NULL;
1473 	struct lease *fixed_lease;
1474 
1475 	/* Figure out what IP address the client is requesting, if any. */
1476 	if (packet->options[DHO_DHCP_REQUESTED_ADDRESS].len == 4) {
1477 		packet->got_requested_address = 1;
1478 		cip.len = 4;
1479 		memcpy(cip.iabuf,
1480 		    packet->options[DHO_DHCP_REQUESTED_ADDRESS].data,
1481 		    cip.len);
1482 	} else if (packet->raw->ciaddr.s_addr) {
1483 		cip.len = 4;
1484 		memcpy(cip.iabuf, &packet->raw->ciaddr, 4);
1485 	} else
1486 		cip.len = 0;
1487 
1488 	/* Try to find a host or lease that's been assigned to the
1489 	   specified unique client identifier. */
1490 	if (packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len) {
1491 		/* First, try to find a fixed host entry for the specified
1492 		   client identifier... */
1493 		hp = find_hosts_by_uid(
1494 		    packet->options[DHO_DHCP_CLIENT_IDENTIFIER].data,
1495 		    packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len);
1496 		if (hp) {
1497 			host = hp;
1498 			fixed_lease = mockup_lease(packet, share, hp);
1499 			uid_lease = NULL;
1500 		} else {
1501 			uid_lease = find_lease_by_uid(
1502 			    packet->options[DHO_DHCP_CLIENT_IDENTIFIER].data,
1503 			    packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len);
1504 			/* Find the lease matching this uid that's on the
1505 			   network the packet came from (if any). */
1506 			for (; uid_lease; uid_lease = uid_lease->n_uid)
1507 				if (uid_lease->shared_network == share)
1508 					break;
1509 			fixed_lease = NULL;
1510 			if (uid_lease && (uid_lease->flags & ABANDONED_LEASE))
1511 				uid_lease = NULL;
1512 		}
1513 	} else {
1514 		uid_lease = NULL;
1515 		fixed_lease = NULL;
1516 	}
1517 
1518 	/* If we didn't find a fixed lease using the uid, try doing
1519 	   it with the hardware address... */
1520 	if (!fixed_lease) {
1521 		hp = find_hosts_by_haddr(packet->raw->htype,
1522 		    packet->raw->chaddr, packet->raw->hlen);
1523 		if (hp) {
1524 			host = hp; /* Save it for later. */
1525 			fixed_lease = mockup_lease(packet, share, hp);
1526 		}
1527 	}
1528 
1529 	/* If fixed_lease is present but does not match the requested
1530 	   IP address, and this is a DHCPREQUEST, then we can't return
1531 	   any other lease, so we might as well return now. */
1532 	if (packet->packet_type == DHCPREQUEST && fixed_lease &&
1533 	    (fixed_lease->ip_addr.len != cip.len ||
1534 	    memcmp(fixed_lease->ip_addr.iabuf, cip.iabuf, cip.len))) {
1535 		if (ours)
1536 			*ours = 1;
1537 		strlcpy(dhcp_message, "requested address is incorrect",
1538 		    sizeof(dhcp_message));
1539 		return NULL;
1540 	}
1541 
1542 	/* Try to find a lease that's been attached to the client's
1543 	   hardware address... */
1544 	hw_lease = find_lease_by_hw_addr(packet->raw->chaddr,
1545 	    packet->raw->hlen);
1546 	/* Find the lease that's on the network the packet came from
1547 	   (if any). */
1548 	for (; hw_lease; hw_lease = hw_lease->n_hw) {
1549 		if (hw_lease->shared_network == share) {
1550 			if ((hw_lease->flags & ABANDONED_LEASE))
1551 				continue;
1552 			if (packet->packet_type)
1553 				break;
1554 			if (hw_lease->flags &
1555 			    (BOOTP_LEASE | DYNAMIC_BOOTP_OK))
1556 				break;
1557 		}
1558 	}
1559 
1560 	/* Try to find a lease that's been allocated to the client's
1561 	   IP address. */
1562 	if (cip.len)
1563 		ip_lease = find_lease_by_ip_addr(cip);
1564 	else
1565 		ip_lease = NULL;
1566 
1567 	/* If ip_lease is valid at this point, set ours to one, so that
1568 	   even if we choose a different lease, we know that the address
1569 	   the client was requesting was ours, and thus we can NAK it. */
1570 	if (ip_lease && ours)
1571 		*ours = 1;
1572 
1573 	/* If the requested IP address isn't on the network the packet
1574 	   came from, don't use it.  Allow abandoned leases to be matched
1575 	   here - if the client is requesting it, there's a decent chance
1576 	   that it's because the lease database got trashed and a client
1577 	   that thought it had this lease answered an ARP or PING, causing the
1578 	   lease to be abandoned.   If so, this request probably came from
1579 	   that client. */
1580 	if (ip_lease && (ip_lease->shared_network != share)) {
1581 		ip_lease = NULL;
1582 		strlcpy(dhcp_message, "requested address on bad subnet",
1583 		    sizeof(dhcp_message));
1584 	}
1585 
1586 	/* Toss ip_lease if it hasn't yet expired and isn't owned by the
1587 	   client. */
1588 	if (ip_lease && ip_lease->ends >= cur_time && ip_lease != uid_lease) {
1589 		int i = DHO_DHCP_CLIENT_IDENTIFIER;
1590 
1591 		/* Make sure that ip_lease actually belongs to the client,
1592 		   and toss it if not. */
1593 		if ((ip_lease->uid_len && packet->options[i].data &&
1594 		    ip_lease->uid_len == packet->options[i].len &&
1595 		    !memcmp(packet->options[i].data, ip_lease->uid,
1596 		    ip_lease->uid_len)) ||
1597 		    (!ip_lease->uid_len &&
1598 		    ip_lease->hardware_addr.htype == packet->raw->htype &&
1599 		    ip_lease->hardware_addr.hlen == packet->raw->hlen &&
1600 		    !memcmp(ip_lease->hardware_addr.haddr, packet->raw->chaddr,
1601 		    ip_lease->hardware_addr.hlen))) {
1602 			if (uid_lease) {
1603 				if (uid_lease->ends > cur_time) {
1604 					log_warnx("client %s has duplicate "
1605 					    "leases on %s",
1606 					    print_hw_addr(packet->raw->htype,
1607 					    packet->raw->hlen,
1608 					    packet->raw->chaddr),
1609 					    ip_lease->shared_network->name);
1610 
1611 					if (uid_lease &&
1612 					   !packet->raw->ciaddr.s_addr)
1613 						release_lease(uid_lease);
1614 				}
1615 				uid_lease = ip_lease;
1616 			}
1617 		} else {
1618 			strlcpy(dhcp_message, "requested address is not "
1619 			    "available", sizeof(dhcp_message));
1620 			ip_lease = NULL;
1621 		}
1622 
1623 		/* If we get to here and fixed_lease is not null, that means
1624 		   that there are both a dynamic lease and a fixed-address
1625 		   declaration for the same IP address. */
1626 		if (packet->packet_type == DHCPREQUEST && fixed_lease) {
1627 			fixed_lease = NULL;
1628 db_conflict:
1629 			log_warnx("Both dynamic and static leases present for "
1630 			    "%s.", piaddr(cip));
1631 			log_warnx("Either remove host declaration %s or "
1632 			    "remove %s", (fixed_lease && fixed_lease->host ?
1633 			    (fixed_lease->host->name ?
1634 			    fixed_lease->host->name : piaddr(cip)) :
1635 			    piaddr(cip)), piaddr(cip));
1636 			log_warnx("from the dynamic address pool for %s",
1637 			    share->name);
1638 			if (fixed_lease)
1639 				ip_lease = NULL;
1640 			strlcpy(dhcp_message, "database conflict - call for "
1641 			    "help!", sizeof(dhcp_message));
1642 		}
1643 	}
1644 
1645 	/* If we get to here with both fixed_lease and ip_lease not
1646 	   null, then we have a configuration file bug. */
1647 	if (packet->packet_type == DHCPREQUEST && fixed_lease && ip_lease)
1648 		goto db_conflict;
1649 
1650 	/* Toss hw_lease if it hasn't yet expired and the uid doesn't
1651 	   match, except that if the hardware address matches and the
1652 	   client is now doing dynamic BOOTP (and thus hasn't provided
1653 	   a uid) we let the client get away with it. */
1654 	if (hw_lease && hw_lease->ends >= cur_time && hw_lease->uid &&
1655 	    packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len &&
1656 	    hw_lease != uid_lease)
1657 		hw_lease = NULL;
1658 
1659 	/* Toss extra pointers to the same lease... */
1660 	if (hw_lease == uid_lease)
1661 		hw_lease = NULL;
1662 	if (ip_lease == hw_lease)
1663 		hw_lease = NULL;
1664 	if (ip_lease == uid_lease)
1665 		uid_lease = NULL;
1666 
1667 	/* If we've already eliminated the lease, it wasn't there to
1668 	   begin with.   If we have come up with a matching lease,
1669 	   set the message to bad network in case we have to throw it out. */
1670 	if (!ip_lease) {
1671 		strlcpy(dhcp_message, "requested address not available",
1672 		    sizeof(dhcp_message));
1673 	}
1674 
1675 	/* Now eliminate leases that are on the wrong network... */
1676 	if (ip_lease && share != ip_lease->shared_network) {
1677 		if (packet->packet_type == DHCPREQUEST)
1678 			release_lease(ip_lease);
1679 		ip_lease = NULL;
1680 	}
1681 	if (uid_lease && share != uid_lease->shared_network) {
1682 		if (packet->packet_type == DHCPREQUEST)
1683 			release_lease(uid_lease);
1684 		uid_lease = NULL;
1685 	}
1686 	if (hw_lease && share != hw_lease->shared_network) {
1687 		if (packet->packet_type == DHCPREQUEST)
1688 			release_lease(hw_lease);
1689 		hw_lease = NULL;
1690 	}
1691 
1692 	/* If this is a DHCPREQUEST, make sure the lease we're going to return
1693 	   matches the requested IP address.   If it doesn't, don't return a
1694 	   lease at all. */
1695 	if (packet->packet_type == DHCPREQUEST && !ip_lease && !fixed_lease)
1696 		return NULL;
1697 
1698 	/* At this point, if fixed_lease is nonzero, we can assign it to
1699 	   this client. */
1700 	if (fixed_lease)
1701 		lease = fixed_lease;
1702 
1703 	/* If we got a lease that matched the ip address and don't have
1704 	   a better offer, use that; otherwise, release it. */
1705 	if (ip_lease) {
1706 		if (lease) {
1707 			if (packet->packet_type == DHCPREQUEST)
1708 				release_lease(ip_lease);
1709 		} else {
1710 			lease = ip_lease;
1711 			lease->host = NULL;
1712 		}
1713 	}
1714 
1715 	/* If we got a lease that matched the client identifier, we may want
1716 	   to use it, but if we already have a lease we like, we must free
1717 	   the lease that matched the client identifier. */
1718 	if (uid_lease) {
1719 		if (lease) {
1720 			if (packet->packet_type == DHCPREQUEST)
1721 				release_lease(uid_lease);
1722 		} else {
1723 			lease = uid_lease;
1724 			lease->host = NULL;
1725 		}
1726 	}
1727 
1728 	/* The lease that matched the hardware address is treated likewise. */
1729 	if (hw_lease) {
1730 		if (lease) {
1731 			if (packet->packet_type == DHCPREQUEST)
1732 				release_lease(hw_lease);
1733 		} else {
1734 			lease = hw_lease;
1735 			lease->host = NULL;
1736 		}
1737 	}
1738 
1739 	/* If we found a host_decl but no matching address, try to
1740 	   find a host_decl that has no address, and if there is one,
1741 	   hang it off the lease so that we can use the supplied
1742 	   options. */
1743 	if (lease && host && !lease->host) {
1744 		for (; host; host = host->n_ipaddr) {
1745 			if (!host->fixed_addr) {
1746 				lease->host = host;
1747 				break;
1748 			}
1749 		}
1750 	}
1751 
1752 	/* If we find an abandoned lease, take it, but print a
1753 	   warning message, so that if it continues to lose,
1754 	   the administrator will eventually investigate. */
1755 	if (lease && (lease->flags & ABANDONED_LEASE)) {
1756 		if (packet->packet_type == DHCPREQUEST) {
1757 			log_warnx("Reclaiming REQUESTed abandoned IP address "
1758 			    "%s.", piaddr(lease->ip_addr));
1759 			lease->flags &= ~ABANDONED_LEASE;
1760 		} else
1761 			lease = NULL;
1762 	}
1763 	return lease;
1764 }
1765 
1766 /*
1767  * Search the provided host_decl structure list for an address that's on
1768  * the specified shared network.  If one is found, mock up and return a
1769  * lease structure for it; otherwise return the null pointer.
1770  */
1771 struct lease *
mockup_lease(struct packet * packet,struct shared_network * share,struct host_decl * hp)1772 mockup_lease(struct packet *packet, struct shared_network *share,
1773     struct host_decl *hp)
1774 {
1775 	static struct lease mock;
1776 
1777 	mock.subnet = find_host_for_network(&hp, &mock.ip_addr, share);
1778 	if (!mock.subnet)
1779 		return (NULL);
1780 	mock.next = mock.prev = NULL;
1781 	mock.shared_network = mock.subnet->shared_network;
1782 	mock.host = hp;
1783 
1784 	if (hp->group->options[DHO_DHCP_CLIENT_IDENTIFIER]) {
1785 		mock.uid =
1786 		    hp->group->options[DHO_DHCP_CLIENT_IDENTIFIER]->value;
1787 		mock.uid_len =
1788 		    hp->group->options[DHO_DHCP_CLIENT_IDENTIFIER]->len;
1789 	} else {
1790 		mock.uid = NULL;
1791 		mock.uid_len = 0;
1792 	}
1793 
1794 	mock.hardware_addr = hp->interface;
1795 	mock.starts = mock.timestamp = mock.ends = MIN_TIME;
1796 	mock.flags = STATIC_LEASE;
1797 	return &mock;
1798 }
1799