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