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