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