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