xref: /openbsd/sbin/dhclient/dhclient.c (revision b205d946)
1 /*	$OpenBSD: dhclient.c,v 1.728 2024/04/28 16:43:42 florian Exp $	*/
2 
3 /*
4  * Copyright 2004 Henning Brauer <henning@openbsd.org>
5  * Copyright (c) 1995, 1996, 1997, 1998, 1999
6  * The Internet Software Consortium.    All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. Neither the name of The Internet Software Consortium nor the names
18  *    of its contributors may be used to endorse or promote products derived
19  *    from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
22  * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
23  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25  * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
26  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
29  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  * This software has been written for the Internet Software Consortium
36  * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
37  * Enterprises.  To learn more about the Internet Software Consortium,
38  * see ``http://www.vix.com/isc''.  To learn more about Vixie
39  * Enterprises, see ``http://www.vix.com''.
40  *
41  * This client was substantially modified and enhanced by Elliot Poger
42  * for use on Linux while he was working on the MosquitoNet project at
43  * Stanford.
44  *
45  * The current version owes much to Elliot's Linux enhancements, but
46  * was substantially reorganized and partially rewritten by Ted Lemon
47  * so as to use the same networking framework that the Internet Software
48  * Consortium DHCP server uses.   Much system-specific configuration code
49  * was moved into a shell script so that as support for more operating
50  * systems is added, it will not be necessary to port and maintain
51  * system-specific configuration code to these operating systems - instead,
52  * the shell script can invoke the native tools to accomplish the same
53  * purpose.
54  */
55 
56 #include <sys/types.h>
57 #include <sys/socket.h>
58 #include <sys/stat.h>
59 #include <sys/ioctl.h>
60 #include <sys/uio.h>
61 #include <sys/queue.h>
62 
63 #include <net/if.h>
64 #include <net/if_types.h>
65 #include <net/if_dl.h>
66 #include <net/route.h>
67 
68 #include <netinet/in.h>
69 #include <netinet/if_ether.h>
70 
71 #include <net80211/ieee80211.h>
72 #include <net80211/ieee80211_ioctl.h>
73 
74 #include <arpa/inet.h>
75 
76 #include <ctype.h>
77 #include <errno.h>
78 #include <fcntl.h>
79 #include <ifaddrs.h>
80 #include <imsg.h>
81 #include <limits.h>
82 #include <paths.h>
83 #include <poll.h>
84 #include <pwd.h>
85 #include <resolv.h>
86 #include <signal.h>
87 #include <stdint.h>
88 #include <stdlib.h>
89 #include <string.h>
90 #include <syslog.h>
91 #include <unistd.h>
92 
93 #include "dhcp.h"
94 #include "dhcpd.h"
95 #include "log.h"
96 #include "privsep.h"
97 
98 char *path_dhclient_conf;
99 char *path_lease_db;
100 char *log_procname;
101 
102 int nullfd = -1;
103 int cmd_opts;
104 int quit;
105 
106 const struct in_addr inaddr_any = { INADDR_ANY };
107 const struct in_addr inaddr_broadcast = { INADDR_BROADCAST };
108 
109 struct client_config *config;
110 struct imsgbuf *unpriv_ibuf;
111 
112 void		 usage(void);
113 int		 res_hnok_list(const char *);
114 int		 addressinuse(char *, struct in_addr, char *);
115 
116 void		 fork_privchld(struct interface_info *, int, int);
117 void		 get_name(struct interface_info *, int, char *);
118 void		 get_ssid(struct interface_info *, int);
119 void		 get_sockets(struct interface_info *);
120 int		 get_routefd(int);
121 void		 set_iff_up(struct interface_info *, int);
122 void		 set_user(char *);
123 int		 get_ifa_family(char *, int);
124 struct ifaddrs	*get_link_ifa(const char *, struct ifaddrs *);
125 void		 interface_state(struct interface_info *);
126 struct interface_info *initialize_interface(char *, int);
127 void		 tick_msg(const char *, int);
128 void		 rtm_dispatch(struct interface_info *, struct rt_msghdr *);
129 
130 struct client_lease *apply_defaults(struct client_lease *);
131 struct client_lease *clone_lease(struct client_lease *);
132 
133 void state_reboot(struct interface_info *);
134 void state_init(struct interface_info *);
135 void state_selecting(struct interface_info *);
136 void state_bound(struct interface_info *);
137 void state_panic(struct interface_info *);
138 
139 void set_interval(struct interface_info *, struct timespec *);
140 void set_resend_timeout(struct interface_info *, struct timespec *,
141     void (*where)(struct interface_info *));
142 void set_secs(struct interface_info *, struct timespec *);
143 
144 void send_discover(struct interface_info *);
145 void send_request(struct interface_info *);
146 void send_decline(struct interface_info *);
147 void send_release(struct interface_info *);
148 
149 void process_offer(struct interface_info *, struct option_data *,
150     const char *);
151 void bind_lease(struct interface_info *);
152 
153 void make_discover(struct interface_info *, struct client_lease *);
154 void make_request(struct interface_info *, struct client_lease *);
155 void make_decline(struct interface_info *, struct client_lease *);
156 void make_release(struct interface_info *, struct client_lease *);
157 
158 void release_lease(struct interface_info *);
159 void propose_release(struct interface_info *);
160 
161 void write_lease_db(struct interface_info *);
162 char *lease_as_string(char *, struct client_lease *);
163 struct proposal *lease_as_proposal(struct client_lease *);
164 struct unwind_info *lease_as_unwind_info(struct client_lease *);
165 void append_statement(char *, size_t, char *, char *);
166 time_t lease_expiry(struct client_lease *);
167 time_t lease_renewal(struct client_lease *);
168 time_t lease_rebind(struct client_lease *);
169 void   get_lease_timeouts(struct interface_info *, struct client_lease *);
170 
171 struct client_lease *packet_to_lease(struct interface_info *,
172     struct option_data *);
173 void go_daemon(void);
174 int rdaemon(int);
175 int take_charge(struct interface_info *, int, char *);
176 int autoconf(struct interface_info *);
177 struct client_lease *get_recorded_lease(struct interface_info *);
178 
179 #define ROUNDUP(a)	\
180 	((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
181 #define	ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
182 
183 #define	TICK_WAIT	0
184 #define	TICK_SUCCESS	1
185 #define	TICK_DAEMON	2
186 
187 static FILE *leaseFile;
188 
189 int
get_ifa_family(char * cp,int n)190 get_ifa_family(char *cp, int n)
191 {
192 	struct sockaddr		*sa;
193 	unsigned int		 i;
194 
195 	for (i = 1; i; i <<= 1) {
196 		if ((i & n) != 0) {
197 			sa = (struct sockaddr *)cp;
198 			if (i == RTA_IFA)
199 				return sa->sa_family;
200 			ADVANCE(cp, sa);
201 		}
202 	}
203 
204 	return AF_UNSPEC;
205 }
206 
207 struct ifaddrs *
get_link_ifa(const char * name,struct ifaddrs * ifap)208 get_link_ifa(const char *name, struct ifaddrs *ifap)
209 {
210 	struct ifaddrs		*ifa;
211 	struct sockaddr_dl	*sdl;
212 
213 	for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
214 		if (strcmp(name, ifa->ifa_name) == 0 &&
215 		    (ifa->ifa_flags & IFF_LOOPBACK) == 0 &&
216 		    (ifa->ifa_flags & IFF_POINTOPOINT) == 0 &&
217 		    ifa->ifa_data != NULL && /* NULL shouldn't be possible. */
218 		    ifa->ifa_addr != NULL &&
219 		    ifa->ifa_addr->sa_family == AF_LINK) {
220 			sdl = (struct sockaddr_dl *)ifa->ifa_addr;
221 			if (sdl->sdl_alen == ETHER_ADDR_LEN &&
222 			    (sdl->sdl_type == IFT_ETHER ||
223 			    sdl->sdl_type == IFT_CARP))
224 				break;
225 		}
226 	}
227 
228 	if (ifa == NULL)
229 		fatal("get_link_ifa()");
230 
231 	return ifa;
232 }
233 
234 void
interface_state(struct interface_info * ifi)235 interface_state(struct interface_info *ifi)
236 {
237 	struct ifaddrs			*ifap, *ifa;
238 	struct if_data			*ifd;
239 	struct sockaddr_dl		*sdl;
240 	char				*oldlladdr;
241 	int				 newlinkup, oldlinkup;
242 
243 	oldlinkup = LINK_STATE_IS_UP(ifi->link_state);
244 
245 	if (getifaddrs(&ifap) == -1)
246 		fatal("getifaddrs");
247 
248 	ifa = get_link_ifa(ifi->name, ifap);
249 	sdl = (struct sockaddr_dl *)ifa->ifa_addr;
250 	ifd = (struct if_data *)ifa->ifa_data;
251 
252 	if ((ifa->ifa_flags & IFF_UP) == 0 ||
253 	    (ifa->ifa_flags & IFF_RUNNING) == 0) {
254 		ifi->link_state = LINK_STATE_DOWN;
255 	} else {
256 		ifi->link_state = ifd->ifi_link_state;
257 		ifi->mtu = ifd->ifi_mtu;
258 	}
259 
260 	newlinkup = LINK_STATE_IS_UP(ifi->link_state);
261 	if (newlinkup != oldlinkup) {
262 		log_debug("%s: link %s -> %s", log_procname,
263 		    (oldlinkup != 0) ? "up" : "down",
264 		    (newlinkup != 0) ? "up" : "down");
265 		tick_msg("link", newlinkup ? TICK_SUCCESS : TICK_WAIT);
266 	}
267 
268 	if (memcmp(&ifi->hw_address, LLADDR(sdl), ETHER_ADDR_LEN) != 0) {
269 		if (log_getverbose()) {
270 			oldlladdr = strdup(ether_ntoa(&ifi->hw_address));
271 			if (oldlladdr == NULL)
272 				fatal("oldlladdr");
273 			log_debug("%s: LLADDR %s -> %s", log_procname,
274 			    oldlladdr,
275 			    ether_ntoa((struct ether_addr *)LLADDR(sdl)));
276 			free(oldlladdr);
277 		}
278 		memcpy(&ifi->hw_address, LLADDR(sdl), ETHER_ADDR_LEN);
279 		quit = RESTART;	/* Even if MTU has changed. */
280 	}
281 
282 	freeifaddrs(ifap);
283 }
284 
285 struct interface_info *
initialize_interface(char * name,int noaction)286 initialize_interface(char *name, int noaction)
287 {
288 	struct interface_info		*ifi;
289 	struct ifaddrs			*ifap, *ifa;
290 	struct if_data			*ifd;
291 	struct sockaddr_dl		*sdl;
292 	int				 ioctlfd;
293 
294 	ifi = calloc(1, sizeof(*ifi));
295 	if (ifi == NULL)
296 		fatal("ifi");
297 
298 	ifi->rbuf_max = RT_BUF_SIZE;
299 	ifi->rbuf = malloc(ifi->rbuf_max);
300 	if (ifi->rbuf == NULL)
301 		fatal("rbuf");
302 
303 	if ((ioctlfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
304 		fatal("socket(AF_INET, SOCK_DGRAM)");
305 
306 	get_name(ifi, ioctlfd, name);
307 	ifi->index = if_nametoindex(ifi->name);
308 	if (ifi->index == 0)
309 		fatalx("if_nametoindex(%s) == 0", ifi->name);
310 
311 	if (getifaddrs(&ifap) == -1)
312 		fatal("getifaddrs()");
313 
314 	ifa = get_link_ifa(ifi->name, ifap);
315 	sdl = (struct sockaddr_dl *)ifa->ifa_addr;
316 	ifd = (struct if_data *)ifa->ifa_data;
317 
318 	if ((ifa->ifa_flags & IFF_UP) == 0 ||
319 	    (ifa->ifa_flags & IFF_RUNNING) == 0)
320 		ifi->link_state = LINK_STATE_DOWN;
321 	else
322 		ifi->link_state = ifd->ifi_link_state;
323 
324 	memcpy(ifi->hw_address.ether_addr_octet, LLADDR(sdl), ETHER_ADDR_LEN);
325 	ifi->rdomain = ifd->ifi_rdomain;
326 
327 	get_sockets(ifi);
328 	get_ssid(ifi, ioctlfd);
329 
330 	if (noaction == 0 && !LINK_STATE_IS_UP(ifi->link_state))
331 		set_iff_up(ifi, ioctlfd);
332 
333 	close(ioctlfd);
334 	freeifaddrs(ifap);
335 
336 	return ifi;
337 }
338 
339 void
get_name(struct interface_info * ifi,int ioctlfd,char * arg)340 get_name(struct interface_info *ifi, int ioctlfd, char *arg)
341 {
342 	struct ifgroupreq	 ifgr;
343 	size_t			 len;
344 
345 	if (strcmp(arg, "egress") == 0) {
346 		memset(&ifgr, 0, sizeof(ifgr));
347 		strlcpy(ifgr.ifgr_name, "egress", sizeof(ifgr.ifgr_name));
348 		if (ioctl(ioctlfd, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1)
349 			fatal("SIOCGIFGMEMB");
350 		if (ifgr.ifgr_len > sizeof(struct ifg_req))
351 			fatalx("too many interfaces in group egress");
352 		if ((ifgr.ifgr_groups = calloc(1, ifgr.ifgr_len)) == NULL)
353 			fatalx("ifgr_groups");
354 		if (ioctl(ioctlfd, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1)
355 			fatal("SIOCGIFGMEMB");
356 		len = strlcpy(ifi->name, ifgr.ifgr_groups->ifgrq_member,
357 		    IFNAMSIZ);
358 		free(ifgr.ifgr_groups);
359 	} else
360 		len = strlcpy(ifi->name, arg, IFNAMSIZ);
361 
362 	if (len >= IFNAMSIZ)
363 		fatalx("interface name too long");
364 }
365 
366 void
get_ssid(struct interface_info * ifi,int ioctlfd)367 get_ssid(struct interface_info *ifi, int ioctlfd)
368 {
369 	struct ieee80211_nwid		nwid;
370 	struct ifreq			ifr;
371 
372 	memset(&ifr, 0, sizeof(ifr));
373 	memset(&nwid, 0, sizeof(nwid));
374 
375 	ifr.ifr_data = (caddr_t)&nwid;
376 	strlcpy(ifr.ifr_name, ifi->name, sizeof(ifr.ifr_name));
377 
378 	if (ioctl(ioctlfd, SIOCG80211NWID, (caddr_t)&ifr) == 0) {
379 		memset(ifi->ssid, 0, sizeof(ifi->ssid));
380 		memcpy(ifi->ssid, nwid.i_nwid, nwid.i_len);
381 		ifi->ssid_len = nwid.i_len;
382 	}
383 }
384 
385 void
set_iff_up(struct interface_info * ifi,int ioctlfd)386 set_iff_up(struct interface_info *ifi, int ioctlfd)
387 {
388 	struct ifreq	 ifr;
389 
390 	memset(&ifr, 0, sizeof(ifr));
391 	strlcpy(ifr.ifr_name, ifi->name, sizeof(ifr.ifr_name));
392 
393 	if (ioctl(ioctlfd, SIOCGIFFLAGS, (caddr_t)&ifr) == -1)
394 		fatal("%s: SIOCGIFFLAGS", ifi->name);
395 
396 	if ((ifr.ifr_flags & IFF_UP) == 0) {
397 		ifi->link_state = LINK_STATE_DOWN;
398 		ifr.ifr_flags |= IFF_UP;
399 		if (ioctl(ioctlfd, SIOCSIFFLAGS, (caddr_t)&ifr) == -1)
400 			fatal("%s: SIOCSIFFLAGS", ifi->name);
401 	}
402 }
403 
404 void
set_user(char * user)405 set_user(char *user)
406 {
407 	struct passwd		*pw;
408 
409 	pw = getpwnam(user);
410 	if (pw == NULL)
411 		fatalx("no such user: %s", user);
412 
413 	if (chroot(pw->pw_dir) == -1)
414 		fatal("chroot(%s)", pw->pw_dir);
415 	if (chdir("/") == -1)
416 		fatal("chdir(\"/\")");
417 	if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1)
418 		fatal("setresgid");
419 	if (setgroups(1, &pw->pw_gid) == -1)
420 		fatal("setgroups");
421 	if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1)
422 		fatal("setresuid");
423 
424 	endpwent();
425 }
426 
427 void
get_sockets(struct interface_info * ifi)428 get_sockets(struct interface_info *ifi)
429 {
430 	unsigned char		*newp;
431 	size_t			 newsize;
432 
433 	ifi->udpfd = get_udp_sock(ifi->rdomain);
434 	ifi->bpffd = get_bpf_sock(ifi->name);
435 
436 	newsize = configure_bpf_sock(ifi->bpffd);
437 	if (newsize > ifi->rbuf_max) {
438 		if ((newp = realloc(ifi->rbuf, newsize)) == NULL)
439 			fatal("rbuf");
440 		ifi->rbuf = newp;
441 		ifi->rbuf_max = newsize;
442 	}
443 }
444 
445 int
get_routefd(int rdomain)446 get_routefd(int rdomain)
447 {
448 	int		routefd, rtfilter;
449 
450 	if ((routefd = socket(AF_ROUTE, SOCK_RAW, AF_INET)) == -1)
451 		fatal("socket(AF_ROUTE, SOCK_RAW)");
452 
453 	rtfilter = ROUTE_FILTER(RTM_PROPOSAL) | ROUTE_FILTER(RTM_IFINFO) |
454 	    ROUTE_FILTER(RTM_NEWADDR) | ROUTE_FILTER(RTM_DELADDR) |
455 	    ROUTE_FILTER(RTM_IFANNOUNCE) | ROUTE_FILTER(RTM_80211INFO);
456 
457 	if (setsockopt(routefd, AF_ROUTE, ROUTE_MSGFILTER,
458 	    &rtfilter, sizeof(rtfilter)) == -1)
459 		fatal("setsockopt(ROUTE_MSGFILTER)");
460 	if (setsockopt(routefd, AF_ROUTE, ROUTE_TABLEFILTER, &rdomain,
461 	    sizeof(rdomain)) == -1)
462 		fatal("setsockopt(ROUTE_TABLEFILTER)");
463 
464 	return routefd;
465 }
466 
467 void
routefd_handler(struct interface_info * ifi,int routefd)468 routefd_handler(struct interface_info *ifi, int routefd)
469 {
470 	struct rt_msghdr		*rtm;
471 	unsigned char			*buf = ifi->rbuf;
472 	unsigned char			*lim, *next;
473 	ssize_t				 n;
474 
475 	do {
476 		n = read(routefd, buf, RT_BUF_SIZE);
477 	} while (n == -1 && errno == EINTR);
478 	if (n == -1) {
479 		log_warn("%s: routing socket", log_procname);
480 		return;
481 	}
482 	if (n == 0)
483 		fatalx("%s: routing socket closed", log_procname);
484 
485 	lim = buf + n;
486 	for (next = buf; next < lim && quit == 0; next += rtm->rtm_msglen) {
487 		rtm = (struct rt_msghdr *)next;
488 		if (lim < next + sizeof(rtm->rtm_msglen) ||
489 		    lim < next + rtm->rtm_msglen)
490 			fatalx("%s: partial rtm in buffer", log_procname);
491 
492 		if (rtm->rtm_version != RTM_VERSION)
493 			continue;
494 
495 		rtm_dispatch(ifi, rtm);
496 	}
497 }
498 
499 void
rtm_dispatch(struct interface_info * ifi,struct rt_msghdr * rtm)500 rtm_dispatch(struct interface_info *ifi, struct rt_msghdr *rtm)
501 {
502 	struct if_msghdr		*ifm;
503 	struct if_announcemsghdr	*ifan;
504 	struct ifa_msghdr		*ifam;
505 	struct if_ieee80211_data	*ifie;
506 	char				*oldssid;
507 	uint32_t			 oldmtu;
508 
509 	switch (rtm->rtm_type) {
510 	case RTM_PROPOSAL:
511 		if (rtm->rtm_priority == RTP_PROPOSAL_SOLICIT) {
512 			if (quit == 0 && ifi->active != NULL)
513 				tell_unwind(ifi->unwind_info, ifi->flags);
514 			return;
515 		}
516 		if (rtm->rtm_index != ifi->index ||
517 		    rtm->rtm_priority != RTP_PROPOSAL_DHCLIENT)
518 			return;
519 		if ((rtm->rtm_flags & RTF_PROTO3) != 0) {
520 			if (rtm->rtm_seq == (int32_t)ifi->xid) {
521 				ifi->flags |= IFI_IN_CHARGE;
522 				return;
523 			} else if ((ifi->flags & IFI_IN_CHARGE) != 0) {
524 				log_debug("%s: yielding responsibility",
525 				    log_procname);
526 				quit = TERMINATE;
527 			}
528 		} else if ((rtm->rtm_flags & RTF_PROTO2) != 0) {
529 			release_lease(ifi); /* OK even if we sent it. */
530 			quit = TERMINATE;
531 		} else
532 			return; /* Ignore tell_unwind() proposals. */
533 		break;
534 
535 	case RTM_DESYNC:
536 		log_warnx("%s: RTM_DESYNC", log_procname);
537 		break;
538 
539 	case RTM_IFINFO:
540 		ifm = (struct if_msghdr *)rtm;
541 		if (ifm->ifm_index != ifi->index)
542 			break;
543 		if ((rtm->rtm_flags & RTF_UP) == 0)
544 			fatalx("down");
545 
546 		oldmtu = ifi->mtu;
547 		interface_state(ifi);
548 		if (oldmtu == ifi->mtu)
549 			quit = RESTART;
550 		else
551 			log_debug("%s: MTU %u -> %u",
552 			    log_procname, oldmtu, ifi->mtu);
553 		break;
554 
555 	case RTM_80211INFO:
556 		if (rtm->rtm_index != ifi->index)
557 			break;
558 		ifie = &((struct if_ieee80211_msghdr *)rtm)->ifim_ifie;
559 		if (ifi->ssid_len != ifie->ifie_nwid_len || memcmp(ifi->ssid,
560 		    ifie->ifie_nwid, ifie->ifie_nwid_len) != 0) {
561 			if (log_getverbose()) {
562 				oldssid = strdup(pretty_print_string(ifi->ssid,
563 				    ifi->ssid_len, 1));
564 				if (oldssid == NULL)
565 					fatal("oldssid");
566 				log_debug("%s: SSID %s -> %s", log_procname,
567 				    oldssid, pretty_print_string(ifie->ifie_nwid,
568 				    ifie->ifie_nwid_len, 1));
569 				free(oldssid);
570 			}
571 			quit = RESTART;
572 		}
573 		break;
574 
575 	case RTM_IFANNOUNCE:
576 		ifan = (struct if_announcemsghdr *)rtm;
577 		if (ifan->ifan_what == IFAN_DEPARTURE && ifan->ifan_index ==
578 		    ifi->index)
579 			fatalx("departed");
580 		break;
581 
582 	case RTM_NEWADDR:
583 	case RTM_DELADDR:
584 		/* Need to check if it is time to write resolv.conf. */
585 		ifam = (struct ifa_msghdr *)rtm;
586 		if (get_ifa_family((char *)ifam + ifam->ifam_hdrlen,
587 		    ifam->ifam_addrs) != AF_INET)
588 			return;
589 		break;
590 
591 	default:
592 		break;
593 	}
594 
595 	/*
596 	 * Responsibility for resolv.conf may have changed hands.
597 	 */
598 	if (quit == 0 && ifi->active != NULL &&
599 	    (ifi->flags & IFI_IN_CHARGE) != 0 &&
600 	    ifi->state == S_BOUND)
601 		write_resolv_conf();
602 }
603 
604 int
main(int argc,char * argv[])605 main(int argc, char *argv[])
606 {
607 	uint8_t			 actions[DHO_END];
608 	struct stat		 sb;
609 	struct interface_info	*ifi;
610 	char			*ignore_list, *p;
611 	int			 fd, socket_fd[2];
612 	int			 routefd;
613 	int			 ch, i;
614 
615 	if (isatty(STDERR_FILENO) != 0)
616 		log_init(1, LOG_DEBUG); /* log to stderr until daemonized */
617 	else
618 		log_init(0, LOG_DEBUG); /* can't log to stderr */
619 
620 	log_setverbose(0);	/* Don't show log_debug() messages. */
621 
622 	if (lstat(_PATH_DHCLIENT_CONF, &sb) == 0)
623 		path_dhclient_conf = _PATH_DHCLIENT_CONF;
624 	memset(actions, ACTION_USELEASE, sizeof(actions));
625 
626 	while ((ch = getopt(argc, argv, "c:di:nrv")) != -1) {
627 		syslog(LOG_ALERT | LOG_CONS,
628 		    "dhclient will go away, so -%c option will not exist", ch);
629 		switch (ch) {
630 		case 'c':
631 			if (strlen(optarg) == 0)
632 				path_dhclient_conf = NULL;
633 			else if (lstat(optarg, &sb) == 0)
634 				path_dhclient_conf = optarg;
635 			else
636 				fatal("lstat(%s)", optarg);
637 			break;
638 		case 'd':
639 			cmd_opts |= OPT_FOREGROUND;
640 			break;
641 		case 'i':
642 			syslog(LOG_ALERT | LOG_CONS,
643 			    "dhclient will go away, for -i learn dhcpleased.conf");
644 			if (strlen(optarg) == 0)
645 				break;
646 			ignore_list = strdup(optarg);
647 			if (ignore_list == NULL)
648 				fatal("ignore_list");
649 			for (p = strsep(&ignore_list, ", "); p != NULL;
650 			     p = strsep(&ignore_list, ", ")) {
651 				if (*p == '\0')
652 					continue;
653 				i = name_to_code(p);
654 				if (i == DHO_END)
655 					fatalx("invalid option name: '%s'", p);
656 				actions[i] = ACTION_IGNORE;
657 			}
658 			free(ignore_list);
659 			break;
660 		case 'n':
661 			cmd_opts |= OPT_NOACTION;
662 			break;
663 		case 'r':
664 			cmd_opts |= OPT_RELEASE;
665 			break;
666 		case 'v':
667 			cmd_opts |= OPT_VERBOSE;
668 			break;
669 		default:
670 			usage();
671 		}
672 	}
673 
674 	argc -= optind;
675 	argv += optind;
676 
677 	if (argc != 1)
678 		usage();
679 
680 	syslog(LOG_ALERT | LOG_CONS,
681 	    "dhclient will go away, stop using it");
682 
683 	execl("/sbin/ifconfig", "ifconfig", argv[0], "inet", "autoconf", NULL);
684 
685 	if ((cmd_opts & (OPT_FOREGROUND | OPT_NOACTION)) != 0)
686 		cmd_opts |= OPT_VERBOSE;
687 
688 	if ((cmd_opts & OPT_VERBOSE) != 0)
689 		log_setverbose(1);	/* Show log_debug() messages. */
690 
691 	ifi = initialize_interface(argv[0], cmd_opts & OPT_NOACTION);
692 
693 	log_procname = strdup(ifi->name);
694 	if (log_procname == NULL)
695 		fatal("log_procname");
696 	setproctitle("%s", log_procname);
697 	log_procinit(log_procname);
698 
699 	tzset();
700 
701 	if (setrtable(ifi->rdomain) == -1)
702 		fatal("setrtable(%u)", ifi->rdomain);
703 
704 	if ((cmd_opts & OPT_RELEASE) != 0) {
705 		if ((cmd_opts & OPT_NOACTION) == 0)
706 			propose_release(ifi);
707 		exit(0);
708 	}
709 
710 	signal(SIGPIPE, SIG_IGN);	/* Don't wait for go_daemon()! */
711 
712 	if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0,
713 	    socket_fd) == -1)
714 		fatal("socketpair");
715 
716 	if ((nullfd = open(_PATH_DEVNULL, O_RDWR)) == -1)
717 		fatal("open(%s)", _PATH_DEVNULL);
718 
719 	fork_privchld(ifi, socket_fd[0], socket_fd[1]);
720 
721 	close(socket_fd[0]);
722 	if ((unpriv_ibuf = malloc(sizeof(*unpriv_ibuf))) == NULL)
723 		fatal("unpriv_ibuf");
724 	imsg_init(unpriv_ibuf, socket_fd[1]);
725 
726 	read_conf(ifi->name, actions, &ifi->hw_address);
727 	if ((cmd_opts & OPT_NOACTION) != 0)
728 		return 0;
729 
730 	if (asprintf(&path_lease_db, "%s.%s", _PATH_LEASE_DB, ifi->name) == -1)
731 		fatal("path_lease_db");
732 
733 	routefd = get_routefd(ifi->rdomain);
734 	fd = take_charge(ifi, routefd, path_lease_db);	/* Kill other dhclients. */
735 	if (autoconf(ifi)) {
736 		/* dhcpleased has been notified to request a new lease. */
737 		return 0;
738 	}
739 	if (fd != -1)
740 		read_lease_db(&ifi->lease_db);
741 
742 	if ((leaseFile = fopen(path_lease_db, "w")) == NULL)
743 		log_warn("%s: fopen(%s)", log_procname, path_lease_db);
744 	write_lease_db(ifi);
745 
746 	set_user("_dhcp");
747 
748 	if ((cmd_opts & OPT_FOREGROUND) == 0) {
749 		if (pledge("stdio inet dns route proc", NULL) == -1)
750 			fatal("pledge");
751 	} else {
752 		if (pledge("stdio inet dns route", NULL) == -1)
753 			fatal("pledge");
754 	}
755 
756 	tick_msg("link", LINK_STATE_IS_UP(ifi->link_state) ? TICK_SUCCESS :
757 	    TICK_WAIT);
758 	quit = RESTART;
759 	dispatch(ifi, routefd);
760 
761 	return 0;
762 }
763 
764 void
usage(void)765 usage(void)
766 {
767 	extern char	*__progname;
768 
769 	fprintf(stderr,
770 	    "usage: %s [-dnrv] [-c file] [-i options] "
771 	    "interface\n", __progname);
772 	exit(1);
773 }
774 
775 void
state_preboot(struct interface_info * ifi)776 state_preboot(struct interface_info *ifi)
777 {
778 	interface_state(ifi);
779 	if (quit != 0)
780 		return;
781 
782 	if (LINK_STATE_IS_UP(ifi->link_state)) {
783 		tick_msg("link", TICK_SUCCESS);
784 		ifi->state = S_REBOOTING;
785 		state_reboot(ifi);
786 	} else {
787 		tick_msg("link", TICK_WAIT);
788 		set_timeout(ifi, 1, state_preboot);
789 	}
790 }
791 
792 /*
793  * Called when the interface link becomes active.
794  */
795 void
state_reboot(struct interface_info * ifi)796 state_reboot(struct interface_info *ifi)
797 {
798 	const struct timespec	 reboot_intvl = {config->reboot_interval, 0};
799 	struct client_lease	*lease;
800 
801 	cancel_timeout(ifi);
802 
803 	/*
804 	 * If there is no recorded lease or the lease is BOOTP then
805 	 * go straight to INIT and try to DISCOVER a new lease.
806 	 */
807 	ifi->active = get_recorded_lease(ifi);
808 	if (ifi->active == NULL || BOOTP_LEASE(ifi->active)) {
809 		ifi->state = S_INIT;
810 		state_init(ifi);
811 		return;
812 	}
813 	lease = apply_defaults(ifi->active);
814 	get_lease_timeouts(ifi, lease);
815 	free_client_lease(lease);
816 
817 	ifi->xid = arc4random();
818 	make_request(ifi, ifi->active);
819 
820 	ifi->destination.s_addr = INADDR_BROADCAST;
821 	clock_gettime(CLOCK_MONOTONIC, &ifi->first_sending);
822 	timespecadd(&ifi->first_sending, &reboot_intvl, &ifi->reboot_timeout);
823 	ifi->interval = 0;
824 
825 	send_request(ifi);
826 }
827 
828 /*
829  * Called when a lease has completely expired and we've been unable to
830  * renew it.
831  */
832 void
state_init(struct interface_info * ifi)833 state_init(struct interface_info *ifi)
834 {
835 	const struct timespec	offer_intvl = {config->offer_interval, 0};
836 
837 	ifi->xid = arc4random();
838 	make_discover(ifi, ifi->active);
839 
840 	ifi->destination.s_addr = INADDR_BROADCAST;
841 	ifi->state = S_SELECTING;
842 	clock_gettime(CLOCK_MONOTONIC, &ifi->first_sending);
843 	timespecadd(&ifi->first_sending, &offer_intvl, &ifi->offer_timeout);
844 	ifi->select_timeout = ifi->offer_timeout;
845 	ifi->interval = 0;
846 
847 	send_discover(ifi);
848 }
849 
850 /*
851  * Called when one or more DHCPOFFER packets have been received and a
852  * configurable period of time has passed.
853  */
854 void
state_selecting(struct interface_info * ifi)855 state_selecting(struct interface_info *ifi)
856 {
857 	cancel_timeout(ifi);
858 
859 	if (ifi->offer == NULL) {
860 		state_panic(ifi);
861 		return;
862 	}
863 
864 	ifi->state = S_REQUESTING;
865 
866 	/* If it was a BOOTREPLY, we can just take the lease right now. */
867 	if (BOOTP_LEASE(ifi->offer)) {
868 		bind_lease(ifi);
869 		return;
870 	}
871 
872 	ifi->destination.s_addr = INADDR_BROADCAST;
873 	clock_gettime(CLOCK_MONOTONIC, &ifi->first_sending);
874 	ifi->interval = 0;
875 
876 	/*
877 	 * Make a DHCPREQUEST packet from the lease we picked. Keep
878 	 * the current xid, as all offers should have had the same
879 	 * one.
880 	 */
881 	make_request(ifi, ifi->offer);
882 
883 	/* Toss the lease we picked - we'll get it back in a DHCPACK. */
884 	free_client_lease(ifi->offer);
885 	ifi->offer = NULL;
886 	free(ifi->offer_src);
887 	ifi->offer_src = NULL;
888 
889 	send_request(ifi);
890 }
891 
892 void
dhcpoffer(struct interface_info * ifi,struct option_data * options,const char * src)893 dhcpoffer(struct interface_info *ifi, struct option_data *options,
894     const char *src)
895 {
896 	if (ifi->state != S_SELECTING) {
897 		log_debug("%s: unexpected DHCPOFFER from %s - state #%d",
898 		    log_procname, src, ifi->state);
899 		return;
900 	}
901 
902 	log_debug("%s: DHCPOFFER from %s", log_procname, src);
903 	process_offer(ifi, options, src);
904 }
905 
906 void
bootreply(struct interface_info * ifi,struct option_data * options,const char * src)907 bootreply(struct interface_info *ifi, struct option_data *options,
908     const char *src)
909 {
910 	if (ifi->state != S_SELECTING) {
911 		log_debug("%s: unexpected BOOTREPLY from %s - state #%d",
912 		    log_procname, src, ifi->state);
913 		return;
914 	}
915 
916 	log_debug("%s: BOOTREPLY from %s", log_procname, src);
917 	process_offer(ifi, options, src);
918 }
919 
920 void
process_offer(struct interface_info * ifi,struct option_data * options,const char * src)921 process_offer(struct interface_info *ifi, struct option_data *options,
922     const char *src)
923 {
924 	const struct timespec	 select_intvl = {config->select_interval, 0};
925 	struct timespec		 now;
926 	struct client_lease	*lease;
927 
928 	clock_gettime(CLOCK_MONOTONIC, &now);
929 
930 	lease = packet_to_lease(ifi, options);
931 	if (lease != NULL) {
932 		if (ifi->offer == NULL) {
933 			ifi->offer = lease;
934 			free(ifi->offer_src);
935 			ifi->offer_src = strdup(src);	/* NULL is OK */
936 			timespecadd(&now, &select_intvl, &ifi->select_timeout);
937 			if (timespeccmp(&ifi->select_timeout,
938 			    &ifi->offer_timeout, >))
939 				ifi->select_timeout = ifi->offer_timeout;
940 		} else if (lease->address.s_addr ==
941 		    ifi->offer->address.s_addr) {
942 			/* Decline duplicate offers. */
943 		} else if (lease->address.s_addr ==
944 		    ifi->requested_address.s_addr) {
945 			free_client_lease(ifi->offer);
946 			ifi->offer = lease;
947 			free(ifi->offer_src);
948 			ifi->offer_src = strdup(src);	/* NULL is OK */
949 		}
950 
951 		if (ifi->offer != lease) {
952 			make_decline(ifi, lease);
953 			send_decline(ifi);
954 			free_client_lease(lease);
955 		} else if (ifi->offer->address.s_addr ==
956 		    ifi->requested_address.s_addr) {
957 			ifi->select_timeout = now;
958 		}
959 	}
960 
961 	if (timespeccmp(&now, &ifi->select_timeout, >=))
962 		state_selecting(ifi);
963 	else {
964 		ifi->timeout = ifi->select_timeout;
965 		ifi->timeout_func = state_selecting;
966 	}
967 }
968 
969 void
dhcpack(struct interface_info * ifi,struct option_data * options,const char * src)970 dhcpack(struct interface_info *ifi, struct option_data *options,
971     const char *src)
972 {
973 	struct client_lease	*lease;
974 
975 	if (ifi->state != S_REBOOTING &&
976 	    ifi->state != S_REQUESTING &&
977 	    ifi->state != S_RENEWING) {
978 		log_debug("%s: unexpected DHCPACK from %s - state #%d",
979 		    log_procname, src, ifi->state);
980 		return;
981 	}
982 
983 	log_debug("%s: DHCPACK", log_procname);
984 
985 	lease = packet_to_lease(ifi, options);
986 	if (lease == NULL) {
987 		ifi->state = S_INIT;
988 		state_init(ifi);
989 		return;
990 	}
991 
992 	ifi->offer = lease;
993 	ifi->offer_src = strdup(src);	/* NULL is OK */
994 	memcpy(ifi->offer->ssid, ifi->ssid, sizeof(ifi->offer->ssid));
995 	ifi->offer->ssid_len = ifi->ssid_len;
996 
997 	/* Stop resending DHCPREQUEST. */
998 	cancel_timeout(ifi);
999 
1000 	bind_lease(ifi);
1001 }
1002 
1003 void
dhcpnak(struct interface_info * ifi,const char * src)1004 dhcpnak(struct interface_info *ifi, const char *src)
1005 {
1006 	struct client_lease		*ll, *pl;
1007 
1008 	if (ifi->state != S_REBOOTING &&
1009 	    ifi->state != S_REQUESTING &&
1010 	    ifi->state != S_RENEWING) {
1011 		log_debug("%s: unexpected DHCPNAK from %s - state #%d",
1012 		    log_procname, src, ifi->state);
1013 		return;
1014 	}
1015 
1016 	log_debug("%s: DHCPNAK", log_procname);
1017 
1018 	/* Remove the NAK'd address from the database. */
1019 	TAILQ_FOREACH_SAFE(ll, &ifi->lease_db, next, pl) {
1020 		if (ifi->ssid_len == ll->ssid_len &&
1021 		    memcmp(ifi->ssid, ll->ssid, ll->ssid_len) == 0 &&
1022 		    ll->address.s_addr == ifi->requested_address.s_addr) {
1023 			if (ll == ifi->active) {
1024 				tell_unwind(NULL, ifi->flags);
1025 				free(ifi->unwind_info);
1026 				ifi->unwind_info = NULL;
1027 				revoke_proposal(ifi->configured);
1028 				free(ifi->configured);
1029 				ifi->configured = NULL;
1030 				ifi->active = NULL;
1031 			}
1032 			TAILQ_REMOVE(&ifi->lease_db, ll, next);
1033 			free_client_lease(ll);
1034 			write_lease_db(ifi);
1035 		}
1036 	}
1037 
1038 	/* Stop sending DHCPREQUEST packets. */
1039 	cancel_timeout(ifi);
1040 
1041 	ifi->state = S_INIT;
1042 	state_init(ifi);
1043 }
1044 
1045 void
bind_lease(struct interface_info * ifi)1046 bind_lease(struct interface_info *ifi)
1047 {
1048 	struct timespec		 now;
1049 	struct client_lease	*lease, *pl, *ll;
1050 	struct proposal		*effective_proposal = NULL;
1051 	struct unwind_info	*unwind_info;
1052 	char			*msg = NULL;
1053 	int			 rslt, seen;
1054 
1055 	tick_msg("lease", TICK_SUCCESS);
1056 	clock_gettime(CLOCK_MONOTONIC, &now);
1057 
1058 	lease = apply_defaults(ifi->offer);
1059 	get_lease_timeouts(ifi, lease);
1060 
1061 	/* Replace the old active lease with the accepted offer. */
1062 	ifi->active = ifi->offer;
1063 	ifi->offer = NULL;
1064 
1065 	/*
1066 	 * Supply unwind with updated info.
1067 	 */
1068 	unwind_info = lease_as_unwind_info(ifi->active);
1069 	if (ifi->unwind_info == NULL && unwind_info != NULL) {
1070 		ifi->unwind_info = unwind_info;
1071 		tell_unwind(ifi->unwind_info, ifi->flags);
1072 	} else if (ifi->unwind_info != NULL && unwind_info == NULL) {
1073 		tell_unwind(NULL, ifi->flags);
1074 		free(ifi->unwind_info);
1075 		ifi->unwind_info = NULL;
1076 	} else if (ifi->unwind_info != NULL && unwind_info != NULL) {
1077 		if (memcmp(ifi->unwind_info, unwind_info,
1078 		    sizeof(*ifi->unwind_info)) != 0) {
1079 			tell_unwind(NULL, ifi->flags);
1080 			free(ifi->unwind_info);
1081 			ifi->unwind_info = unwind_info;
1082 			tell_unwind(ifi->unwind_info, ifi->flags);
1083 		}
1084 	}
1085 
1086 	effective_proposal = lease_as_proposal(lease);
1087 	if (ifi->configured != NULL) {
1088 		if (memcmp(ifi->configured, effective_proposal,
1089 		    sizeof(*ifi->configured)) == 0)
1090 			goto newlease;
1091 	}
1092 	free(ifi->configured);
1093 	ifi->configured = effective_proposal;
1094 	effective_proposal = NULL;
1095 
1096 	propose(ifi->configured);
1097 	rslt = asprintf(&msg, "%s lease accepted from %s",
1098 	    inet_ntoa(ifi->active->address),
1099 	    (ifi->offer_src == NULL) ? "<unknown>" : ifi->offer_src);
1100 	if (rslt == -1)
1101 		fatal("bind msg");
1102 
1103 newlease:
1104 	seen = 0;
1105 	TAILQ_FOREACH_SAFE(ll, &ifi->lease_db, next, pl) {
1106 		if (ifi->ssid_len != ll->ssid_len ||
1107 		    memcmp(ifi->ssid, ll->ssid, ll->ssid_len) != 0)
1108 			continue;
1109 		if (ifi->active == ll)
1110 			seen = 1;
1111 		else if (ll->address.s_addr == ifi->active->address.s_addr) {
1112 			TAILQ_REMOVE(&ifi->lease_db, ll, next);
1113 			free_client_lease(ll);
1114 		}
1115 	}
1116 	if (seen == 0) {
1117 		if (ifi->active->epoch == 0)
1118 			time(&ifi->active->epoch);
1119 		TAILQ_INSERT_HEAD(&ifi->lease_db, ifi->active,  next);
1120 	}
1121 
1122 	/*
1123 	 * Write out updated information before going daemon.
1124 	 *
1125 	 * Some scripts (e.g. the installer in autoinstall mode) assume that
1126 	 * the bind process is complete and all related information is in
1127 	 * place when dhclient(8) goes daemon.
1128 	 */
1129 	write_lease_db(ifi);
1130 
1131 	free_client_lease(lease);
1132 	free(effective_proposal);
1133 	free(ifi->offer_src);
1134 	ifi->offer_src = NULL;
1135 
1136 	if (msg != NULL) {
1137 		if ((cmd_opts & OPT_FOREGROUND) != 0) {
1138 			/* log msg on console only. */
1139 			;
1140 		} else if (isatty(STDERR_FILENO) != 0) {
1141 			/*
1142 			 * log msg to console and then go_daemon() so it is
1143 			 * logged again, this time to /var/log/daemon.
1144 			 */
1145 			log_info("%s: %s", log_procname, msg);
1146 			go_daemon();
1147 		}
1148 		log_info("%s: %s", log_procname, msg);
1149 		free(msg);
1150 	}
1151 
1152 	ifi->state = S_BOUND;
1153 	go_daemon();
1154 
1155 	/*
1156 	 * Set timeout to start the renewal process.
1157 	 *
1158 	 * If the renewal time is in the past, the lease is from the
1159 	 * leaseDB. Rather than immediately trying to contact a server,
1160 	 * pause the configured time between attempts.
1161 	 */
1162 	if (timespeccmp(&now, &ifi->renew, >=))
1163 		set_timeout(ifi, config->retry_interval, state_bound);
1164 	else {
1165 		ifi->timeout = ifi->renew;
1166 		ifi->timeout_func = state_bound;
1167 	}
1168 }
1169 
1170 /*
1171  * Called when we've successfully bound to a particular lease, but the renewal
1172  * time on that lease has expired.  We are expected to unicast a DHCPREQUEST to
1173  * the server that gave us our original lease.
1174  */
1175 void
state_bound(struct interface_info * ifi)1176 state_bound(struct interface_info *ifi)
1177 {
1178 	struct option_data	*opt;
1179 	struct in_addr		*dest;
1180 
1181 	ifi->xid = arc4random();
1182 	make_request(ifi, ifi->active);
1183 
1184 	dest = &ifi->destination;
1185 	opt = &ifi->active->options[DHO_DHCP_SERVER_IDENTIFIER];
1186 
1187 	if (opt->len == sizeof(*dest))
1188 		dest->s_addr = ((struct in_addr *)opt->data)->s_addr;
1189 	else
1190 		dest->s_addr = INADDR_BROADCAST;
1191 
1192 	clock_gettime(CLOCK_MONOTONIC, &ifi->first_sending);
1193 	ifi->interval = 0;
1194 	ifi->state = S_RENEWING;
1195 
1196 	send_request(ifi);
1197 }
1198 
1199 int
addressinuse(char * name,struct in_addr address,char * ifname)1200 addressinuse(char *name, struct in_addr address, char *ifname)
1201 {
1202 	struct ifaddrs		*ifap, *ifa;
1203 	struct sockaddr_in	*sin;
1204 	int			 used = 0;
1205 
1206 	if (getifaddrs(&ifap) != 0) {
1207 		log_warn("%s: getifaddrs", log_procname);
1208 		return 0;
1209 	}
1210 
1211 	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
1212 		if (ifa->ifa_addr == NULL ||
1213 		    ifa->ifa_addr->sa_family != AF_INET)
1214 			continue;
1215 
1216 		sin = (struct sockaddr_in *)ifa->ifa_addr;
1217 		if (memcmp(&address, &sin->sin_addr, sizeof(address)) == 0) {
1218 			strlcpy(ifname, ifa->ifa_name, IF_NAMESIZE);
1219 			used = 1;
1220 			if (strncmp(ifname, name, IF_NAMESIZE) != 0)
1221 				break;
1222 		}
1223 	}
1224 
1225 	freeifaddrs(ifap);
1226 	return used;
1227 }
1228 
1229 /*
1230  * Allocate a client_lease structure and initialize it from the
1231  * parameters in the received packet.
1232  *
1233  * Return NULL and decline the lease if a valid lease cannot be
1234  * constructed.
1235  */
1236 struct client_lease *
packet_to_lease(struct interface_info * ifi,struct option_data * options)1237 packet_to_lease(struct interface_info *ifi, struct option_data *options)
1238 {
1239 	char			 ifname[IF_NAMESIZE];
1240 	struct dhcp_packet	*packet = &ifi->recv_packet;
1241 	struct client_lease	*lease;
1242 	char			*pretty, *name;
1243 	int			 i;
1244 
1245 	lease = calloc(1, sizeof(*lease));
1246 	if (lease == NULL) {
1247 		log_warn("%s: lease", log_procname);
1248 		return NULL;	/* Can't even DECLINE. */
1249 	}
1250 
1251 	/*  Copy the lease addresses. */
1252 	lease->address.s_addr = packet->yiaddr.s_addr;
1253 	lease->next_server.s_addr = packet->siaddr.s_addr;
1254 
1255 	/* Copy the lease options. */
1256 	for (i = 0; i < DHO_COUNT; i++) {
1257 		if (options[i].len == 0)
1258 			continue;
1259 		name = code_to_name(i);
1260 		if (i == DHO_DOMAIN_SEARCH) {
1261 			/* Replace RFC 1035 data with a string. */
1262 			pretty = rfc1035_as_string(options[i].data,
1263 			    options[i].len);
1264 			free(options[i].data);
1265 			options[i].data = strdup(pretty);
1266 			if (options[i].data == NULL)
1267 				fatal("RFC1035 string");
1268 			options[i].len = strlen(options[i].data);
1269 		} else
1270 			pretty = pretty_print_option(i, &options[i], 0);
1271 		if (strlen(pretty) == 0)
1272 			continue;
1273 		switch (i) {
1274 		case DHO_DOMAIN_SEARCH:
1275 		case DHO_DOMAIN_NAME:
1276 			/*
1277 			 * Allow deviant but historically blessed
1278 			 * practice of supplying multiple domain names
1279 			 * with DHO_DOMAIN_NAME. Thus allowing multiple
1280 			 * entries in the resolv.conf 'search' statement.
1281 			 */
1282 			if (res_hnok_list(pretty) == 0) {
1283 				log_debug("%s: invalid host name in %s",
1284 				    log_procname, name);
1285 				continue;
1286 			}
1287 			break;
1288 		case DHO_HOST_NAME:
1289 		case DHO_NIS_DOMAIN:
1290 			if (res_hnok(pretty) == 0) {
1291 				log_debug("%s: invalid host name in %s",
1292 				    log_procname, name);
1293 				continue;
1294 			}
1295 			break;
1296 		default:
1297 			break;
1298 		}
1299 		lease->options[i] = options[i];
1300 		options[i].data = NULL;
1301 		options[i].len = 0;
1302 	}
1303 
1304 	/*
1305 	 * If this lease doesn't supply a required parameter, decline it.
1306 	 */
1307 	for (i = 0; i < config->required_option_count; i++) {
1308 		if (lease->options[config->required_options[i]].len == 0) {
1309 			name = code_to_name(config->required_options[i]);
1310 			log_warnx("%s: %s required but missing", log_procname,
1311 			    name);
1312 			goto decline;
1313 		}
1314 	}
1315 
1316 	/*
1317 	 * If this lease is trying to sell us an address we are already
1318 	 * using, decline it.
1319 	 */
1320 	memset(ifname, 0, sizeof(ifname));
1321 	if (addressinuse(ifi->name, lease->address, ifname) != 0 &&
1322 	    strncmp(ifname, ifi->name, IF_NAMESIZE) != 0) {
1323 		log_warnx("%s: %s already configured on %s", log_procname,
1324 		    inet_ntoa(lease->address), ifname);
1325 		goto decline;
1326 	}
1327 
1328 	/* If the server name was filled out, copy it. */
1329 	if ((lease->options[DHO_DHCP_OPTION_OVERLOAD].len == 0 ||
1330 	    (lease->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 2) == 0) &&
1331 	    packet->sname[0]) {
1332 		lease->server_name = calloc(1, DHCP_SNAME_LEN + 1);
1333 		if (lease->server_name == NULL) {
1334 			log_warn("%s: SNAME", log_procname);
1335 			goto decline;
1336 		}
1337 		memcpy(lease->server_name, packet->sname, DHCP_SNAME_LEN);
1338 		if (res_hnok(lease->server_name) == 0) {
1339 			log_debug("%s: invalid host name in SNAME ignored",
1340 			    log_procname);
1341 			free(lease->server_name);
1342 			lease->server_name = NULL;
1343 		}
1344 	}
1345 
1346 	/* If the file name was filled out, copy it. */
1347 	if ((lease->options[DHO_DHCP_OPTION_OVERLOAD].len == 0 ||
1348 	    (lease->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 1) == 0) &&
1349 	    packet->file[0]) {
1350 		/* Don't count on the NUL terminator. */
1351 		lease->filename = malloc(DHCP_FILE_LEN + 1);
1352 		if (lease->filename == NULL) {
1353 			log_warn("%s: filename", log_procname);
1354 			goto decline;
1355 		}
1356 		memcpy(lease->filename, packet->file, DHCP_FILE_LEN);
1357 		lease->filename[DHCP_FILE_LEN] = '\0';
1358 	}
1359 
1360 	/*
1361 	 * Record the client identifier used to obtain the lease.  We already
1362 	 * checked that the packet client identifier is absent (RFC 2131) or
1363 	 * matches what we sent (RFC 6842),
1364 	 */
1365 	i = DHO_DHCP_CLIENT_IDENTIFIER;
1366 	if (lease->options[i].len == 0 && config->send_options[i].len != 0) {
1367 		lease->options[i].len = config->send_options[i].len;
1368 		lease->options[i].data = malloc(lease->options[i].len);
1369 		if (lease->options[i].data == NULL)
1370 			fatal("lease client-identifier");
1371 		memcpy(lease->options[i].data, config->send_options[i].data,
1372 		    lease->options[i].len);
1373 	}
1374 
1375 	time(&lease->epoch);
1376 	return lease;
1377 
1378 decline:
1379 	make_decline(ifi, lease);
1380 	send_decline(ifi);
1381 	free_client_lease(lease);
1382 	return NULL;
1383 }
1384 
1385 void
set_interval(struct interface_info * ifi,struct timespec * now)1386 set_interval(struct interface_info *ifi, struct timespec *now)
1387 {
1388 	struct timespec		interval;
1389 
1390 	if (timespeccmp(now, &ifi->timeout, >))
1391 		ifi->interval = 1;
1392 	else {
1393 		timespecsub(&ifi->timeout, now, &interval);
1394 		if (interval.tv_sec == 0 || interval.tv_nsec > 500000000LL)
1395 			interval.tv_sec++;
1396 		ifi->interval = interval.tv_sec;
1397 	}
1398 }
1399 
1400 void
set_resend_timeout(struct interface_info * ifi,struct timespec * now,void (* where)(struct interface_info *))1401 set_resend_timeout(struct interface_info *ifi, struct timespec *now,
1402     void (*where)(struct interface_info *))
1403 {
1404 	const struct timespec	reboot_intvl = {config->reboot_interval, 0};
1405 	const struct timespec	initial_intvl = {config->initial_interval, 0};
1406 	const struct timespec	cutoff_intvl = {config->backoff_cutoff, 0};
1407 	const struct timespec	onesecond = {1, 0};
1408 	struct timespec		interval, when;
1409 
1410 	if (timespeccmp(now, &ifi->link_timeout, <))
1411 		interval = onesecond;
1412 	else if (ifi->interval == 0) {
1413 		if (ifi->state == S_REBOOTING)
1414 			interval = reboot_intvl;
1415 		else
1416 			interval = initial_intvl;
1417 	} else {
1418 		timespecclear(&interval);
1419 		interval.tv_sec = ifi->interval + arc4random_uniform(2 *
1420 		    ifi->interval);
1421 	}
1422 	if (timespeccmp(&interval, &onesecond, <))
1423 		interval = onesecond;
1424 	else if (timespeccmp(&interval, &cutoff_intvl, >))
1425 		interval = cutoff_intvl;
1426 
1427 	timespecadd(now, &interval, &when);
1428 	switch (ifi->state) {
1429 	case S_REBOOTING:
1430 	case S_RENEWING:
1431 		if (timespeccmp(&when, &ifi->expiry, >))
1432 			when = ifi->expiry;
1433 		break;
1434 	case S_SELECTING:
1435 		if (timespeccmp(&when, &ifi->select_timeout, >))
1436 			when = ifi->select_timeout;
1437 		break;
1438 	case S_REQUESTING:
1439 		if (timespeccmp(&when, &ifi->offer_timeout, >))
1440 			when = ifi->offer_timeout;
1441 		break;
1442 	default:
1443 		break;
1444 	}
1445 
1446 	ifi->timeout = when;
1447 	ifi->timeout_func = where;
1448 }
1449 
1450 void
set_secs(struct interface_info * ifi,struct timespec * now)1451 set_secs(struct interface_info *ifi, struct timespec *now)
1452 {
1453 	struct timespec interval;
1454 
1455 	if (ifi->state != S_REQUESTING) {
1456 		/* Update the number of seconds since we started sending. */
1457 		timespecsub(now, &ifi->first_sending, &interval);
1458 		if (interval.tv_nsec > 500000000LL)
1459 			interval.tv_sec++;
1460 		if (interval.tv_sec > UINT16_MAX)
1461 			ifi->secs = UINT16_MAX;
1462 		else
1463 			ifi->secs = interval.tv_sec;
1464 	}
1465 
1466 	ifi->sent_packet.secs = htons(ifi->secs);
1467 }
1468 
1469 /*
1470  * Send out a DHCPDISCOVER packet, and set a timeout to send out another
1471  * one after the right interval has expired.  If we don't get an offer by
1472  * the time we reach the panic interval, call the panic function.
1473  */
1474 void
send_discover(struct interface_info * ifi)1475 send_discover(struct interface_info *ifi)
1476 {
1477 	struct timespec		 now;
1478 	ssize_t			 rslt;
1479 
1480 	clock_gettime(CLOCK_MONOTONIC, &now);
1481 	if (timespeccmp(&now, &ifi->offer_timeout, >=)) {
1482 		state_panic(ifi);
1483 		return;
1484 	}
1485 
1486 	set_resend_timeout(ifi, &now, send_discover);
1487 	set_interval(ifi, &now);
1488 	set_secs(ifi, &now);
1489 
1490 	rslt = send_packet(ifi, inaddr_any, inaddr_broadcast, "DHCPDISCOVER");
1491 	if (rslt != -1)
1492 		log_debug("%s: DHCPDISCOVER %s", log_procname,
1493 		    (ifi->requested_address.s_addr == INADDR_ANY) ? "" :
1494 		    inet_ntoa(ifi->requested_address));
1495 
1496 	tick_msg("lease", TICK_WAIT);
1497 }
1498 
1499 /*
1500  * Called if we haven't received any offers in a preset amount of time. When
1501  * this happens, we try to use existing leases that haven't yet expired.
1502  *
1503  * If LINK_STATE_UNKNOWN, do NOT use recorded leases.
1504  */
1505 void
state_panic(struct interface_info * ifi)1506 state_panic(struct interface_info *ifi)
1507 {
1508 	log_debug("%s: no acceptable DHCPOFFERS received", log_procname);
1509 
1510 	if (ifi->link_state >= LINK_STATE_UP) {
1511 		ifi->offer = get_recorded_lease(ifi);
1512 		if (ifi->offer != NULL) {
1513 			ifi->state = S_REQUESTING;
1514 			ifi->offer_src = strdup(path_lease_db); /* NULL is OK. */
1515 			bind_lease(ifi);
1516 			return;
1517 		}
1518 	}
1519 
1520 	/*
1521 	 * No leases were available, or what was available didn't work
1522 	 */
1523 	log_debug("%s: no working leases in persistent database - sleeping",
1524 	    log_procname);
1525 	ifi->state = S_INIT;
1526 	set_timeout(ifi, config->retry_interval, state_init);
1527 	tick_msg("lease", TICK_DAEMON);
1528 }
1529 
1530 void
send_request(struct interface_info * ifi)1531 send_request(struct interface_info *ifi)
1532 {
1533 	struct sockaddr_in	 destination;
1534 	struct in_addr		 from;
1535 	struct timespec		 now;
1536 	ssize_t			 rslt;
1537 	char			*addr;
1538 
1539 	cancel_timeout(ifi);
1540 	clock_gettime(CLOCK_MONOTONIC, &now);
1541 
1542 	switch (ifi->state) {
1543 	case S_REBOOTING:
1544 		if (timespeccmp(&now, &ifi->reboot_timeout, >=))
1545 			ifi->state = S_INIT;
1546 		else {
1547 			destination.sin_addr.s_addr = INADDR_BROADCAST;
1548 			if (ifi->active == NULL)
1549 				from.s_addr = INADDR_ANY;
1550 			else
1551 				from.s_addr = ifi->active->address.s_addr;
1552 		}
1553 		break;
1554 	case S_RENEWING:
1555 		if (timespeccmp(&now, &ifi->expiry, >=))
1556 			ifi->state = S_INIT;
1557 		else {
1558 			if (timespeccmp(&now, &ifi->rebind, >=))
1559 				destination.sin_addr.s_addr = INADDR_BROADCAST;
1560 			else
1561 				destination.sin_addr.s_addr = ifi->destination.s_addr;
1562 			if (ifi->active == NULL)
1563 				from.s_addr = INADDR_ANY;
1564 			else
1565 				from.s_addr = ifi->active->address.s_addr;
1566 		}
1567 		break;
1568 	case S_REQUESTING:
1569 		if (timespeccmp(&now, &ifi->offer_timeout, >=))
1570 			ifi->state = S_INIT;
1571 		else {
1572 			destination.sin_addr.s_addr = INADDR_BROADCAST;
1573 			from.s_addr = INADDR_ANY;
1574 		}
1575 		break;
1576 	default:
1577 		ifi->state = S_INIT;
1578 		break;
1579 	}
1580 
1581 	if (ifi->state == S_INIT) {
1582 		/* Something has gone wrong. Start over. */
1583 		state_init(ifi);
1584 		return;
1585 	}
1586 
1587 	set_resend_timeout(ifi, &now, send_request);
1588 	set_interval(ifi, &now);
1589 	set_secs(ifi, &now);
1590 
1591 	rslt = send_packet(ifi, from, destination.sin_addr, "DHCPREQUEST");
1592 	if (rslt != -1 && log_getverbose()) {
1593 		addr = strdup(inet_ntoa(ifi->requested_address));
1594 		if (addr == NULL)
1595 			fatal("strdup(ifi->requested_address)");
1596 		if (destination.sin_addr.s_addr == INADDR_BROADCAST)
1597 			log_debug("%s: DHCPREQUEST %s", log_procname, addr);
1598 		else
1599 			log_debug("%s: DHCPREQUEST %s from %s", log_procname,
1600 			    addr, inet_ntoa(destination.sin_addr));
1601 		free(addr);
1602 	}
1603 
1604 	tick_msg("lease", TICK_WAIT);
1605 }
1606 
1607 void
send_decline(struct interface_info * ifi)1608 send_decline(struct interface_info *ifi)
1609 {
1610 	ssize_t		rslt;
1611 
1612 	rslt = send_packet(ifi, inaddr_any, inaddr_broadcast, "DHCPDECLINE");
1613 	if (rslt != -1)
1614 		log_debug("%s: DHCPDECLINE", log_procname);
1615 }
1616 
1617 void
send_release(struct interface_info * ifi)1618 send_release(struct interface_info *ifi)
1619 {
1620 	ssize_t		rslt;
1621 
1622 	rslt = send_packet(ifi, ifi->configured->address, ifi->destination,
1623 	    "DHCPRELEASE");
1624 	if (rslt != -1)
1625 		log_debug("%s: DHCPRELEASE", log_procname);
1626 }
1627 
1628 void
make_discover(struct interface_info * ifi,struct client_lease * lease)1629 make_discover(struct interface_info *ifi, struct client_lease *lease)
1630 {
1631 	struct option_data	 options[DHO_COUNT];
1632 	struct dhcp_packet	*packet = &ifi->sent_packet;
1633 	unsigned char		 discover = DHCPDISCOVER;
1634 	int			 i;
1635 
1636 	memset(options, 0, sizeof(options));
1637 	memset(packet, 0, sizeof(*packet));
1638 
1639 	/* Set DHCP_MESSAGE_TYPE to DHCPDISCOVER */
1640 	i = DHO_DHCP_MESSAGE_TYPE;
1641 	options[i].data = &discover;
1642 	options[i].len = sizeof(discover);
1643 
1644 	/* Request the options we want */
1645 	i  = DHO_DHCP_PARAMETER_REQUEST_LIST;
1646 	options[i].data = config->requested_options;
1647 	options[i].len = config->requested_option_count;
1648 
1649 	/* If we had an address, try to get it again. */
1650 	if (lease != NULL) {
1651 		ifi->requested_address = lease->address;
1652 		i = DHO_DHCP_REQUESTED_ADDRESS;
1653 		options[i].data = (char *)&lease->address;
1654 		options[i].len = sizeof(lease->address);
1655 	} else
1656 		ifi->requested_address.s_addr = INADDR_ANY;
1657 
1658 	/* Send any options requested in the config file. */
1659 	for (i = 0; i < DHO_COUNT; i++)
1660 		if (options[i].data == NULL &&
1661 		    config->send_options[i].data != NULL) {
1662 			options[i].data = config->send_options[i].data;
1663 			options[i].len = config->send_options[i].len;
1664 		}
1665 
1666 	/*
1667 	 * Set up the option buffer to fit in a 576-byte UDP packet, which
1668 	 * RFC 791 says is the largest packet that *MUST* be accepted
1669 	 * by any host.
1670 	 */
1671 	i = pack_options(ifi->sent_packet.options, 576 - DHCP_FIXED_LEN,
1672 	    options);
1673 	if (i == -1 || packet->options[i] != DHO_END)
1674 		fatalx("options do not fit in DHCPDISCOVER packet");
1675 	ifi->sent_packet_length = DHCP_FIXED_NON_UDP+i+1;
1676 	if (ifi->sent_packet_length < BOOTP_MIN_LEN)
1677 		ifi->sent_packet_length = BOOTP_MIN_LEN;
1678 
1679 	packet->op = BOOTREQUEST;
1680 	packet->htype = HTYPE_ETHER;
1681 	packet->hlen = ETHER_ADDR_LEN;
1682 	packet->hops = 0;
1683 	packet->xid = ifi->xid;
1684 	packet->secs = 0; /* filled in by send_discover. */
1685 	packet->flags = 0;
1686 
1687 	packet->ciaddr.s_addr = INADDR_ANY;
1688 	packet->yiaddr.s_addr = INADDR_ANY;
1689 	packet->siaddr.s_addr = INADDR_ANY;
1690 	packet->giaddr.s_addr = INADDR_ANY;
1691 
1692 	memcpy(&packet->chaddr, ifi->hw_address.ether_addr_octet,
1693 	    ETHER_ADDR_LEN);
1694 }
1695 
1696 void
make_request(struct interface_info * ifi,struct client_lease * lease)1697 make_request(struct interface_info *ifi, struct client_lease *lease)
1698 {
1699 	struct option_data	 options[DHO_COUNT];
1700 	struct dhcp_packet	*packet = &ifi->sent_packet;
1701 	unsigned char		 request = DHCPREQUEST;
1702 	int			 i;
1703 
1704 	memset(options, 0, sizeof(options));
1705 	memset(packet, 0, sizeof(*packet));
1706 
1707 	/* Set DHCP_MESSAGE_TYPE to DHCPREQUEST */
1708 	i = DHO_DHCP_MESSAGE_TYPE;
1709 	options[i].data = &request;
1710 	options[i].len = sizeof(request);
1711 
1712 	/* Request the options we want */
1713 	i = DHO_DHCP_PARAMETER_REQUEST_LIST;
1714 	options[i].data = config->requested_options;
1715 	options[i].len = config->requested_option_count;
1716 
1717 	/*
1718 	 * If we are requesting an address that hasn't yet been assigned
1719 	 * to us, use the DHCP Requested Address option.
1720 	 */
1721 	if (ifi->state == S_REQUESTING) {
1722 		/* Send back the server identifier. */
1723 		i = DHO_DHCP_SERVER_IDENTIFIER;
1724 		options[i].data = lease->options[i].data;
1725 		options[i].len = lease->options[i].len;
1726 	}
1727 	if (ifi->state == S_REQUESTING ||
1728 	    ifi->state == S_REBOOTING) {
1729 		i = DHO_DHCP_REQUESTED_ADDRESS;
1730 		options[i].data = (char *)&lease->address.s_addr;
1731 		options[i].len = sizeof(lease->address.s_addr);
1732 	}
1733 
1734 	/* Send any options requested in the config file. */
1735 	for (i = 0; i < DHO_COUNT; i++)
1736 		if (options[i].data == NULL &&
1737 		    config->send_options[i].data != NULL) {
1738 			options[i].data = config->send_options[i].data;
1739 			options[i].len = config->send_options[i].len;
1740 		}
1741 
1742 	/*
1743 	 * Set up the option buffer to fit in a 576-byte UDP packet, which
1744 	 * RFC 791 says is the largest packet that *MUST* be accepted
1745 	 * by any host.
1746 	 */
1747 	i = pack_options(ifi->sent_packet.options, 576 - DHCP_FIXED_LEN,
1748 	    options);
1749 	if (i == -1 || packet->options[i] != DHO_END)
1750 		fatalx("options do not fit in DHCPREQUEST packet");
1751 	ifi->sent_packet_length = DHCP_FIXED_NON_UDP+i+1;
1752 	if (ifi->sent_packet_length < BOOTP_MIN_LEN)
1753 		ifi->sent_packet_length = BOOTP_MIN_LEN;
1754 
1755 	packet->op = BOOTREQUEST;
1756 	packet->htype = HTYPE_ETHER;
1757 	packet->hlen = ETHER_ADDR_LEN;
1758 	packet->hops = 0;
1759 	packet->xid = ifi->xid;
1760 	packet->secs = 0; /* Filled in by send_request. */
1761 	packet->flags = 0;
1762 
1763 	/*
1764 	 * If we own the address we're requesting, put it in ciaddr. Otherwise
1765 	 * set ciaddr to zero.
1766 	 */
1767 	ifi->requested_address = lease->address;
1768 	if (ifi->state == S_BOUND ||
1769 	    ifi->state == S_RENEWING)
1770 		packet->ciaddr.s_addr = lease->address.s_addr;
1771 	else
1772 		packet->ciaddr.s_addr = INADDR_ANY;
1773 
1774 	packet->yiaddr.s_addr = INADDR_ANY;
1775 	packet->siaddr.s_addr = INADDR_ANY;
1776 	packet->giaddr.s_addr = INADDR_ANY;
1777 
1778 	memcpy(&packet->chaddr, ifi->hw_address.ether_addr_octet,
1779 	    ETHER_ADDR_LEN);
1780 }
1781 
1782 void
make_decline(struct interface_info * ifi,struct client_lease * lease)1783 make_decline(struct interface_info *ifi, struct client_lease *lease)
1784 {
1785 	struct option_data	 options[DHO_COUNT];
1786 	struct dhcp_packet	*packet = &ifi->sent_packet;
1787 	unsigned char		 decline = DHCPDECLINE;
1788 	int			 i;
1789 
1790 	memset(options, 0, sizeof(options));
1791 	memset(packet, 0, sizeof(*packet));
1792 
1793 	/* Set DHCP_MESSAGE_TYPE to DHCPDECLINE */
1794 	i = DHO_DHCP_MESSAGE_TYPE;
1795 	options[i].data = &decline;
1796 	options[i].len = sizeof(decline);
1797 
1798 	/* Send back the server identifier. */
1799 	i = DHO_DHCP_SERVER_IDENTIFIER;
1800 	options[i].data = lease->options[i].data;
1801 	options[i].len = lease->options[i].len;
1802 
1803 	/* Send back the address we're declining. */
1804 	i = DHO_DHCP_REQUESTED_ADDRESS;
1805 	options[i].data = (char *)&lease->address.s_addr;
1806 	options[i].len = sizeof(lease->address.s_addr);
1807 
1808 	/* Send the uid if the user supplied one. */
1809 	i = DHO_DHCP_CLIENT_IDENTIFIER;
1810 	if (config->send_options[i].len != 0) {
1811 		options[i].data = config->send_options[i].data;
1812 		options[i].len = config->send_options[i].len;
1813 	}
1814 
1815 	/*
1816 	 * Set up the option buffer to fit in a 576-byte UDP packet, which
1817 	 * RFC 791 says is the largest packet that *MUST* be accepted
1818 	 * by any host.
1819 	 */
1820 	i = pack_options(ifi->sent_packet.options, 576 - DHCP_FIXED_LEN,
1821 	    options);
1822 	if (i == -1 || packet->options[i] != DHO_END)
1823 		fatalx("options do not fit in DHCPDECLINE packet");
1824 	ifi->sent_packet_length = DHCP_FIXED_NON_UDP+i+1;
1825 	if (ifi->sent_packet_length < BOOTP_MIN_LEN)
1826 		ifi->sent_packet_length = BOOTP_MIN_LEN;
1827 
1828 	packet->op = BOOTREQUEST;
1829 	packet->htype = HTYPE_ETHER;
1830 	packet->hlen = ETHER_ADDR_LEN;
1831 	packet->hops = 0;
1832 	packet->xid = ifi->xid;
1833 	packet->secs = 0;
1834 	packet->flags = 0;
1835 
1836 	/* ciaddr must always be zero. */
1837 	packet->ciaddr.s_addr = INADDR_ANY;
1838 	packet->yiaddr.s_addr = INADDR_ANY;
1839 	packet->siaddr.s_addr = INADDR_ANY;
1840 	packet->giaddr.s_addr = INADDR_ANY;
1841 
1842 	memcpy(&packet->chaddr, ifi->hw_address.ether_addr_octet,
1843 	    ETHER_ADDR_LEN);
1844 }
1845 
1846 void
make_release(struct interface_info * ifi,struct client_lease * lease)1847 make_release(struct interface_info *ifi, struct client_lease *lease)
1848 {
1849 	struct option_data	 options[DHO_COUNT];
1850 	struct dhcp_packet	*packet = &ifi->sent_packet;
1851 	unsigned char		 release = DHCPRELEASE;
1852 	int			 i;
1853 
1854 	memset(options, 0, sizeof(options));
1855 	memset(packet, 0, sizeof(*packet));
1856 
1857 	/* Set DHCP_MESSAGE_TYPE to DHCPRELEASE */
1858 	i = DHO_DHCP_MESSAGE_TYPE;
1859 	options[i].data = &release;
1860 	options[i].len = sizeof(release);
1861 
1862 	/* Send back the server identifier. */
1863 	i = DHO_DHCP_SERVER_IDENTIFIER;
1864 	options[i].data = lease->options[i].data;
1865 	options[i].len = lease->options[i].len;
1866 
1867 	i = pack_options(ifi->sent_packet.options, 576 - DHCP_FIXED_LEN,
1868 	    options);
1869 	if (i == -1 || packet->options[i] != DHO_END)
1870 		fatalx("options do not fit in DHCPRELEASE packet");
1871 	ifi->sent_packet_length = DHCP_FIXED_NON_UDP+i+1;
1872 	if (ifi->sent_packet_length < BOOTP_MIN_LEN)
1873 		ifi->sent_packet_length = BOOTP_MIN_LEN;
1874 
1875 	packet->op = BOOTREQUEST;
1876 	packet->htype = HTYPE_ETHER;
1877 	packet->hlen = ETHER_ADDR_LEN;
1878 	packet->hops = 0;
1879 	packet->xid = ifi->xid;
1880 	packet->secs = 0;
1881 	packet->flags = 0;
1882 
1883 	/*
1884 	 * Note we return the *offered* address. NOT the configured address
1885 	 * which could have been changed via dhclient.conf. But the packet
1886 	 * is sent from the *configured* address.
1887 	 *
1888 	 * This might easily confuse a server, but if you play with fire
1889 	 * by modifying the address you are on your own!
1890 	 */
1891 	packet->ciaddr.s_addr = ifi->active->address.s_addr;
1892 	packet->yiaddr.s_addr = INADDR_ANY;
1893 	packet->siaddr.s_addr = INADDR_ANY;
1894 	packet->giaddr.s_addr = INADDR_ANY;
1895 
1896 	memcpy(&packet->chaddr, ifi->hw_address.ether_addr_octet,
1897 	    ETHER_ADDR_LEN);
1898 }
1899 
1900 void
free_client_lease(struct client_lease * lease)1901 free_client_lease(struct client_lease *lease)
1902 {
1903 	int	 i;
1904 
1905 	if (lease == NULL)
1906 		return;
1907 
1908 	free(lease->server_name);
1909 	free(lease->filename);
1910 	for (i = 0; i < DHO_COUNT; i++)
1911 		free(lease->options[i].data);
1912 
1913 	free(lease);
1914 }
1915 
1916 void
write_lease_db(struct interface_info * ifi)1917 write_lease_db(struct interface_info *ifi)
1918 {
1919 	struct client_lease_tq *lease_db = &ifi->lease_db;
1920 	struct client_lease	*lp, *pl;
1921 	char			*leasestr;
1922 
1923 	TAILQ_FOREACH_SAFE(lp, lease_db, next, pl) {
1924 		if (lp != ifi->active && lease_expiry(lp) == 0) {
1925 			TAILQ_REMOVE(lease_db, lp, next);
1926 			free_client_lease(lp);
1927 		}
1928 	}
1929 
1930 	if (leaseFile == NULL)
1931 		return;
1932 
1933 	rewind(leaseFile);
1934 
1935 	/*
1936 	 * The leases file is kept in chronological order, with the
1937 	 * most recently bound lease last. When the file was read
1938 	 * leases that were not expired were added to the head of the
1939 	 * TAILQ ifi->leases as they were read. Therefore write out
1940 	 * the leases in ifi->leases in reverse order to recreate
1941 	 * the chonological order required.
1942 	 */
1943 	TAILQ_FOREACH_REVERSE(lp, lease_db, client_lease_tq, next) {
1944 		leasestr = lease_as_string("lease", lp);
1945 		if (leasestr != NULL)
1946 			fprintf(leaseFile, "%s", leasestr);
1947 		else
1948 			log_warnx("%s: cannot make lease into string",
1949 			    log_procname);
1950 	}
1951 
1952 	fflush(leaseFile);
1953 	ftruncate(fileno(leaseFile), ftello(leaseFile));
1954 	fsync(fileno(leaseFile));
1955 }
1956 
1957 void
append_statement(char * string,size_t sz,char * s1,char * s2)1958 append_statement(char *string, size_t sz, char *s1, char *s2)
1959 {
1960 	strlcat(string, s1, sz);
1961 	strlcat(string, s2, sz);
1962 	strlcat(string, ";\n", sz);
1963 }
1964 
1965 struct unwind_info *
lease_as_unwind_info(struct client_lease * lease)1966 lease_as_unwind_info(struct client_lease *lease)
1967 {
1968 	struct unwind_info	*unwind_info;
1969 	struct option_data	*opt;
1970 	unsigned int		 servers;
1971 
1972 	unwind_info = calloc(1, sizeof(*unwind_info));
1973 	if (unwind_info == NULL)
1974 		fatal("unwind_info");
1975 
1976 	opt = &lease->options[DHO_DOMAIN_NAME_SERVERS];
1977 	if (opt->len != 0) {
1978 		servers = opt->len / sizeof(in_addr_t);
1979 		if (servers > MAXNS)
1980 			servers = MAXNS;
1981 		if (servers > 0) {
1982 			unwind_info->count = servers;
1983 			memcpy(unwind_info->ns, opt->data, servers *
1984 			    sizeof(in_addr_t));
1985 		}
1986 	}
1987 
1988 	if (unwind_info->count == 0) {
1989 		free(unwind_info);
1990 		unwind_info = NULL;
1991 	}
1992 
1993 	return unwind_info;
1994 }
1995 
1996 struct proposal *
lease_as_proposal(struct client_lease * lease)1997 lease_as_proposal(struct client_lease *lease)
1998 {
1999 	uint8_t			 defroute[5];	/* 1 + sizeof(in_addr_t) */
2000 	struct option_data	 fake;
2001 	struct option_data	*opt;
2002 	struct proposal		*proposal;
2003 	uint8_t			*ns, *p, *routes, *domains;
2004 	unsigned int		 routes_len = 0, domains_len = 0, ns_len = 0;
2005 	uint16_t		 mtu;
2006 
2007 	/* Determine sizes of variable length data. */
2008 	opt = NULL;
2009 	if (lease->options[DHO_CLASSLESS_STATIC_ROUTES].len != 0) {
2010 		opt = &lease->options[DHO_CLASSLESS_STATIC_ROUTES];
2011 	} else if (lease->options[DHO_CLASSLESS_MS_STATIC_ROUTES].len != 0) {
2012 		opt = &lease->options[DHO_CLASSLESS_MS_STATIC_ROUTES];
2013 	} else if (lease->options[DHO_ROUTERS].len != 0) {
2014 		/* Fake a classless static default route. */
2015 		opt = &lease->options[DHO_ROUTERS];
2016 		fake.len = sizeof(defroute);
2017 		fake.data = defroute;
2018 		fake.data[0] = 0;
2019 		memcpy(&fake.data[1], opt->data, sizeof(defroute) - 1);
2020 		opt = &fake;
2021 	}
2022 	if (opt != NULL) {
2023 		routes_len = opt->len;
2024 		routes = opt->data;
2025 	}
2026 
2027 	opt = NULL;
2028 	if (lease->options[DHO_DOMAIN_SEARCH].len != 0)
2029 		opt = &lease->options[DHO_DOMAIN_SEARCH];
2030 	else if (lease->options[DHO_DOMAIN_NAME].len != 0)
2031 		opt = &lease->options[DHO_DOMAIN_NAME];
2032 	if (opt != NULL) {
2033 		domains_len = opt->len;
2034 		domains = opt->data;
2035 	}
2036 
2037 	if (lease->options[DHO_DOMAIN_NAME_SERVERS].len != 0) {
2038 		opt = &lease->options[DHO_DOMAIN_NAME_SERVERS];
2039 		ns_len = opt->len;
2040 		ns = opt->data;
2041 	}
2042 
2043 	/* Allocate proposal. */
2044 	proposal = calloc(1, sizeof(*proposal) + routes_len + domains_len +
2045 	    ns_len);
2046 	if (proposal == NULL)
2047 		fatal("proposal");
2048 
2049 	/* Fill in proposal. */
2050 	proposal->address = lease->address;
2051 
2052 	opt = &lease->options[DHO_INTERFACE_MTU];
2053 	if (opt->len == sizeof(mtu)) {
2054 		memcpy(&mtu, opt->data, sizeof(mtu));
2055 		proposal->mtu = ntohs(mtu);
2056 	}
2057 
2058 	opt = &lease->options[DHO_SUBNET_MASK];
2059 	if (opt->len == sizeof(proposal->netmask))
2060 		memcpy(&proposal->netmask, opt->data, opt->len);
2061 
2062 	/* Append variable length uint8_t data. */
2063 	p = (uint8_t *)proposal + sizeof(struct proposal);
2064 	memcpy(p, routes, routes_len);
2065 	p += routes_len;
2066 	proposal->routes_len = routes_len;
2067 	memcpy(p, domains, domains_len);
2068 	p += domains_len;
2069 	proposal->domains_len = domains_len;
2070 	memcpy(p, ns, ns_len);
2071 	proposal->ns_len = ns_len;
2072 
2073 	return proposal;
2074 }
2075 
2076 char *
lease_as_string(char * type,struct client_lease * lease)2077 lease_as_string(char *type, struct client_lease *lease)
2078 {
2079 	static char		 string[8192];
2080 	char			 timebuf[27];	/* 6 2017/04/08 05:47:50 UTC; */
2081 	struct option_data	*opt;
2082 	struct tm		*tm;
2083 	char			*buf, *name;
2084 	time_t			 t;
2085 	size_t			 rslt;
2086 	int			 i;
2087 
2088 	memset(string, 0, sizeof(string));
2089 
2090 	strlcat(string, type, sizeof(string));
2091 	strlcat(string, " {\n", sizeof(string));
2092 	strlcat(string, BOOTP_LEASE(lease) ? "  bootp;\n" : "", sizeof(string));
2093 
2094 	append_statement(string, sizeof(string), "  fixed-address ",
2095 	    inet_ntoa(lease->address));
2096 	append_statement(string, sizeof(string), "  next-server ",
2097 	    inet_ntoa(lease->next_server));
2098 
2099 	if (lease->filename != NULL) {
2100 		buf = pretty_print_string(lease->filename,
2101 		    strlen(lease->filename), 1);
2102 		if (buf == NULL)
2103 			return NULL;
2104 		append_statement(string, sizeof(string), "  filename ", buf);
2105 	}
2106 	if (lease->server_name != NULL) {
2107 		buf = pretty_print_string(lease->server_name,
2108 		    strlen(lease->server_name), 1);
2109 		if (buf == NULL)
2110 			return NULL;
2111 		append_statement(string, sizeof(string), "  server-name ",
2112 		    buf);
2113 	}
2114 	if (lease->ssid_len != 0) {
2115 		buf = pretty_print_string(lease->ssid, lease->ssid_len, 1);
2116 		if (buf == NULL)
2117 			return NULL;
2118 		append_statement(string, sizeof(string), "  ssid ", buf);
2119 	}
2120 
2121 	for (i = 0; i < DHO_COUNT; i++) {
2122 		opt = &lease->options[i];
2123 		if (opt->len == 0)
2124 			continue;
2125 		name = code_to_name(i);
2126 
2127 		buf = pretty_print_option(i, opt, 1);
2128 		if (strlen(buf) == 0)
2129 			continue;
2130 		strlcat(string, "  option ", sizeof(string));
2131 		strlcat(string, name, sizeof(string));
2132 		append_statement(string, sizeof(string), " ", buf);
2133 	}
2134 
2135 	i = asprintf(&buf, "%lld", (long long)lease->epoch);
2136 	if (i == -1)
2137 		return NULL;
2138 	append_statement(string, sizeof(string), "  epoch ", buf);
2139 	free(buf);
2140 
2141 	t = lease->epoch + lease_renewal(lease);
2142 	if ((tm = gmtime(&t)) == NULL)
2143 		return NULL;
2144 	rslt = strftime(timebuf, sizeof(timebuf), DB_TIMEFMT, tm);
2145 	if (rslt == 0)
2146 		return NULL;
2147 	append_statement(string, sizeof(string), "  renew ", timebuf);
2148 
2149 	t = lease->epoch + lease_rebind(lease);
2150 	if ((tm = gmtime(&t)) == NULL)
2151 		return NULL;
2152 	rslt = strftime(timebuf, sizeof(timebuf), DB_TIMEFMT, tm);
2153 	if (rslt == 0)
2154 		return NULL;
2155 	append_statement(string, sizeof(string), "  rebind ", timebuf);
2156 
2157 	t = lease->epoch + lease_expiry(lease);
2158 	if ((tm = gmtime(&t)) == NULL)
2159 		return NULL;
2160 	rslt = strftime(timebuf, sizeof(timebuf), DB_TIMEFMT, tm);
2161 	if (rslt == 0)
2162 		return NULL;
2163 	append_statement(string, sizeof(string), "  expire ", timebuf);
2164 
2165 	rslt = strlcat(string, "}\n", sizeof(string));
2166 	if (rslt >= sizeof(string))
2167 		return NULL;
2168 
2169 	return string;
2170 }
2171 
2172 void
go_daemon(void)2173 go_daemon(void)
2174 {
2175 	static int	 daemonized = 0;
2176 
2177 	if ((cmd_opts & OPT_FOREGROUND) != 0 || daemonized != 0)
2178 		return;
2179 
2180 	daemonized = 1;
2181 
2182 	if (rdaemon(nullfd) == -1)
2183 		fatal("daemonize");
2184 
2185 	/* Stop logging to stderr. */
2186 	log_init(0, LOG_DAEMON);
2187 	if ((cmd_opts & OPT_VERBOSE) != 0)
2188 		log_setverbose(1);	/* Show log_debug() messages. */
2189 	log_procinit(log_procname);
2190 
2191 	setproctitle("%s", log_procname);
2192 	signal(SIGHUP, SIG_IGN);
2193 	signal(SIGPIPE, SIG_IGN);
2194 }
2195 
2196 int
rdaemon(int devnull)2197 rdaemon(int devnull)
2198 {
2199 	if (devnull == -1) {
2200 		errno = EBADF;
2201 		return -1;
2202 	}
2203 	if (fcntl(devnull, F_GETFL) == -1)
2204 		return -1;
2205 
2206 	switch (fork()) {
2207 	case -1:
2208 		return -1;
2209 	case 0:
2210 		break;
2211 	default:
2212 		_exit(0);
2213 	}
2214 
2215 	if (setsid() == -1)
2216 		return -1;
2217 
2218 	(void)dup2(devnull, STDIN_FILENO);
2219 	(void)dup2(devnull, STDOUT_FILENO);
2220 	(void)dup2(devnull, STDERR_FILENO);
2221 	if (devnull > 2)
2222 		(void)close(devnull);
2223 
2224 	return 0;
2225 }
2226 
2227 /*
2228  * resolv_conf(5) says a max of DHCP_DOMAIN_SEARCH_CNT domains and total
2229  * length of DHCP_DOMAIN_SEARCH_LEN bytes are acceptable for the 'search'
2230  * statement.
2231  */
2232 int
res_hnok_list(const char * names)2233 res_hnok_list(const char *names)
2234 {
2235 	char	*dupnames, *hn, *inputstring;
2236 	int	 count;
2237 
2238 	if (strlen(names) >= DHCP_DOMAIN_SEARCH_LEN)
2239 		return 0;
2240 
2241 	dupnames = inputstring = strdup(names);
2242 	if (inputstring == NULL)
2243 		fatal("domain name list");
2244 
2245 	count = 0;
2246 	while ((hn = strsep(&inputstring, " \t")) != NULL) {
2247 		if (strlen(hn) == 0)
2248 			continue;
2249 		if (res_hnok(hn) == 0)
2250 			break;
2251 		count++;
2252 		if (count > DHCP_DOMAIN_SEARCH_CNT)
2253 			break;
2254 	}
2255 
2256 	free(dupnames);
2257 
2258 	return count > 0 && count < 7 && hn == NULL;
2259 }
2260 
2261 /*
2262  * Decode a byte string encoding a list of domain names as specified in RFC1035
2263  * section 4.1.4.
2264  *
2265  * The result is a string consisting of a blank separated list of domain names.
2266  *
2267  * e.g.
2268  *
2269  * 3:65:6e:67:5:61:70:70:6c:65:3:63:6f:6d:0:9:6d:61:72:6b:65:74:69:6e:67:c0:04
2270  *
2271  * which represents
2272  *
2273  *    3 |'e'|'n'|'g'| 5 |'a'|'p'|'p'|'l'|
2274  *   'e'| 3 |'c'|'o'|'m'| 0 | 9 |'m'|'a'|
2275  *   'r'|'k'|'e'|'t'|'i'|'n'|'g'|xC0|x04|
2276  *
2277  * will be translated to
2278  *
2279  * "eng.apple.com. marketing.apple.com."
2280  */
2281 char *
rfc1035_as_string(unsigned char * src,size_t srclen)2282 rfc1035_as_string(unsigned char *src, size_t srclen)
2283 {
2284 	static char		 search[DHCP_DOMAIN_SEARCH_LEN];
2285 	unsigned char		 name[DHCP_DOMAIN_SEARCH_LEN];
2286 	unsigned char		*endsrc, *cp;
2287 	int			 len, domains;
2288 
2289 	memset(search, 0, sizeof(search));
2290 
2291 	/* Compute expanded length. */
2292 	domains = 0;
2293 	cp = src;
2294 	endsrc = src + srclen;
2295 
2296 	while (cp < endsrc && domains < DHCP_DOMAIN_SEARCH_CNT) {
2297 		len = dn_expand(src, endsrc, cp, name, sizeof(name));
2298 		if (len == -1)
2299 			goto bad;
2300 		cp += len;
2301 		if (domains > 0)
2302 			strlcat(search, " ", sizeof(search));
2303 		strlcat(search, name, sizeof(search));
2304 		if (strlcat(search, ".", sizeof(search)) >= sizeof(search))
2305 			goto bad;
2306 		domains++;
2307 	}
2308 
2309 	return search;
2310 
2311 bad:
2312 	memset(search, 0, sizeof(search));
2313 	return search;
2314 }
2315 
2316 void
fork_privchld(struct interface_info * ifi,int fd,int fd2)2317 fork_privchld(struct interface_info *ifi, int fd, int fd2)
2318 {
2319 	struct pollfd	 pfd[1];
2320 	struct imsgbuf	*priv_ibuf;
2321 	ssize_t		 n;
2322 	int		 ioctlfd, routefd, nfds, rslt;
2323 
2324 	switch (fork()) {
2325 	case -1:
2326 		fatal("fork");
2327 		break;
2328 	case 0:
2329 		break;
2330 	default:
2331 		return;
2332 	}
2333 
2334 	if (chdir("/") == -1)
2335 		fatal("chdir(\"/\")");
2336 
2337 	go_daemon();
2338 
2339 	free(log_procname);
2340 	rslt = asprintf(&log_procname, "%s [priv]", ifi->name);
2341 	if (rslt == -1)
2342 		fatal("log_procname");
2343 	setproctitle("%s", log_procname);
2344 	log_procinit(log_procname);
2345 
2346 	close(fd2);
2347 
2348 	if ((priv_ibuf = malloc(sizeof(*priv_ibuf))) == NULL)
2349 		fatal("priv_ibuf");
2350 
2351 	imsg_init(priv_ibuf, fd);
2352 
2353 	if ((ioctlfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
2354 		fatal("socket(AF_INET, SOCK_DGRAM)");
2355 	if ((routefd = socket(AF_ROUTE, SOCK_RAW, 0)) == -1)
2356 		fatal("socket(AF_ROUTE, SOCK_RAW)");
2357 
2358 	if (unveil(_PATH_RESCONF, "wc") == -1)
2359 		fatal("unveil %s", _PATH_RESCONF);
2360 	if (unveil("/etc/resolv.conf.tail", "r") == -1)
2361 		fatal("unveil /etc/resolve.conf.tail");
2362 	if (unveil(NULL, NULL) == -1)
2363 		fatal("unveil");
2364 
2365 	while (quit == 0) {
2366 		pfd[0].fd = priv_ibuf->fd;
2367 		pfd[0].events = POLLIN;
2368 
2369 		nfds = ppoll(pfd, 1, NULL, NULL);
2370 		if (nfds == -1) {
2371 			if (errno == EINTR)
2372 				continue;
2373 			log_warn("%s: ppoll(priv_ibuf)", log_procname);
2374 			break;
2375 		}
2376 		if ((pfd[0].revents & (POLLERR | POLLHUP | POLLNVAL)) != 0)
2377 			break;
2378 		if (nfds == 0 || (pfd[0].revents & POLLIN) == 0)
2379 			continue;
2380 
2381 		if ((n = imsg_read(priv_ibuf)) == -1 && errno != EAGAIN) {
2382 			log_warn("%s: imsg_read(priv_ibuf)", log_procname);
2383 			break;
2384 		}
2385 		if (n == 0) {
2386 			/* Connection closed - other end should log message. */
2387 			break;
2388 		}
2389 
2390 		dispatch_imsg(ifi->name, ifi->rdomain, ioctlfd, routefd,
2391 		    priv_ibuf);
2392 	}
2393 	close(routefd);
2394 	close(ioctlfd);
2395 
2396 	imsg_clear(priv_ibuf);
2397 	close(fd);
2398 
2399 	exit(1);
2400 }
2401 
2402 struct client_lease *
apply_defaults(struct client_lease * lease)2403 apply_defaults(struct client_lease *lease)
2404 {
2405 	struct option_data	 emptyopt = {0, NULL};
2406 	struct client_lease	*newlease;
2407 	char			*fmt;
2408 	int			 i;
2409 
2410 	newlease = clone_lease(lease);
2411 	if (newlease == NULL)
2412 		fatalx("unable to clone lease");
2413 
2414 	if (config->filename != NULL) {
2415 		free(newlease->filename);
2416 		newlease->filename = strdup(config->filename);
2417 		if (newlease->filename == NULL)
2418 			fatal("strdup(config->filename)");
2419 	}
2420 	if (config->server_name != NULL) {
2421 		free(newlease->server_name);
2422 		newlease->server_name = strdup(config->server_name);
2423 		if (newlease->server_name == NULL)
2424 			fatal("strdup(config->server_name)");
2425 	}
2426 	if (config->address.s_addr != INADDR_ANY)
2427 		newlease->address.s_addr = config->address.s_addr;
2428 	if (config->next_server.s_addr != INADDR_ANY)
2429 		newlease->next_server.s_addr = config->next_server.s_addr;
2430 
2431 	for (i = 0; i < DHO_COUNT; i++) {
2432 		fmt = code_to_format(i);
2433 		switch (config->default_actions[i]) {
2434 		case ACTION_IGNORE:
2435 			merge_option_data(fmt, &emptyopt, &emptyopt,
2436 			    &newlease->options[i]);
2437 			break;
2438 
2439 		case ACTION_SUPERSEDE:
2440 			merge_option_data(fmt, &config->defaults[i], &emptyopt,
2441 			    &newlease->options[i]);
2442 			break;
2443 
2444 		case ACTION_PREPEND:
2445 			merge_option_data(fmt, &config->defaults[i],
2446 			    &lease->options[i], &newlease->options[i]);
2447 			break;
2448 
2449 		case ACTION_APPEND:
2450 			merge_option_data(fmt, &lease->options[i],
2451 			    &config->defaults[i], &newlease->options[i]);
2452 			break;
2453 
2454 		case ACTION_DEFAULT:
2455 			if (newlease->options[i].len == 0)
2456 				merge_option_data(fmt, &config->defaults[i],
2457 				    &emptyopt, &newlease->options[i]);
2458 			break;
2459 
2460 		default:
2461 			break;
2462 		}
2463 	}
2464 
2465 	if (newlease->options[DHO_STATIC_ROUTES].len != 0) {
2466 		log_debug("%s: DHO_STATIC_ROUTES (option 33) not supported",
2467 		    log_procname);
2468 		free(newlease->options[DHO_STATIC_ROUTES].data);
2469 		newlease->options[DHO_STATIC_ROUTES].data = NULL;
2470 		newlease->options[DHO_STATIC_ROUTES].len = 0;
2471 	}
2472 
2473 	/*
2474 	 * RFC 3442 says client *MUST* ignore DHO_ROUTERS
2475 	 * when DHO_CLASSLESS_[MS_]_ROUTES present.
2476 	 */
2477 	if ((newlease->options[DHO_CLASSLESS_MS_STATIC_ROUTES].len != 0) ||
2478 	    (newlease->options[DHO_CLASSLESS_STATIC_ROUTES].len != 0)) {
2479 		free(newlease->options[DHO_ROUTERS].data);
2480 		newlease->options[DHO_ROUTERS].data = NULL;
2481 		newlease->options[DHO_ROUTERS].len = 0;
2482 	}
2483 
2484 	return newlease;
2485 }
2486 
2487 struct client_lease *
clone_lease(struct client_lease * oldlease)2488 clone_lease(struct client_lease *oldlease)
2489 {
2490 	struct client_lease	*newlease;
2491 	int			 i;
2492 
2493 	newlease = calloc(1, sizeof(*newlease));
2494 	if (newlease == NULL)
2495 		goto cleanup;
2496 
2497 	newlease->epoch = oldlease->epoch;
2498 	newlease->address = oldlease->address;
2499 	newlease->next_server = oldlease->next_server;
2500 	memcpy(newlease->ssid, oldlease->ssid, sizeof(newlease->ssid));
2501 	newlease->ssid_len = oldlease->ssid_len;
2502 
2503 	if (oldlease->server_name != NULL) {
2504 		newlease->server_name = strdup(oldlease->server_name);
2505 		if (newlease->server_name == NULL)
2506 			goto cleanup;
2507 	}
2508 	if (oldlease->filename != NULL) {
2509 		newlease->filename = strdup(oldlease->filename);
2510 		if (newlease->filename == NULL)
2511 			goto cleanup;
2512 	}
2513 
2514 	for (i = 0; i < DHO_COUNT; i++) {
2515 		if (oldlease->options[i].len == 0)
2516 			continue;
2517 		newlease->options[i].len = oldlease->options[i].len;
2518 		newlease->options[i].data = calloc(1,
2519 		    newlease->options[i].len);
2520 		if (newlease->options[i].data == NULL)
2521 			goto cleanup;
2522 		memcpy(newlease->options[i].data, oldlease->options[i].data,
2523 		    newlease->options[i].len);
2524 	}
2525 
2526 	return newlease;
2527 
2528 cleanup:
2529 	free_client_lease(newlease);
2530 
2531 	return NULL;
2532 }
2533 
2534 int
autoconf(struct interface_info * ifi)2535 autoconf(struct interface_info *ifi)
2536 {
2537 	struct ifreq            ifr;
2538 	int			ioctlfd;
2539 
2540 	if ((ioctlfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
2541 		fatal("socket(AF_INET, SOCK_DGRAM)");
2542 
2543 	memset(&ifr, 0, sizeof(ifr));
2544 	strlcpy(ifr.ifr_name, ifi->name, sizeof(ifr.ifr_name));
2545 
2546 	if (ioctl(ioctlfd, SIOCGIFXFLAGS, (caddr_t)&ifr) < 0)
2547 		fatal("SIOGIFXFLAGS");
2548 
2549 	close(ioctlfd);
2550 
2551 	return ifr.ifr_flags & IFXF_AUTOCONF4;
2552 }
2553 
2554 int
take_charge(struct interface_info * ifi,int routefd,char * leasespath)2555 take_charge(struct interface_info *ifi, int routefd, char *leasespath)
2556 {
2557 	const struct timespec	 max_timeout = { 9, 0 };
2558 	const struct timespec	 resend_intvl = { 3, 0 };
2559 	const struct timespec	 leasefile_intvl = { 0, 3000000 };
2560 	struct timespec		 now, resend, stop, timeout;
2561 	struct pollfd		 fds[1];
2562 	struct rt_msghdr	 rtm;
2563 	int			 fd, nfds;
2564 
2565 	clock_gettime(CLOCK_MONOTONIC, &now);
2566 	resend = now;
2567 	timespecadd(&now, &max_timeout, &stop);
2568 
2569 	/*
2570 	 * Send RTM_PROPOSAL with RTF_PROTO3 set.
2571 	 *
2572 	 * When it comes back, we're in charge and other dhclients are
2573 	 * dead processes walking.
2574 	 */
2575 	memset(&rtm, 0, sizeof(rtm));
2576 
2577 	rtm.rtm_version = RTM_VERSION;
2578 	rtm.rtm_type = RTM_PROPOSAL;
2579 	rtm.rtm_msglen = sizeof(rtm);
2580 	rtm.rtm_tableid = ifi->rdomain;
2581 	rtm.rtm_index = ifi->index;
2582 	rtm.rtm_priority = RTP_PROPOSAL_DHCLIENT;
2583 	rtm.rtm_addrs = 0;
2584 	rtm.rtm_flags = RTF_UP | RTF_PROTO3;
2585 
2586 	for (fd = -1; fd == -1 && quit != TERMINATE;) {
2587 		clock_gettime(CLOCK_MONOTONIC, &now);
2588 		if (timespeccmp(&now, &stop, >=))
2589 			fatalx("failed to take charge");
2590 
2591 		if ((ifi->flags & IFI_IN_CHARGE) == 0) {
2592 			if (timespeccmp(&now, &resend, >=)) {
2593 				timespecadd(&resend, &resend_intvl, &resend);
2594 				rtm.rtm_seq = ifi->xid = arc4random();
2595 				if (write(routefd, &rtm, sizeof(rtm)) == -1)
2596 					fatal("write(routefd)");
2597 			}
2598 			timespecsub(&resend, &now, &timeout);
2599 		} else {
2600 			/*
2601 			 * Keep trying to open leasefile in 3ms intervals
2602 			 * while continuing to process any RTM_* messages
2603 			 * that come in.
2604 			 */
2605 			 timeout = leasefile_intvl;
2606 		}
2607 
2608 		fds[0].fd = routefd;
2609 		fds[0].events = POLLIN;
2610 		nfds = ppoll(fds, 1, &timeout, NULL);
2611 		if (nfds == -1) {
2612 			if (errno == EINTR)
2613 				continue;
2614 			fatal("ppoll(routefd)");
2615 		}
2616 
2617 		if ((fds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) != 0)
2618 			fatalx("routefd: ERR|HUP|NVAL");
2619 		if (nfds == 1 && (fds[0].revents & POLLIN) == POLLIN)
2620 			routefd_handler(ifi, routefd);
2621 
2622 		if (quit != TERMINATE && (ifi->flags & IFI_IN_CHARGE) == IFI_IN_CHARGE) {
2623 			fd = open(leasespath, O_NONBLOCK |
2624 			    O_RDONLY|O_EXLOCK|O_CREAT|O_NOFOLLOW, 0640);
2625 			if (fd == -1 && errno != EWOULDBLOCK)
2626 				break;
2627 		}
2628 	}
2629 
2630 	return fd;
2631 }
2632 
2633 struct client_lease *
get_recorded_lease(struct interface_info * ifi)2634 get_recorded_lease(struct interface_info *ifi)
2635 {
2636 	char			 ifname[IF_NAMESIZE];
2637 	struct client_lease	*lp;
2638 	int			 i;
2639 
2640 	/* Update on-disk db, which clears out expired leases. */
2641 	ifi->active = NULL;
2642 	write_lease_db(ifi);
2643 
2644 	/* Run through the list of leases and see if one can be used. */
2645 	i = DHO_DHCP_CLIENT_IDENTIFIER;
2646 	TAILQ_FOREACH(lp, &ifi->lease_db, next) {
2647 		if (lp->ssid_len != ifi->ssid_len)
2648 			continue;
2649 		if (memcmp(lp->ssid, ifi->ssid, lp->ssid_len) != 0)
2650 			continue;
2651 		if ((lp->options[i].len != 0) && ((lp->options[i].len !=
2652 		    config->send_options[i].len) ||
2653 		    memcmp(lp->options[i].data, config->send_options[i].data,
2654 		    lp->options[i].len) != 0))
2655 			continue;
2656 		if (addressinuse(ifi->name, lp->address, ifname) != 0 &&
2657 		    strncmp(ifname, ifi->name, IF_NAMESIZE) != 0)
2658 			continue;
2659 		break;
2660 	}
2661 
2662 	return lp;
2663 }
2664 
2665 time_t
lease_expiry(struct client_lease * lease)2666 lease_expiry(struct client_lease *lease)
2667 {
2668 	time_t		cur_time;
2669 	uint32_t	expiry;
2670 
2671 	time(&cur_time);
2672 	expiry = 0;
2673 	if (lease->options[DHO_DHCP_LEASE_TIME].len == sizeof(expiry)) {
2674 		memcpy(&expiry, lease->options[DHO_DHCP_LEASE_TIME].data,
2675 		    sizeof(expiry));
2676 		expiry = ntohl(expiry);
2677 		if (expiry < 60)
2678 			expiry = 60;
2679 	}
2680 	expiry = lease->epoch + expiry - cur_time;
2681 
2682 	return (expiry > 0) ? expiry : 0;
2683 }
2684 
2685 time_t
lease_renewal(struct client_lease * lease)2686 lease_renewal(struct client_lease *lease)
2687 {
2688 	time_t		 cur_time, expiry;
2689 	uint32_t	 renewal;
2690 
2691 	time(&cur_time);
2692 	expiry = lease_expiry(lease);
2693 
2694 	renewal = expiry / 2;
2695 	if (lease->options[DHO_DHCP_RENEWAL_TIME].len == sizeof(renewal)) {
2696 		memcpy(&renewal, lease->options[DHO_DHCP_RENEWAL_TIME].data,
2697 		    sizeof(renewal));
2698 		renewal = ntohl(renewal);
2699 	}
2700 	renewal = lease->epoch + renewal - cur_time;
2701 
2702 	return (renewal > 0) ? renewal : 0;
2703 }
2704 
2705 time_t
lease_rebind(struct client_lease * lease)2706 lease_rebind(struct client_lease *lease)
2707 {
2708 	time_t		cur_time, expiry;
2709 	uint32_t	rebind;
2710 
2711 	time(&cur_time);
2712 	expiry = lease_expiry(lease);
2713 
2714 	rebind = (expiry / 8) * 7;
2715 	if (lease->options[DHO_DHCP_REBINDING_TIME].len == sizeof(rebind)) {
2716 		memcpy(&rebind, lease->options[DHO_DHCP_REBINDING_TIME].data,
2717 		    sizeof(rebind));
2718 		rebind = ntohl(rebind);
2719 	}
2720 	rebind = lease->epoch + rebind - cur_time;
2721 
2722 	return (rebind > 0) ? rebind : 0;
2723 }
2724 
2725 void
get_lease_timeouts(struct interface_info * ifi,struct client_lease * lease)2726 get_lease_timeouts(struct interface_info *ifi, struct client_lease *lease)
2727 {
2728 	struct timespec	now, interval;
2729 
2730 	clock_gettime(CLOCK_MONOTONIC, &now);
2731 	timespecclear(&interval);
2732 
2733 	interval.tv_sec = lease_expiry(lease);
2734 	timespecadd(&now, &interval, &ifi->expiry);
2735 
2736 	interval.tv_sec = lease_rebind(lease);
2737 	timespecadd(&now, &interval, &ifi->rebind);
2738 
2739 	interval.tv_sec = lease_renewal(lease);
2740 	timespecadd(&now, &interval, &ifi->renew);
2741 
2742 	if (timespeccmp(&ifi->rebind, &ifi->expiry, >))
2743 		ifi->rebind = ifi->expiry;
2744 	if (timespeccmp(&ifi->renew, &ifi->rebind, >))
2745 		ifi->renew = ifi->rebind;
2746 }
2747 
2748 void
tick_msg(const char * preamble,int action)2749 tick_msg(const char *preamble, int action)
2750 {
2751 	const struct timespec		grace_intvl = {3, 0};
2752 	const struct timespec		link_intvl = {config->link_interval, 0};
2753 	static struct timespec		grace, stop;
2754 	struct timespec			now;
2755 	static int			linkup, preamble_sent, sleeping;
2756 	int				printmsg;
2757 
2758 	clock_gettime(CLOCK_MONOTONIC, &now);
2759 
2760 	if (!timespecisset(&stop)) {
2761 		preamble_sent = 0;
2762 		timespecadd(&now, &link_intvl, &stop);
2763 		timespecadd(&now, &grace_intvl, &grace);
2764 		return;
2765 	}
2766 
2767 	if (isatty(STDERR_FILENO) == 0 || sleeping == 1)
2768 		printmsg = 0;	/* Already in the background. */
2769 	else if (timespeccmp(&now, &grace, <))
2770 		printmsg = 0;	/* Wait a bit before speaking. */
2771 	else if (linkup && strcmp("link", preamble) == 0)
2772 		printmsg = 0;	/* One 'got link' is enough for anyone. */
2773 	else if (log_getverbose())
2774 		printmsg = 0;	/* Verbose has sufficent verbiage. */
2775 	else
2776 		printmsg = 1;
2777 
2778 	if (timespeccmp(&now, &stop, >=)) {
2779 		if (action == TICK_WAIT)
2780 			action = TICK_DAEMON;
2781 		if (linkup == 0) {
2782 			log_debug("%s: link timeout (%lld seconds) expired",
2783 			    log_procname, (long long)link_intvl.tv_sec);
2784 			linkup = 1;
2785 		}
2786 	}
2787 
2788 	if (printmsg && preamble_sent == 0) {
2789 		fprintf(stderr, "%s: no %s...", log_procname, preamble);
2790 		preamble_sent = 1;
2791 	}
2792 
2793 	switch (action) {
2794 	case TICK_SUCCESS:
2795 		if (printmsg)
2796 			fprintf(stderr, "got %s\n", preamble);
2797 		preamble_sent = 0;
2798 		if (strcmp("link", preamble) == 0) {
2799 			linkup = 1;
2800 			/* New silent period for "no lease ... got lease". */
2801 			timespecadd(&now, &grace_intvl, &grace);
2802 		}
2803 		break;
2804 	case TICK_WAIT:
2805 		if (printmsg)
2806 			fprintf(stderr, ".");
2807 		break;
2808 	case TICK_DAEMON:
2809 		if (printmsg)
2810 			fprintf(stderr, "sleeping\n");
2811 		go_daemon();
2812 		sleeping = 1;	/* OPT_FOREGROUND means isatty() == 1! */
2813 		break;
2814 	default:
2815 		break;
2816 	}
2817 
2818 	if (printmsg)
2819 		fflush(stderr);
2820 }
2821 
2822 /*
2823  * Release the lease used to configure the interface.
2824  *
2825  * 1) Send DHCPRELEASE.
2826  * 2) Unconfigure address/routes/etc.
2827  * 3) Remove lease from database & write updated DB.
2828  */
2829 void
release_lease(struct interface_info * ifi)2830 release_lease(struct interface_info *ifi)
2831 {
2832 	char			 buf[INET_ADDRSTRLEN];
2833 	struct option_data	*opt;
2834 
2835 	if (ifi->configured == NULL || ifi->active == NULL)
2836 		return;	/* Nothing to release. */
2837 	strlcpy(buf, inet_ntoa(ifi->configured->address), sizeof(buf));
2838 
2839 	opt = &ifi->active->options[DHO_DHCP_SERVER_IDENTIFIER];
2840 	if (opt->len == sizeof(in_addr_t))
2841 		ifi->destination.s_addr = *(in_addr_t *)opt->data;
2842 	else
2843 		ifi->destination.s_addr = INADDR_BROADCAST;
2844 
2845 	ifi->xid = arc4random();
2846 	make_release(ifi, ifi->active);
2847 	send_release(ifi);
2848 
2849 	tell_unwind(NULL, ifi->flags);
2850 
2851 	revoke_proposal(ifi->configured);
2852 	imsg_flush(unpriv_ibuf);
2853 
2854 	TAILQ_REMOVE(&ifi->lease_db, ifi->active, next);
2855 	free_client_lease(ifi->active);
2856 	ifi->active = NULL;
2857 	write_lease_db(ifi);
2858 
2859 	free(ifi->configured);
2860 	ifi->configured = NULL;
2861 	free(ifi->unwind_info);
2862 	ifi->unwind_info = NULL;
2863 
2864 	log_warnx("%s: %s RELEASED to %s", log_procname, buf,
2865 	    inet_ntoa(ifi->destination));
2866 }
2867 
2868 void
propose_release(struct interface_info * ifi)2869 propose_release(struct interface_info *ifi)
2870 {
2871 	const struct timespec	 max_timeout = { 3, 0 };
2872 	struct timespec		 now, stop, timeout;
2873 	struct pollfd		 fds[1];
2874 	struct rt_msghdr	 rtm;
2875 	int			 nfds, routefd, rtfilter;
2876 
2877 	clock_gettime(CLOCK_MONOTONIC, &now);
2878 	timespecadd(&now, &max_timeout, &stop);
2879 
2880 	if ((routefd = socket(AF_ROUTE, SOCK_RAW, AF_INET)) == -1)
2881 		fatal("socket(AF_ROUTE, SOCK_RAW)");
2882 
2883 	rtfilter = ROUTE_FILTER(RTM_PROPOSAL);
2884 
2885 	if (setsockopt(routefd, AF_ROUTE, ROUTE_MSGFILTER,
2886 	    &rtfilter, sizeof(rtfilter)) == -1)
2887 		fatal("setsockopt(ROUTE_MSGFILTER)");
2888 	if (setsockopt(routefd, AF_ROUTE, ROUTE_TABLEFILTER, &ifi->rdomain,
2889 	    sizeof(ifi->rdomain)) == -1)
2890 		fatal("setsockopt(ROUTE_TABLEFILTER)");
2891 
2892 	memset(&rtm, 0, sizeof(rtm));
2893 	rtm.rtm_version = RTM_VERSION;
2894 	rtm.rtm_type = RTM_PROPOSAL;
2895 	rtm.rtm_msglen = sizeof(rtm);
2896 	rtm.rtm_tableid = ifi->rdomain;
2897 	rtm.rtm_index = ifi->index;
2898 	rtm.rtm_priority = RTP_PROPOSAL_DHCLIENT;
2899 	rtm.rtm_addrs = 0;
2900 	rtm.rtm_flags = RTF_UP;
2901 	rtm.rtm_flags |= RTF_PROTO2;
2902 	rtm.rtm_seq = ifi->xid = arc4random();
2903 
2904 	if (write(routefd, &rtm, sizeof(rtm)) == -1)
2905 		fatal("write(routefd)");
2906 	log_debug("%s: sent RTM_PROPOSAL to release lease", log_procname);
2907 
2908 	while (quit == 0) {
2909 		clock_gettime(CLOCK_MONOTONIC, &now);
2910 		if (timespeccmp(&now, &stop, >=))
2911 			break;
2912 		timespecsub(&stop, &now, &timeout);
2913 		fds[0].fd = routefd;
2914 		fds[0].events = POLLIN;
2915 		nfds = ppoll(fds, 1, &timeout, NULL);
2916 		if (nfds == -1) {
2917 			if (errno == EINTR)
2918 				continue;
2919 			fatal("ppoll(routefd)");
2920 		}
2921 		if ((fds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) != 0)
2922 			fatalx("routefd: ERR|HUP|NVAL");
2923 		if (nfds == 0 || (fds[0].revents & POLLIN) == 0)
2924 			continue;
2925 		routefd_handler(ifi, routefd);
2926 	}
2927 }
2928