dhcp.c revision 1.7
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			 * time_t is signed, so really large numbers come
745			 * back as negative.  Don't allow lease_time of 0,
746			 * either.
747			 */
748			if (lease_time < 1 || lease_time > max_lease_time)
749				lease_time = max_lease_time;
750		} else
751			lease_time = default_lease_time;
752
753		state->offered_expiry = cur_time + lease_time;
754		if (when)
755			lt.ends = when;
756		else
757			lt.ends = state->offered_expiry;
758	} else {
759		if (lease->host &&
760		    lease->host->group->bootp_lease_length)
761			lt.ends = (cur_time +
762			    lease->host->group->bootp_lease_length);
763		else if (lease->subnet->group->bootp_lease_length)
764			lt.ends = (cur_time +
765			    lease->subnet->group->bootp_lease_length);
766		else if (lease->host &&
767		    lease->host->group->bootp_lease_cutoff)
768			lt.ends = lease->host->group->bootp_lease_cutoff;
769		else
770			lt.ends = lease->subnet->group->bootp_lease_cutoff;
771		state->offered_expiry = lt.ends;
772		lt.flags = BOOTP_LEASE;
773	}
774
775	/* Record the uid, if given... */
776	i = DHO_DHCP_CLIENT_IDENTIFIER;
777	if (packet->options[i].len) {
778		if (packet->options[i].len <= sizeof lt.uid_buf) {
779			memcpy(lt.uid_buf, packet->options[i].data,
780			    packet->options[i].len);
781			lt.uid = lt.uid_buf;
782			lt.uid_max = sizeof lt.uid_buf;
783			lt.uid_len = packet->options[i].len;
784		} else {
785			lt.uid_max = lt.uid_len = packet->options[i].len;
786			lt.uid = (unsigned char *)malloc(lt.uid_max);
787			if (!lt.uid)
788				error("can't allocate memory for large uid.");
789			memcpy(lt.uid, packet->options[i].data, lt.uid_len);
790		}
791	}
792
793	lt.host = lease->host;
794	lt.subnet = lease->subnet;
795	lt.shared_network = lease->shared_network;
796
797	/* Don't call supersede_lease on a mocked-up lease. */
798	if (lease->flags & STATIC_LEASE) {
799		/* Copy the hardware address into the static lease
800		   structure. */
801		lease->hardware_addr.hlen = packet->raw->hlen;
802		lease->hardware_addr.htype = packet->raw->htype;
803		memcpy(lease->hardware_addr.haddr, packet->raw->chaddr,
804		    sizeof packet->raw->chaddr); /* XXX */
805	} else {
806		/* Record the hardware address, if given... */
807		lt.hardware_addr.hlen = packet->raw->hlen;
808		lt.hardware_addr.htype = packet->raw->htype;
809		memcpy(lt.hardware_addr.haddr, packet->raw->chaddr,
810		    sizeof packet->raw->chaddr);
811
812		/* Install the new information about this lease in the
813		   database.  If this is a DHCPACK or a dynamic BOOTREPLY
814		   and we can't write the lease, don't ACK it (or BOOTREPLY
815		   it) either. */
816
817		if (!(supersede_lease(lease, &lt, !offer || offer == DHCPACK) ||
818		    (offer && offer != DHCPACK)))
819			return;
820	}
821
822	/* Remember the interface on which the packet arrived. */
823	state->ip = packet->interface;
824
825	/* Set a flag if this client is a lame Microsoft client that NUL
826	   terminates string options and expects us to do likewise. */
827	if (packet->options[DHO_HOST_NAME].data &&
828	    packet->options[DHO_HOST_NAME].data[
829	    packet->options[DHO_HOST_NAME].len - 1] == '\0')
830		lease->flags |= MS_NULL_TERMINATION;
831	else
832		lease->flags &= ~MS_NULL_TERMINATION;
833
834	/* Remember the giaddr, xid, secs, flags and hops. */
835	state->giaddr = packet->raw->giaddr;
836	state->ciaddr = packet->raw->ciaddr;
837	state->xid = packet->raw->xid;
838	state->secs = packet->raw->secs;
839	state->bootp_flags = packet->raw->flags;
840	state->hops = packet->raw->hops;
841	state->offer = offer;
842
843	/* Figure out what options to send to the client: */
844
845	/* Start out with the subnet options... */
846	memcpy(state->options, lease->subnet->group->options,
847	    sizeof state->options);
848
849	/* Vendor and user classes are only supported for DHCP clients. */
850	if (state->offer) {
851		/* If we have a vendor class, install those options,
852		   superseding any subnet options. */
853		if (vendor_class) {
854			for (i = 0; i < 256; i++)
855				if (vendor_class->group->options[i])
856					state->options[i] =
857					    vendor_class->group->options[i];
858		}
859
860		/* If we have a user class, install those options,
861		   superseding any subnet and vendor class options. */
862		if (user_class) {
863			for (i = 0; i < 256; i++)
864				if (user_class->group->options[i])
865					state->options[i] =
866					    user_class->group->options[i];
867		}
868
869	}
870
871	/* If we have a host_decl structure, install the associated
872	   options, superseding anything that's in the way. */
873	if (lease->host) {
874		for (i = 0; i < 256; i++)
875			if (lease->host->group->options[i])
876				state->options[i] =
877				    lease->host->group->options[i];
878	}
879
880	/* Get the Maximum Message Size option from the packet, if one
881	   was sent. */
882	i = DHO_DHCP_MAX_MESSAGE_SIZE;
883	if (packet->options[i].data &&
884	    packet->options[i].len == sizeof (u_int16_t))
885		state->max_message_size = getUShort(packet->options[i].data);
886	/* Otherwise, if a maximum message size was specified, use that. */
887	else if (state->options[i] && state->options[i]->value)
888		state->max_message_size = getUShort(state->options[i]->value);
889
890	/* Save the parameter request list if there is one. */
891	i = DHO_DHCP_PARAMETER_REQUEST_LIST;
892	if (packet->options[i].data) {
893		state->prl = dmalloc(packet->options[i].len, "ack_lease: prl");
894		if (!state->prl)
895			warn("no memory for parameter request list");
896		else {
897			memcpy(state->prl, packet->options[i].data,
898			    packet->options[i].len);
899			state->prl_len = packet->options[i].len;
900		}
901	}
902
903	/* If we didn't get a hostname from an option somewhere, see if
904	   we can get one from the lease. */
905	i = DHO_HOST_NAME;
906	if (!state->options[i] && lease->hostname) {
907		state->options[i] = new_tree_cache("hostname");
908		state->options[i]->flags = TC_TEMPORARY;
909		state->options[i]->value = (unsigned char *)lease->hostname;
910		state->options[i]->len = strlen (lease->hostname);
911		state->options[i]->buf_size = state->options[i]->len;
912		state->options[i]->timeout = 0xFFFFFFFF;
913		state->options[i]->tree = NULL;
914	}
915
916	/*
917	 * Now, if appropriate, put in DHCP-specific options that
918	 * override those.
919	 */
920	if (state->offer) {
921		i = DHO_DHCP_MESSAGE_TYPE;
922		state->options[i] = new_tree_cache("message-type");
923		state->options[i]->flags = TC_TEMPORARY;
924		state->options[i]->value = &state->offer;
925		state->options[i]->len = sizeof state->offer;
926		state->options[i]->buf_size = sizeof state->offer;
927		state->options[i]->timeout = 0xFFFFFFFF;
928		state->options[i]->tree = NULL;
929
930		i = DHO_DHCP_SERVER_IDENTIFIER;
931		if (!state->options[i]) {
932		 use_primary:
933			state->options[i] = new_tree_cache("server-id");
934			state->options[i]->value =
935			    (unsigned char *)&state->ip->primary_address;
936			state->options[i]->len =
937			    sizeof state->ip->primary_address;
938			state->options[i]->buf_size =
939			    state->options[i]->len;
940			state->options[i]->timeout = 0xFFFFFFFF;
941			state->options[i]->tree = NULL;
942			state->from.len = sizeof state->ip->primary_address;
943			memcpy(state->from.iabuf, &state->ip->primary_address,
944			    state->from.len);
945		} else {
946			/* Find the value of the server identifier... */
947			if (!tree_evaluate (state->options[i]))
948				goto use_primary;
949			if (!state->options[i]->value ||
950			    (state->options[i]->len > sizeof state->from.iabuf))
951				goto use_primary;
952
953			state->from.len = state->options[i]->len;
954			memcpy(state->from.iabuf, state->options[i]->value,
955			    state->from.len);
956		}
957
958		/* Sanity check the lease time. */
959		if ((state->offered_expiry - cur_time) < 15)
960			offered_lease_time = default_lease_time;
961		else if (state->offered_expiry - cur_time > max_lease_time)
962			offered_lease_time = max_lease_time;
963		else
964			offered_lease_time =
965			    state->offered_expiry - cur_time;
966
967		putULong((unsigned char *)&state->expiry,
968		    offered_lease_time);
969		i = DHO_DHCP_LEASE_TIME;
970		state->options[i] = new_tree_cache ("lease-expiry");
971		state->options[i]->flags = TC_TEMPORARY;
972		state->options[i]->value = (unsigned char *)&state->expiry;
973		state->options[i]->len = sizeof state->expiry;
974		state->options[i]->buf_size = sizeof state->expiry;
975		state->options[i]->timeout = 0xFFFFFFFF;
976		state->options[i]->tree = NULL;
977
978		/* Renewal time is lease time * 0.5. */
979		offered_lease_time /= 2;
980		putULong ((unsigned char *)&state->renewal,
981			  offered_lease_time);
982		i = DHO_DHCP_RENEWAL_TIME;
983		state->options[i] = new_tree_cache ("renewal-time");
984		state->options[i]->flags = TC_TEMPORARY;
985		state->options[i]->value =
986			(unsigned char *)&state->renewal;
987		state->options[i]->len = sizeof state->renewal;
988		state->options[i]->buf_size = sizeof state->renewal;
989		state->options[i]->timeout = 0xFFFFFFFF;
990		state->options[i]->tree = NULL;
991
992
993		/* Rebinding time is lease time * 0.875. */
994		offered_lease_time += (offered_lease_time / 2 +
995		    offered_lease_time / 4);
996		putULong ((unsigned char *)&state->rebind,
997		    offered_lease_time);
998		i = DHO_DHCP_REBINDING_TIME;
999		state->options[i] = new_tree_cache ("rebind-time");
1000		state->options[i]->flags = TC_TEMPORARY;
1001		state->options[i]->value =
1002			(unsigned char *)&state->rebind;
1003		state->options[i]->len = sizeof state->rebind;
1004		state->options[i]->buf_size = sizeof state->rebind;
1005		state->options[i]->timeout = 0xFFFFFFFF;
1006		state->options[i]->tree = NULL;
1007
1008		/* If we used the vendor class the client specified, we
1009		   have to return it. */
1010		if (vendor_class) {
1011			i = DHO_DHCP_CLASS_IDENTIFIER;
1012			state->options[i] =
1013				new_tree_cache ("class-identifier");
1014			state->options[i]->flags = TC_TEMPORARY;
1015			state->options[i]->value =
1016				(unsigned char *)vendor_class->name;
1017			state->options[i]->len =
1018				strlen (vendor_class->name);
1019			state->options[i]->buf_size =
1020				state->options[i]->len;
1021			state->options[i]->timeout = 0xFFFFFFFF;
1022			state->options[i]->tree = NULL;
1023		}
1024
1025		/* If we used the user class the client specified, we
1026		   have to return it. */
1027		if (user_class) {
1028			i = DHO_DHCP_USER_CLASS_ID;
1029			state->options[i] = new_tree_cache ("user-class");
1030			state->options[i]->flags = TC_TEMPORARY;
1031			state->options[i]->value =
1032				(unsigned char *)user_class->name;
1033			state->options[i]->len =
1034				strlen (user_class->name);
1035			state->options[i]->buf_size =
1036				state->options[i]->len;
1037			state->options[i]->timeout = 0xFFFFFFFF;
1038			state->options[i]->tree = NULL;
1039		}
1040	}
1041
1042	/* Use the subnet mask from the subnet declaration if no other
1043	   mask has been provided. */
1044	i = DHO_SUBNET_MASK;
1045	if (!state->options[i]) {
1046		state->options[i] = new_tree_cache ("subnet-mask");
1047		state->options[i]->flags = TC_TEMPORARY;
1048		state->options[i]->value =
1049			lease->subnet->netmask.iabuf;
1050		state->options[i]->len = lease->subnet->netmask.len;
1051		state->options[i]->buf_size =
1052			lease->subnet->netmask.len;
1053		state->options[i]->timeout = 0xFFFFFFFF;
1054		state->options[i]->tree = NULL;
1055	}
1056
1057	/* If so directed, use the leased IP address as the router address.
1058	   This supposedly makes Win95 machines ARP for all IP addresses,
1059	   so if the local router does proxy arp, you win. */
1060
1061	ulafdr = 0;
1062	if (lease->host) {
1063		if (lease->host->group->use_lease_addr_for_default_route)
1064			ulafdr = 1;
1065	} else if (user_class) {
1066		if (user_class->group->use_lease_addr_for_default_route)
1067			ulafdr = 1;
1068	} else if (vendor_class) {
1069		if (vendor_class->group->use_lease_addr_for_default_route)
1070			ulafdr = 1;
1071	} else if (lease->subnet->group->use_lease_addr_for_default_route)
1072		ulafdr = 1;
1073	else
1074		ulafdr = 0;
1075
1076	i = DHO_ROUTERS;
1077	if (ulafdr && !state->options[i]) {
1078		state->options[i] = new_tree_cache ("routers");
1079		state->options[i]->flags = TC_TEMPORARY;
1080		state->options[i]->value = lease->ip_addr.iabuf;
1081		state->options[i]->len = lease->ip_addr.len;
1082		state->options[i]->buf_size = lease->ip_addr.len;
1083		state->options[i]->timeout = 0xFFFFFFFF;
1084		state->options[i]->tree = NULL;
1085	}
1086
1087#ifdef DEBUG_PACKET
1088	dump_packet(packet);
1089	dump_raw((unsigned char *)packet->raw, packet->packet_length);
1090#endif
1091
1092	lease->state = state;
1093
1094	/* If this is a DHCPOFFER, ping the lease address before actually
1095	   sending the offer. */
1096	if (offer == DHCPOFFER && !(lease->flags & STATIC_LEASE) &&
1097	    cur_time - lease->timestamp > 60) {
1098		lease->timestamp = cur_time;
1099		icmp_echorequest (&lease->ip_addr);
1100		add_timeout (cur_time + 1, lease_ping_timeout, lease);
1101		++outstanding_pings;
1102	} else {
1103		lease->timestamp = cur_time;
1104		dhcp_reply (lease);
1105	}
1106}
1107
1108void
1109dhcp_reply(struct lease *lease)
1110{
1111	int bufs = 0, packet_length, result, i;
1112	struct dhcp_packet raw;
1113	struct sockaddr_in to;
1114	struct in_addr from;
1115	struct hardware hto;
1116	struct lease_state *state = lease->state;
1117	int nulltp, bootpp;
1118	u_int8_t *prl;
1119	int prl_len;
1120
1121	if (!state)
1122		error("dhcp_reply was supplied lease with no state!");
1123
1124	/* Compose a response for the client... */
1125	memset(&raw, 0, sizeof raw);
1126
1127	/* Copy in the filename if given; otherwise, flag the filename
1128	   buffer as available for options. */
1129	if (state->filename[0])
1130		strlcpy(raw.file, state->filename, sizeof raw.file);
1131	else
1132		bufs |= 1;
1133
1134	/* Copy in the server name if given; otherwise, flag the
1135	   server_name buffer as available for options. */
1136	if (state->server_name)
1137		strlcpy(raw.sname, state->server_name, sizeof raw.sname);
1138	else
1139		bufs |= 2; /* XXX */
1140
1141	memcpy(raw.chaddr, lease->hardware_addr.haddr, sizeof raw.chaddr);
1142	raw.hlen = lease->hardware_addr.hlen;
1143	raw.htype = lease->hardware_addr.htype;
1144
1145	/* See if this is a Microsoft client that NUL-terminates its
1146	   strings and expects us to do likewise... */
1147	if (lease->flags & MS_NULL_TERMINATION)
1148		nulltp = 1;
1149	else
1150		nulltp = 0;
1151
1152	/* See if this is a bootp client... */
1153	if (state->offer)
1154		bootpp = 0;
1155	else
1156		bootpp = 1;
1157
1158	if (state->options[DHO_DHCP_PARAMETER_REQUEST_LIST] &&
1159	    state->options[DHO_DHCP_PARAMETER_REQUEST_LIST]->value) {
1160		prl = state->options[DHO_DHCP_PARAMETER_REQUEST_LIST]->value;
1161		prl_len = state->options[DHO_DHCP_PARAMETER_REQUEST_LIST]->len;
1162	} else if (state->prl) {
1163		prl = state->prl;
1164		prl_len = state->prl_len;
1165	} else {
1166		prl = NULL;
1167		prl_len = 0;
1168	}
1169
1170	/* Insert such options as will fit into the buffer. */
1171	packet_length = cons_options(NULL, &raw, state->max_message_size,
1172	    state->options, bufs, nulltp, bootpp, prl, prl_len);
1173
1174	/* Having done the cons_options(), we can release the tree_cache
1175	   entries. */
1176	for (i = 0; i < 256; i++) {
1177		if (state->options[i] &&
1178		    state->options[i]->flags & TC_TEMPORARY)
1179			free_tree_cache(state->options[i], "dhcp_reply");
1180	}
1181
1182	memcpy(&raw.ciaddr, &state->ciaddr, sizeof raw.ciaddr);
1183	memcpy(&raw.yiaddr, lease->ip_addr.iabuf, 4);
1184
1185	/* Figure out the address of the next server. */
1186	if (lease->host && lease->host->group->next_server.len)
1187		memcpy(&raw.siaddr, lease->host->group->next_server.iabuf, 4);
1188	else if (lease->subnet->group->next_server.len)
1189		memcpy(&raw.siaddr, lease->subnet->group->next_server.iabuf, 4);
1190	else if (lease->subnet->interface_address.len)
1191		memcpy(&raw.siaddr, lease->subnet->interface_address.iabuf, 4);
1192	else
1193		raw.siaddr = state->ip->primary_address;
1194
1195	raw.giaddr = state->giaddr;
1196
1197	raw.xid = state->xid;
1198	raw.secs = state->secs;
1199	raw.flags = state->bootp_flags;
1200	raw.hops = state->hops;
1201	raw.op = BOOTREPLY;
1202
1203	/* Say what we're doing... */
1204	note("%s on %s to %s via %s",
1205	    (state->offer ? (state->offer == DHCPACK ? "DHCPACK" : "DHCPOFFER") :
1206	    "BOOTREPLY"),
1207	    piaddr(lease->ip_addr),
1208	    print_hw_addr(lease->hardware_addr.htype, lease->hardware_addr.hlen,
1209	    lease->hardware_addr.haddr),
1210	    state->giaddr.s_addr ? inet_ntoa(state->giaddr) : state->ip->name);
1211
1212	/* Set up the hardware address... */
1213	hto.htype = lease->hardware_addr.htype;
1214	hto.hlen = lease->hardware_addr.hlen;
1215	memcpy(hto.haddr, lease->hardware_addr.haddr, hto.hlen);
1216
1217	memset(&to, 0, sizeof to);
1218	to.sin_family = AF_INET;
1219#ifdef HAVE_SA_LEN
1220	to.sin_len = sizeof to;
1221#endif
1222
1223#ifdef DEBUG_PACKET
1224	dump_raw((unsigned char *)&raw, packet_length);
1225#endif
1226
1227	/* Make sure outgoing packets are at least as big
1228	   as a BOOTP packet. */
1229	if (packet_length < BOOTP_MIN_LEN)
1230		packet_length = BOOTP_MIN_LEN;
1231
1232	/* If this was gatewayed, send it back to the gateway... */
1233	if (raw.giaddr.s_addr) {
1234		to.sin_addr = raw.giaddr;
1235		to.sin_port = local_port;
1236
1237		if (fallback_interface) {
1238			result = send_packet(fallback_interface, NULL,
1239			    &raw, packet_length,raw.siaddr, &to, NULL);
1240
1241			free_lease_state(state, "dhcp_reply fallback 1");
1242			lease->state = NULL;
1243			return;
1244		}
1245
1246	/* If the client is RENEWING, unicast to the client using the
1247	   regular IP stack.  Some clients, particularly those that
1248	   follow RFC1541, are buggy, and send both ciaddr and
1249	   server-identifier.  We deal with this situation by assuming
1250	   that if we got both dhcp-server-identifier and ciaddr, and
1251	   giaddr was not set, then the client is on the local
1252	   network, and we can therefore unicast or broadcast to it
1253	   successfully.  A client in REQUESTING state on another
1254	   network that's making this mistake will have set giaddr,
1255	   and will therefore get a relayed response from the above
1256	   code. */
1257	} else if (raw.ciaddr.s_addr &&
1258	    !((state->got_server_identifier ||
1259	    (raw.flags & htons(BOOTP_BROADCAST))) &&
1260	    /* XXX This won't work if giaddr isn't zero, but it is: */
1261	    (state->shared_network == lease->shared_network)) &&
1262	    state->offer == DHCPACK) {
1263		to.sin_addr = raw.ciaddr;
1264		to.sin_port = remote_port;
1265
1266		if (fallback_interface) {
1267			result = send_packet(fallback_interface, NULL,
1268			    &raw, packet_length, raw.siaddr, &to, NULL);
1269			free_lease_state(state, "dhcp_reply fallback 2");
1270			lease->state = NULL;
1271			return;
1272		}
1273
1274	/* If it comes from a client that already knows its address
1275	   and is not requesting a broadcast response, and we can
1276	   unicast to a client without using the ARP protocol, sent it
1277	   directly to that client. */
1278	} else if (!(raw.flags & htons (BOOTP_BROADCAST))) {
1279		to.sin_addr = raw.yiaddr;
1280		to.sin_port = remote_port;
1281
1282	/* Otherwise, broadcast it on the local network. */
1283	} else {
1284		to.sin_addr.s_addr = htonl(INADDR_BROADCAST);
1285		to.sin_port = remote_port;
1286	}
1287
1288	memcpy(&from, state->from.iabuf, sizeof from);
1289
1290	result = send_packet(state->ip, NULL, &raw, packet_length,
1291	    from, &to, &hto);
1292
1293	free_lease_state(state, "dhcp_reply");
1294	lease->state = NULL;
1295}
1296
1297struct lease *
1298find_lease(struct packet *packet, struct shared_network *share,
1299    int *ours)
1300{
1301	struct lease *uid_lease, *ip_lease, *hw_lease;
1302	struct lease *lease = NULL;
1303	struct iaddr cip;
1304	struct host_decl *hp, *host = NULL;
1305	struct lease *fixed_lease;
1306
1307	/* Figure out what IP address the client is requesting, if any. */
1308	if (packet->options[DHO_DHCP_REQUESTED_ADDRESS].len &&
1309	    packet->options[DHO_DHCP_REQUESTED_ADDRESS].len == 4) {
1310		packet->got_requested_address = 1;
1311		cip.len = 4;
1312		memcpy(cip.iabuf,
1313		    packet->options[DHO_DHCP_REQUESTED_ADDRESS].data,
1314		    cip.len);
1315	} else if (packet->raw->ciaddr.s_addr) {
1316		cip.len = 4;
1317		memcpy(cip.iabuf, &packet->raw->ciaddr, 4);
1318	} else
1319		cip.len = 0;
1320
1321	/* Try to find a host or lease that's been assigned to the
1322	   specified unique client identifier. */
1323	if (packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len) {
1324		/* First, try to find a fixed host entry for the specified
1325		   client identifier... */
1326		hp = find_hosts_by_uid(
1327		    packet->options[DHO_DHCP_CLIENT_IDENTIFIER].data,
1328		    packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len);
1329		if (hp) {
1330			host = hp;
1331			fixed_lease = mockup_lease(packet, share, hp);
1332			uid_lease = NULL;
1333		} else {
1334			uid_lease = find_lease_by_uid(
1335			    packet->options[DHO_DHCP_CLIENT_IDENTIFIER].data,
1336			    packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len);
1337			/* Find the lease matching this uid that's on the
1338			   network the packet came from (if any). */
1339			for (; uid_lease; uid_lease = uid_lease->n_uid)
1340				if (uid_lease->shared_network == share)
1341					break;
1342			fixed_lease = NULL;
1343			if (uid_lease && (uid_lease->flags & ABANDONED_LEASE))
1344				uid_lease = NULL;
1345		}
1346	} else {
1347		uid_lease = NULL;
1348		fixed_lease = NULL;
1349	}
1350
1351	/* If we didn't find a fixed lease using the uid, try doing
1352	   it with the hardware address... */
1353	if (!fixed_lease) {
1354		hp = find_hosts_by_haddr(packet->raw->htype,
1355		    packet->raw->chaddr, packet->raw->hlen);
1356		if (hp) {
1357			host = hp; /* Save it for later. */
1358			fixed_lease = mockup_lease (packet, share, hp);
1359		}
1360	}
1361
1362	/* If fixed_lease is present but does not match the requested
1363	   IP address, and this is a DHCPREQUEST, then we can't return
1364	   any other lease, so we might as well return now. */
1365	if (packet->packet_type == DHCPREQUEST && fixed_lease &&
1366	    (fixed_lease->ip_addr.len != cip.len ||
1367	    memcmp(fixed_lease->ip_addr.iabuf, cip.iabuf, cip.len))) {
1368		if (ours)
1369			*ours = 1;
1370		strlcpy(dhcp_message, "requested address is incorrect",
1371		    sizeof (dhcp_message));
1372		return NULL;
1373	}
1374
1375	/* Try to find a lease that's been attached to the client's
1376	   hardware address... */
1377	hw_lease = find_lease_by_hw_addr(packet->raw->chaddr,
1378	    packet->raw->hlen);
1379	/* Find the lease that's on the network the packet came from
1380	   (if any). */
1381	for (; hw_lease; hw_lease = hw_lease->n_hw) {
1382		if (hw_lease->shared_network == share) {
1383			if ((hw_lease->flags & ABANDONED_LEASE))
1384				continue;
1385			if (packet->packet_type)
1386				break;
1387			if (hw_lease->flags &
1388			    (BOOTP_LEASE | DYNAMIC_BOOTP_OK))
1389				break;
1390		}
1391	}
1392
1393	/* Try to find a lease that's been allocated to the client's
1394	   IP address. */
1395	if (cip.len)
1396		ip_lease = find_lease_by_ip_addr(cip);
1397	else
1398		ip_lease = NULL;
1399
1400	/* If ip_lease is valid at this point, set ours to one, so that
1401	   even if we choose a different lease, we know that the address
1402	   the client was requesting was ours, and thus we can NAK it. */
1403	if (ip_lease && ours)
1404		*ours = 1;
1405
1406	/* If the requested IP address isn't on the network the packet
1407	   came from, don't use it.  Allow abandoned leases to be matched
1408	   here - if the client is requesting it, there's a decent chance
1409	   that it's because the lease database got trashed and a client
1410	   that thought it had this lease answered an ARP or PING, causing the
1411	   lease to be abandoned.   If so, this request probably came from
1412	   that client. */
1413	if (ip_lease && (ip_lease->shared_network != share)) {
1414		ip_lease = NULL;
1415		strlcpy(dhcp_message, "requested address on bad subnet",
1416		    sizeof(dhcp_message));
1417	}
1418
1419	/* Toss ip_lease if it hasn't yet expired and isn't owned by the
1420	   client. */
1421	if (ip_lease && ip_lease->ends >= cur_time && ip_lease != uid_lease) {
1422		int i = DHO_DHCP_CLIENT_IDENTIFIER;
1423
1424		/* Make sure that ip_lease actually belongs to the client,
1425		   and toss it if not. */
1426		if ((ip_lease->uid_len && packet->options[i].data &&
1427		    ip_lease->uid_len == packet->options[i].len &&
1428		    !memcmp(packet->options[i].data, ip_lease->uid,
1429		    ip_lease->uid_len)) ||
1430		    (!ip_lease->uid_len &&
1431		    ip_lease->hardware_addr.htype == packet->raw->htype &&
1432		    ip_lease->hardware_addr.hlen == packet->raw->hlen &&
1433		    !memcmp(ip_lease->hardware_addr.haddr, packet->raw->chaddr,
1434		    ip_lease->hardware_addr.hlen))) {
1435			if (uid_lease) {
1436				if (uid_lease->ends > cur_time) {
1437					warn("client %s has duplicate leases on %s",
1438					    print_hw_addr(packet->raw->htype,
1439					    packet->raw->hlen, packet->raw->chaddr),
1440					    ip_lease->shared_network->name);
1441
1442					if (uid_lease && !packet->raw->ciaddr.s_addr)
1443						release_lease (uid_lease);
1444				}
1445				uid_lease = ip_lease;
1446			}
1447		} else {
1448			strlcpy(dhcp_message, "requested address is not available",
1449			    sizeof(dhcp_message));
1450			ip_lease = NULL;
1451		}
1452
1453		/* If we get to here and fixed_lease is not null, that means
1454		   that there are both a dynamic lease and a fixed-address
1455		   declaration for the same IP address. */
1456		if (packet->packet_type == DHCPREQUEST && fixed_lease) {
1457			fixed_lease = NULL;
1458db_conflict:
1459			warn("Both dynamic and static leases present for %s.",
1460			    piaddr(cip));
1461			warn("Either remove host declaration %s or remove %s",
1462			    (fixed_lease && fixed_lease->host ?
1463			    (fixed_lease->host->name ? fixed_lease->host->name :
1464			    piaddr(cip)) : piaddr(cip)), piaddr(cip));
1465			warn("from the dynamic address pool for %s",
1466			    share->name);
1467			if (fixed_lease)
1468				ip_lease = NULL;
1469			strlcpy(dhcp_message, "database conflict - call for help!",
1470			    sizeof(dhcp_message));
1471		}
1472	}
1473
1474	/* If we get to here with both fixed_lease and ip_lease not
1475	   null, then we have a configuration file bug. */
1476	if (packet->packet_type == DHCPREQUEST && fixed_lease && ip_lease)
1477		goto db_conflict;
1478
1479	/* Toss hw_lease if it hasn't yet expired and the uid doesn't
1480	   match, except that if the hardware address matches and the
1481	   client is now doing dynamic BOOTP (and thus hasn't provided
1482	   a uid) we let the client get away with it. */
1483	if (hw_lease && hw_lease->ends >= cur_time && hw_lease->uid &&
1484	    packet->options[DHO_DHCP_CLIENT_IDENTIFIER].len &&
1485	    hw_lease != uid_lease)
1486		hw_lease = NULL;
1487
1488	/* Toss extra pointers to the same lease... */
1489	if (hw_lease == uid_lease)
1490		hw_lease = NULL;
1491	if (ip_lease == hw_lease)
1492		hw_lease = NULL;
1493	if (ip_lease == uid_lease)
1494		uid_lease = NULL;
1495
1496	/* If we've already eliminated the lease, it wasn't there to
1497	   begin with.   If we have come up with a matching lease,
1498	   set the message to bad network in case we have to throw it out. */
1499	if (!ip_lease) {
1500		strlcpy(dhcp_message, "requested address not available",
1501		    sizeof(dhcp_message));
1502	}
1503
1504	/* Now eliminate leases that are on the wrong network... */
1505	if (ip_lease && share != ip_lease->shared_network) {
1506		if (packet->packet_type == DHCPREQUEST)
1507			release_lease(ip_lease);
1508		ip_lease = NULL;
1509	}
1510	if (uid_lease && share != uid_lease->shared_network) {
1511		if (packet->packet_type == DHCPREQUEST)
1512			release_lease(uid_lease);
1513		uid_lease = NULL;
1514	}
1515	if (hw_lease && share != hw_lease->shared_network) {
1516		if (packet->packet_type == DHCPREQUEST)
1517			release_lease(hw_lease);
1518		hw_lease = NULL;
1519	}
1520
1521	/* If this is a DHCPREQUEST, make sure the lease we're going to return
1522	   matches the requested IP address.   If it doesn't, don't return a
1523	   lease at all. */
1524	if (packet->packet_type == DHCPREQUEST && !ip_lease && !fixed_lease)
1525		return NULL;
1526
1527	/* At this point, if fixed_lease is nonzero, we can assign it to
1528	   this client. */
1529	if (fixed_lease)
1530		lease = fixed_lease;
1531
1532	/* If we got a lease that matched the ip address and don't have
1533	   a better offer, use that; otherwise, release it. */
1534	if (ip_lease) {
1535		if (lease) {
1536			if (packet->packet_type == DHCPREQUEST)
1537				release_lease(ip_lease);
1538		} else {
1539			lease = ip_lease;
1540			lease->host = NULL;
1541		}
1542	}
1543
1544	/* If we got a lease that matched the client identifier, we may want
1545	   to use it, but if we already have a lease we like, we must free
1546	   the lease that matched the client identifier. */
1547	if (uid_lease) {
1548		if (lease) {
1549			if (packet->packet_type == DHCPREQUEST)
1550				release_lease(uid_lease);
1551		} else {
1552			lease = uid_lease;
1553			lease->host = NULL;
1554		}
1555	}
1556
1557	/* The lease that matched the hardware address is treated likewise. */
1558	if (hw_lease) {
1559		if (lease) {
1560			if (packet->packet_type == DHCPREQUEST)
1561				release_lease(hw_lease);
1562		} else {
1563			lease = hw_lease;
1564			lease->host = NULL;
1565		}
1566	}
1567
1568	/* If we found a host_decl but no matching address, try to
1569	   find a host_decl that has no address, and if there is one,
1570	   hang it off the lease so that we can use the supplied
1571	   options. */
1572	if (lease && host && !lease->host) {
1573		for (; host; host = host->n_ipaddr) {
1574			if (!host->fixed_addr) {
1575				lease->host = host;
1576				break;
1577			}
1578		}
1579	}
1580
1581	/* If we find an abandoned lease, take it, but print a
1582	   warning message, so that if it continues to lose,
1583	   the administrator will eventually investigate. */
1584	if (lease && (lease->flags & ABANDONED_LEASE)) {
1585		if (packet->packet_type == DHCPREQUEST) {
1586			warn("Reclaiming REQUESTed abandoned IP address %s.",
1587			    piaddr(lease->ip_addr));
1588			lease->flags &= ~ABANDONED_LEASE;
1589		} else
1590			lease = NULL;
1591	}
1592	return lease;
1593}
1594
1595/*
1596 * Search the provided host_decl structure list for an address that's on
1597 * the specified shared network.  If one is found, mock up and return a
1598 * lease structure for it; otherwise return the null pointer.
1599 */
1600struct lease *
1601mockup_lease(struct packet *packet, struct shared_network *share,
1602    struct host_decl *hp)
1603{
1604	static struct lease mock;
1605
1606	mock.subnet = find_host_for_network(&hp, &mock.ip_addr, share);
1607	if (!mock.subnet)
1608		return (NULL);
1609	mock.next = mock.prev = NULL;
1610	mock.shared_network = mock.subnet->shared_network;
1611	mock.host = hp;
1612
1613	if (hp->group->options[DHO_DHCP_CLIENT_IDENTIFIER]) {
1614		mock.uid = hp->group->options[DHO_DHCP_CLIENT_IDENTIFIER]->value;
1615		mock.uid_len = hp->group->options[DHO_DHCP_CLIENT_IDENTIFIER]->len;
1616	} else {
1617		mock.uid = NULL;
1618		mock.uid_len = 0;
1619	}
1620
1621	mock.hardware_addr = hp->interface;
1622	mock.starts = mock.timestamp = mock.ends = MIN_TIME;
1623	mock.flags = STATIC_LEASE;
1624	return &mock;
1625}
1626