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