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