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