xref: /freebsd/sbin/dhclient/dhclient.c (revision 5956d97f4b3204318ceb6aa9c77bd0bc6ea87a41)
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 (caph_rights_limit(privfd, &rights) < 0)
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 (caph_rights_limit(routefd, &rights) < 0)
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 		u_int16_t old_mtu = 0;
867 		bool supersede = (ip->client->config->default_actions[DHO_INTERFACE_MTU] ==
868 			ACTION_SUPERSEDE);
869 
870 		if (supersede)
871 			mtu = getUShort(ip->client->config->defaults[DHO_INTERFACE_MTU].data);
872 		else
873 			mtu = be16dec(opt->data);
874 
875 		if (ip->client->active) {
876 			opt = &ip->client->active->options[DHO_INTERFACE_MTU];
877 			if (opt->len == sizeof(u_int16_t)) {
878 				old_mtu = be16dec(opt->data);
879 			}
880 		}
881 
882 		if (mtu < MIN_MTU) {
883 			/* Treat 0 like a user intentionally doesn't want to change MTU and,
884 			 * therefore, warning is not needed */
885 			if (!supersede || mtu != 0)
886 				warning("mtu size %u < %d: ignored", (unsigned)mtu, MIN_MTU);
887 		} else if (ip->client->state != S_RENEWING || mtu != old_mtu) {
888 			interface_set_mtu_unpriv(privfd, mtu);
889 		}
890 	}
891 
892 	/* Write out the new lease. */
893 	write_client_lease(ip, ip->client->new, 0);
894 
895 	/* Run the client script with the new parameters. */
896 	script_init((ip->client->state == S_REQUESTING ? "BOUND" :
897 	    (ip->client->state == S_RENEWING ? "RENEW" :
898 	    (ip->client->state == S_REBOOTING ? "REBOOT" : "REBIND"))),
899 	    ip->client->new->medium);
900 	if (ip->client->active && ip->client->state != S_REBOOTING)
901 		script_write_params("old_", ip->client->active);
902 	script_write_params("new_", ip->client->new);
903 	if (ip->client->alias)
904 		script_write_params("alias_", ip->client->alias);
905 	script_go();
906 
907 	/* Replace the old active lease with the new one. */
908 	if (ip->client->active)
909 		free_client_lease(ip->client->active);
910 	ip->client->active = ip->client->new;
911 	ip->client->new = NULL;
912 
913 	/* Set up a timeout to start the renewal process. */
914 	add_timeout(ip->client->active->renewal, state_bound, ip);
915 
916 	note("bound to %s -- renewal in %d seconds.",
917 	    piaddr(ip->client->active->address),
918 	    (int)(ip->client->active->renewal - cur_time));
919 	ip->client->state = S_BOUND;
920 	reinitialize_interfaces();
921 	go_daemon();
922 }
923 
924 /*
925  * state_bound is called when we've successfully bound to a particular
926  * lease, but the renewal time on that lease has expired.   We are
927  * expected to unicast a DHCPREQUEST to the server that gave us our
928  * original lease.
929  */
930 void
931 state_bound(void *ipp)
932 {
933 	struct interface_info *ip = ipp;
934 	u_int8_t *dp = NULL;
935 	int len;
936 
937 	ASSERT_STATE(state, S_BOUND);
938 
939 	/* T1 has expired. */
940 	make_request(ip, ip->client->active);
941 	ip->client->xid = ip->client->packet.xid;
942 
943 	if (ip->client->config->default_actions[DHO_DHCP_SERVER_IDENTIFIER] ==
944 	    ACTION_SUPERSEDE) {
945 		dp = ip->client->config->defaults[DHO_DHCP_SERVER_IDENTIFIER].data;
946 		len = ip->client->config->defaults[DHO_DHCP_SERVER_IDENTIFIER].len;
947 	} else {
948 		dp = ip->client->active->options[DHO_DHCP_SERVER_IDENTIFIER].data;
949 		len = ip->client->active->options[DHO_DHCP_SERVER_IDENTIFIER].len;
950 	}
951 	if (len == 4) {
952 		memcpy(ip->client->destination.iabuf, dp, len);
953 		ip->client->destination.len = len;
954 	} else
955 		ip->client->destination = iaddr_broadcast;
956 
957 	ip->client->first_sending = cur_time;
958 	ip->client->interval = ip->client->config->initial_interval;
959 	ip->client->state = S_RENEWING;
960 
961 	/* Send the first packet immediately. */
962 	send_request(ip);
963 }
964 
965 void
966 bootp(struct packet *packet)
967 {
968 	struct iaddrlist *ap;
969 
970 	if (packet->raw->op != BOOTREPLY)
971 		return;
972 
973 	/* If there's a reject list, make sure this packet's sender isn't
974 	   on it. */
975 	for (ap = packet->interface->client->config->reject_list;
976 	    ap; ap = ap->next) {
977 		if (addr_eq(packet->client_addr, ap->addr)) {
978 			note("BOOTREPLY from %s rejected.", piaddr(ap->addr));
979 			return;
980 		}
981 	}
982 	dhcpoffer(packet);
983 }
984 
985 void
986 dhcp(struct packet *packet)
987 {
988 	struct iaddrlist *ap;
989 	void (*handler)(struct packet *);
990 	const char *type;
991 
992 	switch (packet->packet_type) {
993 	case DHCPOFFER:
994 		handler = dhcpoffer;
995 		type = "DHCPOFFER";
996 		break;
997 	case DHCPNAK:
998 		handler = dhcpnak;
999 		type = "DHCPNACK";
1000 		break;
1001 	case DHCPACK:
1002 		handler = dhcpack;
1003 		type = "DHCPACK";
1004 		break;
1005 	default:
1006 		return;
1007 	}
1008 
1009 	/* If there's a reject list, make sure this packet's sender isn't
1010 	   on it. */
1011 	for (ap = packet->interface->client->config->reject_list;
1012 	    ap; ap = ap->next) {
1013 		if (addr_eq(packet->client_addr, ap->addr)) {
1014 			note("%s from %s rejected.", type, piaddr(ap->addr));
1015 			return;
1016 		}
1017 	}
1018 	(*handler)(packet);
1019 }
1020 
1021 void
1022 dhcpoffer(struct packet *packet)
1023 {
1024 	struct interface_info *ip = packet->interface;
1025 	struct client_lease *lease, *lp;
1026 	int i;
1027 	int arp_timeout_needed, stop_selecting;
1028 	const char *name = packet->options[DHO_DHCP_MESSAGE_TYPE].len ?
1029 	    "DHCPOFFER" : "BOOTREPLY";
1030 
1031 	/* If we're not receptive to an offer right now, or if the offer
1032 	   has an unrecognizable transaction id, then just drop it. */
1033 	if (ip->client->state != S_SELECTING ||
1034 	    packet->interface->client->xid != packet->raw->xid ||
1035 	    (packet->interface->hw_address.hlen != packet->raw->hlen) ||
1036 	    (memcmp(packet->interface->hw_address.haddr,
1037 	    packet->raw->chaddr, packet->raw->hlen)))
1038 		return;
1039 
1040 	note("%s from %s", name, piaddr(packet->client_addr));
1041 
1042 
1043 	/* If this lease doesn't supply the minimum required parameters,
1044 	   blow it off. */
1045 	for (i = 0; ip->client->config->required_options[i]; i++) {
1046 		if (!packet->options[ip->client->config->
1047 		    required_options[i]].len) {
1048 			note("%s isn't satisfactory.", name);
1049 			return;
1050 		}
1051 	}
1052 
1053 	/* If we've already seen this lease, don't record it again. */
1054 	for (lease = ip->client->offered_leases;
1055 	    lease; lease = lease->next) {
1056 		if (lease->address.len == sizeof(packet->raw->yiaddr) &&
1057 		    !memcmp(lease->address.iabuf,
1058 		    &packet->raw->yiaddr, lease->address.len)) {
1059 			debug("%s already seen.", name);
1060 			return;
1061 		}
1062 	}
1063 
1064 	lease = packet_to_lease(packet);
1065 	if (!lease) {
1066 		note("packet_to_lease failed.");
1067 		return;
1068 	}
1069 
1070 	/* If this lease was acquired through a BOOTREPLY, record that
1071 	   fact. */
1072 	if (!packet->options[DHO_DHCP_MESSAGE_TYPE].len)
1073 		lease->is_bootp = 1;
1074 
1075 	/* Record the medium under which this lease was offered. */
1076 	lease->medium = ip->client->medium;
1077 
1078 	/* Send out an ARP Request for the offered IP address. */
1079 	script_init("ARPSEND", lease->medium);
1080 	script_write_params("check_", lease);
1081 	/* If the script can't send an ARP request without waiting,
1082 	   we'll be waiting when we do the ARPCHECK, so don't wait now. */
1083 	if (script_go())
1084 		arp_timeout_needed = 0;
1085 	else
1086 		arp_timeout_needed = 2;
1087 
1088 	/* Figure out when we're supposed to stop selecting. */
1089 	stop_selecting =
1090 	    ip->client->first_sending + ip->client->config->select_interval;
1091 
1092 	/* If this is the lease we asked for, put it at the head of the
1093 	   list, and don't mess with the arp request timeout. */
1094 	if (lease->address.len == ip->client->requested_address.len &&
1095 	    !memcmp(lease->address.iabuf,
1096 	    ip->client->requested_address.iabuf,
1097 	    ip->client->requested_address.len)) {
1098 		lease->next = ip->client->offered_leases;
1099 		ip->client->offered_leases = lease;
1100 	} else {
1101 		/* If we already have an offer, and arping for this
1102 		   offer would take us past the selection timeout,
1103 		   then don't extend the timeout - just hope for the
1104 		   best. */
1105 		if (ip->client->offered_leases &&
1106 		    (cur_time + arp_timeout_needed) > stop_selecting)
1107 			arp_timeout_needed = 0;
1108 
1109 		/* Put the lease at the end of the list. */
1110 		lease->next = NULL;
1111 		if (!ip->client->offered_leases)
1112 			ip->client->offered_leases = lease;
1113 		else {
1114 			for (lp = ip->client->offered_leases; lp->next;
1115 			    lp = lp->next)
1116 				;	/* nothing */
1117 			lp->next = lease;
1118 		}
1119 	}
1120 
1121 	/* If we're supposed to stop selecting before we've had time
1122 	   to wait for the ARPREPLY, add some delay to wait for
1123 	   the ARPREPLY. */
1124 	if (stop_selecting - cur_time < arp_timeout_needed)
1125 		stop_selecting = cur_time + arp_timeout_needed;
1126 
1127 	/* If the selecting interval has expired, go immediately to
1128 	   state_selecting().  Otherwise, time out into
1129 	   state_selecting at the select interval. */
1130 	if (stop_selecting <= 0)
1131 		state_selecting(ip);
1132 	else {
1133 		add_timeout(stop_selecting, state_selecting, ip);
1134 		cancel_timeout(send_discover, ip);
1135 	}
1136 }
1137 
1138 /* Allocate a client_lease structure and initialize it from the parameters
1139    in the specified packet. */
1140 
1141 struct client_lease *
1142 packet_to_lease(struct packet *packet)
1143 {
1144 	struct client_lease *lease;
1145 	int i;
1146 
1147 	lease = malloc(sizeof(struct client_lease));
1148 
1149 	if (!lease) {
1150 		warning("dhcpoffer: no memory to record lease.");
1151 		return (NULL);
1152 	}
1153 
1154 	memset(lease, 0, sizeof(*lease));
1155 
1156 	/* Copy the lease options. */
1157 	for (i = 0; i < 256; i++) {
1158 		if (packet->options[i].len) {
1159 			lease->options[i].data =
1160 			    malloc(packet->options[i].len + 1);
1161 			if (!lease->options[i].data) {
1162 				warning("dhcpoffer: no memory for option %d", i);
1163 				free_client_lease(lease);
1164 				return (NULL);
1165 			} else {
1166 				memcpy(lease->options[i].data,
1167 				    packet->options[i].data,
1168 				    packet->options[i].len);
1169 				lease->options[i].len =
1170 				    packet->options[i].len;
1171 				lease->options[i].data[lease->options[i].len] =
1172 				    0;
1173 			}
1174 			if (!check_option(lease,i)) {
1175 				/* ignore a bogus lease offer */
1176 				warning("Invalid lease option - ignoring offer");
1177 				free_client_lease(lease);
1178 				return (NULL);
1179 			}
1180 		}
1181 	}
1182 
1183 	lease->address.len = sizeof(packet->raw->yiaddr);
1184 	memcpy(lease->address.iabuf, &packet->raw->yiaddr, lease->address.len);
1185 
1186 	lease->nextserver.len = sizeof(packet->raw->siaddr);
1187 	memcpy(lease->nextserver.iabuf, &packet->raw->siaddr, lease->nextserver.len);
1188 
1189 	/* If the server name was filled out, copy it.
1190 	   Do not attempt to validate the server name as a host name.
1191 	   RFC 2131 merely states that sname is NUL-terminated (which do
1192 	   do not assume) and that it is the server's host name.  Since
1193 	   the ISC client and server allow arbitrary characters, we do
1194 	   as well. */
1195 	if ((!packet->options[DHO_DHCP_OPTION_OVERLOAD].len ||
1196 	    !(packet->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 2)) &&
1197 	    packet->raw->sname[0]) {
1198 		lease->server_name = malloc(DHCP_SNAME_LEN + 1);
1199 		if (!lease->server_name) {
1200 			warning("dhcpoffer: no memory for server name.");
1201 			free_client_lease(lease);
1202 			return (NULL);
1203 		}
1204 		memcpy(lease->server_name, packet->raw->sname, DHCP_SNAME_LEN);
1205 		lease->server_name[DHCP_SNAME_LEN]='\0';
1206 	}
1207 
1208 	/* Ditto for the filename. */
1209 	if ((!packet->options[DHO_DHCP_OPTION_OVERLOAD].len ||
1210 	    !(packet->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 1)) &&
1211 	    packet->raw->file[0]) {
1212 		/* Don't count on the NUL terminator. */
1213 		lease->filename = malloc(DHCP_FILE_LEN + 1);
1214 		if (!lease->filename) {
1215 			warning("dhcpoffer: no memory for filename.");
1216 			free_client_lease(lease);
1217 			return (NULL);
1218 		}
1219 		memcpy(lease->filename, packet->raw->file, DHCP_FILE_LEN);
1220 		lease->filename[DHCP_FILE_LEN]='\0';
1221 	}
1222 	return lease;
1223 }
1224 
1225 void
1226 dhcpnak(struct packet *packet)
1227 {
1228 	struct interface_info *ip = packet->interface;
1229 
1230 	/* If we're not receptive to an offer right now, or if the offer
1231 	   has an unrecognizable transaction id, then just drop it. */
1232 	if (packet->interface->client->xid != packet->raw->xid ||
1233 	    (packet->interface->hw_address.hlen != packet->raw->hlen) ||
1234 	    (memcmp(packet->interface->hw_address.haddr,
1235 	    packet->raw->chaddr, packet->raw->hlen)))
1236 		return;
1237 
1238 	if (ip->client->state != S_REBOOTING &&
1239 	    ip->client->state != S_REQUESTING &&
1240 	    ip->client->state != S_RENEWING &&
1241 	    ip->client->state != S_REBINDING)
1242 		return;
1243 
1244 	note("DHCPNAK from %s", piaddr(packet->client_addr));
1245 
1246 	if (!ip->client->active) {
1247 		note("DHCPNAK with no active lease.\n");
1248 		return;
1249 	}
1250 
1251 	free_client_lease(ip->client->active);
1252 	ip->client->active = NULL;
1253 
1254 	/* Stop sending DHCPREQUEST packets... */
1255 	cancel_timeout(send_request, ip);
1256 
1257 	ip->client->state = S_INIT;
1258 	state_init(ip);
1259 }
1260 
1261 /* Send out a DHCPDISCOVER packet, and set a timeout to send out another
1262    one after the right interval has expired.  If we don't get an offer by
1263    the time we reach the panic interval, call the panic function. */
1264 
1265 void
1266 send_discover(void *ipp)
1267 {
1268 	struct interface_info *ip = ipp;
1269 	int interval, increase = 1;
1270 
1271 	/* Figure out how long it's been since we started transmitting. */
1272 	interval = cur_time - ip->client->first_sending;
1273 
1274 	/* If we're past the panic timeout, call the script and tell it
1275 	   we haven't found anything for this interface yet. */
1276 	if (interval > ip->client->config->timeout) {
1277 		state_panic(ip);
1278 		return;
1279 	}
1280 
1281 	/* If we're selecting media, try the whole list before doing
1282 	   the exponential backoff, but if we've already received an
1283 	   offer, stop looping, because we obviously have it right. */
1284 	if (!ip->client->offered_leases &&
1285 	    ip->client->config->media) {
1286 		int fail = 0;
1287 again:
1288 		if (ip->client->medium) {
1289 			ip->client->medium = ip->client->medium->next;
1290 			increase = 0;
1291 		}
1292 		if (!ip->client->medium) {
1293 			if (fail)
1294 				error("No valid media types for %s!", ip->name);
1295 			ip->client->medium = ip->client->config->media;
1296 			increase = 1;
1297 		}
1298 
1299 		note("Trying medium \"%s\" %d", ip->client->medium->string,
1300 		    increase);
1301 		script_init("MEDIUM", ip->client->medium);
1302 		if (script_go())
1303 			goto again;
1304 	}
1305 
1306 	/*
1307 	 * If we're supposed to increase the interval, do so.  If it's
1308 	 * currently zero (i.e., we haven't sent any packets yet), set
1309 	 * it to one; otherwise, add to it a random number between zero
1310 	 * and two times itself.  On average, this means that it will
1311 	 * double with every transmission.
1312 	 */
1313 	if (increase) {
1314 		if (!ip->client->interval)
1315 			ip->client->interval =
1316 			    ip->client->config->initial_interval;
1317 		else {
1318 			ip->client->interval += (arc4random() >> 2) %
1319 			    (2 * ip->client->interval);
1320 		}
1321 
1322 		/* Don't backoff past cutoff. */
1323 		if (ip->client->interval >
1324 		    ip->client->config->backoff_cutoff)
1325 			ip->client->interval =
1326 				((ip->client->config->backoff_cutoff / 2)
1327 				 + ((arc4random() >> 2) %
1328 				    ip->client->config->backoff_cutoff));
1329 	} else if (!ip->client->interval)
1330 		ip->client->interval =
1331 			ip->client->config->initial_interval;
1332 
1333 	/* If the backoff would take us to the panic timeout, just use that
1334 	   as the interval. */
1335 	if (cur_time + ip->client->interval >
1336 	    ip->client->first_sending + ip->client->config->timeout)
1337 		ip->client->interval =
1338 			(ip->client->first_sending +
1339 			 ip->client->config->timeout) - cur_time + 1;
1340 
1341 	/* Record the number of seconds since we started sending. */
1342 	if (interval < 65536)
1343 		ip->client->packet.secs = htons(interval);
1344 	else
1345 		ip->client->packet.secs = htons(65535);
1346 	ip->client->secs = ip->client->packet.secs;
1347 
1348 	note("DHCPDISCOVER on %s to %s port %d interval %d",
1349 	    ip->name, inet_ntoa(inaddr_broadcast), REMOTE_PORT,
1350 	    (int)ip->client->interval);
1351 
1352 	/* Send out a packet. */
1353 	send_packet_unpriv(privfd, &ip->client->packet,
1354 	    ip->client->packet_length, inaddr_any, inaddr_broadcast);
1355 
1356 	add_timeout(cur_time + ip->client->interval, send_discover, ip);
1357 }
1358 
1359 /*
1360  * state_panic gets called if we haven't received any offers in a preset
1361  * amount of time.   When this happens, we try to use existing leases
1362  * that haven't yet expired, and failing that, we call the client script
1363  * and hope it can do something.
1364  */
1365 void
1366 state_panic(void *ipp)
1367 {
1368 	struct interface_info *ip = ipp;
1369 	struct client_lease *loop = ip->client->active;
1370 	struct client_lease *lp;
1371 
1372 	note("No DHCPOFFERS received.");
1373 
1374 	/* We may not have an active lease, but we may have some
1375 	   predefined leases that we can try. */
1376 	if (!ip->client->active && ip->client->leases)
1377 		goto activate_next;
1378 
1379 	/* Run through the list of leases and see if one can be used. */
1380 	while (ip->client->active) {
1381 		if (ip->client->active->expiry > cur_time) {
1382 			note("Trying recorded lease %s",
1383 			    piaddr(ip->client->active->address));
1384 			/* Run the client script with the existing
1385 			   parameters. */
1386 			script_init("TIMEOUT",
1387 			    ip->client->active->medium);
1388 			script_write_params("new_", ip->client->active);
1389 			if (ip->client->alias)
1390 				script_write_params("alias_",
1391 				    ip->client->alias);
1392 
1393 			/* If the old lease is still good and doesn't
1394 			   yet need renewal, go into BOUND state and
1395 			   timeout at the renewal time. */
1396 			if (!script_go()) {
1397 				if (cur_time <
1398 				    ip->client->active->renewal) {
1399 					ip->client->state = S_BOUND;
1400 					note("bound: renewal in %d seconds.",
1401 					    (int)(ip->client->active->renewal -
1402 					    cur_time));
1403 					add_timeout(
1404 					    ip->client->active->renewal,
1405 					    state_bound, ip);
1406 				} else {
1407 					ip->client->state = S_BOUND;
1408 					note("bound: immediate renewal.");
1409 					state_bound(ip);
1410 				}
1411 				reinitialize_interfaces();
1412 				go_daemon();
1413 				return;
1414 			}
1415 		}
1416 
1417 		/* If there are no other leases, give up. */
1418 		if (!ip->client->leases) {
1419 			ip->client->leases = ip->client->active;
1420 			ip->client->active = NULL;
1421 			break;
1422 		}
1423 
1424 activate_next:
1425 		/* Otherwise, put the active lease at the end of the
1426 		   lease list, and try another lease.. */
1427 		for (lp = ip->client->leases; lp->next; lp = lp->next)
1428 			;
1429 		lp->next = ip->client->active;
1430 		if (lp->next)
1431 			lp->next->next = NULL;
1432 		ip->client->active = ip->client->leases;
1433 		ip->client->leases = ip->client->leases->next;
1434 
1435 		/* If we already tried this lease, we've exhausted the
1436 		   set of leases, so we might as well give up for
1437 		   now. */
1438 		if (ip->client->active == loop)
1439 			break;
1440 		else if (!loop)
1441 			loop = ip->client->active;
1442 	}
1443 
1444 	/* No leases were available, or what was available didn't work, so
1445 	   tell the shell script that we failed to allocate an address,
1446 	   and try again later. */
1447 	note("No working leases in persistent database - sleeping.\n");
1448 	script_init("FAIL", NULL);
1449 	if (ip->client->alias)
1450 		script_write_params("alias_", ip->client->alias);
1451 	script_go();
1452 	ip->client->state = S_INIT;
1453 	add_timeout(cur_time + ip->client->config->retry_interval, state_init,
1454 	    ip);
1455 	go_daemon();
1456 }
1457 
1458 void
1459 send_request(void *ipp)
1460 {
1461 	struct interface_info *ip = ipp;
1462 	struct in_addr from, to;
1463 	int interval;
1464 
1465 	/* Figure out how long it's been since we started transmitting. */
1466 	interval = cur_time - ip->client->first_sending;
1467 
1468 	/* If we're in the INIT-REBOOT or REQUESTING state and we're
1469 	   past the reboot timeout, go to INIT and see if we can
1470 	   DISCOVER an address... */
1471 	/* XXX In the INIT-REBOOT state, if we don't get an ACK, it
1472 	   means either that we're on a network with no DHCP server,
1473 	   or that our server is down.  In the latter case, assuming
1474 	   that there is a backup DHCP server, DHCPDISCOVER will get
1475 	   us a new address, but we could also have successfully
1476 	   reused our old address.  In the former case, we're hosed
1477 	   anyway.  This is not a win-prone situation. */
1478 	if ((ip->client->state == S_REBOOTING ||
1479 	    ip->client->state == S_REQUESTING) &&
1480 	    interval > ip->client->config->reboot_timeout) {
1481 cancel:
1482 		ip->client->state = S_INIT;
1483 		cancel_timeout(send_request, ip);
1484 		state_init(ip);
1485 		return;
1486 	}
1487 
1488 	/* If we're in the reboot state, make sure the media is set up
1489 	   correctly. */
1490 	if (ip->client->state == S_REBOOTING &&
1491 	    !ip->client->medium &&
1492 	    ip->client->active->medium ) {
1493 		script_init("MEDIUM", ip->client->active->medium);
1494 
1495 		/* If the medium we chose won't fly, go to INIT state. */
1496 		if (script_go())
1497 			goto cancel;
1498 
1499 		/* Record the medium. */
1500 		ip->client->medium = ip->client->active->medium;
1501 	}
1502 
1503 	/* If the lease has expired, relinquish the address and go back
1504 	   to the INIT state. */
1505 	if (ip->client->state != S_REQUESTING &&
1506 	    cur_time > ip->client->active->expiry) {
1507 		/* Run the client script with the new parameters. */
1508 		script_init("EXPIRE", NULL);
1509 		script_write_params("old_", ip->client->active);
1510 		if (ip->client->alias)
1511 			script_write_params("alias_", ip->client->alias);
1512 		script_go();
1513 
1514 		/* Now do a preinit on the interface so that we can
1515 		   discover a new address. */
1516 		script_init("PREINIT", NULL);
1517 		if (ip->client->alias)
1518 			script_write_params("alias_", ip->client->alias);
1519 		script_go();
1520 
1521 		ip->client->state = S_INIT;
1522 		state_init(ip);
1523 		return;
1524 	}
1525 
1526 	/* Do the exponential backoff... */
1527 	if (!ip->client->interval)
1528 		ip->client->interval = ip->client->config->initial_interval;
1529 	else
1530 		ip->client->interval += ((arc4random() >> 2) %
1531 		    (2 * ip->client->interval));
1532 
1533 	/* Don't backoff past cutoff. */
1534 	if (ip->client->interval >
1535 	    ip->client->config->backoff_cutoff)
1536 		ip->client->interval =
1537 		    ((ip->client->config->backoff_cutoff / 2) +
1538 		    ((arc4random() >> 2) % ip->client->interval));
1539 
1540 	/* If the backoff would take us to the expiry time, just set the
1541 	   timeout to the expiry time. */
1542 	if (ip->client->state != S_REQUESTING &&
1543 	    cur_time + ip->client->interval >
1544 	    ip->client->active->expiry)
1545 		ip->client->interval =
1546 		    ip->client->active->expiry - cur_time + 1;
1547 
1548 	/* If the lease T2 time has elapsed, or if we're not yet bound,
1549 	   broadcast the DHCPREQUEST rather than unicasting. */
1550 	if (ip->client->state == S_REQUESTING ||
1551 	    ip->client->state == S_REBOOTING ||
1552 	    cur_time > ip->client->active->rebind)
1553 		to.s_addr = INADDR_BROADCAST;
1554 	else
1555 		memcpy(&to.s_addr, ip->client->destination.iabuf,
1556 		    sizeof(to.s_addr));
1557 
1558 	if (ip->client->state != S_REQUESTING &&
1559 	    ip->client->state != S_REBOOTING)
1560 		memcpy(&from, ip->client->active->address.iabuf,
1561 		    sizeof(from));
1562 	else
1563 		from.s_addr = INADDR_ANY;
1564 
1565 	/* Record the number of seconds since we started sending. */
1566 	if (ip->client->state == S_REQUESTING)
1567 		ip->client->packet.secs = ip->client->secs;
1568 	else {
1569 		if (interval < 65536)
1570 			ip->client->packet.secs = htons(interval);
1571 		else
1572 			ip->client->packet.secs = htons(65535);
1573 	}
1574 
1575 	note("DHCPREQUEST on %s to %s port %d", ip->name, inet_ntoa(to),
1576 	    REMOTE_PORT);
1577 
1578 	/* Send out a packet. */
1579 	send_packet_unpriv(privfd, &ip->client->packet,
1580 	    ip->client->packet_length, from, to);
1581 
1582 	add_timeout(cur_time + ip->client->interval, send_request, ip);
1583 }
1584 
1585 void
1586 send_decline(void *ipp)
1587 {
1588 	struct interface_info *ip = ipp;
1589 
1590 	note("DHCPDECLINE on %s to %s port %d", ip->name,
1591 	    inet_ntoa(inaddr_broadcast), REMOTE_PORT);
1592 
1593 	/* Send out a packet. */
1594 	send_packet_unpriv(privfd, &ip->client->packet,
1595 	    ip->client->packet_length, inaddr_any, inaddr_broadcast);
1596 }
1597 
1598 void
1599 make_discover(struct interface_info *ip, struct client_lease *lease)
1600 {
1601 	unsigned char discover = DHCPDISCOVER;
1602 	struct tree_cache *options[256];
1603 	struct tree_cache option_elements[256];
1604 	int i;
1605 
1606 	memset(option_elements, 0, sizeof(option_elements));
1607 	memset(options, 0, sizeof(options));
1608 	memset(&ip->client->packet, 0, sizeof(ip->client->packet));
1609 
1610 	/* Set DHCP_MESSAGE_TYPE to DHCPDISCOVER */
1611 	i = DHO_DHCP_MESSAGE_TYPE;
1612 	options[i] = &option_elements[i];
1613 	options[i]->value = &discover;
1614 	options[i]->len = sizeof(discover);
1615 	options[i]->buf_size = sizeof(discover);
1616 	options[i]->timeout = 0xFFFFFFFF;
1617 
1618 	/* Request the options we want */
1619 	i  = DHO_DHCP_PARAMETER_REQUEST_LIST;
1620 	options[i] = &option_elements[i];
1621 	options[i]->value = ip->client->config->requested_options;
1622 	options[i]->len = ip->client->config->requested_option_count;
1623 	options[i]->buf_size =
1624 		ip->client->config->requested_option_count;
1625 	options[i]->timeout = 0xFFFFFFFF;
1626 
1627 	/* If we had an address, try to get it again. */
1628 	if (lease) {
1629 		ip->client->requested_address = lease->address;
1630 		i = DHO_DHCP_REQUESTED_ADDRESS;
1631 		options[i] = &option_elements[i];
1632 		options[i]->value = lease->address.iabuf;
1633 		options[i]->len = lease->address.len;
1634 		options[i]->buf_size = lease->address.len;
1635 		options[i]->timeout = 0xFFFFFFFF;
1636 	} else
1637 		ip->client->requested_address.len = 0;
1638 
1639 	/* Send any options requested in the config file. */
1640 	for (i = 0; i < 256; i++)
1641 		if (!options[i] &&
1642 		    ip->client->config->send_options[i].data) {
1643 			options[i] = &option_elements[i];
1644 			options[i]->value =
1645 			    ip->client->config->send_options[i].data;
1646 			options[i]->len =
1647 			    ip->client->config->send_options[i].len;
1648 			options[i]->buf_size =
1649 			    ip->client->config->send_options[i].len;
1650 			options[i]->timeout = 0xFFFFFFFF;
1651 		}
1652 
1653 	/* send host name if not set via config file. */
1654 	if (!options[DHO_HOST_NAME]) {
1655 		if (hostname[0] != '\0') {
1656 			size_t len;
1657 			char* posDot = strchr(hostname, '.');
1658 			if (posDot != NULL)
1659 				len = posDot - hostname;
1660 			else
1661 				len = strlen(hostname);
1662 			options[DHO_HOST_NAME] = &option_elements[DHO_HOST_NAME];
1663 			options[DHO_HOST_NAME]->value = hostname;
1664 			options[DHO_HOST_NAME]->len = len;
1665 			options[DHO_HOST_NAME]->buf_size = len;
1666 			options[DHO_HOST_NAME]->timeout = 0xFFFFFFFF;
1667 		}
1668 	}
1669 
1670 	/* set unique client identifier */
1671 	char client_ident[sizeof(ip->hw_address.haddr) + 1];
1672 	if (!options[DHO_DHCP_CLIENT_IDENTIFIER]) {
1673 		int hwlen = (ip->hw_address.hlen < sizeof(client_ident)-1) ?
1674 				ip->hw_address.hlen : sizeof(client_ident)-1;
1675 		client_ident[0] = ip->hw_address.htype;
1676 		memcpy(&client_ident[1], ip->hw_address.haddr, hwlen);
1677 		options[DHO_DHCP_CLIENT_IDENTIFIER] = &option_elements[DHO_DHCP_CLIENT_IDENTIFIER];
1678 		options[DHO_DHCP_CLIENT_IDENTIFIER]->value = client_ident;
1679 		options[DHO_DHCP_CLIENT_IDENTIFIER]->len = hwlen+1;
1680 		options[DHO_DHCP_CLIENT_IDENTIFIER]->buf_size = hwlen+1;
1681 		options[DHO_DHCP_CLIENT_IDENTIFIER]->timeout = 0xFFFFFFFF;
1682 	}
1683 
1684 	/* Set up the option buffer... */
1685 	ip->client->packet_length = cons_options(NULL, &ip->client->packet, 0,
1686 	    options, 0, 0, 0, NULL, 0);
1687 	if (ip->client->packet_length < BOOTP_MIN_LEN)
1688 		ip->client->packet_length = BOOTP_MIN_LEN;
1689 
1690 	ip->client->packet.op = BOOTREQUEST;
1691 	ip->client->packet.htype = ip->hw_address.htype;
1692 	ip->client->packet.hlen = ip->hw_address.hlen;
1693 	ip->client->packet.hops = 0;
1694 	ip->client->packet.xid = arc4random();
1695 	ip->client->packet.secs = 0; /* filled in by send_discover. */
1696 	ip->client->packet.flags = 0;
1697 
1698 	memset(&(ip->client->packet.ciaddr),
1699 	    0, sizeof(ip->client->packet.ciaddr));
1700 	memset(&(ip->client->packet.yiaddr),
1701 	    0, sizeof(ip->client->packet.yiaddr));
1702 	memset(&(ip->client->packet.siaddr),
1703 	    0, sizeof(ip->client->packet.siaddr));
1704 	memset(&(ip->client->packet.giaddr),
1705 	    0, sizeof(ip->client->packet.giaddr));
1706 	memcpy(ip->client->packet.chaddr,
1707 	    ip->hw_address.haddr, ip->hw_address.hlen);
1708 }
1709 
1710 
1711 void
1712 make_request(struct interface_info *ip, struct client_lease * lease)
1713 {
1714 	unsigned char request = DHCPREQUEST;
1715 	struct tree_cache *options[256];
1716 	struct tree_cache option_elements[256];
1717 	int i;
1718 
1719 	memset(options, 0, sizeof(options));
1720 	memset(&ip->client->packet, 0, sizeof(ip->client->packet));
1721 
1722 	/* Set DHCP_MESSAGE_TYPE to DHCPREQUEST */
1723 	i = DHO_DHCP_MESSAGE_TYPE;
1724 	options[i] = &option_elements[i];
1725 	options[i]->value = &request;
1726 	options[i]->len = sizeof(request);
1727 	options[i]->buf_size = sizeof(request);
1728 	options[i]->timeout = 0xFFFFFFFF;
1729 
1730 	/* Request the options we want */
1731 	i = DHO_DHCP_PARAMETER_REQUEST_LIST;
1732 	options[i] = &option_elements[i];
1733 	options[i]->value = ip->client->config->requested_options;
1734 	options[i]->len = ip->client->config->requested_option_count;
1735 	options[i]->buf_size =
1736 		ip->client->config->requested_option_count;
1737 	options[i]->timeout = 0xFFFFFFFF;
1738 
1739 	/* If we are requesting an address that hasn't yet been assigned
1740 	   to us, use the DHCP Requested Address option. */
1741 	if (ip->client->state == S_REQUESTING) {
1742 		/* Send back the server identifier... */
1743 		i = DHO_DHCP_SERVER_IDENTIFIER;
1744 		options[i] = &option_elements[i];
1745 		options[i]->value = lease->options[i].data;
1746 		options[i]->len = lease->options[i].len;
1747 		options[i]->buf_size = lease->options[i].len;
1748 		options[i]->timeout = 0xFFFFFFFF;
1749 	}
1750 	if (ip->client->state == S_REQUESTING ||
1751 	    ip->client->state == S_REBOOTING) {
1752 		ip->client->requested_address = lease->address;
1753 		i = DHO_DHCP_REQUESTED_ADDRESS;
1754 		options[i] = &option_elements[i];
1755 		options[i]->value = lease->address.iabuf;
1756 		options[i]->len = lease->address.len;
1757 		options[i]->buf_size = lease->address.len;
1758 		options[i]->timeout = 0xFFFFFFFF;
1759 	} else
1760 		ip->client->requested_address.len = 0;
1761 
1762 	/* Send any options requested in the config file. */
1763 	for (i = 0; i < 256; i++)
1764 		if (!options[i] &&
1765 		    ip->client->config->send_options[i].data) {
1766 			options[i] = &option_elements[i];
1767 			options[i]->value =
1768 			    ip->client->config->send_options[i].data;
1769 			options[i]->len =
1770 			    ip->client->config->send_options[i].len;
1771 			options[i]->buf_size =
1772 			    ip->client->config->send_options[i].len;
1773 			options[i]->timeout = 0xFFFFFFFF;
1774 		}
1775 
1776 	/* send host name if not set via config file. */
1777 	if (!options[DHO_HOST_NAME]) {
1778 		if (hostname[0] != '\0') {
1779 			size_t len;
1780 			char* posDot = strchr(hostname, '.');
1781 			if (posDot != NULL)
1782 				len = posDot - hostname;
1783 			else
1784 				len = strlen(hostname);
1785 			options[DHO_HOST_NAME] = &option_elements[DHO_HOST_NAME];
1786 			options[DHO_HOST_NAME]->value = hostname;
1787 			options[DHO_HOST_NAME]->len = len;
1788 			options[DHO_HOST_NAME]->buf_size = len;
1789 			options[DHO_HOST_NAME]->timeout = 0xFFFFFFFF;
1790 		}
1791 	}
1792 
1793 	/* set unique client identifier */
1794 	char client_ident[sizeof(ip->hw_address.haddr) + 1];
1795 	if (!options[DHO_DHCP_CLIENT_IDENTIFIER]) {
1796 		int hwlen = (ip->hw_address.hlen < sizeof(client_ident)-1) ?
1797 				ip->hw_address.hlen : sizeof(client_ident)-1;
1798 		client_ident[0] = ip->hw_address.htype;
1799 		memcpy(&client_ident[1], ip->hw_address.haddr, hwlen);
1800 		options[DHO_DHCP_CLIENT_IDENTIFIER] = &option_elements[DHO_DHCP_CLIENT_IDENTIFIER];
1801 		options[DHO_DHCP_CLIENT_IDENTIFIER]->value = client_ident;
1802 		options[DHO_DHCP_CLIENT_IDENTIFIER]->len = hwlen+1;
1803 		options[DHO_DHCP_CLIENT_IDENTIFIER]->buf_size = hwlen+1;
1804 		options[DHO_DHCP_CLIENT_IDENTIFIER]->timeout = 0xFFFFFFFF;
1805 	}
1806 
1807 	/* Set up the option buffer... */
1808 	ip->client->packet_length = cons_options(NULL, &ip->client->packet, 0,
1809 	    options, 0, 0, 0, NULL, 0);
1810 	if (ip->client->packet_length < BOOTP_MIN_LEN)
1811 		ip->client->packet_length = BOOTP_MIN_LEN;
1812 
1813 	ip->client->packet.op = BOOTREQUEST;
1814 	ip->client->packet.htype = ip->hw_address.htype;
1815 	ip->client->packet.hlen = ip->hw_address.hlen;
1816 	ip->client->packet.hops = 0;
1817 	ip->client->packet.xid = ip->client->xid;
1818 	ip->client->packet.secs = 0; /* Filled in by send_request. */
1819 
1820 	/* If we own the address we're requesting, put it in ciaddr;
1821 	   otherwise set ciaddr to zero. */
1822 	if (ip->client->state == S_BOUND ||
1823 	    ip->client->state == S_RENEWING ||
1824 	    ip->client->state == S_REBINDING) {
1825 		memcpy(&ip->client->packet.ciaddr,
1826 		    lease->address.iabuf, lease->address.len);
1827 		ip->client->packet.flags = 0;
1828 	} else {
1829 		memset(&ip->client->packet.ciaddr, 0,
1830 		    sizeof(ip->client->packet.ciaddr));
1831 		ip->client->packet.flags = 0;
1832 	}
1833 
1834 	memset(&ip->client->packet.yiaddr, 0,
1835 	    sizeof(ip->client->packet.yiaddr));
1836 	memset(&ip->client->packet.siaddr, 0,
1837 	    sizeof(ip->client->packet.siaddr));
1838 	memset(&ip->client->packet.giaddr, 0,
1839 	    sizeof(ip->client->packet.giaddr));
1840 	memcpy(ip->client->packet.chaddr,
1841 	    ip->hw_address.haddr, ip->hw_address.hlen);
1842 }
1843 
1844 void
1845 make_decline(struct interface_info *ip, struct client_lease *lease)
1846 {
1847 	struct tree_cache *options[256], message_type_tree;
1848 	struct tree_cache requested_address_tree;
1849 	struct tree_cache server_id_tree, client_id_tree;
1850 	unsigned char decline = DHCPDECLINE;
1851 	int i;
1852 
1853 	memset(options, 0, sizeof(options));
1854 	memset(&ip->client->packet, 0, sizeof(ip->client->packet));
1855 
1856 	/* Set DHCP_MESSAGE_TYPE to DHCPDECLINE */
1857 	i = DHO_DHCP_MESSAGE_TYPE;
1858 	options[i] = &message_type_tree;
1859 	options[i]->value = &decline;
1860 	options[i]->len = sizeof(decline);
1861 	options[i]->buf_size = sizeof(decline);
1862 	options[i]->timeout = 0xFFFFFFFF;
1863 
1864 	/* Send back the server identifier... */
1865 	i = DHO_DHCP_SERVER_IDENTIFIER;
1866 	options[i] = &server_id_tree;
1867 	options[i]->value = lease->options[i].data;
1868 	options[i]->len = lease->options[i].len;
1869 	options[i]->buf_size = lease->options[i].len;
1870 	options[i]->timeout = 0xFFFFFFFF;
1871 
1872 	/* Send back the address we're declining. */
1873 	i = DHO_DHCP_REQUESTED_ADDRESS;
1874 	options[i] = &requested_address_tree;
1875 	options[i]->value = lease->address.iabuf;
1876 	options[i]->len = lease->address.len;
1877 	options[i]->buf_size = lease->address.len;
1878 	options[i]->timeout = 0xFFFFFFFF;
1879 
1880 	/* Send the uid if the user supplied one. */
1881 	i = DHO_DHCP_CLIENT_IDENTIFIER;
1882 	if (ip->client->config->send_options[i].len) {
1883 		options[i] = &client_id_tree;
1884 		options[i]->value = ip->client->config->send_options[i].data;
1885 		options[i]->len = ip->client->config->send_options[i].len;
1886 		options[i]->buf_size = ip->client->config->send_options[i].len;
1887 		options[i]->timeout = 0xFFFFFFFF;
1888 	}
1889 
1890 
1891 	/* Set up the option buffer... */
1892 	ip->client->packet_length = cons_options(NULL, &ip->client->packet, 0,
1893 	    options, 0, 0, 0, NULL, 0);
1894 	if (ip->client->packet_length < BOOTP_MIN_LEN)
1895 		ip->client->packet_length = BOOTP_MIN_LEN;
1896 
1897 	ip->client->packet.op = BOOTREQUEST;
1898 	ip->client->packet.htype = ip->hw_address.htype;
1899 	ip->client->packet.hlen = ip->hw_address.hlen;
1900 	ip->client->packet.hops = 0;
1901 	ip->client->packet.xid = ip->client->xid;
1902 	ip->client->packet.secs = 0; /* Filled in by send_request. */
1903 	ip->client->packet.flags = 0;
1904 
1905 	/* ciaddr must always be zero. */
1906 	memset(&ip->client->packet.ciaddr, 0,
1907 	    sizeof(ip->client->packet.ciaddr));
1908 	memset(&ip->client->packet.yiaddr, 0,
1909 	    sizeof(ip->client->packet.yiaddr));
1910 	memset(&ip->client->packet.siaddr, 0,
1911 	    sizeof(ip->client->packet.siaddr));
1912 	memset(&ip->client->packet.giaddr, 0,
1913 	    sizeof(ip->client->packet.giaddr));
1914 	memcpy(ip->client->packet.chaddr,
1915 	    ip->hw_address.haddr, ip->hw_address.hlen);
1916 }
1917 
1918 void
1919 free_client_lease(struct client_lease *lease)
1920 {
1921 	int i;
1922 
1923 	if (lease->server_name)
1924 		free(lease->server_name);
1925 	if (lease->filename)
1926 		free(lease->filename);
1927 	for (i = 0; i < 256; i++) {
1928 		if (lease->options[i].len)
1929 			free(lease->options[i].data);
1930 	}
1931 	free(lease);
1932 }
1933 
1934 static FILE *leaseFile;
1935 
1936 void
1937 rewrite_client_leases(void)
1938 {
1939 	struct client_lease *lp;
1940 	cap_rights_t rights;
1941 
1942 	if (!leaseFile) {
1943 		leaseFile = fopen(path_dhclient_db, "w");
1944 		if (!leaseFile)
1945 			error("can't create %s: %m", path_dhclient_db);
1946 		cap_rights_init(&rights, CAP_FCNTL, CAP_FSTAT, CAP_FSYNC,
1947 		    CAP_FTRUNCATE, CAP_SEEK, CAP_WRITE);
1948 		if (caph_rights_limit(fileno(leaseFile), &rights) < 0) {
1949 			error("can't limit lease descriptor: %m");
1950 		}
1951 		if (caph_fcntls_limit(fileno(leaseFile), CAP_FCNTL_GETFL) < 0) {
1952 			error("can't limit lease descriptor fcntls: %m");
1953 		}
1954 	} else {
1955 		fflush(leaseFile);
1956 		rewind(leaseFile);
1957 	}
1958 
1959 	for (lp = ifi->client->leases; lp; lp = lp->next)
1960 		write_client_lease(ifi, lp, 1);
1961 	if (ifi->client->active)
1962 		write_client_lease(ifi, ifi->client->active, 1);
1963 
1964 	fflush(leaseFile);
1965 	ftruncate(fileno(leaseFile), ftello(leaseFile));
1966 	fsync(fileno(leaseFile));
1967 }
1968 
1969 void
1970 write_client_lease(struct interface_info *ip, struct client_lease *lease,
1971     int rewrite)
1972 {
1973 	static int leases_written;
1974 	struct tm *t;
1975 	int i;
1976 
1977 	if (!rewrite) {
1978 		if (leases_written++ > 20) {
1979 			rewrite_client_leases();
1980 			leases_written = 0;
1981 		}
1982 	}
1983 
1984 	/* If the lease came from the config file, we don't need to stash
1985 	   a copy in the lease database. */
1986 	if (lease->is_static)
1987 		return;
1988 
1989 	if (!leaseFile) {	/* XXX */
1990 		leaseFile = fopen(path_dhclient_db, "w");
1991 		if (!leaseFile)
1992 			error("can't create %s: %m", path_dhclient_db);
1993 	}
1994 
1995 	fprintf(leaseFile, "lease {\n");
1996 	if (lease->is_bootp)
1997 		fprintf(leaseFile, "  bootp;\n");
1998 	fprintf(leaseFile, "  interface \"%s\";\n", ip->name);
1999 	fprintf(leaseFile, "  fixed-address %s;\n", piaddr(lease->address));
2000 	if (lease->nextserver.len == sizeof(inaddr_any) &&
2001 	    0 != memcmp(lease->nextserver.iabuf, &inaddr_any,
2002 	    sizeof(inaddr_any)))
2003 		fprintf(leaseFile, "  next-server %s;\n",
2004 		    piaddr(lease->nextserver));
2005 	if (lease->filename)
2006 		fprintf(leaseFile, "  filename \"%s\";\n", lease->filename);
2007 	if (lease->server_name)
2008 		fprintf(leaseFile, "  server-name \"%s\";\n",
2009 		    lease->server_name);
2010 	if (lease->medium)
2011 		fprintf(leaseFile, "  medium \"%s\";\n", lease->medium->string);
2012 	for (i = 0; i < 256; i++)
2013 		if (lease->options[i].len)
2014 			fprintf(leaseFile, "  option %s %s;\n",
2015 			    dhcp_options[i].name,
2016 			    pretty_print_option(i, lease->options[i].data,
2017 			    lease->options[i].len, 1, 1));
2018 
2019 	t = gmtime(&lease->renewal);
2020 	fprintf(leaseFile, "  renew %d %d/%d/%d %02d:%02d:%02d;\n",
2021 	    t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
2022 	    t->tm_hour, t->tm_min, t->tm_sec);
2023 	t = gmtime(&lease->rebind);
2024 	fprintf(leaseFile, "  rebind %d %d/%d/%d %02d:%02d:%02d;\n",
2025 	    t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
2026 	    t->tm_hour, t->tm_min, t->tm_sec);
2027 	t = gmtime(&lease->expiry);
2028 	fprintf(leaseFile, "  expire %d %d/%d/%d %02d:%02d:%02d;\n",
2029 	    t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
2030 	    t->tm_hour, t->tm_min, t->tm_sec);
2031 	fprintf(leaseFile, "}\n");
2032 	fflush(leaseFile);
2033 }
2034 
2035 void
2036 script_init(const char *reason, struct string_list *medium)
2037 {
2038 	size_t		 len, mediumlen = 0;
2039 	struct imsg_hdr	 hdr;
2040 	struct buf	*buf;
2041 	int		 errs;
2042 
2043 	if (medium != NULL && medium->string != NULL)
2044 		mediumlen = strlen(medium->string);
2045 
2046 	hdr.code = IMSG_SCRIPT_INIT;
2047 	hdr.len = sizeof(struct imsg_hdr) +
2048 	    sizeof(size_t) + mediumlen +
2049 	    sizeof(size_t) + strlen(reason);
2050 
2051 	if ((buf = buf_open(hdr.len)) == NULL)
2052 		error("buf_open: %m");
2053 
2054 	errs = 0;
2055 	errs += buf_add(buf, &hdr, sizeof(hdr));
2056 	errs += buf_add(buf, &mediumlen, sizeof(mediumlen));
2057 	if (mediumlen > 0)
2058 		errs += buf_add(buf, medium->string, mediumlen);
2059 	len = strlen(reason);
2060 	errs += buf_add(buf, &len, sizeof(len));
2061 	errs += buf_add(buf, reason, len);
2062 
2063 	if (errs)
2064 		error("buf_add: %m");
2065 
2066 	if (buf_close(privfd, buf) == -1)
2067 		error("buf_close: %m");
2068 }
2069 
2070 void
2071 priv_script_init(const char *reason, char *medium)
2072 {
2073 	struct interface_info *ip = ifi;
2074 
2075 	if (ip) {
2076 		ip->client->scriptEnvsize = 100;
2077 		if (ip->client->scriptEnv == NULL)
2078 			ip->client->scriptEnv =
2079 			    malloc(ip->client->scriptEnvsize * sizeof(char *));
2080 		if (ip->client->scriptEnv == NULL)
2081 			error("script_init: no memory for environment");
2082 
2083 		ip->client->scriptEnv[0] = strdup(CLIENT_PATH);
2084 		if (ip->client->scriptEnv[0] == NULL)
2085 			error("script_init: no memory for environment");
2086 
2087 		ip->client->scriptEnv[1] = NULL;
2088 
2089 		script_set_env(ip->client, "", "interface", ip->name);
2090 
2091 		if (medium)
2092 			script_set_env(ip->client, "", "medium", medium);
2093 
2094 		script_set_env(ip->client, "", "reason", reason);
2095 	}
2096 }
2097 
2098 void
2099 priv_script_write_params(const char *prefix, struct client_lease *lease)
2100 {
2101 	struct interface_info *ip = ifi;
2102 	u_int8_t dbuf[1500], *dp = NULL;
2103 	int i;
2104 	size_t len;
2105 	char tbuf[128];
2106 
2107 	script_set_env(ip->client, prefix, "ip_address",
2108 	    piaddr(lease->address));
2109 
2110 	if (ip->client->config->default_actions[DHO_SUBNET_MASK] ==
2111 	    ACTION_SUPERSEDE) {
2112 		dp = ip->client->config->defaults[DHO_SUBNET_MASK].data;
2113 		len = ip->client->config->defaults[DHO_SUBNET_MASK].len;
2114 	} else {
2115 		dp = lease->options[DHO_SUBNET_MASK].data;
2116 		len = lease->options[DHO_SUBNET_MASK].len;
2117 	}
2118 	if (len && (len < sizeof(lease->address.iabuf))) {
2119 		struct iaddr netmask, subnet, broadcast;
2120 
2121 		memcpy(netmask.iabuf, dp, len);
2122 		netmask.len = len;
2123 		subnet = subnet_number(lease->address, netmask);
2124 		if (subnet.len) {
2125 			script_set_env(ip->client, prefix, "network_number",
2126 			    piaddr(subnet));
2127 			if (!lease->options[DHO_BROADCAST_ADDRESS].len) {
2128 				broadcast = broadcast_addr(subnet, netmask);
2129 				if (broadcast.len)
2130 					script_set_env(ip->client, prefix,
2131 					    "broadcast_address",
2132 					    piaddr(broadcast));
2133 			}
2134 		}
2135 	}
2136 
2137 	if (lease->filename)
2138 		script_set_env(ip->client, prefix, "filename", lease->filename);
2139 	if (lease->server_name)
2140 		script_set_env(ip->client, prefix, "server_name",
2141 		    lease->server_name);
2142 	for (i = 0; i < 256; i++) {
2143 		len = 0;
2144 
2145 		if (ip->client->config->defaults[i].len) {
2146 			if (lease->options[i].len) {
2147 				switch (
2148 				    ip->client->config->default_actions[i]) {
2149 				case ACTION_DEFAULT:
2150 					dp = lease->options[i].data;
2151 					len = lease->options[i].len;
2152 					break;
2153 				case ACTION_SUPERSEDE:
2154 supersede:
2155 					dp = ip->client->
2156 						config->defaults[i].data;
2157 					len = ip->client->
2158 						config->defaults[i].len;
2159 					break;
2160 				case ACTION_PREPEND:
2161 					len = ip->client->
2162 					    config->defaults[i].len +
2163 					    lease->options[i].len;
2164 					if (len >= sizeof(dbuf)) {
2165 						warning("no space to %s %s",
2166 						    "prepend option",
2167 						    dhcp_options[i].name);
2168 						goto supersede;
2169 					}
2170 					dp = dbuf;
2171 					memcpy(dp,
2172 						ip->client->
2173 						config->defaults[i].data,
2174 						ip->client->
2175 						config->defaults[i].len);
2176 					memcpy(dp + ip->client->
2177 						config->defaults[i].len,
2178 						lease->options[i].data,
2179 						lease->options[i].len);
2180 					dp[len] = '\0';
2181 					break;
2182 				case ACTION_APPEND:
2183 					/*
2184 					 * When we append, we assume that we're
2185 					 * appending to text.  Some MS servers
2186 					 * include a NUL byte at the end of
2187 					 * the search string provided.
2188 					 */
2189 					len = ip->client->
2190 					    config->defaults[i].len +
2191 					    lease->options[i].len;
2192 					if (len >= sizeof(dbuf)) {
2193 						warning("no space to %s %s",
2194 						    "append option",
2195 						    dhcp_options[i].name);
2196 						goto supersede;
2197 					}
2198 					memcpy(dbuf,
2199 						lease->options[i].data,
2200 						lease->options[i].len);
2201 					for (dp = dbuf + lease->options[i].len;
2202 					    dp > dbuf; dp--, len--)
2203 						if (dp[-1] != '\0')
2204 							break;
2205 					memcpy(dp,
2206 						ip->client->
2207 						config->defaults[i].data,
2208 						ip->client->
2209 						config->defaults[i].len);
2210 					dp = dbuf;
2211 					dp[len] = '\0';
2212 				}
2213 			} else {
2214 				dp = ip->client->
2215 					config->defaults[i].data;
2216 				len = ip->client->
2217 					config->defaults[i].len;
2218 			}
2219 		} else if (lease->options[i].len) {
2220 			len = lease->options[i].len;
2221 			dp = lease->options[i].data;
2222 		} else {
2223 			len = 0;
2224 		}
2225 		if (len) {
2226 			char name[256];
2227 
2228 			if (dhcp_option_ev_name(name, sizeof(name),
2229 			    &dhcp_options[i]))
2230 				script_set_env(ip->client, prefix, name,
2231 				    pretty_print_option(i, dp, len, 0, 0));
2232 		}
2233 	}
2234 	snprintf(tbuf, sizeof(tbuf), "%d", (int)lease->expiry);
2235 	script_set_env(ip->client, prefix, "expiry", tbuf);
2236 }
2237 
2238 void
2239 script_write_params(const char *prefix, struct client_lease *lease)
2240 {
2241 	size_t		 fn_len = 0, sn_len = 0, pr_len = 0;
2242 	struct imsg_hdr	 hdr;
2243 	struct buf	*buf;
2244 	int		 errs, i;
2245 
2246 	if (lease->filename != NULL)
2247 		fn_len = strlen(lease->filename);
2248 	if (lease->server_name != NULL)
2249 		sn_len = strlen(lease->server_name);
2250 	if (prefix != NULL)
2251 		pr_len = strlen(prefix);
2252 
2253 	hdr.code = IMSG_SCRIPT_WRITE_PARAMS;
2254 	hdr.len = sizeof(hdr) + sizeof(*lease) +
2255 	    sizeof(fn_len) + fn_len + sizeof(sn_len) + sn_len +
2256 	    sizeof(pr_len) + pr_len;
2257 
2258 	for (i = 0; i < 256; i++) {
2259 		hdr.len += sizeof(lease->options[i].len);
2260 		hdr.len += lease->options[i].len;
2261 	}
2262 
2263 	scripttime = time(NULL);
2264 
2265 	if ((buf = buf_open(hdr.len)) == NULL)
2266 		error("buf_open: %m");
2267 
2268 	errs = 0;
2269 	errs += buf_add(buf, &hdr, sizeof(hdr));
2270 	errs += buf_add(buf, lease, sizeof(*lease));
2271 	errs += buf_add(buf, &fn_len, sizeof(fn_len));
2272 	errs += buf_add(buf, lease->filename, fn_len);
2273 	errs += buf_add(buf, &sn_len, sizeof(sn_len));
2274 	errs += buf_add(buf, lease->server_name, sn_len);
2275 	errs += buf_add(buf, &pr_len, sizeof(pr_len));
2276 	errs += buf_add(buf, prefix, pr_len);
2277 
2278 	for (i = 0; i < 256; i++) {
2279 		errs += buf_add(buf, &lease->options[i].len,
2280 		    sizeof(lease->options[i].len));
2281 		errs += buf_add(buf, lease->options[i].data,
2282 		    lease->options[i].len);
2283 	}
2284 
2285 	if (errs)
2286 		error("buf_add: %m");
2287 
2288 	if (buf_close(privfd, buf) == -1)
2289 		error("buf_close: %m");
2290 }
2291 
2292 int
2293 script_go(void)
2294 {
2295 	struct imsg_hdr	 hdr;
2296 	struct buf	*buf;
2297 	int		 ret;
2298 
2299 	hdr.code = IMSG_SCRIPT_GO;
2300 	hdr.len = sizeof(struct imsg_hdr);
2301 
2302 	if ((buf = buf_open(hdr.len)) == NULL)
2303 		error("buf_open: %m");
2304 
2305 	if (buf_add(buf, &hdr, sizeof(hdr)))
2306 		error("buf_add: %m");
2307 
2308 	if (buf_close(privfd, buf) == -1)
2309 		error("buf_close: %m");
2310 
2311 	bzero(&hdr, sizeof(hdr));
2312 	buf_read(privfd, &hdr, sizeof(hdr));
2313 	if (hdr.code != IMSG_SCRIPT_GO_RET)
2314 		error("unexpected msg type %u", hdr.code);
2315 	if (hdr.len != sizeof(hdr) + sizeof(int))
2316 		error("received corrupted message");
2317 	buf_read(privfd, &ret, sizeof(ret));
2318 
2319 	scripttime = time(NULL);
2320 
2321 	return (ret);
2322 }
2323 
2324 int
2325 priv_script_go(void)
2326 {
2327 	char *scriptName, *argv[2], **envp, *epp[3], reason[] = "REASON=NBI";
2328 	static char client_path[] = CLIENT_PATH;
2329 	struct interface_info *ip = ifi;
2330 	int pid, wpid, wstatus;
2331 
2332 	scripttime = time(NULL);
2333 
2334 	if (ip) {
2335 		scriptName = ip->client->config->script_name;
2336 		envp = ip->client->scriptEnv;
2337 	} else {
2338 		scriptName = top_level_config.script_name;
2339 		epp[0] = reason;
2340 		epp[1] = client_path;
2341 		epp[2] = NULL;
2342 		envp = epp;
2343 	}
2344 
2345 	argv[0] = scriptName;
2346 	argv[1] = NULL;
2347 
2348 	pid = fork();
2349 	if (pid < 0) {
2350 		error("fork: %m");
2351 		wstatus = 0;
2352 	} else if (pid) {
2353 		do {
2354 			wpid = wait(&wstatus);
2355 		} while (wpid != pid && wpid > 0);
2356 		if (wpid < 0) {
2357 			error("wait: %m");
2358 			wstatus = 0;
2359 		}
2360 	} else {
2361 		execve(scriptName, argv, envp);
2362 		error("execve (%s, ...): %m", scriptName);
2363 	}
2364 
2365 	if (ip)
2366 		script_flush_env(ip->client);
2367 
2368 	return (WIFEXITED(wstatus) ?
2369 	    WEXITSTATUS(wstatus) : 128 + WTERMSIG(wstatus));
2370 }
2371 
2372 void
2373 script_set_env(struct client_state *client, const char *prefix,
2374     const char *name, const char *value)
2375 {
2376 	int i, namelen;
2377 	size_t j;
2378 
2379 	/* No `` or $() command substitution allowed in environment values! */
2380 	for (j=0; j < strlen(value); j++)
2381 		switch (value[j]) {
2382 		case '`':
2383 		case '$':
2384 			warning("illegal character (%c) in value '%s'",
2385 			    value[j], value);
2386 			/* Ignore this option */
2387 			return;
2388 		}
2389 
2390 	namelen = strlen(name);
2391 
2392 	for (i = 0; client->scriptEnv[i]; i++)
2393 		if (strncmp(client->scriptEnv[i], name, namelen) == 0 &&
2394 		    client->scriptEnv[i][namelen] == '=')
2395 			break;
2396 
2397 	if (client->scriptEnv[i])
2398 		/* Reuse the slot. */
2399 		free(client->scriptEnv[i]);
2400 	else {
2401 		/* New variable.  Expand if necessary. */
2402 		if (i >= client->scriptEnvsize - 1) {
2403 			char **newscriptEnv;
2404 			int newscriptEnvsize = client->scriptEnvsize + 50;
2405 
2406 			newscriptEnv = realloc(client->scriptEnv,
2407 			    newscriptEnvsize);
2408 			if (newscriptEnv == NULL) {
2409 				free(client->scriptEnv);
2410 				client->scriptEnv = NULL;
2411 				client->scriptEnvsize = 0;
2412 				error("script_set_env: no memory for variable");
2413 			}
2414 			client->scriptEnv = newscriptEnv;
2415 			client->scriptEnvsize = newscriptEnvsize;
2416 		}
2417 		/* need to set the NULL pointer at end of array beyond
2418 		   the new slot. */
2419 		client->scriptEnv[i + 1] = NULL;
2420 	}
2421 	/* Allocate space and format the variable in the appropriate slot. */
2422 	client->scriptEnv[i] = malloc(strlen(prefix) + strlen(name) + 1 +
2423 	    strlen(value) + 1);
2424 	if (client->scriptEnv[i] == NULL)
2425 		error("script_set_env: no memory for variable assignment");
2426 	snprintf(client->scriptEnv[i], strlen(prefix) + strlen(name) +
2427 	    1 + strlen(value) + 1, "%s%s=%s", prefix, name, value);
2428 }
2429 
2430 void
2431 script_flush_env(struct client_state *client)
2432 {
2433 	int i;
2434 
2435 	for (i = 0; client->scriptEnv[i]; i++) {
2436 		free(client->scriptEnv[i]);
2437 		client->scriptEnv[i] = NULL;
2438 	}
2439 	client->scriptEnvsize = 0;
2440 }
2441 
2442 int
2443 dhcp_option_ev_name(char *buf, size_t buflen, struct option *option)
2444 {
2445 	size_t i;
2446 
2447 	for (i = 0; option->name[i]; i++) {
2448 		if (i + 1 == buflen)
2449 			return 0;
2450 		if (option->name[i] == '-')
2451 			buf[i] = '_';
2452 		else
2453 			buf[i] = option->name[i];
2454 	}
2455 
2456 	buf[i] = 0;
2457 	return 1;
2458 }
2459 
2460 void
2461 go_daemon(void)
2462 {
2463 	static int state = 0;
2464 	cap_rights_t rights;
2465 
2466 	if (no_daemon || state)
2467 		return;
2468 
2469 	state = 1;
2470 
2471 	/* Stop logging to stderr... */
2472 	log_perror = 0;
2473 
2474 	if (daemonfd(-1, nullfd) == -1)
2475 		error("daemon");
2476 
2477 	cap_rights_init(&rights);
2478 
2479 	if (pidfile != NULL) {
2480 		pidfile_write(pidfile);
2481 
2482 		if (caph_rights_limit(pidfile_fileno(pidfile), &rights) < 0)
2483 			error("can't limit pidfile descriptor: %m");
2484 	}
2485 
2486 	if (nullfd != -1) {
2487 		close(nullfd);
2488 		nullfd = -1;
2489 	}
2490 
2491 	if (caph_rights_limit(STDIN_FILENO, &rights) < 0)
2492 		error("can't limit stdin: %m");
2493 	cap_rights_init(&rights, CAP_WRITE);
2494 	if (caph_rights_limit(STDOUT_FILENO, &rights) < 0)
2495 		error("can't limit stdout: %m");
2496 	if (caph_rights_limit(STDERR_FILENO, &rights) < 0)
2497 		error("can't limit stderr: %m");
2498 }
2499 
2500 int
2501 check_option(struct client_lease *l, int option)
2502 {
2503 	const char *opbuf;
2504 	const char *sbuf;
2505 
2506 	/* we use this, since this is what gets passed to dhclient-script */
2507 
2508 	opbuf = pretty_print_option(option, l->options[option].data,
2509 	    l->options[option].len, 0, 0);
2510 
2511 	sbuf = option_as_string(option, l->options[option].data,
2512 	    l->options[option].len);
2513 
2514 	switch (option) {
2515 	case DHO_SUBNET_MASK:
2516 	case DHO_TIME_SERVERS:
2517 	case DHO_NAME_SERVERS:
2518 	case DHO_ROUTERS:
2519 	case DHO_DOMAIN_NAME_SERVERS:
2520 	case DHO_LOG_SERVERS:
2521 	case DHO_COOKIE_SERVERS:
2522 	case DHO_LPR_SERVERS:
2523 	case DHO_IMPRESS_SERVERS:
2524 	case DHO_RESOURCE_LOCATION_SERVERS:
2525 	case DHO_SWAP_SERVER:
2526 	case DHO_BROADCAST_ADDRESS:
2527 	case DHO_NIS_SERVERS:
2528 	case DHO_NTP_SERVERS:
2529 	case DHO_NETBIOS_NAME_SERVERS:
2530 	case DHO_NETBIOS_DD_SERVER:
2531 	case DHO_FONT_SERVERS:
2532 	case DHO_DHCP_SERVER_IDENTIFIER:
2533 	case DHO_NISPLUS_SERVERS:
2534 	case DHO_MOBILE_IP_HOME_AGENT:
2535 	case DHO_SMTP_SERVER:
2536 	case DHO_POP_SERVER:
2537 	case DHO_NNTP_SERVER:
2538 	case DHO_WWW_SERVER:
2539 	case DHO_FINGER_SERVER:
2540 	case DHO_IRC_SERVER:
2541 	case DHO_STREETTALK_SERVER:
2542 	case DHO_STREETTALK_DA_SERVER:
2543 		if (!ipv4addrs(opbuf)) {
2544 			warning("Invalid IP address in option: %s", opbuf);
2545 			return (0);
2546 		}
2547 		return (1)  ;
2548 	case DHO_HOST_NAME:
2549 	case DHO_NIS_DOMAIN:
2550 	case DHO_NISPLUS_DOMAIN:
2551 	case DHO_TFTP_SERVER_NAME:
2552 		if (!res_hnok(sbuf)) {
2553 			warning("Bogus Host Name option %d: %s (%s)", option,
2554 			    sbuf, opbuf);
2555 			l->options[option].len = 0;
2556 			free(l->options[option].data);
2557 		}
2558 		return (1);
2559 	case DHO_DOMAIN_NAME:
2560 	case DHO_DOMAIN_SEARCH:
2561 		if (!res_hnok(sbuf)) {
2562 			if (!check_search(sbuf)) {
2563 				warning("Bogus domain search list %d: %s (%s)",
2564 				    option, sbuf, opbuf);
2565 				l->options[option].len = 0;
2566 				free(l->options[option].data);
2567 			}
2568 		}
2569 		return (1);
2570 	case DHO_PAD:
2571 	case DHO_TIME_OFFSET:
2572 	case DHO_BOOT_SIZE:
2573 	case DHO_MERIT_DUMP:
2574 	case DHO_ROOT_PATH:
2575 	case DHO_EXTENSIONS_PATH:
2576 	case DHO_IP_FORWARDING:
2577 	case DHO_NON_LOCAL_SOURCE_ROUTING:
2578 	case DHO_POLICY_FILTER:
2579 	case DHO_MAX_DGRAM_REASSEMBLY:
2580 	case DHO_DEFAULT_IP_TTL:
2581 	case DHO_PATH_MTU_AGING_TIMEOUT:
2582 	case DHO_PATH_MTU_PLATEAU_TABLE:
2583 	case DHO_INTERFACE_MTU:
2584 	case DHO_ALL_SUBNETS_LOCAL:
2585 	case DHO_PERFORM_MASK_DISCOVERY:
2586 	case DHO_MASK_SUPPLIER:
2587 	case DHO_ROUTER_DISCOVERY:
2588 	case DHO_ROUTER_SOLICITATION_ADDRESS:
2589 	case DHO_STATIC_ROUTES:
2590 	case DHO_TRAILER_ENCAPSULATION:
2591 	case DHO_ARP_CACHE_TIMEOUT:
2592 	case DHO_IEEE802_3_ENCAPSULATION:
2593 	case DHO_DEFAULT_TCP_TTL:
2594 	case DHO_TCP_KEEPALIVE_INTERVAL:
2595 	case DHO_TCP_KEEPALIVE_GARBAGE:
2596 	case DHO_VENDOR_ENCAPSULATED_OPTIONS:
2597 	case DHO_NETBIOS_NODE_TYPE:
2598 	case DHO_NETBIOS_SCOPE:
2599 	case DHO_X_DISPLAY_MANAGER:
2600 	case DHO_DHCP_REQUESTED_ADDRESS:
2601 	case DHO_DHCP_LEASE_TIME:
2602 	case DHO_DHCP_OPTION_OVERLOAD:
2603 	case DHO_DHCP_MESSAGE_TYPE:
2604 	case DHO_DHCP_PARAMETER_REQUEST_LIST:
2605 	case DHO_DHCP_MESSAGE:
2606 	case DHO_DHCP_MAX_MESSAGE_SIZE:
2607 	case DHO_DHCP_RENEWAL_TIME:
2608 	case DHO_DHCP_REBINDING_TIME:
2609 	case DHO_DHCP_CLASS_IDENTIFIER:
2610 	case DHO_DHCP_CLIENT_IDENTIFIER:
2611 	case DHO_BOOTFILE_NAME:
2612 	case DHO_DHCP_USER_CLASS_ID:
2613 	case DHO_URL:
2614 	case DHO_END:
2615 		return (1);
2616 	case DHO_CLASSLESS_ROUTES:
2617 		return (check_classless_option(l->options[option].data,
2618 		    l->options[option].len));
2619 	default:
2620 		warning("unknown dhcp option value 0x%x", option);
2621 		return (unknown_ok);
2622 	}
2623 }
2624 
2625 /* RFC 3442 The Classless Static Routes option checks */
2626 int
2627 check_classless_option(unsigned char *data, int len)
2628 {
2629 	int i = 0;
2630 	unsigned char width;
2631 	in_addr_t addr, mask;
2632 
2633 	if (len < 5) {
2634 		warning("Too small length: %d", len);
2635 		return (0);
2636 	}
2637 	while(i < len) {
2638 		width = data[i++];
2639 		if (width == 0) {
2640 			i += 4;
2641 			continue;
2642 		} else if (width < 9) {
2643 			addr =  (in_addr_t)(data[i]	<< 24);
2644 			i += 1;
2645 		} else if (width < 17) {
2646 			addr =  (in_addr_t)(data[i]	<< 24) +
2647 				(in_addr_t)(data[i + 1]	<< 16);
2648 			i += 2;
2649 		} else if (width < 25) {
2650 			addr =  (in_addr_t)(data[i]	<< 24) +
2651 				(in_addr_t)(data[i + 1]	<< 16) +
2652 				(in_addr_t)(data[i + 2]	<< 8);
2653 			i += 3;
2654 		} else if (width < 33) {
2655 			addr =  (in_addr_t)(data[i]	<< 24) +
2656 				(in_addr_t)(data[i + 1]	<< 16) +
2657 				(in_addr_t)(data[i + 2]	<< 8)  +
2658 				data[i + 3];
2659 			i += 4;
2660 		} else {
2661 			warning("Incorrect subnet width: %d", width);
2662 			return (0);
2663 		}
2664 		mask = (in_addr_t)(~0) << (32 - width);
2665 		addr = ntohl(addr);
2666 		mask = ntohl(mask);
2667 
2668 		/*
2669 		 * From RFC 3442:
2670 		 * ... After deriving a subnet number and subnet mask
2671 		 * from each destination descriptor, the DHCP client
2672 		 * MUST zero any bits in the subnet number where the
2673 		 * corresponding bit in the mask is zero...
2674 		 */
2675 		if ((addr & mask) != addr) {
2676 			addr &= mask;
2677 			data[i - 1] = (unsigned char)(
2678 				(addr >> (((32 - width)/8)*8)) & 0xFF);
2679 		}
2680 		i += 4;
2681 	}
2682 	if (i > len) {
2683 		warning("Incorrect data length: %d (must be %d)", len, i);
2684 		return (0);
2685 	}
2686 	return (1);
2687 }
2688 
2689 int
2690 res_hnok(const char *dn)
2691 {
2692 	int pch = PERIOD, ch = *dn++;
2693 
2694 	while (ch != '\0') {
2695 		int nch = *dn++;
2696 
2697 		if (periodchar(ch)) {
2698 			;
2699 		} else if (periodchar(pch)) {
2700 			if (!borderchar(ch))
2701 				return (0);
2702 		} else if (periodchar(nch) || nch == '\0') {
2703 			if (!borderchar(ch))
2704 				return (0);
2705 		} else {
2706 			if (!middlechar(ch))
2707 				return (0);
2708 		}
2709 		pch = ch, ch = nch;
2710 	}
2711 	return (1);
2712 }
2713 
2714 int
2715 check_search(const char *srch)
2716 {
2717         int pch = PERIOD, ch = *srch++;
2718 	int domains = 1;
2719 
2720 	/* 256 char limit re resolv.conf(5) */
2721 	if (strlen(srch) > 256)
2722 		return (0);
2723 
2724 	while (whitechar(ch))
2725 		ch = *srch++;
2726 
2727         while (ch != '\0') {
2728                 int nch = *srch++;
2729 
2730                 if (periodchar(ch) || whitechar(ch)) {
2731                         ;
2732                 } else if (periodchar(pch)) {
2733                         if (!borderchar(ch))
2734                                 return (0);
2735                 } else if (periodchar(nch) || nch == '\0') {
2736                         if (!borderchar(ch))
2737                                 return (0);
2738                 } else {
2739                         if (!middlechar(ch))
2740                                 return (0);
2741                 }
2742 		if (!whitechar(ch)) {
2743 			pch = ch;
2744 		} else {
2745 			while (whitechar(nch)) {
2746 				nch = *srch++;
2747 			}
2748 			if (nch != '\0')
2749 				domains++;
2750 			pch = PERIOD;
2751 		}
2752 		ch = nch;
2753         }
2754 	/* 6 domain limit re resolv.conf(5) */
2755 	if (domains > 6)
2756 		return (0);
2757         return (1);
2758 }
2759 
2760 /* Does buf consist only of dotted decimal ipv4 addrs?
2761  * return how many if so,
2762  * otherwise, return 0
2763  */
2764 int
2765 ipv4addrs(const char * buf)
2766 {
2767 	struct in_addr jnk;
2768 	int count = 0;
2769 
2770 	while (inet_aton(buf, &jnk) == 1){
2771 		count++;
2772 		while (periodchar(*buf) || digitchar(*buf))
2773 			buf++;
2774 		if (*buf == '\0')
2775 			return (count);
2776 		while (*buf ==  ' ')
2777 			buf++;
2778 	}
2779 	return (0);
2780 }
2781 
2782 
2783 const char *
2784 option_as_string(unsigned int code, unsigned char *data, int len)
2785 {
2786 	static char optbuf[32768]; /* XXX */
2787 	char *op = optbuf;
2788 	int opleft = sizeof(optbuf);
2789 	unsigned char *dp = data;
2790 
2791 	if (code > 255)
2792 		error("option_as_string: bad code %d", code);
2793 
2794 	for (; dp < data + len; dp++) {
2795 		if (!isascii(*dp) || !isprint(*dp)) {
2796 			if (dp + 1 != data + len || *dp != 0) {
2797 				snprintf(op, opleft, "\\%03o", *dp);
2798 				op += 4;
2799 				opleft -= 4;
2800 			}
2801 		} else if (*dp == '"' || *dp == '\'' || *dp == '$' ||
2802 		    *dp == '`' || *dp == '\\') {
2803 			*op++ = '\\';
2804 			*op++ = *dp;
2805 			opleft -= 2;
2806 		} else {
2807 			*op++ = *dp;
2808 			opleft--;
2809 		}
2810 	}
2811 	if (opleft < 1)
2812 		goto toobig;
2813 	*op = 0;
2814 	return optbuf;
2815 toobig:
2816 	warning("dhcp option too large");
2817 	return "<error>";
2818 }
2819 
2820 int
2821 fork_privchld(int fd, int fd2)
2822 {
2823 	struct pollfd pfd[1];
2824 	int nfds;
2825 
2826 	switch (fork()) {
2827 	case -1:
2828 		error("cannot fork");
2829 	case 0:
2830 		break;
2831 	default:
2832 		return (0);
2833 	}
2834 
2835 	setproctitle("%s [priv]", ifi->name);
2836 
2837 	setsid();
2838 	dup2(nullfd, STDIN_FILENO);
2839 	dup2(nullfd, STDOUT_FILENO);
2840 	dup2(nullfd, STDERR_FILENO);
2841 	close(nullfd);
2842 	close(fd2);
2843 	close(ifi->rfdesc);
2844 	ifi->rfdesc = -1;
2845 
2846 	for (;;) {
2847 		pfd[0].fd = fd;
2848 		pfd[0].events = POLLIN;
2849 		if ((nfds = poll(pfd, 1, INFTIM)) == -1)
2850 			if (errno != EINTR)
2851 				error("poll error");
2852 
2853 		if (nfds == 0 || !(pfd[0].revents & POLLIN))
2854 			continue;
2855 
2856 		dispatch_imsg(ifi, fd);
2857 	}
2858 }
2859