xref: /freebsd/sbin/dhclient/dhclient.c (revision 9bfb310cf39c686dfa54b4910ee9ccabd200bae4)
1 /*	$OpenBSD: dhclient.c,v 1.63 2005/02/06 17:10:13 krw Exp $	*/
2 
3 /*
4  * Copyright 2004 Henning Brauer <henning@openbsd.org>
5  * Copyright (c) 1995, 1996, 1997, 1998, 1999
6  * The Internet Software Consortium.    All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. Neither the name of The Internet Software Consortium nor the names
18  *    of its contributors may be used to endorse or promote products derived
19  *    from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
22  * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
23  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25  * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
26  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
29  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  * This software has been written for the Internet Software Consortium
36  * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
37  * Enterprises.  To learn more about the Internet Software Consortium,
38  * see ``http://www.vix.com/isc''.  To learn more about Vixie
39  * Enterprises, see ``http://www.vix.com''.
40  *
41  * This client was substantially modified and enhanced by Elliot Poger
42  * for use on Linux while he was working on the MosquitoNet project at
43  * Stanford.
44  *
45  * The current version owes much to Elliot's Linux enhancements, but
46  * was substantially reorganized and partially rewritten by Ted Lemon
47  * so as to use the same networking framework that the Internet Software
48  * Consortium DHCP server uses.   Much system-specific configuration code
49  * was moved into a shell script so that as support for more operating
50  * systems is added, it will not be necessary to port and maintain
51  * system-specific configuration code to these operating systems - instead,
52  * the shell script can invoke the native tools to accomplish the same
53  * purpose.
54  */
55 
56 #include <sys/cdefs.h>
57 __FBSDID("$FreeBSD$");
58 
59 #include "dhcpd.h"
60 #include "privsep.h"
61 
62 #include <sys/capsicum.h>
63 #include <sys/endian.h>
64 
65 #include <net80211/ieee80211_freebsd.h>
66 
67 #ifndef _PATH_VAREMPTY
68 #define	_PATH_VAREMPTY	"/var/empty"
69 #endif
70 
71 #define	PERIOD 0x2e
72 #define	hyphenchar(c) ((c) == 0x2d)
73 #define	bslashchar(c) ((c) == 0x5c)
74 #define	periodchar(c) ((c) == PERIOD)
75 #define	asterchar(c) ((c) == 0x2a)
76 #define	alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) || \
77 	    ((c) >= 0x61 && (c) <= 0x7a))
78 #define	digitchar(c) ((c) >= 0x30 && (c) <= 0x39)
79 #define	whitechar(c) ((c) == ' ' || (c) == '\t')
80 
81 #define	borderchar(c) (alphachar(c) || digitchar(c))
82 #define	middlechar(c) (borderchar(c) || hyphenchar(c))
83 #define	domainchar(c) ((c) > 0x20 && (c) < 0x7f)
84 
85 #define	CLIENT_PATH "PATH=/usr/bin:/usr/sbin:/bin:/sbin"
86 
87 time_t cur_time;
88 time_t default_lease_time = 43200; /* 12 hours... */
89 
90 char *path_dhclient_conf = _PATH_DHCLIENT_CONF;
91 char *path_dhclient_db = NULL;
92 
93 int log_perror = 1;
94 int privfd;
95 int nullfd = -1;
96 
97 char hostname[_POSIX_HOST_NAME_MAX + 1];
98 
99 struct iaddr iaddr_broadcast = { 4, { 255, 255, 255, 255 } };
100 struct in_addr inaddr_any, inaddr_broadcast;
101 
102 char *path_dhclient_pidfile;
103 struct pidfh *pidfile;
104 
105 /*
106  * ASSERT_STATE() does nothing now; it used to be
107  * assert (state_is == state_shouldbe).
108  */
109 #define ASSERT_STATE(state_is, state_shouldbe) {}
110 
111 #define TIME_MAX 2147483647
112 
113 int		log_priority;
114 int		no_daemon;
115 int		unknown_ok = 1;
116 int		routefd;
117 
118 struct interface_info	*ifi;
119 
120 int		 findproto(char *, int);
121 struct sockaddr	*get_ifa(char *, int);
122 void		 routehandler(struct protocol *);
123 void		 usage(void);
124 int		 check_option(struct client_lease *l, int option);
125 int		 check_classless_option(unsigned char *data, int len);
126 int		 ipv4addrs(char * buf);
127 int		 res_hnok(const char *dn);
128 int		 check_search(const char *srch);
129 char		*option_as_string(unsigned int code, unsigned char *data, int len);
130 int		 fork_privchld(int, int);
131 
132 #define	ROUNDUP(a) \
133 	    ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
134 #define	ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
135 
136 /* Minimum MTU is 68 as per RFC791, p. 24 */
137 #define MIN_MTU 68
138 
139 static time_t	scripttime;
140 
141 int
142 findproto(char *cp, int n)
143 {
144 	struct sockaddr *sa;
145 	int i;
146 
147 	if (n == 0)
148 		return -1;
149 	for (i = 1; i; i <<= 1) {
150 		if (i & n) {
151 			sa = (struct sockaddr *)cp;
152 			switch (i) {
153 			case RTA_IFA:
154 			case RTA_DST:
155 			case RTA_GATEWAY:
156 			case RTA_NETMASK:
157 				if (sa->sa_family == AF_INET)
158 					return AF_INET;
159 				if (sa->sa_family == AF_INET6)
160 					return AF_INET6;
161 				break;
162 			case RTA_IFP:
163 				break;
164 			}
165 			ADVANCE(cp, sa);
166 		}
167 	}
168 	return (-1);
169 }
170 
171 struct sockaddr *
172 get_ifa(char *cp, int n)
173 {
174 	struct sockaddr *sa;
175 	int i;
176 
177 	if (n == 0)
178 		return (NULL);
179 	for (i = 1; i; i <<= 1)
180 		if (i & n) {
181 			sa = (struct sockaddr *)cp;
182 			if (i == RTA_IFA)
183 				return (sa);
184 			ADVANCE(cp, sa);
185 		}
186 
187 	return (NULL);
188 }
189 
190 struct iaddr defaddr = { 4 };
191 uint8_t curbssid[6];
192 
193 static void
194 disassoc(void *arg)
195 {
196 	struct interface_info *ifi = arg;
197 
198 	/*
199 	 * Clear existing state.
200 	 */
201 	if (ifi->client->active != NULL) {
202 		script_init("EXPIRE", NULL);
203 		script_write_params("old_",
204 		    ifi->client->active);
205 		if (ifi->client->alias)
206 			script_write_params("alias_",
207 				ifi->client->alias);
208 		script_go();
209 	}
210 	ifi->client->state = S_INIT;
211 }
212 
213 /* ARGSUSED */
214 void
215 routehandler(struct protocol *p)
216 {
217 	char msg[2048], *addr;
218 	struct rt_msghdr *rtm;
219 	struct if_msghdr *ifm;
220 	struct ifa_msghdr *ifam;
221 	struct if_announcemsghdr *ifan;
222 	struct ieee80211_join_event *jev;
223 	struct client_lease *l;
224 	time_t t = time(NULL);
225 	struct sockaddr *sa;
226 	struct iaddr a;
227 	ssize_t n;
228 	int linkstat;
229 
230 	n = read(routefd, &msg, sizeof(msg));
231 	rtm = (struct rt_msghdr *)msg;
232 	if (n < sizeof(rtm->rtm_msglen) || n < rtm->rtm_msglen ||
233 	    rtm->rtm_version != RTM_VERSION)
234 		return;
235 
236 	switch (rtm->rtm_type) {
237 	case RTM_NEWADDR:
238 	case RTM_DELADDR:
239 		ifam = (struct ifa_msghdr *)rtm;
240 
241 		if (ifam->ifam_index != ifi->index)
242 			break;
243 		if (findproto((char *)(ifam + 1), ifam->ifam_addrs) != AF_INET)
244 			break;
245 		if (scripttime == 0 || t < scripttime + 10)
246 			break;
247 
248 		sa = get_ifa((char *)(ifam + 1), ifam->ifam_addrs);
249 		if (sa == NULL)
250 			break;
251 
252 		if ((a.len = sizeof(struct in_addr)) > sizeof(a.iabuf))
253 			error("king bula sez: len mismatch");
254 		memcpy(a.iabuf, &((struct sockaddr_in *)sa)->sin_addr, a.len);
255 		if (addr_eq(a, defaddr))
256 			break;
257 
258 		for (l = ifi->client->active; l != NULL; l = l->next)
259 			if (addr_eq(a, l->address))
260 				break;
261 
262 		if (l == NULL)	/* added/deleted addr is not the one we set */
263 			break;
264 
265 		addr = inet_ntoa(((struct sockaddr_in *)sa)->sin_addr);
266 		if (rtm->rtm_type == RTM_NEWADDR)  {
267 			/*
268 			 * XXX: If someone other than us adds our address,
269 			 * should we assume they are taking over from us,
270 			 * delete the lease record, and exit without modifying
271 			 * the interface?
272 			 */
273 			warning("My address (%s) was re-added", addr);
274 		} else {
275 			warning("My address (%s) was deleted, dhclient exiting",
276 			    addr);
277 			goto die;
278 		}
279 		break;
280 	case RTM_IFINFO:
281 		ifm = (struct if_msghdr *)rtm;
282 		if (ifm->ifm_index != ifi->index)
283 			break;
284 		if ((rtm->rtm_flags & RTF_UP) == 0) {
285 			warning("Interface %s is down, dhclient exiting",
286 			    ifi->name);
287 			goto die;
288 		}
289 		linkstat = interface_link_status(ifi->name);
290 		if (linkstat != ifi->linkstat) {
291 			debug("%s link state %s -> %s", ifi->name,
292 			    ifi->linkstat ? "up" : "down",
293 			    linkstat ? "up" : "down");
294 			ifi->linkstat = linkstat;
295 			if (linkstat)
296 				state_reboot(ifi);
297 		}
298 		break;
299 	case RTM_IFANNOUNCE:
300 		ifan = (struct if_announcemsghdr *)rtm;
301 		if (ifan->ifan_what == IFAN_DEPARTURE &&
302 		    ifan->ifan_index == ifi->index) {
303 			warning("Interface %s is gone, dhclient exiting",
304 			    ifi->name);
305 			goto die;
306 		}
307 		break;
308 	case RTM_IEEE80211:
309 		ifan = (struct if_announcemsghdr *)rtm;
310 		if (ifan->ifan_index != ifi->index)
311 			break;
312 		switch (ifan->ifan_what) {
313 		case RTM_IEEE80211_ASSOC:
314 		case RTM_IEEE80211_REASSOC:
315 			/*
316 			 * Use assoc/reassoc event to kick state machine
317 			 * in case we roam.  Otherwise fall back to the
318 			 * normal state machine just like a wired network.
319 			 */
320 			jev = (struct ieee80211_join_event *) &ifan[1];
321 			if (memcmp(curbssid, jev->iev_addr, 6)) {
322 				disassoc(ifi);
323 				state_reboot(ifi);
324 			}
325 			memcpy(curbssid, jev->iev_addr, 6);
326 			break;
327 		}
328 		break;
329 	default:
330 		break;
331 	}
332 	return;
333 
334 die:
335 	script_init("FAIL", NULL);
336 	if (ifi->client->alias)
337 		script_write_params("alias_", ifi->client->alias);
338 	script_go();
339 	if (pidfile != NULL)
340 		pidfile_remove(pidfile);
341 	exit(1);
342 }
343 
344 int
345 main(int argc, char *argv[])
346 {
347 	extern char		*__progname;
348 	int			 ch, fd, quiet = 0, i = 0;
349 	int			 pipe_fd[2];
350 	int			 immediate_daemon = 0;
351 	struct passwd		*pw;
352 	pid_t			 otherpid;
353 	cap_rights_t		 rights;
354 
355 	/* Initially, log errors to stderr as well as to syslogd. */
356 	openlog(__progname, LOG_PID | LOG_NDELAY, DHCPD_LOG_FACILITY);
357 	setlogmask(LOG_UPTO(LOG_DEBUG));
358 
359 	while ((ch = getopt(argc, argv, "bc:dl:p:qu")) != -1)
360 		switch (ch) {
361 		case 'b':
362 			immediate_daemon = 1;
363 			break;
364 		case 'c':
365 			path_dhclient_conf = optarg;
366 			break;
367 		case 'd':
368 			no_daemon = 1;
369 			break;
370 		case 'l':
371 			path_dhclient_db = optarg;
372 			break;
373 		case 'p':
374 			path_dhclient_pidfile = optarg;
375 			break;
376 		case 'q':
377 			quiet = 1;
378 			break;
379 		case 'u':
380 			unknown_ok = 0;
381 			break;
382 		default:
383 			usage();
384 		}
385 
386 	argc -= optind;
387 	argv += optind;
388 
389 	if (argc != 1)
390 		usage();
391 
392 	if (path_dhclient_pidfile == NULL) {
393 		asprintf(&path_dhclient_pidfile,
394 		    "%sdhclient.%s.pid", _PATH_VARRUN, *argv);
395 		if (path_dhclient_pidfile == NULL)
396 			error("asprintf");
397 	}
398 	pidfile = pidfile_open(path_dhclient_pidfile, 0644, &otherpid);
399 	if (pidfile == NULL) {
400 		if (errno == EEXIST)
401 			error("dhclient already running, pid: %d.", otherpid);
402 		if (errno == EAGAIN)
403 			error("dhclient already running.");
404 		warning("Cannot open or create pidfile: %m");
405 	}
406 
407 	if ((ifi = calloc(1, sizeof(struct interface_info))) == NULL)
408 		error("calloc");
409 	if (strlcpy(ifi->name, argv[0], IFNAMSIZ) >= IFNAMSIZ)
410 		error("Interface name too long");
411 	if (path_dhclient_db == NULL && asprintf(&path_dhclient_db, "%s.%s",
412 	    _PATH_DHCLIENT_DB, ifi->name) == -1)
413 		error("asprintf");
414 
415 	if (quiet)
416 		log_perror = 0;
417 
418 	tzset();
419 	time(&cur_time);
420 
421 	inaddr_broadcast.s_addr = INADDR_BROADCAST;
422 	inaddr_any.s_addr = INADDR_ANY;
423 
424 	read_client_conf();
425 
426 	/* The next bit is potentially very time-consuming, so write out
427 	   the pidfile right away.  We will write it out again with the
428 	   correct pid after daemonizing. */
429 	if (pidfile != NULL)
430 		pidfile_write(pidfile);
431 
432 	if (!interface_link_status(ifi->name)) {
433 		fprintf(stderr, "%s: no link ...", ifi->name);
434 		fflush(stderr);
435 		sleep(1);
436 		while (!interface_link_status(ifi->name)) {
437 			fprintf(stderr, ".");
438 			fflush(stderr);
439 			if (++i > 10) {
440 				fprintf(stderr, " giving up\n");
441 				exit(1);
442 			}
443 			sleep(1);
444 		}
445 		fprintf(stderr, " got link\n");
446 	}
447 	ifi->linkstat = 1;
448 
449 	if ((nullfd = open(_PATH_DEVNULL, O_RDWR, 0)) == -1)
450 		error("cannot open %s: %m", _PATH_DEVNULL);
451 
452 	if ((pw = getpwnam("_dhcp")) == NULL) {
453 		warning("no such user: _dhcp, falling back to \"nobody\"");
454 		if ((pw = getpwnam("nobody")) == NULL)
455 			error("no such user: nobody");
456 	}
457 
458 	/*
459 	 * Obtain hostname before entering capability mode - it won't be
460 	 * possible then, as reading kern.hostname is not permitted.
461 	 */
462 	if (gethostname(hostname, sizeof(hostname)) < 0)
463 		hostname[0] = '\0';
464 
465 	priv_script_init("PREINIT", NULL);
466 	if (ifi->client->alias)
467 		priv_script_write_params("alias_", ifi->client->alias);
468 	priv_script_go();
469 
470 	/* set up the interface */
471 	discover_interfaces(ifi);
472 
473 	if (pipe(pipe_fd) == -1)
474 		error("pipe");
475 
476 	fork_privchld(pipe_fd[0], pipe_fd[1]);
477 
478 	close(ifi->ufdesc);
479 	ifi->ufdesc = -1;
480 	close(ifi->wfdesc);
481 	ifi->wfdesc = -1;
482 
483 	close(pipe_fd[0]);
484 	privfd = pipe_fd[1];
485 	cap_rights_init(&rights, CAP_READ, CAP_WRITE);
486 	if (cap_rights_limit(privfd, &rights) < 0 && errno != ENOSYS)
487 		error("can't limit private descriptor: %m");
488 
489 	if ((fd = open(path_dhclient_db, O_RDONLY|O_EXLOCK|O_CREAT, 0)) == -1)
490 		error("can't open and lock %s: %m", path_dhclient_db);
491 	read_client_leases();
492 	rewrite_client_leases();
493 	close(fd);
494 
495 	if ((routefd = socket(PF_ROUTE, SOCK_RAW, 0)) != -1)
496 		add_protocol("AF_ROUTE", routefd, routehandler, ifi);
497 	if (shutdown(routefd, SHUT_WR) < 0)
498 		error("can't shutdown route socket: %m");
499 	cap_rights_init(&rights, CAP_EVENT, CAP_READ);
500 	if (cap_rights_limit(routefd, &rights) < 0 && errno != ENOSYS)
501 		error("can't limit route socket: %m");
502 
503 	if (chroot(_PATH_VAREMPTY) == -1)
504 		error("chroot");
505 	if (chdir("/") == -1)
506 		error("chdir(\"/\")");
507 
508 	if (setgroups(1, &pw->pw_gid) ||
509 	    setegid(pw->pw_gid) || setgid(pw->pw_gid) ||
510 	    seteuid(pw->pw_uid) || setuid(pw->pw_uid))
511 		error("can't drop privileges: %m");
512 
513 	endpwent();
514 
515 	setproctitle("%s", ifi->name);
516 
517 	if (cap_enter() < 0 && errno != ENOSYS)
518 		error("can't enter capability mode: %m");
519 
520 	if (immediate_daemon)
521 		go_daemon();
522 
523 	ifi->client->state = S_INIT;
524 	state_reboot(ifi);
525 
526 	bootp_packet_handler = do_packet;
527 
528 	dispatch();
529 
530 	/* not reached */
531 	return (0);
532 }
533 
534 void
535 usage(void)
536 {
537 	extern char	*__progname;
538 
539 	fprintf(stderr, "usage: %s [-bdqu] ", __progname);
540 	fprintf(stderr, "[-c conffile] [-l leasefile] interface\n");
541 	exit(1);
542 }
543 
544 /*
545  * Individual States:
546  *
547  * Each routine is called from the dhclient_state_machine() in one of
548  * these conditions:
549  * -> entering INIT state
550  * -> recvpacket_flag == 0: timeout in this state
551  * -> otherwise: received a packet in this state
552  *
553  * Return conditions as handled by dhclient_state_machine():
554  * Returns 1, sendpacket_flag = 1: send packet, reset timer.
555  * Returns 1, sendpacket_flag = 0: just reset the timer (wait for a milestone).
556  * Returns 0: finish the nap which was interrupted for no good reason.
557  *
558  * Several per-interface variables are used to keep track of the process:
559  *   active_lease: the lease that is being used on the interface
560  *                 (null pointer if not configured yet).
561  *   offered_leases: leases corresponding to DHCPOFFER messages that have
562  *                   been sent to us by DHCP servers.
563  *   acked_leases: leases corresponding to DHCPACK messages that have been
564  *                 sent to us by DHCP servers.
565  *   sendpacket: DHCP packet we're trying to send.
566  *   destination: IP address to send sendpacket to
567  * In addition, there are several relevant per-lease variables.
568  *   T1_expiry, T2_expiry, lease_expiry: lease milestones
569  * In the active lease, these control the process of renewing the lease;
570  * In leases on the acked_leases list, this simply determines when we
571  * can no longer legitimately use the lease.
572  */
573 
574 void
575 state_reboot(void *ipp)
576 {
577 	struct interface_info *ip = ipp;
578 
579 	/* If we don't remember an active lease, go straight to INIT. */
580 	if (!ip->client->active || ip->client->active->is_bootp) {
581 		state_init(ip);
582 		return;
583 	}
584 
585 	/* We are in the rebooting state. */
586 	ip->client->state = S_REBOOTING;
587 
588 	/* make_request doesn't initialize xid because it normally comes
589 	   from the DHCPDISCOVER, but we haven't sent a DHCPDISCOVER,
590 	   so pick an xid now. */
591 	ip->client->xid = arc4random();
592 
593 	/* Make a DHCPREQUEST packet, and set appropriate per-interface
594 	   flags. */
595 	make_request(ip, ip->client->active);
596 	ip->client->destination = iaddr_broadcast;
597 	ip->client->first_sending = cur_time;
598 	ip->client->interval = ip->client->config->initial_interval;
599 
600 	/* Zap the medium list... */
601 	ip->client->medium = NULL;
602 
603 	/* Send out the first DHCPREQUEST packet. */
604 	send_request(ip);
605 }
606 
607 /*
608  * Called when a lease has completely expired and we've
609  * been unable to renew it.
610  */
611 void
612 state_init(void *ipp)
613 {
614 	struct interface_info *ip = ipp;
615 
616 	ASSERT_STATE(state, S_INIT);
617 
618 	/* Make a DHCPDISCOVER packet, and set appropriate per-interface
619 	   flags. */
620 	make_discover(ip, ip->client->active);
621 	ip->client->xid = ip->client->packet.xid;
622 	ip->client->destination = iaddr_broadcast;
623 	ip->client->state = S_SELECTING;
624 	ip->client->first_sending = cur_time;
625 	ip->client->interval = ip->client->config->initial_interval;
626 
627 	/* Add an immediate timeout to cause the first DHCPDISCOVER packet
628 	   to go out. */
629 	send_discover(ip);
630 }
631 
632 /*
633  * state_selecting is called when one or more DHCPOFFER packets
634  * have been received and a configurable period of time has passed.
635  */
636 void
637 state_selecting(void *ipp)
638 {
639 	struct interface_info *ip = ipp;
640 	struct client_lease *lp, *next, *picked;
641 
642 	ASSERT_STATE(state, S_SELECTING);
643 
644 	/* Cancel state_selecting and send_discover timeouts, since either
645 	   one could have got us here. */
646 	cancel_timeout(state_selecting, ip);
647 	cancel_timeout(send_discover, ip);
648 
649 	/* We have received one or more DHCPOFFER packets.   Currently,
650 	   the only criterion by which we judge leases is whether or
651 	   not we get a response when we arp for them. */
652 	picked = NULL;
653 	for (lp = ip->client->offered_leases; lp; lp = next) {
654 		next = lp->next;
655 
656 		/* Check to see if we got an ARPREPLY for the address
657 		   in this particular lease. */
658 		if (!picked) {
659 			script_init("ARPCHECK", lp->medium);
660 			script_write_params("check_", lp);
661 
662 			/* If the ARPCHECK code detects another
663 			   machine using the offered address, it exits
664 			   nonzero.  We need to send a DHCPDECLINE and
665 			   toss the lease. */
666 			if (script_go()) {
667 				make_decline(ip, lp);
668 				send_decline(ip);
669 				goto freeit;
670 			}
671 			picked = lp;
672 			picked->next = NULL;
673 		} else {
674 freeit:
675 			free_client_lease(lp);
676 		}
677 	}
678 	ip->client->offered_leases = NULL;
679 
680 	/* If we just tossed all the leases we were offered, go back
681 	   to square one. */
682 	if (!picked) {
683 		ip->client->state = S_INIT;
684 		state_init(ip);
685 		return;
686 	}
687 
688 	/* If it was a BOOTREPLY, we can just take the address right now. */
689 	if (!picked->options[DHO_DHCP_MESSAGE_TYPE].len) {
690 		ip->client->new = picked;
691 
692 		/* Make up some lease expiry times
693 		   XXX these should be configurable. */
694 		ip->client->new->expiry = cur_time + 12000;
695 		ip->client->new->renewal += cur_time + 8000;
696 		ip->client->new->rebind += cur_time + 10000;
697 
698 		ip->client->state = S_REQUESTING;
699 
700 		/* Bind to the address we received. */
701 		bind_lease(ip);
702 		return;
703 	}
704 
705 	/* Go to the REQUESTING state. */
706 	ip->client->destination = iaddr_broadcast;
707 	ip->client->state = S_REQUESTING;
708 	ip->client->first_sending = cur_time;
709 	ip->client->interval = ip->client->config->initial_interval;
710 
711 	/* Make a DHCPREQUEST packet from the lease we picked. */
712 	make_request(ip, picked);
713 	ip->client->xid = ip->client->packet.xid;
714 
715 	/* Toss the lease we picked - we'll get it back in a DHCPACK. */
716 	free_client_lease(picked);
717 
718 	/* Add an immediate timeout to send the first DHCPREQUEST packet. */
719 	send_request(ip);
720 }
721 
722 /* state_requesting is called when we receive a DHCPACK message after
723    having sent out one or more DHCPREQUEST packets. */
724 
725 void
726 dhcpack(struct packet *packet)
727 {
728 	struct interface_info *ip = packet->interface;
729 	struct client_lease *lease;
730 
731 	/* If we're not receptive to an offer right now, or if the offer
732 	   has an unrecognizable transaction id, then just drop it. */
733 	if (packet->interface->client->xid != packet->raw->xid ||
734 	    (packet->interface->hw_address.hlen != packet->raw->hlen) ||
735 	    (memcmp(packet->interface->hw_address.haddr,
736 	    packet->raw->chaddr, packet->raw->hlen)))
737 		return;
738 
739 	if (ip->client->state != S_REBOOTING &&
740 	    ip->client->state != S_REQUESTING &&
741 	    ip->client->state != S_RENEWING &&
742 	    ip->client->state != S_REBINDING)
743 		return;
744 
745 	note("DHCPACK from %s", piaddr(packet->client_addr));
746 
747 	lease = packet_to_lease(packet);
748 	if (!lease) {
749 		note("packet_to_lease failed.");
750 		return;
751 	}
752 
753 	ip->client->new = lease;
754 
755 	/* Stop resending DHCPREQUEST. */
756 	cancel_timeout(send_request, ip);
757 
758 	/* Figure out the lease time. */
759 	if (ip->client->new->options[DHO_DHCP_LEASE_TIME].data)
760 		ip->client->new->expiry = getULong(
761 		    ip->client->new->options[DHO_DHCP_LEASE_TIME].data);
762 	else
763 		ip->client->new->expiry = default_lease_time;
764 	/* A number that looks negative here is really just very large,
765 	   because the lease expiry offset is unsigned. */
766 	if (ip->client->new->expiry < 0)
767 		ip->client->new->expiry = TIME_MAX;
768 	/* XXX should be fixed by resetting the client state */
769 	if (ip->client->new->expiry < 60)
770 		ip->client->new->expiry = 60;
771 
772         /* Unless overridden in the config, take the server-provided renewal
773          * time if there is one; otherwise figure it out according to the spec.
774          * Also make sure the renewal time does not exceed the expiry time.
775          */
776         if (ip->client->config->default_actions[DHO_DHCP_RENEWAL_TIME] ==
777             ACTION_SUPERSEDE)
778 		ip->client->new->renewal = getULong(
779 		    ip->client->config->defaults[DHO_DHCP_RENEWAL_TIME].data);
780         else if (ip->client->new->options[DHO_DHCP_RENEWAL_TIME].len)
781 		ip->client->new->renewal = getULong(
782 		    ip->client->new->options[DHO_DHCP_RENEWAL_TIME].data);
783 	else
784 		ip->client->new->renewal = ip->client->new->expiry / 2;
785         if (ip->client->new->renewal > ip->client->new->expiry / 2)
786                 ip->client->new->renewal = ip->client->new->expiry / 2;
787 
788 	/* Same deal with the rebind time. */
789         if (ip->client->config->default_actions[DHO_DHCP_REBINDING_TIME] ==
790             ACTION_SUPERSEDE)
791 		ip->client->new->rebind = getULong(
792 		    ip->client->config->defaults[DHO_DHCP_REBINDING_TIME].data);
793         else if (ip->client->new->options[DHO_DHCP_REBINDING_TIME].len)
794 		ip->client->new->rebind = getULong(
795 		    ip->client->new->options[DHO_DHCP_REBINDING_TIME].data);
796 	else
797 		ip->client->new->rebind = ip->client->new->renewal * 7 / 4;
798         if (ip->client->new->rebind > ip->client->new->renewal * 7 / 4)
799                 ip->client->new->rebind = ip->client->new->renewal * 7 / 4;
800 
801 	ip->client->new->expiry += cur_time;
802 	/* Lease lengths can never be negative. */
803 	if (ip->client->new->expiry < cur_time)
804 		ip->client->new->expiry = TIME_MAX;
805 	ip->client->new->renewal += cur_time;
806 	if (ip->client->new->renewal < cur_time)
807 		ip->client->new->renewal = TIME_MAX;
808 	ip->client->new->rebind += cur_time;
809 	if (ip->client->new->rebind < cur_time)
810 		ip->client->new->rebind = TIME_MAX;
811 
812 	bind_lease(ip);
813 }
814 
815 void
816 bind_lease(struct interface_info *ip)
817 {
818 	struct option_data *opt;
819 
820 	/* Remember the medium. */
821 	ip->client->new->medium = ip->client->medium;
822 
823 	opt = &ip->client->new->options[DHO_INTERFACE_MTU];
824 	if (opt->len == sizeof(u_int16_t)) {
825 		u_int16_t mtu = be16dec(opt->data);
826 		if (mtu < MIN_MTU)
827 			warning("mtu size %u < %d: ignored", (unsigned)mtu, MIN_MTU);
828 		else
829 			interface_set_mtu_unpriv(privfd, mtu);
830 	}
831 
832 	/* Write out the new lease. */
833 	write_client_lease(ip, ip->client->new, 0);
834 
835 	/* Run the client script with the new parameters. */
836 	script_init((ip->client->state == S_REQUESTING ? "BOUND" :
837 	    (ip->client->state == S_RENEWING ? "RENEW" :
838 	    (ip->client->state == S_REBOOTING ? "REBOOT" : "REBIND"))),
839 	    ip->client->new->medium);
840 	if (ip->client->active && ip->client->state != S_REBOOTING)
841 		script_write_params("old_", ip->client->active);
842 	script_write_params("new_", ip->client->new);
843 	if (ip->client->alias)
844 		script_write_params("alias_", ip->client->alias);
845 	script_go();
846 
847 	/* Replace the old active lease with the new one. */
848 	if (ip->client->active)
849 		free_client_lease(ip->client->active);
850 	ip->client->active = ip->client->new;
851 	ip->client->new = NULL;
852 
853 	/* Set up a timeout to start the renewal process. */
854 	add_timeout(ip->client->active->renewal, state_bound, ip);
855 
856 	note("bound to %s -- renewal in %d seconds.",
857 	    piaddr(ip->client->active->address),
858 	    (int)(ip->client->active->renewal - cur_time));
859 	ip->client->state = S_BOUND;
860 	reinitialize_interfaces();
861 	go_daemon();
862 }
863 
864 /*
865  * state_bound is called when we've successfully bound to a particular
866  * lease, but the renewal time on that lease has expired.   We are
867  * expected to unicast a DHCPREQUEST to the server that gave us our
868  * original lease.
869  */
870 void
871 state_bound(void *ipp)
872 {
873 	struct interface_info *ip = ipp;
874 
875 	ASSERT_STATE(state, S_BOUND);
876 
877 	/* T1 has expired. */
878 	make_request(ip, ip->client->active);
879 	ip->client->xid = ip->client->packet.xid;
880 
881 	if (ip->client->active->options[DHO_DHCP_SERVER_IDENTIFIER].len == 4) {
882 		memcpy(ip->client->destination.iabuf, ip->client->active->
883 		    options[DHO_DHCP_SERVER_IDENTIFIER].data, 4);
884 		ip->client->destination.len = 4;
885 	} else
886 		ip->client->destination = iaddr_broadcast;
887 
888 	ip->client->first_sending = cur_time;
889 	ip->client->interval = ip->client->config->initial_interval;
890 	ip->client->state = S_RENEWING;
891 
892 	/* Send the first packet immediately. */
893 	send_request(ip);
894 }
895 
896 void
897 bootp(struct packet *packet)
898 {
899 	struct iaddrlist *ap;
900 
901 	if (packet->raw->op != BOOTREPLY)
902 		return;
903 
904 	/* If there's a reject list, make sure this packet's sender isn't
905 	   on it. */
906 	for (ap = packet->interface->client->config->reject_list;
907 	    ap; ap = ap->next) {
908 		if (addr_eq(packet->client_addr, ap->addr)) {
909 			note("BOOTREPLY from %s rejected.", piaddr(ap->addr));
910 			return;
911 		}
912 	}
913 	dhcpoffer(packet);
914 }
915 
916 void
917 dhcp(struct packet *packet)
918 {
919 	struct iaddrlist *ap;
920 	void (*handler)(struct packet *);
921 	char *type;
922 
923 	switch (packet->packet_type) {
924 	case DHCPOFFER:
925 		handler = dhcpoffer;
926 		type = "DHCPOFFER";
927 		break;
928 	case DHCPNAK:
929 		handler = dhcpnak;
930 		type = "DHCPNACK";
931 		break;
932 	case DHCPACK:
933 		handler = dhcpack;
934 		type = "DHCPACK";
935 		break;
936 	default:
937 		return;
938 	}
939 
940 	/* If there's a reject list, make sure this packet's sender isn't
941 	   on it. */
942 	for (ap = packet->interface->client->config->reject_list;
943 	    ap; ap = ap->next) {
944 		if (addr_eq(packet->client_addr, ap->addr)) {
945 			note("%s from %s rejected.", type, piaddr(ap->addr));
946 			return;
947 		}
948 	}
949 	(*handler)(packet);
950 }
951 
952 void
953 dhcpoffer(struct packet *packet)
954 {
955 	struct interface_info *ip = packet->interface;
956 	struct client_lease *lease, *lp;
957 	int i;
958 	int arp_timeout_needed, stop_selecting;
959 	char *name = packet->options[DHO_DHCP_MESSAGE_TYPE].len ?
960 	    "DHCPOFFER" : "BOOTREPLY";
961 
962 	/* If we're not receptive to an offer right now, or if the offer
963 	   has an unrecognizable transaction id, then just drop it. */
964 	if (ip->client->state != S_SELECTING ||
965 	    packet->interface->client->xid != packet->raw->xid ||
966 	    (packet->interface->hw_address.hlen != packet->raw->hlen) ||
967 	    (memcmp(packet->interface->hw_address.haddr,
968 	    packet->raw->chaddr, packet->raw->hlen)))
969 		return;
970 
971 	note("%s from %s", name, piaddr(packet->client_addr));
972 
973 
974 	/* If this lease doesn't supply the minimum required parameters,
975 	   blow it off. */
976 	for (i = 0; ip->client->config->required_options[i]; i++) {
977 		if (!packet->options[ip->client->config->
978 		    required_options[i]].len) {
979 			note("%s isn't satisfactory.", name);
980 			return;
981 		}
982 	}
983 
984 	/* If we've already seen this lease, don't record it again. */
985 	for (lease = ip->client->offered_leases;
986 	    lease; lease = lease->next) {
987 		if (lease->address.len == sizeof(packet->raw->yiaddr) &&
988 		    !memcmp(lease->address.iabuf,
989 		    &packet->raw->yiaddr, lease->address.len)) {
990 			debug("%s already seen.", name);
991 			return;
992 		}
993 	}
994 
995 	lease = packet_to_lease(packet);
996 	if (!lease) {
997 		note("packet_to_lease failed.");
998 		return;
999 	}
1000 
1001 	/* If this lease was acquired through a BOOTREPLY, record that
1002 	   fact. */
1003 	if (!packet->options[DHO_DHCP_MESSAGE_TYPE].len)
1004 		lease->is_bootp = 1;
1005 
1006 	/* Record the medium under which this lease was offered. */
1007 	lease->medium = ip->client->medium;
1008 
1009 	/* Send out an ARP Request for the offered IP address. */
1010 	script_init("ARPSEND", lease->medium);
1011 	script_write_params("check_", lease);
1012 	/* If the script can't send an ARP request without waiting,
1013 	   we'll be waiting when we do the ARPCHECK, so don't wait now. */
1014 	if (script_go())
1015 		arp_timeout_needed = 0;
1016 	else
1017 		arp_timeout_needed = 2;
1018 
1019 	/* Figure out when we're supposed to stop selecting. */
1020 	stop_selecting =
1021 	    ip->client->first_sending + ip->client->config->select_interval;
1022 
1023 	/* If this is the lease we asked for, put it at the head of the
1024 	   list, and don't mess with the arp request timeout. */
1025 	if (lease->address.len == ip->client->requested_address.len &&
1026 	    !memcmp(lease->address.iabuf,
1027 	    ip->client->requested_address.iabuf,
1028 	    ip->client->requested_address.len)) {
1029 		lease->next = ip->client->offered_leases;
1030 		ip->client->offered_leases = lease;
1031 	} else {
1032 		/* If we already have an offer, and arping for this
1033 		   offer would take us past the selection timeout,
1034 		   then don't extend the timeout - just hope for the
1035 		   best. */
1036 		if (ip->client->offered_leases &&
1037 		    (cur_time + arp_timeout_needed) > stop_selecting)
1038 			arp_timeout_needed = 0;
1039 
1040 		/* Put the lease at the end of the list. */
1041 		lease->next = NULL;
1042 		if (!ip->client->offered_leases)
1043 			ip->client->offered_leases = lease;
1044 		else {
1045 			for (lp = ip->client->offered_leases; lp->next;
1046 			    lp = lp->next)
1047 				;	/* nothing */
1048 			lp->next = lease;
1049 		}
1050 	}
1051 
1052 	/* If we're supposed to stop selecting before we've had time
1053 	   to wait for the ARPREPLY, add some delay to wait for
1054 	   the ARPREPLY. */
1055 	if (stop_selecting - cur_time < arp_timeout_needed)
1056 		stop_selecting = cur_time + arp_timeout_needed;
1057 
1058 	/* If the selecting interval has expired, go immediately to
1059 	   state_selecting().  Otherwise, time out into
1060 	   state_selecting at the select interval. */
1061 	if (stop_selecting <= 0)
1062 		state_selecting(ip);
1063 	else {
1064 		add_timeout(stop_selecting, state_selecting, ip);
1065 		cancel_timeout(send_discover, ip);
1066 	}
1067 }
1068 
1069 /* Allocate a client_lease structure and initialize it from the parameters
1070    in the specified packet. */
1071 
1072 struct client_lease *
1073 packet_to_lease(struct packet *packet)
1074 {
1075 	struct client_lease *lease;
1076 	int i;
1077 
1078 	lease = malloc(sizeof(struct client_lease));
1079 
1080 	if (!lease) {
1081 		warning("dhcpoffer: no memory to record lease.");
1082 		return (NULL);
1083 	}
1084 
1085 	memset(lease, 0, sizeof(*lease));
1086 
1087 	/* Copy the lease options. */
1088 	for (i = 0; i < 256; i++) {
1089 		if (packet->options[i].len) {
1090 			lease->options[i].data =
1091 			    malloc(packet->options[i].len + 1);
1092 			if (!lease->options[i].data) {
1093 				warning("dhcpoffer: no memory for option %d", i);
1094 				free_client_lease(lease);
1095 				return (NULL);
1096 			} else {
1097 				memcpy(lease->options[i].data,
1098 				    packet->options[i].data,
1099 				    packet->options[i].len);
1100 				lease->options[i].len =
1101 				    packet->options[i].len;
1102 				lease->options[i].data[lease->options[i].len] =
1103 				    0;
1104 			}
1105 			if (!check_option(lease,i)) {
1106 				/* ignore a bogus lease offer */
1107 				warning("Invalid lease option - ignoring offer");
1108 				free_client_lease(lease);
1109 				return (NULL);
1110 			}
1111 		}
1112 	}
1113 
1114 	lease->address.len = sizeof(packet->raw->yiaddr);
1115 	memcpy(lease->address.iabuf, &packet->raw->yiaddr, lease->address.len);
1116 
1117 	lease->nextserver.len = sizeof(packet->raw->siaddr);
1118 	memcpy(lease->nextserver.iabuf, &packet->raw->siaddr, lease->nextserver.len);
1119 
1120 	/* If the server name was filled out, copy it.
1121 	   Do not attempt to validate the server name as a host name.
1122 	   RFC 2131 merely states that sname is NUL-terminated (which do
1123 	   do not assume) and that it is the server's host name.  Since
1124 	   the ISC client and server allow arbitrary characters, we do
1125 	   as well. */
1126 	if ((!packet->options[DHO_DHCP_OPTION_OVERLOAD].len ||
1127 	    !(packet->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 2)) &&
1128 	    packet->raw->sname[0]) {
1129 		lease->server_name = malloc(DHCP_SNAME_LEN + 1);
1130 		if (!lease->server_name) {
1131 			warning("dhcpoffer: no memory for server name.");
1132 			free_client_lease(lease);
1133 			return (NULL);
1134 		}
1135 		memcpy(lease->server_name, packet->raw->sname, DHCP_SNAME_LEN);
1136 		lease->server_name[DHCP_SNAME_LEN]='\0';
1137 	}
1138 
1139 	/* Ditto for the filename. */
1140 	if ((!packet->options[DHO_DHCP_OPTION_OVERLOAD].len ||
1141 	    !(packet->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 1)) &&
1142 	    packet->raw->file[0]) {
1143 		/* Don't count on the NUL terminator. */
1144 		lease->filename = malloc(DHCP_FILE_LEN + 1);
1145 		if (!lease->filename) {
1146 			warning("dhcpoffer: no memory for filename.");
1147 			free_client_lease(lease);
1148 			return (NULL);
1149 		}
1150 		memcpy(lease->filename, packet->raw->file, DHCP_FILE_LEN);
1151 		lease->filename[DHCP_FILE_LEN]='\0';
1152 	}
1153 	return lease;
1154 }
1155 
1156 void
1157 dhcpnak(struct packet *packet)
1158 {
1159 	struct interface_info *ip = packet->interface;
1160 
1161 	/* If we're not receptive to an offer right now, or if the offer
1162 	   has an unrecognizable transaction id, then just drop it. */
1163 	if (packet->interface->client->xid != packet->raw->xid ||
1164 	    (packet->interface->hw_address.hlen != packet->raw->hlen) ||
1165 	    (memcmp(packet->interface->hw_address.haddr,
1166 	    packet->raw->chaddr, packet->raw->hlen)))
1167 		return;
1168 
1169 	if (ip->client->state != S_REBOOTING &&
1170 	    ip->client->state != S_REQUESTING &&
1171 	    ip->client->state != S_RENEWING &&
1172 	    ip->client->state != S_REBINDING)
1173 		return;
1174 
1175 	note("DHCPNAK from %s", piaddr(packet->client_addr));
1176 
1177 	if (!ip->client->active) {
1178 		note("DHCPNAK with no active lease.\n");
1179 		return;
1180 	}
1181 
1182 	free_client_lease(ip->client->active);
1183 	ip->client->active = NULL;
1184 
1185 	/* Stop sending DHCPREQUEST packets... */
1186 	cancel_timeout(send_request, ip);
1187 
1188 	ip->client->state = S_INIT;
1189 	state_init(ip);
1190 }
1191 
1192 /* Send out a DHCPDISCOVER packet, and set a timeout to send out another
1193    one after the right interval has expired.  If we don't get an offer by
1194    the time we reach the panic interval, call the panic function. */
1195 
1196 void
1197 send_discover(void *ipp)
1198 {
1199 	struct interface_info *ip = ipp;
1200 	int interval, increase = 1;
1201 
1202 	/* Figure out how long it's been since we started transmitting. */
1203 	interval = cur_time - ip->client->first_sending;
1204 
1205 	/* If we're past the panic timeout, call the script and tell it
1206 	   we haven't found anything for this interface yet. */
1207 	if (interval > ip->client->config->timeout) {
1208 		state_panic(ip);
1209 		return;
1210 	}
1211 
1212 	/* If we're selecting media, try the whole list before doing
1213 	   the exponential backoff, but if we've already received an
1214 	   offer, stop looping, because we obviously have it right. */
1215 	if (!ip->client->offered_leases &&
1216 	    ip->client->config->media) {
1217 		int fail = 0;
1218 again:
1219 		if (ip->client->medium) {
1220 			ip->client->medium = ip->client->medium->next;
1221 			increase = 0;
1222 		}
1223 		if (!ip->client->medium) {
1224 			if (fail)
1225 				error("No valid media types for %s!", ip->name);
1226 			ip->client->medium = ip->client->config->media;
1227 			increase = 1;
1228 		}
1229 
1230 		note("Trying medium \"%s\" %d", ip->client->medium->string,
1231 		    increase);
1232 		script_init("MEDIUM", ip->client->medium);
1233 		if (script_go())
1234 			goto again;
1235 	}
1236 
1237 	/*
1238 	 * If we're supposed to increase the interval, do so.  If it's
1239 	 * currently zero (i.e., we haven't sent any packets yet), set
1240 	 * it to one; otherwise, add to it a random number between zero
1241 	 * and two times itself.  On average, this means that it will
1242 	 * double with every transmission.
1243 	 */
1244 	if (increase) {
1245 		if (!ip->client->interval)
1246 			ip->client->interval =
1247 			    ip->client->config->initial_interval;
1248 		else {
1249 			ip->client->interval += (arc4random() >> 2) %
1250 			    (2 * ip->client->interval);
1251 		}
1252 
1253 		/* Don't backoff past cutoff. */
1254 		if (ip->client->interval >
1255 		    ip->client->config->backoff_cutoff)
1256 			ip->client->interval =
1257 				((ip->client->config->backoff_cutoff / 2)
1258 				 + ((arc4random() >> 2) %
1259 				    ip->client->config->backoff_cutoff));
1260 	} else if (!ip->client->interval)
1261 		ip->client->interval =
1262 			ip->client->config->initial_interval;
1263 
1264 	/* If the backoff would take us to the panic timeout, just use that
1265 	   as the interval. */
1266 	if (cur_time + ip->client->interval >
1267 	    ip->client->first_sending + ip->client->config->timeout)
1268 		ip->client->interval =
1269 			(ip->client->first_sending +
1270 			 ip->client->config->timeout) - cur_time + 1;
1271 
1272 	/* Record the number of seconds since we started sending. */
1273 	if (interval < 65536)
1274 		ip->client->packet.secs = htons(interval);
1275 	else
1276 		ip->client->packet.secs = htons(65535);
1277 	ip->client->secs = ip->client->packet.secs;
1278 
1279 	note("DHCPDISCOVER on %s to %s port %d interval %d",
1280 	    ip->name, inet_ntoa(inaddr_broadcast), REMOTE_PORT,
1281 	    (int)ip->client->interval);
1282 
1283 	/* Send out a packet. */
1284 	send_packet_unpriv(privfd, &ip->client->packet,
1285 	    ip->client->packet_length, inaddr_any, inaddr_broadcast);
1286 
1287 	add_timeout(cur_time + ip->client->interval, send_discover, ip);
1288 }
1289 
1290 /*
1291  * state_panic gets called if we haven't received any offers in a preset
1292  * amount of time.   When this happens, we try to use existing leases
1293  * that haven't yet expired, and failing that, we call the client script
1294  * and hope it can do something.
1295  */
1296 void
1297 state_panic(void *ipp)
1298 {
1299 	struct interface_info *ip = ipp;
1300 	struct client_lease *loop = ip->client->active;
1301 	struct client_lease *lp;
1302 
1303 	note("No DHCPOFFERS received.");
1304 
1305 	/* We may not have an active lease, but we may have some
1306 	   predefined leases that we can try. */
1307 	if (!ip->client->active && ip->client->leases)
1308 		goto activate_next;
1309 
1310 	/* Run through the list of leases and see if one can be used. */
1311 	while (ip->client->active) {
1312 		if (ip->client->active->expiry > cur_time) {
1313 			note("Trying recorded lease %s",
1314 			    piaddr(ip->client->active->address));
1315 			/* Run the client script with the existing
1316 			   parameters. */
1317 			script_init("TIMEOUT",
1318 			    ip->client->active->medium);
1319 			script_write_params("new_", ip->client->active);
1320 			if (ip->client->alias)
1321 				script_write_params("alias_",
1322 				    ip->client->alias);
1323 
1324 			/* If the old lease is still good and doesn't
1325 			   yet need renewal, go into BOUND state and
1326 			   timeout at the renewal time. */
1327 			if (!script_go()) {
1328 				if (cur_time <
1329 				    ip->client->active->renewal) {
1330 					ip->client->state = S_BOUND;
1331 					note("bound: renewal in %d seconds.",
1332 					    (int)(ip->client->active->renewal -
1333 					    cur_time));
1334 					add_timeout(
1335 					    ip->client->active->renewal,
1336 					    state_bound, ip);
1337 				} else {
1338 					ip->client->state = S_BOUND;
1339 					note("bound: immediate renewal.");
1340 					state_bound(ip);
1341 				}
1342 				reinitialize_interfaces();
1343 				go_daemon();
1344 				return;
1345 			}
1346 		}
1347 
1348 		/* If there are no other leases, give up. */
1349 		if (!ip->client->leases) {
1350 			ip->client->leases = ip->client->active;
1351 			ip->client->active = NULL;
1352 			break;
1353 		}
1354 
1355 activate_next:
1356 		/* Otherwise, put the active lease at the end of the
1357 		   lease list, and try another lease.. */
1358 		for (lp = ip->client->leases; lp->next; lp = lp->next)
1359 			;
1360 		lp->next = ip->client->active;
1361 		if (lp->next)
1362 			lp->next->next = NULL;
1363 		ip->client->active = ip->client->leases;
1364 		ip->client->leases = ip->client->leases->next;
1365 
1366 		/* If we already tried this lease, we've exhausted the
1367 		   set of leases, so we might as well give up for
1368 		   now. */
1369 		if (ip->client->active == loop)
1370 			break;
1371 		else if (!loop)
1372 			loop = ip->client->active;
1373 	}
1374 
1375 	/* No leases were available, or what was available didn't work, so
1376 	   tell the shell script that we failed to allocate an address,
1377 	   and try again later. */
1378 	note("No working leases in persistent database - sleeping.\n");
1379 	script_init("FAIL", NULL);
1380 	if (ip->client->alias)
1381 		script_write_params("alias_", ip->client->alias);
1382 	script_go();
1383 	ip->client->state = S_INIT;
1384 	add_timeout(cur_time + ip->client->config->retry_interval, state_init,
1385 	    ip);
1386 	go_daemon();
1387 }
1388 
1389 void
1390 send_request(void *ipp)
1391 {
1392 	struct interface_info *ip = ipp;
1393 	struct in_addr from, to;
1394 	int interval;
1395 
1396 	/* Figure out how long it's been since we started transmitting. */
1397 	interval = cur_time - ip->client->first_sending;
1398 
1399 	/* If we're in the INIT-REBOOT or REQUESTING state and we're
1400 	   past the reboot timeout, go to INIT and see if we can
1401 	   DISCOVER an address... */
1402 	/* XXX In the INIT-REBOOT state, if we don't get an ACK, it
1403 	   means either that we're on a network with no DHCP server,
1404 	   or that our server is down.  In the latter case, assuming
1405 	   that there is a backup DHCP server, DHCPDISCOVER will get
1406 	   us a new address, but we could also have successfully
1407 	   reused our old address.  In the former case, we're hosed
1408 	   anyway.  This is not a win-prone situation. */
1409 	if ((ip->client->state == S_REBOOTING ||
1410 	    ip->client->state == S_REQUESTING) &&
1411 	    interval > ip->client->config->reboot_timeout) {
1412 cancel:
1413 		ip->client->state = S_INIT;
1414 		cancel_timeout(send_request, ip);
1415 		state_init(ip);
1416 		return;
1417 	}
1418 
1419 	/* If we're in the reboot state, make sure the media is set up
1420 	   correctly. */
1421 	if (ip->client->state == S_REBOOTING &&
1422 	    !ip->client->medium &&
1423 	    ip->client->active->medium ) {
1424 		script_init("MEDIUM", ip->client->active->medium);
1425 
1426 		/* If the medium we chose won't fly, go to INIT state. */
1427 		if (script_go())
1428 			goto cancel;
1429 
1430 		/* Record the medium. */
1431 		ip->client->medium = ip->client->active->medium;
1432 	}
1433 
1434 	/* If the lease has expired, relinquish the address and go back
1435 	   to the INIT state. */
1436 	if (ip->client->state != S_REQUESTING &&
1437 	    cur_time > ip->client->active->expiry) {
1438 		/* Run the client script with the new parameters. */
1439 		script_init("EXPIRE", NULL);
1440 		script_write_params("old_", ip->client->active);
1441 		if (ip->client->alias)
1442 			script_write_params("alias_", ip->client->alias);
1443 		script_go();
1444 
1445 		/* Now do a preinit on the interface so that we can
1446 		   discover a new address. */
1447 		script_init("PREINIT", NULL);
1448 		if (ip->client->alias)
1449 			script_write_params("alias_", ip->client->alias);
1450 		script_go();
1451 
1452 		ip->client->state = S_INIT;
1453 		state_init(ip);
1454 		return;
1455 	}
1456 
1457 	/* Do the exponential backoff... */
1458 	if (!ip->client->interval)
1459 		ip->client->interval = ip->client->config->initial_interval;
1460 	else
1461 		ip->client->interval += ((arc4random() >> 2) %
1462 		    (2 * ip->client->interval));
1463 
1464 	/* Don't backoff past cutoff. */
1465 	if (ip->client->interval >
1466 	    ip->client->config->backoff_cutoff)
1467 		ip->client->interval =
1468 		    ((ip->client->config->backoff_cutoff / 2) +
1469 		    ((arc4random() >> 2) % ip->client->interval));
1470 
1471 	/* If the backoff would take us to the expiry time, just set the
1472 	   timeout to the expiry time. */
1473 	if (ip->client->state != S_REQUESTING &&
1474 	    cur_time + ip->client->interval >
1475 	    ip->client->active->expiry)
1476 		ip->client->interval =
1477 		    ip->client->active->expiry - cur_time + 1;
1478 
1479 	/* If the lease T2 time has elapsed, or if we're not yet bound,
1480 	   broadcast the DHCPREQUEST rather than unicasting. */
1481 	if (ip->client->state == S_REQUESTING ||
1482 	    ip->client->state == S_REBOOTING ||
1483 	    cur_time > ip->client->active->rebind)
1484 		to.s_addr = INADDR_BROADCAST;
1485 	else
1486 		memcpy(&to.s_addr, ip->client->destination.iabuf,
1487 		    sizeof(to.s_addr));
1488 
1489 	if (ip->client->state != S_REQUESTING)
1490 		memcpy(&from, ip->client->active->address.iabuf,
1491 		    sizeof(from));
1492 	else
1493 		from.s_addr = INADDR_ANY;
1494 
1495 	/* Record the number of seconds since we started sending. */
1496 	if (ip->client->state == S_REQUESTING)
1497 		ip->client->packet.secs = ip->client->secs;
1498 	else {
1499 		if (interval < 65536)
1500 			ip->client->packet.secs = htons(interval);
1501 		else
1502 			ip->client->packet.secs = htons(65535);
1503 	}
1504 
1505 	note("DHCPREQUEST on %s to %s port %d", ip->name, inet_ntoa(to),
1506 	    REMOTE_PORT);
1507 
1508 	/* Send out a packet. */
1509 	send_packet_unpriv(privfd, &ip->client->packet,
1510 	    ip->client->packet_length, from, to);
1511 
1512 	add_timeout(cur_time + ip->client->interval, send_request, ip);
1513 }
1514 
1515 void
1516 send_decline(void *ipp)
1517 {
1518 	struct interface_info *ip = ipp;
1519 
1520 	note("DHCPDECLINE on %s to %s port %d", ip->name,
1521 	    inet_ntoa(inaddr_broadcast), REMOTE_PORT);
1522 
1523 	/* Send out a packet. */
1524 	send_packet_unpriv(privfd, &ip->client->packet,
1525 	    ip->client->packet_length, inaddr_any, inaddr_broadcast);
1526 }
1527 
1528 void
1529 make_discover(struct interface_info *ip, struct client_lease *lease)
1530 {
1531 	unsigned char discover = DHCPDISCOVER;
1532 	struct tree_cache *options[256];
1533 	struct tree_cache option_elements[256];
1534 	int i;
1535 
1536 	memset(option_elements, 0, sizeof(option_elements));
1537 	memset(options, 0, sizeof(options));
1538 	memset(&ip->client->packet, 0, sizeof(ip->client->packet));
1539 
1540 	/* Set DHCP_MESSAGE_TYPE to DHCPDISCOVER */
1541 	i = DHO_DHCP_MESSAGE_TYPE;
1542 	options[i] = &option_elements[i];
1543 	options[i]->value = &discover;
1544 	options[i]->len = sizeof(discover);
1545 	options[i]->buf_size = sizeof(discover);
1546 	options[i]->timeout = 0xFFFFFFFF;
1547 
1548 	/* Request the options we want */
1549 	i  = DHO_DHCP_PARAMETER_REQUEST_LIST;
1550 	options[i] = &option_elements[i];
1551 	options[i]->value = ip->client->config->requested_options;
1552 	options[i]->len = ip->client->config->requested_option_count;
1553 	options[i]->buf_size =
1554 		ip->client->config->requested_option_count;
1555 	options[i]->timeout = 0xFFFFFFFF;
1556 
1557 	/* If we had an address, try to get it again. */
1558 	if (lease) {
1559 		ip->client->requested_address = lease->address;
1560 		i = DHO_DHCP_REQUESTED_ADDRESS;
1561 		options[i] = &option_elements[i];
1562 		options[i]->value = lease->address.iabuf;
1563 		options[i]->len = lease->address.len;
1564 		options[i]->buf_size = lease->address.len;
1565 		options[i]->timeout = 0xFFFFFFFF;
1566 	} else
1567 		ip->client->requested_address.len = 0;
1568 
1569 	/* Send any options requested in the config file. */
1570 	for (i = 0; i < 256; i++)
1571 		if (!options[i] &&
1572 		    ip->client->config->send_options[i].data) {
1573 			options[i] = &option_elements[i];
1574 			options[i]->value =
1575 			    ip->client->config->send_options[i].data;
1576 			options[i]->len =
1577 			    ip->client->config->send_options[i].len;
1578 			options[i]->buf_size =
1579 			    ip->client->config->send_options[i].len;
1580 			options[i]->timeout = 0xFFFFFFFF;
1581 		}
1582 
1583 	/* send host name if not set via config file. */
1584 	if (!options[DHO_HOST_NAME]) {
1585 		if (hostname[0] != '\0') {
1586 			size_t len;
1587 			char* posDot = strchr(hostname, '.');
1588 			if (posDot != NULL)
1589 				len = posDot - hostname;
1590 			else
1591 				len = strlen(hostname);
1592 			options[DHO_HOST_NAME] = &option_elements[DHO_HOST_NAME];
1593 			options[DHO_HOST_NAME]->value = hostname;
1594 			options[DHO_HOST_NAME]->len = len;
1595 			options[DHO_HOST_NAME]->buf_size = len;
1596 			options[DHO_HOST_NAME]->timeout = 0xFFFFFFFF;
1597 		}
1598 	}
1599 
1600 	/* set unique client identifier */
1601 	char client_ident[sizeof(ip->hw_address.haddr) + 1];
1602 	if (!options[DHO_DHCP_CLIENT_IDENTIFIER]) {
1603 		int hwlen = (ip->hw_address.hlen < sizeof(client_ident)-1) ?
1604 				ip->hw_address.hlen : sizeof(client_ident)-1;
1605 		client_ident[0] = ip->hw_address.htype;
1606 		memcpy(&client_ident[1], ip->hw_address.haddr, hwlen);
1607 		options[DHO_DHCP_CLIENT_IDENTIFIER] = &option_elements[DHO_DHCP_CLIENT_IDENTIFIER];
1608 		options[DHO_DHCP_CLIENT_IDENTIFIER]->value = client_ident;
1609 		options[DHO_DHCP_CLIENT_IDENTIFIER]->len = hwlen+1;
1610 		options[DHO_DHCP_CLIENT_IDENTIFIER]->buf_size = hwlen+1;
1611 		options[DHO_DHCP_CLIENT_IDENTIFIER]->timeout = 0xFFFFFFFF;
1612 	}
1613 
1614 	/* Set up the option buffer... */
1615 	ip->client->packet_length = cons_options(NULL, &ip->client->packet, 0,
1616 	    options, 0, 0, 0, NULL, 0);
1617 	if (ip->client->packet_length < BOOTP_MIN_LEN)
1618 		ip->client->packet_length = BOOTP_MIN_LEN;
1619 
1620 	ip->client->packet.op = BOOTREQUEST;
1621 	ip->client->packet.htype = ip->hw_address.htype;
1622 	ip->client->packet.hlen = ip->hw_address.hlen;
1623 	ip->client->packet.hops = 0;
1624 	ip->client->packet.xid = arc4random();
1625 	ip->client->packet.secs = 0; /* filled in by send_discover. */
1626 	ip->client->packet.flags = 0;
1627 
1628 	memset(&(ip->client->packet.ciaddr),
1629 	    0, sizeof(ip->client->packet.ciaddr));
1630 	memset(&(ip->client->packet.yiaddr),
1631 	    0, sizeof(ip->client->packet.yiaddr));
1632 	memset(&(ip->client->packet.siaddr),
1633 	    0, sizeof(ip->client->packet.siaddr));
1634 	memset(&(ip->client->packet.giaddr),
1635 	    0, sizeof(ip->client->packet.giaddr));
1636 	memcpy(ip->client->packet.chaddr,
1637 	    ip->hw_address.haddr, ip->hw_address.hlen);
1638 }
1639 
1640 
1641 void
1642 make_request(struct interface_info *ip, struct client_lease * lease)
1643 {
1644 	unsigned char request = DHCPREQUEST;
1645 	struct tree_cache *options[256];
1646 	struct tree_cache option_elements[256];
1647 	int i;
1648 
1649 	memset(options, 0, sizeof(options));
1650 	memset(&ip->client->packet, 0, sizeof(ip->client->packet));
1651 
1652 	/* Set DHCP_MESSAGE_TYPE to DHCPREQUEST */
1653 	i = DHO_DHCP_MESSAGE_TYPE;
1654 	options[i] = &option_elements[i];
1655 	options[i]->value = &request;
1656 	options[i]->len = sizeof(request);
1657 	options[i]->buf_size = sizeof(request);
1658 	options[i]->timeout = 0xFFFFFFFF;
1659 
1660 	/* Request the options we want */
1661 	i = DHO_DHCP_PARAMETER_REQUEST_LIST;
1662 	options[i] = &option_elements[i];
1663 	options[i]->value = ip->client->config->requested_options;
1664 	options[i]->len = ip->client->config->requested_option_count;
1665 	options[i]->buf_size =
1666 		ip->client->config->requested_option_count;
1667 	options[i]->timeout = 0xFFFFFFFF;
1668 
1669 	/* If we are requesting an address that hasn't yet been assigned
1670 	   to us, use the DHCP Requested Address option. */
1671 	if (ip->client->state == S_REQUESTING) {
1672 		/* Send back the server identifier... */
1673 		i = DHO_DHCP_SERVER_IDENTIFIER;
1674 		options[i] = &option_elements[i];
1675 		options[i]->value = lease->options[i].data;
1676 		options[i]->len = lease->options[i].len;
1677 		options[i]->buf_size = lease->options[i].len;
1678 		options[i]->timeout = 0xFFFFFFFF;
1679 	}
1680 	if (ip->client->state == S_REQUESTING ||
1681 	    ip->client->state == S_REBOOTING) {
1682 		ip->client->requested_address = lease->address;
1683 		i = DHO_DHCP_REQUESTED_ADDRESS;
1684 		options[i] = &option_elements[i];
1685 		options[i]->value = lease->address.iabuf;
1686 		options[i]->len = lease->address.len;
1687 		options[i]->buf_size = lease->address.len;
1688 		options[i]->timeout = 0xFFFFFFFF;
1689 	} else
1690 		ip->client->requested_address.len = 0;
1691 
1692 	/* Send any options requested in the config file. */
1693 	for (i = 0; i < 256; i++)
1694 		if (!options[i] &&
1695 		    ip->client->config->send_options[i].data) {
1696 			options[i] = &option_elements[i];
1697 			options[i]->value =
1698 			    ip->client->config->send_options[i].data;
1699 			options[i]->len =
1700 			    ip->client->config->send_options[i].len;
1701 			options[i]->buf_size =
1702 			    ip->client->config->send_options[i].len;
1703 			options[i]->timeout = 0xFFFFFFFF;
1704 		}
1705 
1706 	/* send host name if not set via config file. */
1707 	if (!options[DHO_HOST_NAME]) {
1708 		if (hostname[0] != '\0') {
1709 			size_t len;
1710 			char* posDot = strchr(hostname, '.');
1711 			if (posDot != NULL)
1712 				len = posDot - hostname;
1713 			else
1714 				len = strlen(hostname);
1715 			options[DHO_HOST_NAME] = &option_elements[DHO_HOST_NAME];
1716 			options[DHO_HOST_NAME]->value = hostname;
1717 			options[DHO_HOST_NAME]->len = len;
1718 			options[DHO_HOST_NAME]->buf_size = len;
1719 			options[DHO_HOST_NAME]->timeout = 0xFFFFFFFF;
1720 		}
1721 	}
1722 
1723 	/* set unique client identifier */
1724 	char client_ident[sizeof(struct hardware)];
1725 	if (!options[DHO_DHCP_CLIENT_IDENTIFIER]) {
1726 		int hwlen = (ip->hw_address.hlen < sizeof(client_ident)-1) ?
1727 				ip->hw_address.hlen : sizeof(client_ident)-1;
1728 		client_ident[0] = ip->hw_address.htype;
1729 		memcpy(&client_ident[1], ip->hw_address.haddr, hwlen);
1730 		options[DHO_DHCP_CLIENT_IDENTIFIER] = &option_elements[DHO_DHCP_CLIENT_IDENTIFIER];
1731 		options[DHO_DHCP_CLIENT_IDENTIFIER]->value = client_ident;
1732 		options[DHO_DHCP_CLIENT_IDENTIFIER]->len = hwlen+1;
1733 		options[DHO_DHCP_CLIENT_IDENTIFIER]->buf_size = hwlen+1;
1734 		options[DHO_DHCP_CLIENT_IDENTIFIER]->timeout = 0xFFFFFFFF;
1735 	}
1736 
1737 	/* Set up the option buffer... */
1738 	ip->client->packet_length = cons_options(NULL, &ip->client->packet, 0,
1739 	    options, 0, 0, 0, NULL, 0);
1740 	if (ip->client->packet_length < BOOTP_MIN_LEN)
1741 		ip->client->packet_length = BOOTP_MIN_LEN;
1742 
1743 	ip->client->packet.op = BOOTREQUEST;
1744 	ip->client->packet.htype = ip->hw_address.htype;
1745 	ip->client->packet.hlen = ip->hw_address.hlen;
1746 	ip->client->packet.hops = 0;
1747 	ip->client->packet.xid = ip->client->xid;
1748 	ip->client->packet.secs = 0; /* Filled in by send_request. */
1749 
1750 	/* If we own the address we're requesting, put it in ciaddr;
1751 	   otherwise set ciaddr to zero. */
1752 	if (ip->client->state == S_BOUND ||
1753 	    ip->client->state == S_RENEWING ||
1754 	    ip->client->state == S_REBINDING) {
1755 		memcpy(&ip->client->packet.ciaddr,
1756 		    lease->address.iabuf, lease->address.len);
1757 		ip->client->packet.flags = 0;
1758 	} else {
1759 		memset(&ip->client->packet.ciaddr, 0,
1760 		    sizeof(ip->client->packet.ciaddr));
1761 		ip->client->packet.flags = 0;
1762 	}
1763 
1764 	memset(&ip->client->packet.yiaddr, 0,
1765 	    sizeof(ip->client->packet.yiaddr));
1766 	memset(&ip->client->packet.siaddr, 0,
1767 	    sizeof(ip->client->packet.siaddr));
1768 	memset(&ip->client->packet.giaddr, 0,
1769 	    sizeof(ip->client->packet.giaddr));
1770 	memcpy(ip->client->packet.chaddr,
1771 	    ip->hw_address.haddr, ip->hw_address.hlen);
1772 }
1773 
1774 void
1775 make_decline(struct interface_info *ip, struct client_lease *lease)
1776 {
1777 	struct tree_cache *options[256], message_type_tree;
1778 	struct tree_cache requested_address_tree;
1779 	struct tree_cache server_id_tree, client_id_tree;
1780 	unsigned char decline = DHCPDECLINE;
1781 	int i;
1782 
1783 	memset(options, 0, sizeof(options));
1784 	memset(&ip->client->packet, 0, sizeof(ip->client->packet));
1785 
1786 	/* Set DHCP_MESSAGE_TYPE to DHCPDECLINE */
1787 	i = DHO_DHCP_MESSAGE_TYPE;
1788 	options[i] = &message_type_tree;
1789 	options[i]->value = &decline;
1790 	options[i]->len = sizeof(decline);
1791 	options[i]->buf_size = sizeof(decline);
1792 	options[i]->timeout = 0xFFFFFFFF;
1793 
1794 	/* Send back the server identifier... */
1795 	i = DHO_DHCP_SERVER_IDENTIFIER;
1796 	options[i] = &server_id_tree;
1797 	options[i]->value = lease->options[i].data;
1798 	options[i]->len = lease->options[i].len;
1799 	options[i]->buf_size = lease->options[i].len;
1800 	options[i]->timeout = 0xFFFFFFFF;
1801 
1802 	/* Send back the address we're declining. */
1803 	i = DHO_DHCP_REQUESTED_ADDRESS;
1804 	options[i] = &requested_address_tree;
1805 	options[i]->value = lease->address.iabuf;
1806 	options[i]->len = lease->address.len;
1807 	options[i]->buf_size = lease->address.len;
1808 	options[i]->timeout = 0xFFFFFFFF;
1809 
1810 	/* Send the uid if the user supplied one. */
1811 	i = DHO_DHCP_CLIENT_IDENTIFIER;
1812 	if (ip->client->config->send_options[i].len) {
1813 		options[i] = &client_id_tree;
1814 		options[i]->value = ip->client->config->send_options[i].data;
1815 		options[i]->len = ip->client->config->send_options[i].len;
1816 		options[i]->buf_size = ip->client->config->send_options[i].len;
1817 		options[i]->timeout = 0xFFFFFFFF;
1818 	}
1819 
1820 
1821 	/* Set up the option buffer... */
1822 	ip->client->packet_length = cons_options(NULL, &ip->client->packet, 0,
1823 	    options, 0, 0, 0, NULL, 0);
1824 	if (ip->client->packet_length < BOOTP_MIN_LEN)
1825 		ip->client->packet_length = BOOTP_MIN_LEN;
1826 
1827 	ip->client->packet.op = BOOTREQUEST;
1828 	ip->client->packet.htype = ip->hw_address.htype;
1829 	ip->client->packet.hlen = ip->hw_address.hlen;
1830 	ip->client->packet.hops = 0;
1831 	ip->client->packet.xid = ip->client->xid;
1832 	ip->client->packet.secs = 0; /* Filled in by send_request. */
1833 	ip->client->packet.flags = 0;
1834 
1835 	/* ciaddr must always be zero. */
1836 	memset(&ip->client->packet.ciaddr, 0,
1837 	    sizeof(ip->client->packet.ciaddr));
1838 	memset(&ip->client->packet.yiaddr, 0,
1839 	    sizeof(ip->client->packet.yiaddr));
1840 	memset(&ip->client->packet.siaddr, 0,
1841 	    sizeof(ip->client->packet.siaddr));
1842 	memset(&ip->client->packet.giaddr, 0,
1843 	    sizeof(ip->client->packet.giaddr));
1844 	memcpy(ip->client->packet.chaddr,
1845 	    ip->hw_address.haddr, ip->hw_address.hlen);
1846 }
1847 
1848 void
1849 free_client_lease(struct client_lease *lease)
1850 {
1851 	int i;
1852 
1853 	if (lease->server_name)
1854 		free(lease->server_name);
1855 	if (lease->filename)
1856 		free(lease->filename);
1857 	for (i = 0; i < 256; i++) {
1858 		if (lease->options[i].len)
1859 			free(lease->options[i].data);
1860 	}
1861 	free(lease);
1862 }
1863 
1864 FILE *leaseFile;
1865 
1866 void
1867 rewrite_client_leases(void)
1868 {
1869 	struct client_lease *lp;
1870 	cap_rights_t rights;
1871 
1872 	if (!leaseFile) {
1873 		leaseFile = fopen(path_dhclient_db, "w");
1874 		if (!leaseFile)
1875 			error("can't create %s: %m", path_dhclient_db);
1876 		cap_rights_init(&rights, CAP_FCNTL, CAP_FSTAT, CAP_FSYNC,
1877 		    CAP_FTRUNCATE, CAP_SEEK, CAP_WRITE);
1878 		if (cap_rights_limit(fileno(leaseFile), &rights) < 0 &&
1879 		    errno != ENOSYS) {
1880 			error("can't limit lease descriptor: %m");
1881 		}
1882 		if (cap_fcntls_limit(fileno(leaseFile), CAP_FCNTL_GETFL) < 0 &&
1883 		    errno != ENOSYS) {
1884 			error("can't limit lease descriptor fcntls: %m");
1885 		}
1886 	} else {
1887 		fflush(leaseFile);
1888 		rewind(leaseFile);
1889 	}
1890 
1891 	for (lp = ifi->client->leases; lp; lp = lp->next)
1892 		write_client_lease(ifi, lp, 1);
1893 	if (ifi->client->active)
1894 		write_client_lease(ifi, ifi->client->active, 1);
1895 
1896 	fflush(leaseFile);
1897 	ftruncate(fileno(leaseFile), ftello(leaseFile));
1898 	fsync(fileno(leaseFile));
1899 }
1900 
1901 void
1902 write_client_lease(struct interface_info *ip, struct client_lease *lease,
1903     int rewrite)
1904 {
1905 	static int leases_written;
1906 	struct tm *t;
1907 	int i;
1908 
1909 	if (!rewrite) {
1910 		if (leases_written++ > 20) {
1911 			rewrite_client_leases();
1912 			leases_written = 0;
1913 		}
1914 	}
1915 
1916 	/* If the lease came from the config file, we don't need to stash
1917 	   a copy in the lease database. */
1918 	if (lease->is_static)
1919 		return;
1920 
1921 	if (!leaseFile) {	/* XXX */
1922 		leaseFile = fopen(path_dhclient_db, "w");
1923 		if (!leaseFile)
1924 			error("can't create %s: %m", path_dhclient_db);
1925 	}
1926 
1927 	fprintf(leaseFile, "lease {\n");
1928 	if (lease->is_bootp)
1929 		fprintf(leaseFile, "  bootp;\n");
1930 	fprintf(leaseFile, "  interface \"%s\";\n", ip->name);
1931 	fprintf(leaseFile, "  fixed-address %s;\n", piaddr(lease->address));
1932 	if (lease->nextserver.len == sizeof(inaddr_any) &&
1933 	    0 != memcmp(lease->nextserver.iabuf, &inaddr_any,
1934 	    sizeof(inaddr_any)))
1935 		fprintf(leaseFile, "  next-server %s;\n",
1936 		    piaddr(lease->nextserver));
1937 	if (lease->filename)
1938 		fprintf(leaseFile, "  filename \"%s\";\n", lease->filename);
1939 	if (lease->server_name)
1940 		fprintf(leaseFile, "  server-name \"%s\";\n",
1941 		    lease->server_name);
1942 	if (lease->medium)
1943 		fprintf(leaseFile, "  medium \"%s\";\n", lease->medium->string);
1944 	for (i = 0; i < 256; i++)
1945 		if (lease->options[i].len)
1946 			fprintf(leaseFile, "  option %s %s;\n",
1947 			    dhcp_options[i].name,
1948 			    pretty_print_option(i, lease->options[i].data,
1949 			    lease->options[i].len, 1, 1));
1950 
1951 	t = gmtime(&lease->renewal);
1952 	fprintf(leaseFile, "  renew %d %d/%d/%d %02d:%02d:%02d;\n",
1953 	    t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
1954 	    t->tm_hour, t->tm_min, t->tm_sec);
1955 	t = gmtime(&lease->rebind);
1956 	fprintf(leaseFile, "  rebind %d %d/%d/%d %02d:%02d:%02d;\n",
1957 	    t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
1958 	    t->tm_hour, t->tm_min, t->tm_sec);
1959 	t = gmtime(&lease->expiry);
1960 	fprintf(leaseFile, "  expire %d %d/%d/%d %02d:%02d:%02d;\n",
1961 	    t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
1962 	    t->tm_hour, t->tm_min, t->tm_sec);
1963 	fprintf(leaseFile, "}\n");
1964 	fflush(leaseFile);
1965 }
1966 
1967 void
1968 script_init(char *reason, struct string_list *medium)
1969 {
1970 	size_t		 len, mediumlen = 0;
1971 	struct imsg_hdr	 hdr;
1972 	struct buf	*buf;
1973 	int		 errs;
1974 
1975 	if (medium != NULL && medium->string != NULL)
1976 		mediumlen = strlen(medium->string);
1977 
1978 	hdr.code = IMSG_SCRIPT_INIT;
1979 	hdr.len = sizeof(struct imsg_hdr) +
1980 	    sizeof(size_t) + mediumlen +
1981 	    sizeof(size_t) + strlen(reason);
1982 
1983 	if ((buf = buf_open(hdr.len)) == NULL)
1984 		error("buf_open: %m");
1985 
1986 	errs = 0;
1987 	errs += buf_add(buf, &hdr, sizeof(hdr));
1988 	errs += buf_add(buf, &mediumlen, sizeof(mediumlen));
1989 	if (mediumlen > 0)
1990 		errs += buf_add(buf, medium->string, mediumlen);
1991 	len = strlen(reason);
1992 	errs += buf_add(buf, &len, sizeof(len));
1993 	errs += buf_add(buf, reason, len);
1994 
1995 	if (errs)
1996 		error("buf_add: %m");
1997 
1998 	if (buf_close(privfd, buf) == -1)
1999 		error("buf_close: %m");
2000 }
2001 
2002 void
2003 priv_script_init(char *reason, char *medium)
2004 {
2005 	struct interface_info *ip = ifi;
2006 
2007 	if (ip) {
2008 		ip->client->scriptEnvsize = 100;
2009 		if (ip->client->scriptEnv == NULL)
2010 			ip->client->scriptEnv =
2011 			    malloc(ip->client->scriptEnvsize * sizeof(char *));
2012 		if (ip->client->scriptEnv == NULL)
2013 			error("script_init: no memory for environment");
2014 
2015 		ip->client->scriptEnv[0] = strdup(CLIENT_PATH);
2016 		if (ip->client->scriptEnv[0] == NULL)
2017 			error("script_init: no memory for environment");
2018 
2019 		ip->client->scriptEnv[1] = NULL;
2020 
2021 		script_set_env(ip->client, "", "interface", ip->name);
2022 
2023 		if (medium)
2024 			script_set_env(ip->client, "", "medium", medium);
2025 
2026 		script_set_env(ip->client, "", "reason", reason);
2027 	}
2028 }
2029 
2030 void
2031 priv_script_write_params(char *prefix, struct client_lease *lease)
2032 {
2033 	struct interface_info *ip = ifi;
2034 	u_int8_t dbuf[1500], *dp = NULL;
2035 	int i, len;
2036 	char tbuf[128];
2037 
2038 	script_set_env(ip->client, prefix, "ip_address",
2039 	    piaddr(lease->address));
2040 
2041 	if (ip->client->config->default_actions[DHO_SUBNET_MASK] ==
2042 	    ACTION_SUPERSEDE) {
2043 		dp = ip->client->config->defaults[DHO_SUBNET_MASK].data;
2044 		len = ip->client->config->defaults[DHO_SUBNET_MASK].len;
2045 	} else {
2046 		dp = lease->options[DHO_SUBNET_MASK].data;
2047 		len = lease->options[DHO_SUBNET_MASK].len;
2048 	}
2049 	if (len && (len < sizeof(lease->address.iabuf))) {
2050 		struct iaddr netmask, subnet, broadcast;
2051 
2052 		memcpy(netmask.iabuf, dp, len);
2053 		netmask.len = len;
2054 		subnet = subnet_number(lease->address, netmask);
2055 		if (subnet.len) {
2056 			script_set_env(ip->client, prefix, "network_number",
2057 			    piaddr(subnet));
2058 			if (!lease->options[DHO_BROADCAST_ADDRESS].len) {
2059 				broadcast = broadcast_addr(subnet, netmask);
2060 				if (broadcast.len)
2061 					script_set_env(ip->client, prefix,
2062 					    "broadcast_address",
2063 					    piaddr(broadcast));
2064 			}
2065 		}
2066 	}
2067 
2068 	if (lease->filename)
2069 		script_set_env(ip->client, prefix, "filename", lease->filename);
2070 	if (lease->server_name)
2071 		script_set_env(ip->client, prefix, "server_name",
2072 		    lease->server_name);
2073 	for (i = 0; i < 256; i++) {
2074 		len = 0;
2075 
2076 		if (ip->client->config->defaults[i].len) {
2077 			if (lease->options[i].len) {
2078 				switch (
2079 				    ip->client->config->default_actions[i]) {
2080 				case ACTION_DEFAULT:
2081 					dp = lease->options[i].data;
2082 					len = lease->options[i].len;
2083 					break;
2084 				case ACTION_SUPERSEDE:
2085 supersede:
2086 					dp = ip->client->
2087 						config->defaults[i].data;
2088 					len = ip->client->
2089 						config->defaults[i].len;
2090 					break;
2091 				case ACTION_PREPEND:
2092 					len = ip->client->
2093 					    config->defaults[i].len +
2094 					    lease->options[i].len;
2095 					if (len >= sizeof(dbuf)) {
2096 						warning("no space to %s %s",
2097 						    "prepend option",
2098 						    dhcp_options[i].name);
2099 						goto supersede;
2100 					}
2101 					dp = dbuf;
2102 					memcpy(dp,
2103 						ip->client->
2104 						config->defaults[i].data,
2105 						ip->client->
2106 						config->defaults[i].len);
2107 					memcpy(dp + ip->client->
2108 						config->defaults[i].len,
2109 						lease->options[i].data,
2110 						lease->options[i].len);
2111 					dp[len] = '\0';
2112 					break;
2113 				case ACTION_APPEND:
2114 					/*
2115 					 * When we append, we assume that we're
2116 					 * appending to text.  Some MS servers
2117 					 * include a NUL byte at the end of
2118 					 * the search string provided.
2119 					 */
2120 					len = ip->client->
2121 					    config->defaults[i].len +
2122 					    lease->options[i].len;
2123 					if (len >= sizeof(dbuf)) {
2124 						warning("no space to %s %s",
2125 						    "append option",
2126 						    dhcp_options[i].name);
2127 						goto supersede;
2128 					}
2129 					memcpy(dbuf,
2130 						lease->options[i].data,
2131 						lease->options[i].len);
2132 					for (dp = dbuf + lease->options[i].len;
2133 					    dp > dbuf; dp--, len--)
2134 						if (dp[-1] != '\0')
2135 							break;
2136 					memcpy(dp,
2137 						ip->client->
2138 						config->defaults[i].data,
2139 						ip->client->
2140 						config->defaults[i].len);
2141 					dp = dbuf;
2142 					dp[len] = '\0';
2143 				}
2144 			} else {
2145 				dp = ip->client->
2146 					config->defaults[i].data;
2147 				len = ip->client->
2148 					config->defaults[i].len;
2149 			}
2150 		} else if (lease->options[i].len) {
2151 			len = lease->options[i].len;
2152 			dp = lease->options[i].data;
2153 		} else {
2154 			len = 0;
2155 		}
2156 		if (len) {
2157 			char name[256];
2158 
2159 			if (dhcp_option_ev_name(name, sizeof(name),
2160 			    &dhcp_options[i]))
2161 				script_set_env(ip->client, prefix, name,
2162 				    pretty_print_option(i, dp, len, 0, 0));
2163 		}
2164 	}
2165 	snprintf(tbuf, sizeof(tbuf), "%d", (int)lease->expiry);
2166 	script_set_env(ip->client, prefix, "expiry", tbuf);
2167 }
2168 
2169 void
2170 script_write_params(char *prefix, struct client_lease *lease)
2171 {
2172 	size_t		 fn_len = 0, sn_len = 0, pr_len = 0;
2173 	struct imsg_hdr	 hdr;
2174 	struct buf	*buf;
2175 	int		 errs, i;
2176 
2177 	if (lease->filename != NULL)
2178 		fn_len = strlen(lease->filename);
2179 	if (lease->server_name != NULL)
2180 		sn_len = strlen(lease->server_name);
2181 	if (prefix != NULL)
2182 		pr_len = strlen(prefix);
2183 
2184 	hdr.code = IMSG_SCRIPT_WRITE_PARAMS;
2185 	hdr.len = sizeof(hdr) + sizeof(struct client_lease) +
2186 	    sizeof(size_t) + fn_len + sizeof(size_t) + sn_len +
2187 	    sizeof(size_t) + pr_len;
2188 
2189 	for (i = 0; i < 256; i++)
2190 		hdr.len += sizeof(int) + lease->options[i].len;
2191 
2192 	scripttime = time(NULL);
2193 
2194 	if ((buf = buf_open(hdr.len)) == NULL)
2195 		error("buf_open: %m");
2196 
2197 	errs = 0;
2198 	errs += buf_add(buf, &hdr, sizeof(hdr));
2199 	errs += buf_add(buf, lease, sizeof(struct client_lease));
2200 	errs += buf_add(buf, &fn_len, sizeof(fn_len));
2201 	errs += buf_add(buf, lease->filename, fn_len);
2202 	errs += buf_add(buf, &sn_len, sizeof(sn_len));
2203 	errs += buf_add(buf, lease->server_name, sn_len);
2204 	errs += buf_add(buf, &pr_len, sizeof(pr_len));
2205 	errs += buf_add(buf, prefix, pr_len);
2206 
2207 	for (i = 0; i < 256; i++) {
2208 		errs += buf_add(buf, &lease->options[i].len,
2209 		    sizeof(lease->options[i].len));
2210 		errs += buf_add(buf, lease->options[i].data,
2211 		    lease->options[i].len);
2212 	}
2213 
2214 	if (errs)
2215 		error("buf_add: %m");
2216 
2217 	if (buf_close(privfd, buf) == -1)
2218 		error("buf_close: %m");
2219 }
2220 
2221 int
2222 script_go(void)
2223 {
2224 	struct imsg_hdr	 hdr;
2225 	struct buf	*buf;
2226 	int		 ret;
2227 
2228 	hdr.code = IMSG_SCRIPT_GO;
2229 	hdr.len = sizeof(struct imsg_hdr);
2230 
2231 	if ((buf = buf_open(hdr.len)) == NULL)
2232 		error("buf_open: %m");
2233 
2234 	if (buf_add(buf, &hdr, sizeof(hdr)))
2235 		error("buf_add: %m");
2236 
2237 	if (buf_close(privfd, buf) == -1)
2238 		error("buf_close: %m");
2239 
2240 	bzero(&hdr, sizeof(hdr));
2241 	buf_read(privfd, &hdr, sizeof(hdr));
2242 	if (hdr.code != IMSG_SCRIPT_GO_RET)
2243 		error("unexpected msg type %u", hdr.code);
2244 	if (hdr.len != sizeof(hdr) + sizeof(int))
2245 		error("received corrupted message");
2246 	buf_read(privfd, &ret, sizeof(ret));
2247 
2248 	scripttime = time(NULL);
2249 
2250 	return (ret);
2251 }
2252 
2253 int
2254 priv_script_go(void)
2255 {
2256 	char *scriptName, *argv[2], **envp, *epp[3], reason[] = "REASON=NBI";
2257 	static char client_path[] = CLIENT_PATH;
2258 	struct interface_info *ip = ifi;
2259 	int pid, wpid, wstatus;
2260 
2261 	scripttime = time(NULL);
2262 
2263 	if (ip) {
2264 		scriptName = ip->client->config->script_name;
2265 		envp = ip->client->scriptEnv;
2266 	} else {
2267 		scriptName = top_level_config.script_name;
2268 		epp[0] = reason;
2269 		epp[1] = client_path;
2270 		epp[2] = NULL;
2271 		envp = epp;
2272 	}
2273 
2274 	argv[0] = scriptName;
2275 	argv[1] = NULL;
2276 
2277 	pid = fork();
2278 	if (pid < 0) {
2279 		error("fork: %m");
2280 		wstatus = 0;
2281 	} else if (pid) {
2282 		do {
2283 			wpid = wait(&wstatus);
2284 		} while (wpid != pid && wpid > 0);
2285 		if (wpid < 0) {
2286 			error("wait: %m");
2287 			wstatus = 0;
2288 		}
2289 	} else {
2290 		execve(scriptName, argv, envp);
2291 		error("execve (%s, ...): %m", scriptName);
2292 	}
2293 
2294 	if (ip)
2295 		script_flush_env(ip->client);
2296 
2297 	return (wstatus & 0xff);
2298 }
2299 
2300 void
2301 script_set_env(struct client_state *client, const char *prefix,
2302     const char *name, const char *value)
2303 {
2304 	int i, j, namelen;
2305 
2306 	/* No `` or $() command substitution allowed in environment values! */
2307 	for (j=0; j < strlen(value); j++)
2308 		switch (value[j]) {
2309 		case '`':
2310 		case '$':
2311 			warning("illegal character (%c) in value '%s'",
2312 			    value[j], value);
2313 			/* Ignore this option */
2314 			return;
2315 		}
2316 
2317 	namelen = strlen(name);
2318 
2319 	for (i = 0; client->scriptEnv[i]; i++)
2320 		if (strncmp(client->scriptEnv[i], name, namelen) == 0 &&
2321 		    client->scriptEnv[i][namelen] == '=')
2322 			break;
2323 
2324 	if (client->scriptEnv[i])
2325 		/* Reuse the slot. */
2326 		free(client->scriptEnv[i]);
2327 	else {
2328 		/* New variable.  Expand if necessary. */
2329 		if (i >= client->scriptEnvsize - 1) {
2330 			char **newscriptEnv;
2331 			int newscriptEnvsize = client->scriptEnvsize + 50;
2332 
2333 			newscriptEnv = realloc(client->scriptEnv,
2334 			    newscriptEnvsize);
2335 			if (newscriptEnv == NULL) {
2336 				free(client->scriptEnv);
2337 				client->scriptEnv = NULL;
2338 				client->scriptEnvsize = 0;
2339 				error("script_set_env: no memory for variable");
2340 			}
2341 			client->scriptEnv = newscriptEnv;
2342 			client->scriptEnvsize = newscriptEnvsize;
2343 		}
2344 		/* need to set the NULL pointer at end of array beyond
2345 		   the new slot. */
2346 		client->scriptEnv[i + 1] = NULL;
2347 	}
2348 	/* Allocate space and format the variable in the appropriate slot. */
2349 	client->scriptEnv[i] = malloc(strlen(prefix) + strlen(name) + 1 +
2350 	    strlen(value) + 1);
2351 	if (client->scriptEnv[i] == NULL)
2352 		error("script_set_env: no memory for variable assignment");
2353 	snprintf(client->scriptEnv[i], strlen(prefix) + strlen(name) +
2354 	    1 + strlen(value) + 1, "%s%s=%s", prefix, name, value);
2355 }
2356 
2357 void
2358 script_flush_env(struct client_state *client)
2359 {
2360 	int i;
2361 
2362 	for (i = 0; client->scriptEnv[i]; i++) {
2363 		free(client->scriptEnv[i]);
2364 		client->scriptEnv[i] = NULL;
2365 	}
2366 	client->scriptEnvsize = 0;
2367 }
2368 
2369 int
2370 dhcp_option_ev_name(char *buf, size_t buflen, struct option *option)
2371 {
2372 	int i;
2373 
2374 	for (i = 0; option->name[i]; i++) {
2375 		if (i + 1 == buflen)
2376 			return 0;
2377 		if (option->name[i] == '-')
2378 			buf[i] = '_';
2379 		else
2380 			buf[i] = option->name[i];
2381 	}
2382 
2383 	buf[i] = 0;
2384 	return 1;
2385 }
2386 
2387 void
2388 go_daemon(void)
2389 {
2390 	static int state = 0;
2391 	cap_rights_t rights;
2392 
2393 	if (no_daemon || state)
2394 		return;
2395 
2396 	state = 1;
2397 
2398 	/* Stop logging to stderr... */
2399 	log_perror = 0;
2400 
2401 	if (daemon(1, 0) == -1)
2402 		error("daemon");
2403 
2404 	cap_rights_init(&rights);
2405 
2406 	if (pidfile != NULL) {
2407 		pidfile_write(pidfile);
2408 		if (cap_rights_limit(pidfile_fileno(pidfile), &rights) < 0 &&
2409 		    errno != ENOSYS) {
2410 			error("can't limit pidfile descriptor: %m");
2411 		}
2412 	}
2413 
2414 	/* we are chrooted, daemon(3) fails to open /dev/null */
2415 	if (nullfd != -1) {
2416 		dup2(nullfd, STDIN_FILENO);
2417 		dup2(nullfd, STDOUT_FILENO);
2418 		dup2(nullfd, STDERR_FILENO);
2419 		close(nullfd);
2420 		nullfd = -1;
2421 	}
2422 
2423 	if (cap_rights_limit(STDIN_FILENO, &rights) < 0 && errno != ENOSYS)
2424 		error("can't limit stdin: %m");
2425 	cap_rights_init(&rights, CAP_WRITE);
2426 	if (cap_rights_limit(STDOUT_FILENO, &rights) < 0 && errno != ENOSYS)
2427 		error("can't limit stdout: %m");
2428 	if (cap_rights_limit(STDERR_FILENO, &rights) < 0 && errno != ENOSYS)
2429 		error("can't limit stderr: %m");
2430 }
2431 
2432 int
2433 check_option(struct client_lease *l, int option)
2434 {
2435 	char *opbuf;
2436 	char *sbuf;
2437 
2438 	/* we use this, since this is what gets passed to dhclient-script */
2439 
2440 	opbuf = pretty_print_option(option, l->options[option].data,
2441 	    l->options[option].len, 0, 0);
2442 
2443 	sbuf = option_as_string(option, l->options[option].data,
2444 	    l->options[option].len);
2445 
2446 	switch (option) {
2447 	case DHO_SUBNET_MASK:
2448 	case DHO_TIME_SERVERS:
2449 	case DHO_NAME_SERVERS:
2450 	case DHO_ROUTERS:
2451 	case DHO_DOMAIN_NAME_SERVERS:
2452 	case DHO_LOG_SERVERS:
2453 	case DHO_COOKIE_SERVERS:
2454 	case DHO_LPR_SERVERS:
2455 	case DHO_IMPRESS_SERVERS:
2456 	case DHO_RESOURCE_LOCATION_SERVERS:
2457 	case DHO_SWAP_SERVER:
2458 	case DHO_BROADCAST_ADDRESS:
2459 	case DHO_NIS_SERVERS:
2460 	case DHO_NTP_SERVERS:
2461 	case DHO_NETBIOS_NAME_SERVERS:
2462 	case DHO_NETBIOS_DD_SERVER:
2463 	case DHO_FONT_SERVERS:
2464 	case DHO_DHCP_SERVER_IDENTIFIER:
2465 	case DHO_NISPLUS_SERVERS:
2466 	case DHO_MOBILE_IP_HOME_AGENT:
2467 	case DHO_SMTP_SERVER:
2468 	case DHO_POP_SERVER:
2469 	case DHO_NNTP_SERVER:
2470 	case DHO_WWW_SERVER:
2471 	case DHO_FINGER_SERVER:
2472 	case DHO_IRC_SERVER:
2473 	case DHO_STREETTALK_SERVER:
2474 	case DHO_STREETTALK_DA_SERVER:
2475 		if (!ipv4addrs(opbuf)) {
2476 			warning("Invalid IP address in option: %s", opbuf);
2477 			return (0);
2478 		}
2479 		return (1)  ;
2480 	case DHO_HOST_NAME:
2481 	case DHO_NIS_DOMAIN:
2482 	case DHO_NISPLUS_DOMAIN:
2483 	case DHO_TFTP_SERVER_NAME:
2484 		if (!res_hnok(sbuf)) {
2485 			warning("Bogus Host Name option %d: %s (%s)", option,
2486 			    sbuf, opbuf);
2487 			l->options[option].len = 0;
2488 			free(l->options[option].data);
2489 		}
2490 		return (1);
2491 	case DHO_DOMAIN_NAME:
2492 	case DHO_DOMAIN_SEARCH:
2493 		if (!res_hnok(sbuf)) {
2494 			if (!check_search(sbuf)) {
2495 				warning("Bogus domain search list %d: %s (%s)",
2496 				    option, sbuf, opbuf);
2497 				l->options[option].len = 0;
2498 				free(l->options[option].data);
2499 			}
2500 		}
2501 		return (1);
2502 	case DHO_PAD:
2503 	case DHO_TIME_OFFSET:
2504 	case DHO_BOOT_SIZE:
2505 	case DHO_MERIT_DUMP:
2506 	case DHO_ROOT_PATH:
2507 	case DHO_EXTENSIONS_PATH:
2508 	case DHO_IP_FORWARDING:
2509 	case DHO_NON_LOCAL_SOURCE_ROUTING:
2510 	case DHO_POLICY_FILTER:
2511 	case DHO_MAX_DGRAM_REASSEMBLY:
2512 	case DHO_DEFAULT_IP_TTL:
2513 	case DHO_PATH_MTU_AGING_TIMEOUT:
2514 	case DHO_PATH_MTU_PLATEAU_TABLE:
2515 	case DHO_INTERFACE_MTU:
2516 	case DHO_ALL_SUBNETS_LOCAL:
2517 	case DHO_PERFORM_MASK_DISCOVERY:
2518 	case DHO_MASK_SUPPLIER:
2519 	case DHO_ROUTER_DISCOVERY:
2520 	case DHO_ROUTER_SOLICITATION_ADDRESS:
2521 	case DHO_STATIC_ROUTES:
2522 	case DHO_TRAILER_ENCAPSULATION:
2523 	case DHO_ARP_CACHE_TIMEOUT:
2524 	case DHO_IEEE802_3_ENCAPSULATION:
2525 	case DHO_DEFAULT_TCP_TTL:
2526 	case DHO_TCP_KEEPALIVE_INTERVAL:
2527 	case DHO_TCP_KEEPALIVE_GARBAGE:
2528 	case DHO_VENDOR_ENCAPSULATED_OPTIONS:
2529 	case DHO_NETBIOS_NODE_TYPE:
2530 	case DHO_NETBIOS_SCOPE:
2531 	case DHO_X_DISPLAY_MANAGER:
2532 	case DHO_DHCP_REQUESTED_ADDRESS:
2533 	case DHO_DHCP_LEASE_TIME:
2534 	case DHO_DHCP_OPTION_OVERLOAD:
2535 	case DHO_DHCP_MESSAGE_TYPE:
2536 	case DHO_DHCP_PARAMETER_REQUEST_LIST:
2537 	case DHO_DHCP_MESSAGE:
2538 	case DHO_DHCP_MAX_MESSAGE_SIZE:
2539 	case DHO_DHCP_RENEWAL_TIME:
2540 	case DHO_DHCP_REBINDING_TIME:
2541 	case DHO_DHCP_CLASS_IDENTIFIER:
2542 	case DHO_DHCP_CLIENT_IDENTIFIER:
2543 	case DHO_BOOTFILE_NAME:
2544 	case DHO_DHCP_USER_CLASS_ID:
2545 	case DHO_END:
2546 		return (1);
2547 	case DHO_CLASSLESS_ROUTES:
2548 		return (check_classless_option(l->options[option].data,
2549 		    l->options[option].len));
2550 	default:
2551 		warning("unknown dhcp option value 0x%x", option);
2552 		return (unknown_ok);
2553 	}
2554 }
2555 
2556 /* RFC 3442 The Classless Static Routes option checks */
2557 int
2558 check_classless_option(unsigned char *data, int len)
2559 {
2560 	int i = 0;
2561 	unsigned char width;
2562 	in_addr_t addr, mask;
2563 
2564 	if (len < 5) {
2565 		warning("Too small length: %d", len);
2566 		return (0);
2567 	}
2568 	while(i < len) {
2569 		width = data[i++];
2570 		if (width == 0) {
2571 			i += 4;
2572 			continue;
2573 		} else if (width < 9) {
2574 			addr =  (in_addr_t)(data[i]	<< 24);
2575 			i += 1;
2576 		} else if (width < 17) {
2577 			addr =  (in_addr_t)(data[i]	<< 24) +
2578 				(in_addr_t)(data[i + 1]	<< 16);
2579 			i += 2;
2580 		} else if (width < 25) {
2581 			addr =  (in_addr_t)(data[i]	<< 24) +
2582 				(in_addr_t)(data[i + 1]	<< 16) +
2583 				(in_addr_t)(data[i + 2]	<< 8);
2584 			i += 3;
2585 		} else if (width < 33) {
2586 			addr =  (in_addr_t)(data[i]	<< 24) +
2587 				(in_addr_t)(data[i + 1]	<< 16) +
2588 				(in_addr_t)(data[i + 2]	<< 8)  +
2589 				data[i + 3];
2590 			i += 4;
2591 		} else {
2592 			warning("Incorrect subnet width: %d", width);
2593 			return (0);
2594 		}
2595 		mask = (in_addr_t)(~0) << (32 - width);
2596 		addr = ntohl(addr);
2597 		mask = ntohl(mask);
2598 
2599 		/*
2600 		 * From RFC 3442:
2601 		 * ... After deriving a subnet number and subnet mask
2602 		 * from each destination descriptor, the DHCP client
2603 		 * MUST zero any bits in the subnet number where the
2604 		 * corresponding bit in the mask is zero...
2605 		 */
2606 		if ((addr & mask) != addr) {
2607 			addr &= mask;
2608 			data[i - 1] = (unsigned char)(
2609 				(addr >> (((32 - width)/8)*8)) & 0xFF);
2610 		}
2611 		i += 4;
2612 	}
2613 	if (i > len) {
2614 		warning("Incorrect data length: %d (must be %d)", len, i);
2615 		return (0);
2616 	}
2617 	return (1);
2618 }
2619 
2620 int
2621 res_hnok(const char *dn)
2622 {
2623 	int pch = PERIOD, ch = *dn++;
2624 
2625 	while (ch != '\0') {
2626 		int nch = *dn++;
2627 
2628 		if (periodchar(ch)) {
2629 			;
2630 		} else if (periodchar(pch)) {
2631 			if (!borderchar(ch))
2632 				return (0);
2633 		} else if (periodchar(nch) || nch == '\0') {
2634 			if (!borderchar(ch))
2635 				return (0);
2636 		} else {
2637 			if (!middlechar(ch))
2638 				return (0);
2639 		}
2640 		pch = ch, ch = nch;
2641 	}
2642 	return (1);
2643 }
2644 
2645 int
2646 check_search(const char *srch)
2647 {
2648         int pch = PERIOD, ch = *srch++;
2649 	int domains = 1;
2650 
2651 	/* 256 char limit re resolv.conf(5) */
2652 	if (strlen(srch) > 256)
2653 		return (0);
2654 
2655 	while (whitechar(ch))
2656 		ch = *srch++;
2657 
2658         while (ch != '\0') {
2659                 int nch = *srch++;
2660 
2661                 if (periodchar(ch) || whitechar(ch)) {
2662                         ;
2663                 } else if (periodchar(pch)) {
2664                         if (!borderchar(ch))
2665                                 return (0);
2666                 } else if (periodchar(nch) || nch == '\0') {
2667                         if (!borderchar(ch))
2668                                 return (0);
2669                 } else {
2670                         if (!middlechar(ch))
2671                                 return (0);
2672                 }
2673 		if (!whitechar(ch)) {
2674 			pch = ch;
2675 		} else {
2676 			while (whitechar(nch)) {
2677 				nch = *srch++;
2678 			}
2679 			if (nch != '\0')
2680 				domains++;
2681 			pch = PERIOD;
2682 		}
2683 		ch = nch;
2684         }
2685 	/* 6 domain limit re resolv.conf(5) */
2686 	if (domains > 6)
2687 		return (0);
2688         return (1);
2689 }
2690 
2691 /* Does buf consist only of dotted decimal ipv4 addrs?
2692  * return how many if so,
2693  * otherwise, return 0
2694  */
2695 int
2696 ipv4addrs(char * buf)
2697 {
2698 	struct in_addr jnk;
2699 	int count = 0;
2700 
2701 	while (inet_aton(buf, &jnk) == 1){
2702 		count++;
2703 		while (periodchar(*buf) || digitchar(*buf))
2704 			buf++;
2705 		if (*buf == '\0')
2706 			return (count);
2707 		while (*buf ==  ' ')
2708 			buf++;
2709 	}
2710 	return (0);
2711 }
2712 
2713 
2714 char *
2715 option_as_string(unsigned int code, unsigned char *data, int len)
2716 {
2717 	static char optbuf[32768]; /* XXX */
2718 	char *op = optbuf;
2719 	int opleft = sizeof(optbuf);
2720 	unsigned char *dp = data;
2721 
2722 	if (code > 255)
2723 		error("option_as_string: bad code %d", code);
2724 
2725 	for (; dp < data + len; dp++) {
2726 		if (!isascii(*dp) || !isprint(*dp)) {
2727 			if (dp + 1 != data + len || *dp != 0) {
2728 				snprintf(op, opleft, "\\%03o", *dp);
2729 				op += 4;
2730 				opleft -= 4;
2731 			}
2732 		} else if (*dp == '"' || *dp == '\'' || *dp == '$' ||
2733 		    *dp == '`' || *dp == '\\') {
2734 			*op++ = '\\';
2735 			*op++ = *dp;
2736 			opleft -= 2;
2737 		} else {
2738 			*op++ = *dp;
2739 			opleft--;
2740 		}
2741 	}
2742 	if (opleft < 1)
2743 		goto toobig;
2744 	*op = 0;
2745 	return optbuf;
2746 toobig:
2747 	warning("dhcp option too large");
2748 	return "<error>";
2749 }
2750 
2751 int
2752 fork_privchld(int fd, int fd2)
2753 {
2754 	struct pollfd pfd[1];
2755 	int nfds;
2756 
2757 	switch (fork()) {
2758 	case -1:
2759 		error("cannot fork");
2760 	case 0:
2761 		break;
2762 	default:
2763 		return (0);
2764 	}
2765 
2766 	setproctitle("%s [priv]", ifi->name);
2767 
2768 	setsid();
2769 	dup2(nullfd, STDIN_FILENO);
2770 	dup2(nullfd, STDOUT_FILENO);
2771 	dup2(nullfd, STDERR_FILENO);
2772 	close(nullfd);
2773 	close(fd2);
2774 	close(ifi->rfdesc);
2775 	ifi->rfdesc = -1;
2776 
2777 	for (;;) {
2778 		pfd[0].fd = fd;
2779 		pfd[0].events = POLLIN;
2780 		if ((nfds = poll(pfd, 1, INFTIM)) == -1)
2781 			if (errno != EINTR)
2782 				error("poll error");
2783 
2784 		if (nfds == 0 || !(pfd[0].revents & POLLIN))
2785 			continue;
2786 
2787 		dispatch_imsg(ifi, fd);
2788 	}
2789 }
2790