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