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