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