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