GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: sbin/dhclient/dhclient.c Lines: 0 1240 0.0 %
Date: 2017-11-07 Branches: 0 792 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: dhclient.c,v 1.514 2017/09/28 21:25:49 krw Exp $	*/
2
3
/*
4
 * Copyright 2004 Henning Brauer <henning@openbsd.org>
5
 * Copyright (c) 1995, 1996, 1997, 1998, 1999
6
 * The Internet Software Consortium.    All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 *
12
 * 1. Redistributions of source code must retain the above copyright
13
 *    notice, this list of conditions and the following disclaimer.
14
 * 2. Redistributions in binary form must reproduce the above copyright
15
 *    notice, this list of conditions and the following disclaimer in the
16
 *    documentation and/or other materials provided with the distribution.
17
 * 3. Neither the name of The Internet Software Consortium nor the names
18
 *    of its contributors may be used to endorse or promote products derived
19
 *    from this software without specific prior written permission.
20
 *
21
 * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
22
 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
23
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25
 * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
26
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
29
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33
 * SUCH DAMAGE.
34
 *
35
 * This software has been written for the Internet Software Consortium
36
 * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
37
 * Enterprises.  To learn more about the Internet Software Consortium,
38
 * see ``http://www.vix.com/isc''.  To learn more about Vixie
39
 * Enterprises, see ``http://www.vix.com''.
40
 *
41
 * This client was substantially modified and enhanced by Elliot Poger
42
 * for use on Linux while he was working on the MosquitoNet project at
43
 * Stanford.
44
 *
45
 * The current version owes much to Elliot's Linux enhancements, but
46
 * was substantially reorganized and partially rewritten by Ted Lemon
47
 * so as to use the same networking framework that the Internet Software
48
 * Consortium DHCP server uses.   Much system-specific configuration code
49
 * was moved into a shell script so that as support for more operating
50
 * systems is added, it will not be necessary to port and maintain
51
 * system-specific configuration code to these operating systems - instead,
52
 * the shell script can invoke the native tools to accomplish the same
53
 * purpose.
54
 */
55
56
#include <sys/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 = _PATH_DHCLIENT_CONF;
99
char *path_dhclient_db = NULL;
100
char *log_procname;
101
102
char path_option_db[PATH_MAX];
103
104
int log_perror = 1;
105
int nullfd = -1;
106
int daemonize = 1;
107
108
volatile sig_atomic_t quit;
109
110
const struct in_addr inaddr_any = { INADDR_ANY };
111
const struct in_addr inaddr_broadcast = { INADDR_BROADCAST };
112
113
struct client_config *config;
114
struct imsgbuf *unpriv_ibuf;
115
116
struct proposal {
117
	uint8_t		rtstatic[RTSTATIC_LEN];
118
	uint8_t		rtsearch[RTSEARCH_LEN];
119
	uint8_t		rtdns[RTDNS_LEN];
120
	struct in_addr	ifa;
121
	struct in_addr	netmask;
122
	unsigned int	rtstatic_len;
123
	unsigned int	rtsearch_len;
124
	unsigned int	rtdns_len;
125
	int		mtu;
126
	int		addrs;
127
	int		inits;
128
};
129
130
void		 sighdlr(int);
131
void		 usage(void);
132
int		 res_hnok(const char *dn);
133
int		 res_hnok_list(const char *dn);
134
int		 addressinuse(char *, struct in_addr, char *);
135
136
void		 fork_privchld(struct interface_info *, int, int);
137
void		 get_ifname(struct interface_info *, int, char *);
138
int		 get_ifa_family(char *, int);
139
void		 interface_link_forceup(char *, int);
140
int		 interface_status(char *);
141
void		 get_hw_address(struct interface_info *);
142
143
struct client_lease *apply_defaults(struct client_lease *);
144
struct client_lease *clone_lease(struct client_lease *);
145
void		 apply_ignore_list(char *);
146
147
void set_lease_times(struct client_lease *);
148
149
void state_preboot(struct interface_info *);
150
void state_reboot(struct interface_info *);
151
void state_init(struct interface_info *);
152
void state_selecting(struct interface_info *);
153
void state_bound(struct interface_info *);
154
void state_panic(struct interface_info *);
155
156
void send_discover(struct interface_info *);
157
void send_request(struct interface_info *);
158
void send_decline(struct interface_info *);
159
160
void bind_lease(struct interface_info *);
161
162
void make_discover(struct interface_info *, struct client_lease *);
163
void make_request(struct interface_info *, struct client_lease *);
164
void make_decline(struct interface_info *, struct client_lease *);
165
166
void rewrite_client_leases(struct interface_info *);
167
void rewrite_option_db(char *, struct client_lease *, struct client_lease *);
168
char *lease_as_string(char *, char *, struct client_lease *);
169
struct proposal *lease_as_proposal(struct client_lease *);
170
void append_statement(char *, size_t, char *, char *);
171
172
struct client_lease *packet_to_lease(struct interface_info *,
173
    struct option_data *);
174
void go_daemon(const char *);
175
int rdaemon(int);
176
void	take_charge(struct interface_info *, int);
177
void	set_default_client_identifier(struct interface_info *);
178
struct client_lease *get_recorded_lease(struct interface_info *);
179
180
#define ROUNDUP(a) \
181
	((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
182
#define	ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
183
184
static FILE *leaseFile;
185
static FILE *optionDB;
186
187
void
188
sighdlr(int sig)
189
{
190
	quit = sig;
191
}
192
193
int
194
get_ifa_family(char *cp, int n)
195
{
196
	struct sockaddr		*sa;
197
	unsigned int		 i;
198
199
	for (i = 1; i; i <<= 1) {
200
		if ((i & n) != 0) {
201
			sa = (struct sockaddr *)cp;
202
			if (i == RTA_IFA)
203
				return sa->sa_family;
204
			ADVANCE(cp, sa);
205
		}
206
	}
207
208
	return AF_UNSPEC;
209
}
210
211
void
212
interface_link_forceup(char *name, int ioctlfd)
213
{
214
	struct ifreq	 ifr;
215
216
	memset(&ifr, 0, sizeof(ifr));
217
	strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
218
	if (ioctl(ioctlfd, SIOCGIFFLAGS, (caddr_t)&ifr) == -1) {
219
		log_warn("%s: SIOCGIFFLAGS", log_procname);
220
		return;
221
	}
222
223
	/* Force it up if it isn't already. */
224
	if ((ifr.ifr_flags & IFF_UP) == 0) {
225
		ifr.ifr_flags |= IFF_UP;
226
		if (ioctl(ioctlfd, SIOCSIFFLAGS, (caddr_t)&ifr) == -1) {
227
			log_warn("%s: SIOCSIFFLAGS", log_procname);
228
			return;
229
		}
230
	}
231
}
232
233
int
234
interface_status(char *name)
235
{
236
	struct ifaddrs	*ifap, *ifa;
237
	struct if_data	*ifdata;
238
	int		 ret;
239
240
	if (getifaddrs(&ifap) != 0)
241
		fatal("getifaddrs");
242
243
	for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
244
		if (strcmp(name, ifa->ifa_name) == 0 &&
245
		    (ifa->ifa_flags & IFF_LOOPBACK) == 0 &&
246
		    (ifa->ifa_flags & IFF_POINTOPOINT) == 0 &&
247
		    ifa->ifa_addr->sa_family == AF_LINK)
248
			break;
249
	}
250
251
	if (ifa == NULL ||
252
	    (ifa->ifa_flags & IFF_UP) == 0 ||
253
	    (ifa->ifa_flags & IFF_RUNNING) == 0) {
254
		ret = 0;
255
	} else {
256
		ifdata = ifa->ifa_data;
257
		ret = LINK_STATE_IS_UP(ifdata->ifi_link_state);
258
	}
259
260
	freeifaddrs(ifap);
261
	return ret;
262
}
263
264
void
265
get_hw_address(struct interface_info *ifi)
266
{
267
	struct ifaddrs		*ifap, *ifa;
268
	struct sockaddr_dl	*sdl;
269
	struct if_data		*ifdata;
270
	int			 found;
271
272
	if (getifaddrs(&ifap) != 0)
273
		fatal("getifaddrs");
274
275
	found = 0;
276
	for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
277
		if ((ifa->ifa_flags & IFF_LOOPBACK) ||
278
		    (ifa->ifa_flags & IFF_POINTOPOINT))
279
			continue;
280
281
		if (strcmp(ifi->name, ifa->ifa_name) != 0)
282
			continue;
283
		found = 1;
284
285
		if (ifa->ifa_addr->sa_family != AF_LINK)
286
			continue;
287
288
		sdl = (struct sockaddr_dl *)ifa->ifa_addr;
289
		if (sdl->sdl_type != IFT_ETHER ||
290
		    sdl->sdl_alen != ETHER_ADDR_LEN)
291
			continue;
292
293
		ifdata = ifa->ifa_data;
294
		ifi->rdomain = ifdata->ifi_rdomain;
295
296
		memcpy(ifi->hw_address.ether_addr_octet, LLADDR(sdl),
297
		    ETHER_ADDR_LEN);
298
		ifi->flags |= IFI_VALID_LLADDR;
299
	}
300
301
	if (found == 0)
302
		fatalx("no such interface");
303
304
	freeifaddrs(ifap);
305
}
306
307
void
308
routehandler(struct interface_info *ifi, int routefd)
309
{
310
	struct ether_addr		 hw;
311
	struct rt_msghdr		*rtm;
312
	struct if_msghdr		*ifm;
313
	struct if_announcemsghdr	*ifan;
314
	struct ifa_msghdr		*ifam;
315
	char				*rtmmsg;
316
	ssize_t				 n;
317
	int				 linkstat;
318
319
	rtmmsg = calloc(1, 2048);
320
	if (rtmmsg == NULL)
321
		fatal("rtmmsg");
322
323
	do {
324
		n = read(routefd, rtmmsg, 2048);
325
	} while (n == -1 && errno == EINTR);
326
	if (n == -1)
327
		goto done;
328
329
	rtm = (struct rt_msghdr *)rtmmsg;
330
	if ((size_t)n < sizeof(rtm->rtm_msglen) || n < rtm->rtm_msglen ||
331
	    rtm->rtm_version != RTM_VERSION)
332
		goto done;
333
334
	switch (rtm->rtm_type) {
335
	case RTM_PROPOSAL:
336
		if (rtm->rtm_index != ifi->index ||
337
		    rtm->rtm_priority != RTP_PROPOSAL_DHCLIENT)
338
			goto done;
339
		if ((rtm->rtm_flags & RTF_PROTO3) != 0) {
340
			if (rtm->rtm_seq == (int32_t)ifi->xid) {
341
				ifi->flags |= IFI_IN_CHARGE;
342
				goto done;
343
			} else if ((ifi->flags & IFI_IN_CHARGE) != 0)
344
				fatal("yielding responsibility");
345
		}
346
		break;
347
	case RTM_DESYNC:
348
		log_warnx("%s: RTM_DESYNC", log_procname);
349
		break;
350
	case RTM_IFINFO:
351
		ifm = (struct if_msghdr *)rtm;
352
		if (ifm->ifm_index != ifi->index)
353
			break;
354
		if ((rtm->rtm_flags & RTF_UP) == 0)
355
			fatal("down");
356
357
		if ((ifi->flags & IFI_VALID_LLADDR) != 0) {
358
			memcpy(&hw, &ifi->hw_address, sizeof(hw));
359
			get_hw_address(ifi);
360
			if (memcmp(&hw, &ifi->hw_address, sizeof(hw))) {
361
				log_warnx("%s: LLADDR changed; restarting",
362
				    log_procname);
363
				sendhup();
364
				goto done;
365
			}
366
		}
367
368
		linkstat = interface_status(ifi->name);
369
		if (linkstat != ifi->linkstat) {
370
#ifdef DEBUG
371
			log_debug("%s: link %s -> %s", log_procname,
372
			    (ifi->linkstat != 0) ? "up" : "down",
373
			    (linkstat != 0) ? "up" : "down");
374
#endif	/* DEBUG */
375
			ifi->linkstat = linkstat;
376
			if (ifi->linkstat != 0) {
377
				if (ifi->state == S_PREBOOT) {
378
					state_preboot(ifi);
379
					get_hw_address(ifi);
380
				} else {
381
					ifi->state = S_REBOOTING;
382
					state_reboot(ifi);
383
				}
384
			} else {
385
				/* No need to wait for anything but link. */
386
				cancel_timeout(ifi);
387
			}
388
		}
389
		break;
390
	case RTM_IFANNOUNCE:
391
		ifan = (struct if_announcemsghdr *)rtm;
392
		if (ifan->ifan_what == IFAN_DEPARTURE &&
393
		    ifan->ifan_index == ifi->index)
394
			fatal("departed");
395
		break;
396
	case RTM_NEWADDR:
397
	case RTM_DELADDR:
398
		/* Need to check if it is time to write resolv.conf. */
399
		ifam = (struct ifa_msghdr *)rtm;
400
		if (ifam->ifam_index != ifi->index)
401
			goto done;
402
		if (get_ifa_family((char *)ifam + ifam->ifam_hdrlen,
403
		    ifam->ifam_addrs) != AF_INET)
404
			goto done;
405
		break;
406
	default:
407
		break;
408
	}
409
410
	/* Something has happened. Try to write out the resolv.conf. */
411
	if (ifi->active != NULL && (ifi->flags & IFI_IN_CHARGE) != 0)
412
		write_resolv_conf();
413
414
done:
415
	free(rtmmsg);
416
	return;
417
}
418
419
char **saved_argv;
420
421
int
422
main(int argc, char *argv[])
423
{
424
	struct ieee80211_nwid	 nwid;
425
	struct ifreq		 ifr;
426
	struct stat		 sb;
427
	const char		*tail_path = "/etc/resolv.conf.tail";
428
	struct interface_info	*ifi;
429
	struct passwd		*pw;
430
	struct client_lease	*lp, *nlp;
431
	char			*ignore_list = NULL;
432
	ssize_t			 tailn;
433
	int			 fd, socket_fd[2];
434
	int			 rtfilter, ioctlfd, routefd, tailfd;
435
	int			 ch, q_flag, d_flag;
436
437
	saved_argv = argv;
438
439
	if (isatty(STDERR_FILENO) != 0)
440
		log_perror = 1; /* log to stderr until daemonized */
441
	else
442
		log_perror = 0; /* can't log to stderr */
443
444
	log_init(log_perror, LOG_DAEMON);
445
	log_setverbose(1);
446
447
	q_flag = d_flag = 0;
448
	while ((ch = getopt(argc, argv, "c:di:l:L:q")) != -1)
449
		switch (ch) {
450
		case 'c':
451
			path_dhclient_conf = optarg;
452
			break;
453
		case 'd':
454
			d_flag = 1;
455
			break;
456
		case 'i':
457
			ignore_list = optarg;
458
			break;
459
		case 'l':
460
			path_dhclient_db = optarg;
461
			if (lstat(path_dhclient_db, &sb) != -1) {
462
				if (S_ISREG(sb.st_mode) == 0)
463
					fatalx("'%s' is not a regular file",
464
					    path_dhclient_db);
465
			}
466
			break;
467
		case 'L':
468
			strlcat(path_option_db, optarg, PATH_MAX);
469
			if (lstat(path_option_db, &sb) != -1) {
470
				if (S_ISREG(sb.st_mode) == 0)
471
					fatalx("'%s' is not a regular file",
472
					    path_option_db);
473
			}
474
			break;
475
		case 'q':
476
			q_flag = 1;
477
			break;
478
		default:
479
			usage();
480
		}
481
482
	argc -= optind;
483
	argv += optind;
484
485
	if (argc != 1 || (q_flag != 0 && d_flag != 0))
486
		usage();
487
488
	if (d_flag != 0)
489
		daemonize = 0;
490
491
	if (q_flag != 0)
492
		log_perror = 0;
493
494
	log_init(log_perror, LOG_DAEMON);
495
496
	ifi = calloc(1, sizeof(*ifi));
497
	if (ifi == NULL)
498
		fatal("ifi");
499
	if ((ioctlfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
500
		fatal("socket(AF_INET, SOCK_DGRAM)");
501
	get_ifname(ifi, ioctlfd, argv[0]);
502
	log_procname = strdup(ifi->name);
503
	if (log_procname == NULL)
504
		fatal("log_procname");
505
	setproctitle("%s", log_procname);
506
	log_procinit(log_procname);
507
	ifi->index = if_nametoindex(ifi->name);
508
	if (ifi->index == 0)
509
		fatalx("no such interface");
510
	get_hw_address(ifi);
511
512
	tzset();
513
514
	/* Get the ssid if present. */
515
	memset(&ifr, 0, sizeof(ifr));
516
	memset(&nwid, 0, sizeof(nwid));
517
	ifr.ifr_data = (caddr_t)&nwid;
518
	strlcpy(ifr.ifr_name, ifi->name, sizeof(ifr.ifr_name));
519
	if (ioctl(ioctlfd, SIOCG80211NWID, (caddr_t)&ifr) == 0) {
520
		memset(ifi->ssid, 0, sizeof(ifi->ssid));
521
		memcpy(ifi->ssid, nwid.i_nwid, nwid.i_len);
522
		ifi->ssid_len = nwid.i_len;
523
	}
524
525
	/* Put us into the correct rdomain */
526
	if (setrtable(ifi->rdomain) == -1)
527
		fatal("setrtable(%u)", ifi->rdomain);
528
529
	if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC,
530
	    PF_UNSPEC, socket_fd) == -1)
531
		fatal("socketpair");
532
533
	if ((nullfd = open(_PATH_DEVNULL, O_RDWR, 0)) == -1)
534
		fatal("open(%s)", _PATH_DEVNULL);
535
536
	fork_privchld(ifi, socket_fd[0], socket_fd[1]);
537
538
	close(socket_fd[0]);
539
	if ((unpriv_ibuf = malloc(sizeof(*unpriv_ibuf))) == NULL)
540
		fatal("unpriv_ibuf");
541
	imsg_init(unpriv_ibuf, socket_fd[1]);
542
543
	config = calloc(1, sizeof(*config));
544
	if (config == NULL)
545
		fatal("config");
546
547
	read_client_conf(ifi->name);
548
549
	/*
550
	 * Set default client identifier, if needed, *before* reading
551
	 * the leases file! Changes to the lladdr will trigger a restart
552
	 * and go through here again.
553
	 */
554
	set_default_client_identifier(ifi);
555
556
	if ((pw = getpwnam("_dhcp")) == NULL)
557
		fatalx("no such user: _dhcp");
558
559
	if (path_dhclient_db == NULL && asprintf(&path_dhclient_db, "%s.%s",
560
	    _PATH_DHCLIENT_DB, ifi->name) == -1)
561
		fatal("path_dhclient_db");
562
563
	/* 2nd stage (post fork) config setup. */
564
	if (ignore_list != NULL)
565
		apply_ignore_list(ignore_list);
566
567
	tailfd = open(tail_path, O_RDONLY);
568
	if (tailfd == -1) {
569
		if (errno != ENOENT)
570
			fatal("open(%s)", tail_path);
571
	} else if (fstat(tailfd, &sb) == -1) {
572
		fatal("fstat(%s)", tail_path);
573
	} else {
574
		if (sb.st_size > 0 && sb.st_size < LLONG_MAX) {
575
			config->resolv_tail = calloc(1, sb.st_size + 1);
576
			if (config->resolv_tail == NULL) {
577
				fatal("%s contents", tail_path);
578
			}
579
			tailn = read(tailfd, config->resolv_tail, sb.st_size);
580
			if (tailn == -1)
581
				fatal("read(%s)", tail_path);
582
			else if (tailn == 0)
583
				fatalx("got no data from %s", tail_path);
584
			else if (tailn != sb.st_size)
585
				fatalx("short read of %s", tail_path);
586
		}
587
		close(tailfd);
588
	}
589
590
	/*
591
	 * Do the initial status check and possible force up before creating
592
	 * the routing socket. If we bounce the interface down and up while
593
	 * the routing socket is listening, the RTM_IFINFO message with the
594
	 * RTF_UP flag reset will cause premature exit.
595
	 */
596
	ifi->linkstat = interface_status(ifi->name);
597
	if (ifi->linkstat == 0)
598
		interface_link_forceup(ifi->name, ioctlfd);
599
	close(ioctlfd);
600
	ioctlfd = -1;
601
602
	if ((routefd = socket(PF_ROUTE, SOCK_RAW, AF_INET)) == -1)
603
		fatal("socket(PF_ROUTE, SOCK_RAW)");
604
605
	rtfilter = ROUTE_FILTER(RTM_PROPOSAL) | ROUTE_FILTER(RTM_IFINFO) |
606
	    ROUTE_FILTER(RTM_NEWADDR) | ROUTE_FILTER(RTM_DELADDR) |
607
	    ROUTE_FILTER(RTM_IFANNOUNCE);
608
609
	if (setsockopt(routefd, PF_ROUTE, ROUTE_MSGFILTER,
610
	    &rtfilter, sizeof(rtfilter)) == -1)
611
		fatal("setsockopt(ROUTE_MSGFILTER)");
612
	if (setsockopt(routefd, AF_ROUTE, ROUTE_TABLEFILTER, &ifi->rdomain,
613
	    sizeof(ifi->rdomain)) == -1)
614
		fatal("setsockopt(ROUTE_TABLEFILTER)");
615
616
	take_charge(ifi, routefd);
617
618
	if ((fd = open(path_dhclient_db,
619
	    O_RDONLY|O_EXLOCK|O_CREAT|O_NOFOLLOW, 0640)) == -1)
620
		fatal("open(%s)", path_dhclient_db);
621
	read_client_leases(ifi->name, &ifi->leases);
622
	if ((leaseFile = fopen(path_dhclient_db, "w")) == NULL)
623
		fatal("fopen(%s)", path_dhclient_db);
624
	rewrite_client_leases(ifi);
625
	close(fd);
626
627
	/* Add the static leases to the end of the list of available leases. */
628
	TAILQ_FOREACH_SAFE(lp, &config->static_leases, next, nlp) {
629
		TAILQ_REMOVE(&config->static_leases, lp, next);
630
		lp->is_static = 1;
631
		TAILQ_INSERT_TAIL(&ifi->leases, lp, next);
632
	}
633
634
	if (strlen(path_option_db) != 0) {
635
		if ((optionDB = fopen(path_option_db, "a")) == NULL)
636
			fatal("fopen(%s)", path_option_db);
637
	}
638
639
	/* Register the interface. */
640
	ifi->ufdesc = get_udp_sock(ifi->rdomain);
641
	ifi->bfdesc = get_bpf_sock(ifi->name);
642
	ifi->rbuf_max = configure_bpf_sock(ifi->bfdesc);
643
	ifi->rbuf = malloc(ifi->rbuf_max);
644
	if (ifi->rbuf == NULL)
645
		fatal("bpf input buffer");
646
	ifi->rbuf_offset = 0;
647
	ifi->rbuf_len = 0;
648
649
	if (chroot(_PATH_VAREMPTY) == -1)
650
		fatal("chroot(%s)", _PATH_VAREMPTY);
651
	if (chdir("/") == -1)
652
		fatal("chdir(\"/\")");
653
654
	if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1)
655
		fatal("setresgid");
656
	if (setgroups(1, &pw->pw_gid) == -1)
657
		fatal("setgroups");
658
	if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1)
659
		fatal("setresuid");
660
661
	endpwent();
662
663
	if (daemonize != 0) {
664
		if (pledge("stdio inet dns route proc flock rpath cpath wpath", NULL) == -1)
665
			fatal("pledge");
666
	} else {
667
		if (pledge("stdio inet dns route flock rpath cpath wpath", NULL) == -1)
668
			fatal("pledge");
669
	}
670
671
	time(&ifi->startup_time);
672
673
	if (ifi->linkstat != 0) {
674
		ifi->state = S_REBOOTING;
675
		state_reboot(ifi);
676
	} else {
677
		ifi->state = S_PREBOOT;
678
		state_preboot(ifi);
679
	}
680
681
	dispatch(ifi, routefd);
682
683
	/* not reached */
684
	return 0;
685
}
686
687
void
688
usage(void)
689
{
690
	extern char	*__progname;
691
692
	fprintf(stderr,
693
	    "usage: %s [-d | -q] [-c file] [-i options] [-L file] "
694
	    "[-l file] interface\n", __progname);
695
	exit(1);
696
}
697
698
void
699
state_preboot(struct interface_info *ifi)
700
{
701
	static int	 preamble;
702
	time_t		 cur_time;
703
	int		 interval;
704
705
	time(&cur_time);
706
707
	interval = cur_time - ifi->startup_time;
708
709
	ifi->linkstat = interface_status(ifi->name);
710
711
	if (log_perror != 0 && interval > 3) {
712
		if (preamble == 0 && ifi->linkstat == 0) {
713
			fprintf(stderr, "%s: no link ....", ifi->name);
714
			preamble = 1;
715
		}
716
		if (preamble != 0) {
717
			if (ifi->linkstat != 0)
718
				fprintf(stderr, " got link\n");
719
			else if (interval > config->link_timeout)
720
				fprintf(stderr, " sleeping\n");
721
			else
722
				fprintf(stderr, ".");
723
			fflush(stderr);
724
		}
725
	}
726
727
	if (ifi->linkstat != 0) {
728
		ifi->state = S_REBOOTING;
729
		set_timeout(ifi, 1, state_reboot);
730
	} else {
731
		if (interval > config->link_timeout)
732
			go_daemon(ifi->name);
733
		ifi->state = S_PREBOOT;
734
		set_timeout(ifi, 1, state_preboot);
735
	}
736
}
737
738
/*
739
 * Called when the interface link becomes active.
740
 */
741
void
742
state_reboot(struct interface_info *ifi)
743
{
744
	cancel_timeout(ifi);
745
746
	/*
747
	 * If there is no recorded lease or the lease is BOOTP then
748
	 * go straight to INIT and try to DISCOVER a new lease.
749
	 */
750
	ifi->active = get_recorded_lease(ifi);
751
	if (ifi->active == NULL || BOOTP_LEASE(ifi->active)) {
752
		ifi->state = S_INIT;
753
		state_init(ifi);
754
		return;
755
	}
756
757
	ifi->xid = arc4random();
758
	make_request(ifi, ifi->active);
759
760
	ifi->destination.s_addr = INADDR_BROADCAST;
761
	time(&ifi->first_sending);
762
	ifi->interval = 0;
763
764
	send_request(ifi);
765
}
766
767
/*
768
 * Called when a lease has completely expired and we've been unable to
769
 * renew it.
770
 */
771
void
772
state_init(struct interface_info *ifi)
773
{
774
	ifi->xid = arc4random();
775
	make_discover(ifi, ifi->active);
776
777
	ifi->destination.s_addr = INADDR_BROADCAST;
778
	ifi->state = S_SELECTING;
779
	time(&ifi->first_sending);
780
	ifi->interval = 0;
781
782
	send_discover(ifi);
783
}
784
785
/*
786
 * Called when one or more DHCPOFFER packets have been received and a
787
 * configurable period of time has passed.
788
 */
789
void
790
state_selecting(struct interface_info *ifi)
791
{
792
	struct option_data	*option;
793
794
	cancel_timeout(ifi);
795
796
	if (ifi->offer == NULL) {
797
		state_panic(ifi);
798
		return;
799
	}
800
801
	/* If it was a BOOTREPLY, we can just take the lease right now. */
802
	if (BOOTP_LEASE(ifi->offer)) {
803
		/*
804
		 * Set (unsigned 32 bit) options
805
		 *
806
		 * DHO_DHCP_LEASE_TIME (12000 seconds),
807
		 * DHO_RENEWAL_TIME (8000 seconds)
808
		 * DHO_REBINDING_TIME (10000 seconds)
809
		 *
810
		 * so bind_lease() can set the lease times. Note that the
811
		 * values must be big-endian.
812
		 */
813
		option = &ifi->offer->options[DHO_DHCP_LEASE_TIME];
814
		option->data = malloc(4);
815
		if (option->data) {
816
			option->len = 4;
817
			memcpy(option->data, "\x00\x00\x2e\xe0", 4);
818
		}
819
		option = &ifi->offer->options[DHO_DHCP_RENEWAL_TIME];
820
		option->data = malloc(4);
821
		if (option->data) {
822
			option->len = 4;
823
			memcpy(option->data, "\x00\x00\x1f\x40", 4);
824
		}
825
		option = &ifi->offer->options[DHO_DHCP_REBINDING_TIME];
826
		option->data = malloc(4);
827
		if (option->data) {
828
			option->len = 4;
829
			memcpy(option->data, "\x00\x00\x27\x10", 4);
830
		}
831
832
		ifi->state = S_REQUESTING;
833
		bind_lease(ifi);
834
835
		return;
836
	}
837
838
	ifi->destination.s_addr = INADDR_BROADCAST;
839
	ifi->state = S_REQUESTING;
840
	time(&ifi->first_sending);
841
842
	ifi->interval = 0;
843
844
	/*
845
	 * Make a DHCPREQUEST packet from the lease we picked. Keep
846
	 * the current xid, as all offers should have had the same
847
	 * one.
848
	 */
849
	make_request(ifi, ifi->offer);
850
851
	/* Toss the lease we picked - we'll get it back in a DHCPACK. */
852
	free_client_lease(ifi->offer);
853
854
	send_request(ifi);
855
}
856
857
void
858
dhcpoffer(struct interface_info *ifi, struct option_data *options, char *info)
859
{
860
	struct client_lease	*lease;
861
	time_t			 cur_time, stop_selecting;
862
863
	if (ifi->state != S_SELECTING) {
864
#ifdef DEBUG
865
		log_debug("%s: unexpected %s - state #%d", log_procname, info,
866
		    ifi->state);
867
#endif	/* DEBUG */
868
		return;
869
	}
870
871
	time(&cur_time);
872
	log_info("%s: %s", log_procname, info);
873
874
	lease = packet_to_lease(ifi, options);
875
	if (lease != NULL) {
876
		if (ifi->offer == NULL) {
877
			ifi->offer = lease;
878
		} else if (lease->address.s_addr ==
879
		    ifi->requested_address.s_addr) {
880
			free_client_lease(ifi->offer);
881
			ifi->offer = lease;
882
		}
883
		if (ifi->offer != lease) {
884
			make_decline(ifi, lease);
885
			send_decline(ifi);
886
			free_client_lease(lease);
887
		}
888
	}
889
890
	/* Figure out when we're supposed to stop selecting. */
891
	stop_selecting = ifi->first_sending + config->select_interval;
892
	if (stop_selecting <= cur_time)
893
		state_selecting(ifi);
894
	else
895
		set_timeout(ifi, stop_selecting - cur_time, state_selecting);
896
}
897
898
void
899
dhcpack(struct interface_info *ifi, struct option_data *options, char *info)
900
{
901
	struct client_lease	*lease;
902
903
	if (ifi->state != S_REBOOTING &&
904
	    ifi->state != S_REQUESTING &&
905
	    ifi->state != S_RENEWING &&
906
	    ifi->state != S_REBINDING) {
907
#ifdef DEBUG
908
		log_debug("%s: unexpected %s - state #%d", log_procname, info,
909
		    ifi->state);
910
#endif	/* DEBUG */
911
		return;
912
	}
913
914
	log_info("%s: %s", log_procname, info);
915
916
	lease = packet_to_lease(ifi, options);
917
	if (lease == NULL) {
918
		ifi->state = S_INIT;
919
		state_init(ifi);
920
		return;
921
	}
922
923
	ifi->offer = lease;
924
	memcpy(ifi->offer->ssid, ifi->ssid, sizeof(ifi->offer->ssid));
925
	ifi->offer->ssid_len = ifi->ssid_len;
926
927
	/* Stop resending DHCPREQUEST. */
928
	cancel_timeout(ifi);
929
930
	bind_lease(ifi);
931
}
932
933
void
934
dhcpnak(struct interface_info *ifi, struct option_data *options, char *info)
935
{
936
	if (ifi->state != S_REBOOTING &&
937
	    ifi->state != S_REQUESTING &&
938
	    ifi->state != S_RENEWING &&
939
	    ifi->state != S_REBINDING) {
940
#ifdef DEBUG
941
		log_debug("%s: unexpected %s - state #%d", log_procname, info,
942
		    ifi->state);
943
#endif	/* DEBUG */
944
		return;
945
	}
946
947
	if (ifi->active == NULL) {
948
#ifdef DEBUG
949
		log_debug("%s: unexpected %s - no active lease", log_procname,
950
		    info);
951
#endif	/* DEBUG */
952
		return;
953
	}
954
955
	log_info("%s: %s", log_procname, info);
956
	delete_address(ifi->active->address);
957
958
	/* XXX Do we really want to remove a NAK'd lease from the database? */
959
	if (ifi->active->is_static == 0) {
960
		TAILQ_REMOVE(&ifi->leases, ifi->active, next);
961
		free_client_lease(ifi->active);
962
	}
963
964
	ifi->active = NULL;
965
966
	/* Stop sending DHCPREQUEST packets. */
967
	cancel_timeout(ifi);
968
969
	ifi->state = S_INIT;
970
	state_init(ifi);
971
}
972
973
void
974
bind_lease(struct interface_info *ifi)
975
{
976
	struct client_lease	*lease, *pl;
977
	struct proposal		*active_proposal = NULL;
978
	struct proposal		*offered_proposal = NULL;
979
	struct proposal		*effective_proposal = NULL;
980
	time_t			 cur_time;
981
	int			 seen;
982
983
	lease = apply_defaults(ifi->offer);
984
985
	set_lease_times(lease);
986
987
	ifi->offer->expiry = lease->expiry;
988
	ifi->offer->renewal = lease->renewal;
989
	ifi->offer->rebind = lease->rebind;
990
991
	/*
992
	 * A duplicate proposal once we are responsible & S_RENEWING means we
993
	 * don't need to change the interface, routing table or resolv.conf.
994
	 */
995
	if ((ifi->flags & IFI_IN_CHARGE) && ifi->state == S_RENEWING) {
996
		active_proposal = lease_as_proposal(ifi->active);
997
		offered_proposal = lease_as_proposal(ifi->offer);
998
		if (memcmp(active_proposal, offered_proposal,
999
		    sizeof(*active_proposal)) == 0) {
1000
			ifi->active = ifi->offer;
1001
			ifi->offer = NULL;
1002
			goto newlease;
1003
		}
1004
	}
1005
1006
	/* Replace the old active lease with the accepted offer. */
1007
	ifi->active = ifi->offer;
1008
	ifi->offer = NULL;
1009
	effective_proposal = lease_as_proposal(lease);
1010
1011
	set_resolv_conf(ifi->name,
1012
	    effective_proposal->rtsearch,
1013
	    effective_proposal->rtsearch_len,
1014
	    effective_proposal->rtdns,
1015
	    effective_proposal->rtdns_len);
1016
1017
	set_mtu(effective_proposal->inits, effective_proposal->mtu);
1018
1019
	set_address(ifi->name, effective_proposal->ifa,
1020
	    effective_proposal->netmask);
1021
1022
	set_routes(effective_proposal->ifa, effective_proposal->netmask,
1023
	    effective_proposal->rtstatic, effective_proposal->rtstatic_len);
1024
1025
newlease:
1026
	write_resolv_conf();
1027
	log_info("%s: bound to %s -- renewal in %lld seconds", log_procname,
1028
	    inet_ntoa(ifi->active->address),
1029
	    (long long)(ifi->active->renewal - time(NULL)));
1030
	go_daemon(ifi->name);
1031
	rewrite_option_db(ifi->name, ifi->active, lease);
1032
	free_client_lease(lease);
1033
	free(active_proposal);
1034
	free(offered_proposal);
1035
	free(effective_proposal);
1036
1037
	/*
1038
	 * Remove previous dynamic lease(es) for this address, and any expired
1039
	 * dynamic leases.
1040
	 */
1041
	seen = 0;
1042
	time(&cur_time);
1043
	TAILQ_FOREACH_SAFE(lease, &ifi->leases, next, pl) {
1044
		if (lease->is_static != 0)
1045
			break;
1046
		if (ifi->active == NULL)
1047
			continue;
1048
		if (ifi->active->ssid_len != lease->ssid_len)
1049
			continue;
1050
		if (memcmp(ifi->active->ssid, lease->ssid, lease->ssid_len)
1051
		    != 0)
1052
			continue;
1053
		if (ifi->active == lease)
1054
			seen = 1;
1055
		else if (lease->expiry <= cur_time || lease->address.s_addr ==
1056
		    ifi->active->address.s_addr) {
1057
			TAILQ_REMOVE(&ifi->leases, lease, next);
1058
			free_client_lease(lease);
1059
		}
1060
	}
1061
	if (ifi->active->is_static == 0 && seen == 0)
1062
		TAILQ_INSERT_HEAD(&ifi->leases, ifi->active,  next);
1063
1064
	/* Write out new leases file. */
1065
	rewrite_client_leases(ifi);
1066
1067
	ifi->state = S_BOUND;
1068
1069
	/* Set timeout to start the renewal process. */
1070
	set_timeout(ifi, ifi->active->renewal - cur_time, state_bound);
1071
}
1072
1073
/*
1074
 * Called when we've successfully bound to a particular lease, but the renewal
1075
 * time on that lease has expired.  We are expected to unicast a DHCPREQUEST to
1076
 * the server that gave us our original lease.
1077
 */
1078
void
1079
state_bound(struct interface_info *ifi)
1080
{
1081
	struct option_data	*opt;
1082
	struct in_addr		*dest;
1083
1084
	ifi->xid = arc4random();
1085
	make_request(ifi, ifi->active);
1086
1087
	dest = &ifi->destination;
1088
	opt = &ifi->active->options[DHO_DHCP_SERVER_IDENTIFIER];
1089
1090
	if (opt->len == sizeof(*dest))
1091
		dest->s_addr = ((struct in_addr *)opt->data)->s_addr;
1092
	else
1093
		dest->s_addr = INADDR_BROADCAST;
1094
1095
	time(&ifi->first_sending);
1096
	ifi->interval = 0;
1097
	ifi->state = S_RENEWING;
1098
1099
	send_request(ifi);
1100
}
1101
1102
int
1103
addressinuse(char *name, struct in_addr address, char *ifname)
1104
{
1105
	struct ifaddrs		*ifap, *ifa;
1106
	struct sockaddr_in	*sin;
1107
	int			 used = 0;
1108
1109
	if (getifaddrs(&ifap) != 0) {
1110
		log_warn("%s: getifaddrs", log_procname);
1111
		return 0;
1112
	}
1113
1114
	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
1115
		if (ifa->ifa_addr == NULL ||
1116
		    ifa->ifa_addr->sa_family != AF_INET)
1117
			continue;
1118
1119
		sin = (struct sockaddr_in *)ifa->ifa_addr;
1120
		if (memcmp(&address, &sin->sin_addr, sizeof(address)) == 0) {
1121
			strlcpy(ifname, ifa->ifa_name, IF_NAMESIZE);
1122
			used = 1;
1123
			if (strncmp(ifname, name, IF_NAMESIZE) != 0)
1124
				break;
1125
		}
1126
	}
1127
1128
	freeifaddrs(ifap);
1129
	return used;
1130
}
1131
1132
/*
1133
 * Allocate a client_lease structure and initialize it from the
1134
 * parameters in the received packet.
1135
 *
1136
 * Return NULL and decline the lease if a valid lease cannot be
1137
 * constructed.
1138
 */
1139
struct client_lease *
1140
packet_to_lease(struct interface_info *ifi, struct option_data *options)
1141
{
1142
	char			 ifname[IF_NAMESIZE];
1143
	struct dhcp_packet	*packet = &ifi->recv_packet;
1144
	struct client_lease	*lease;
1145
	char			*pretty, *buf, *name;
1146
	int			 i;
1147
1148
	lease = calloc(1, sizeof(*lease));
1149
	if (lease == NULL) {
1150
		log_warn("%s: lease", log_procname);
1151
		return NULL;
1152
	}
1153
1154
	/* Copy the lease options. */
1155
	for (i = 0; i < DHO_COUNT; i++) {
1156
		if (options[i].len == 0)
1157
			continue;
1158
		name = code_to_name(i);
1159
		pretty = pretty_print_option(i, &options[i], 0);
1160
		if (strlen(pretty) == 0)
1161
			continue;
1162
		switch (i) {
1163
		case DHO_DOMAIN_SEARCH:
1164
			/* Must decode the option into text to check names. */
1165
			buf = pretty_print_domain_search(options[i].data,
1166
			    options[i].len);
1167
			if (buf == NULL || res_hnok_list(buf) == 0) {
1168
				log_warnx("%s: invalid host name in %s",
1169
				    log_procname, name);
1170
				continue;
1171
			}
1172
			break;
1173
		case DHO_DOMAIN_NAME:
1174
			/*
1175
			 * Allow deviant but historically blessed
1176
			 * practice of supplying multiple domain names
1177
			 * with DHO_DOMAIN_NAME. Thus allowing multiple
1178
			 * entries in the resolv.conf 'search' statement.
1179
			 */
1180
			if (res_hnok_list(pretty) == 0) {
1181
				log_warnx("%s: invalid host name in %s",
1182
				    log_procname, name);
1183
				continue;
1184
			}
1185
			break;
1186
		case DHO_HOST_NAME:
1187
		case DHO_NIS_DOMAIN:
1188
			if (res_hnok(pretty) == 0) {
1189
				log_warnx("%s: invalid host name in %s",
1190
				    log_procname, name);
1191
				continue;
1192
			}
1193
			break;
1194
		default:
1195
			break;
1196
		}
1197
		lease->options[i] = options[i];
1198
		options[i].data = NULL;
1199
		options[i].len = 0;
1200
	}
1201
1202
	/*
1203
	 * If this lease doesn't supply a required parameter, decline it.
1204
	 */
1205
	for (i = 0; i < config->required_option_count; i++) {
1206
		if (lease->options[config->required_options[i]].len == 0) {
1207
			name = code_to_name(i);
1208
			log_warnx("%s: %s required but missing", log_procname,
1209
			    name);
1210
			goto decline;
1211
		}
1212
	}
1213
1214
	/*
1215
	 * If this lease is trying to sell us an address we are already
1216
	 * using, decline it.
1217
	 */
1218
	lease->address.s_addr = packet->yiaddr.s_addr;
1219
	memset(ifname, 0, sizeof(ifname));
1220
	if (addressinuse(ifi->name, lease->address, ifname) != 0 &&
1221
	    strncmp(ifname, ifi->name, IF_NAMESIZE) != 0) {
1222
		log_warnx("%s: %s already configured on %s", log_procname,
1223
		    inet_ntoa(lease->address), ifname);
1224
		goto decline;
1225
	}
1226
1227
	/* Save the siaddr (a.k.a. next-server) info. */
1228
	lease->next_server.s_addr = packet->siaddr.s_addr;
1229
1230
	/* If the server name was filled out, copy it. */
1231
	if ((lease->options[DHO_DHCP_OPTION_OVERLOAD].len == 0 ||
1232
	    (lease->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 2) == 0) &&
1233
	    packet->sname[0]) {
1234
		lease->server_name = malloc(DHCP_SNAME_LEN + 1);
1235
		if (lease->server_name == NULL) {
1236
			log_warn("%s: SNAME", log_procname);
1237
			goto decline;
1238
		}
1239
		memcpy(lease->server_name, packet->sname, DHCP_SNAME_LEN);
1240
		lease->server_name[DHCP_SNAME_LEN] = '\0';
1241
		if (res_hnok(lease->server_name) == 0) {
1242
			log_warnx("%s: invalid host name in SNAME",
1243
			    log_procname);
1244
			goto decline;
1245
		}
1246
	}
1247
1248
	/* If the file name was filled out, copy it. */
1249
	if ((lease->options[DHO_DHCP_OPTION_OVERLOAD].len == 0 ||
1250
	    (lease->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 1) == 0) &&
1251
	    packet->file[0]) {
1252
		/* Don't count on the NUL terminator. */
1253
		lease->filename = malloc(DHCP_FILE_LEN + 1);
1254
		if (lease->filename == NULL) {
1255
			log_warn("%s: filename", log_procname);
1256
			goto decline;
1257
		}
1258
		memcpy(lease->filename, packet->file, DHCP_FILE_LEN);
1259
		lease->filename[DHCP_FILE_LEN] = '\0';
1260
	}
1261
	return lease;
1262
1263
decline:
1264
	make_decline(ifi, lease);
1265
	send_decline(ifi);
1266
	free_client_lease(lease);
1267
	return NULL;
1268
}
1269
1270
/*
1271
 * Send out a DHCPDISCOVER packet, and set a timeout to send out another
1272
 * one after the right interval has expired.  If we don't get an offer by
1273
 * the time we reach the panic interval, call the panic function.
1274
 */
1275
void
1276
send_discover(struct interface_info *ifi)
1277
{
1278
	struct dhcp_packet	*packet = &ifi->sent_packet;
1279
	time_t			 cur_time;
1280
	ssize_t			 rslt;
1281
	int			 interval;
1282
1283
	time(&cur_time);
1284
1285
	/* Figure out how long it's been since we started transmitting. */
1286
	interval = cur_time - ifi->first_sending;
1287
1288
	if (interval > config->timeout) {
1289
		state_panic(ifi);
1290
		return;
1291
	}
1292
1293
	/*
1294
	 * If we're supposed to increase the interval, do so.  If it's
1295
	 * currently zero (i.e., we haven't sent any packets yet), set
1296
	 * it to initial_interval; otherwise, add to it a random
1297
	 * number between zero and two times itself.  On average, this
1298
	 * means that it will double with every transmission.
1299
	 */
1300
	if (ifi->interval == 0)
1301
		ifi->interval = config->initial_interval;
1302
	else {
1303
		ifi->interval += arc4random_uniform(2 * ifi->interval);
1304
	}
1305
1306
	/* Don't backoff past cutoff. */
1307
	if (ifi->interval > config->backoff_cutoff)
1308
		ifi->interval = config->backoff_cutoff;
1309
1310
	/*
1311
	 * If the backoff would take us to the panic timeout, just use that
1312
	 * as the interval.
1313
	 */
1314
	if (cur_time + ifi->interval >
1315
	    ifi->first_sending + config->timeout)
1316
		ifi->interval = (ifi->first_sending +
1317
		    config->timeout) - cur_time + 1;
1318
1319
	/* Record the number of seconds since we started sending. */
1320
	if (interval < UINT16_MAX)
1321
		packet->secs = htons(interval);
1322
	else
1323
		packet->secs = htons(UINT16_MAX);
1324
	ifi->secs = packet->secs;
1325
1326
1327
	rslt = send_packet(ifi, inaddr_any, inaddr_broadcast, "DHCPDISCOVER");
1328
	if (rslt != -1)
1329
		log_info("%s: DHCPDISCOVER - interval %lld", log_procname,
1330
		    (long long)ifi->interval);
1331
1332
	set_timeout(ifi, ifi->interval, send_discover);
1333
}
1334
1335
/*
1336
 * Called if we haven't received any offers in a preset amount of time. When
1337
 * this happens, we try to use existing leases that haven't yet expired.
1338
 */
1339
void
1340
state_panic(struct interface_info *ifi)
1341
{
1342
	log_info("%s: no acceptable DHCPOFFERS received", log_procname);
1343
1344
	ifi->offer = get_recorded_lease(ifi);
1345
	if (ifi->offer != NULL) {
1346
		ifi->state = S_REQUESTING;
1347
		bind_lease(ifi);
1348
		return;
1349
	}
1350
1351
	/*
1352
	 * No leases were available, or what was available didn't work
1353
	 */
1354
	log_info("%s: no working leases in persistent database - sleeping",
1355
	    log_procname);
1356
	ifi->state = S_INIT;
1357
	set_timeout(ifi, config->retry_interval, state_init);
1358
	go_daemon(ifi->name);
1359
}
1360
1361
void
1362
send_request(struct interface_info *ifi)
1363
{
1364
	struct sockaddr_in	 destination;
1365
	struct in_addr		 from;
1366
	struct dhcp_packet	*packet = &ifi->sent_packet;
1367
	ssize_t			 rslt;
1368
	time_t			 cur_time;
1369
	int			 interval;
1370
1371
	time(&cur_time);
1372
1373
	/* Figure out how long it's been since we started transmitting. */
1374
	interval = cur_time - ifi->first_sending;
1375
1376
	/*
1377
	 * If we're in the INIT-REBOOT state and we've been trying longer
1378
	 * than reboot_timeout, go to INIT state and DISCOVER an address.
1379
	 *
1380
	 * In the INIT-REBOOT state, if we don't get an ACK, it
1381
	 * means either that we're on a network with no DHCP server,
1382
	 * or that our server is down.  In the latter case, assuming
1383
	 * that there is a backup DHCP server, DHCPDISCOVER will get
1384
	 * us a new address, but we could also have successfully
1385
	 * reused our old address.  In the former case, we're hosed
1386
	 * anyway.  This is not a win-prone situation.
1387
	 */
1388
	if (ifi->state == S_REBOOTING && interval >
1389
	    config->reboot_timeout) {
1390
		ifi->state = S_INIT;
1391
		cancel_timeout(ifi);
1392
		state_init(ifi);
1393
		return;
1394
	}
1395
1396
	/*
1397
	 * If the lease has expired go back to the INIT state.
1398
	 */
1399
	if (ifi->state != S_REQUESTING &&
1400
	    cur_time > ifi->active->expiry) {
1401
		ifi->active = NULL;
1402
		ifi->state = S_INIT;
1403
		state_init(ifi);
1404
		return;
1405
	}
1406
1407
	/* Do the exponential backoff. */
1408
	if (ifi->interval == 0) {
1409
		if (ifi->state == S_REBOOTING)
1410
			ifi->interval = config->reboot_timeout;
1411
		else
1412
			ifi->interval = config->initial_interval;
1413
	} else
1414
		ifi->interval += arc4random_uniform(2 * ifi->interval);
1415
1416
	/* Don't backoff past cutoff. */
1417
	if (ifi->interval > config->backoff_cutoff)
1418
		ifi->interval = config->backoff_cutoff;
1419
1420
	/*
1421
	 * If the backoff would take us to the expiry time, just set the
1422
	 * timeout to the expiry time.
1423
	 */
1424
	if (ifi->state != S_REQUESTING && cur_time + ifi->interval >
1425
	    ifi->active->expiry)
1426
		ifi->interval = ifi->active->expiry - cur_time + 1;
1427
1428
	/*
1429
	 * If the reboot timeout has expired, or the lease rebind time has
1430
	 * elapsed, or if we're not yet bound, broadcast the DHCPREQUEST rather
1431
	 * than unicasting.
1432
	 */
1433
	memset(&destination, 0, sizeof(destination));
1434
	if (ifi->state == S_REQUESTING ||
1435
	    ifi->state == S_REBOOTING ||
1436
	    cur_time > ifi->active->rebind ||
1437
	    interval > config->reboot_timeout)
1438
		destination.sin_addr.s_addr = INADDR_BROADCAST;
1439
	else
1440
		destination.sin_addr.s_addr = ifi->destination.s_addr;
1441
1442
	if (ifi->state != S_REQUESTING)
1443
		from.s_addr = ifi->active->address.s_addr;
1444
	else
1445
		from.s_addr = INADDR_ANY;
1446
1447
	/* Record the number of seconds since we started sending. */
1448
	if (ifi->state == S_REQUESTING)
1449
		packet->secs = ifi->secs;
1450
	else {
1451
		if (interval < UINT16_MAX)
1452
			packet->secs = htons(interval);
1453
		else
1454
			packet->secs = htons(UINT16_MAX);
1455
	}
1456
1457
1458
	rslt = send_packet(ifi, from, destination.sin_addr, "DHCPREQUEST");
1459
	if (rslt != -1)
1460
		log_info("%s: DHCPREQUEST to %s", log_procname,
1461
		    inet_ntoa(destination.sin_addr));
1462
1463
	set_timeout(ifi, ifi->interval, send_request);
1464
}
1465
1466
void
1467
send_decline(struct interface_info *ifi)
1468
{
1469
	ssize_t		rslt;
1470
1471
	rslt = send_packet(ifi, inaddr_any, inaddr_broadcast, "DHCPDECLINE");
1472
	if (rslt != -1)
1473
		log_info("%s: DHCPDECLINE", log_procname);
1474
}
1475
1476
void
1477
make_discover(struct interface_info *ifi, struct client_lease *lease)
1478
{
1479
	struct option_data	 options[DHO_COUNT];
1480
	struct dhcp_packet	*packet = &ifi->sent_packet;
1481
	unsigned char		 discover = DHCPDISCOVER;
1482
	int			 i;
1483
1484
	memset(options, 0, sizeof(options));
1485
	memset(packet, 0, sizeof(*packet));
1486
1487
	/* Set DHCP_MESSAGE_TYPE to DHCPDISCOVER */
1488
	i = DHO_DHCP_MESSAGE_TYPE;
1489
	options[i].data = &discover;
1490
	options[i].len = sizeof(discover);
1491
1492
	/* Request the options we want */
1493
	i  = DHO_DHCP_PARAMETER_REQUEST_LIST;
1494
	options[i].data = config->requested_options;
1495
	options[i].len = config->requested_option_count;
1496
1497
	/* If we had an address, try to get it again. */
1498
	if (lease != NULL) {
1499
		ifi->requested_address = lease->address;
1500
		i = DHO_DHCP_REQUESTED_ADDRESS;
1501
		options[i].data = (char *)&lease->address;
1502
		options[i].len = sizeof(lease->address);
1503
	} else
1504
		ifi->requested_address.s_addr = INADDR_ANY;
1505
1506
	/* Send any options requested in the config file. */
1507
	for (i = 0; i < DHO_COUNT; i++)
1508
		if (options[i].data == NULL &&
1509
		    config->send_options[i].data != NULL) {
1510
			options[i].data = config->send_options[i].data;
1511
			options[i].len = config->send_options[i].len;
1512
		}
1513
1514
	/*
1515
	 * Set up the option buffer to fit in a 576-byte UDP packet, which
1516
	 * RFC 791 says is the largest packet that *MUST* be accepted
1517
	 * by any host.
1518
	 */
1519
	i = pack_options(ifi->sent_packet.options, 576 - DHCP_FIXED_LEN,
1520
	    options);
1521
	if (i == -1 || packet->options[i] != DHO_END)
1522
		fatalx("options do not fit in DHCPDISCOVER packet");
1523
	ifi->sent_packet_length = DHCP_FIXED_NON_UDP+i+1;
1524
	if (ifi->sent_packet_length < BOOTP_MIN_LEN)
1525
		ifi->sent_packet_length = BOOTP_MIN_LEN;
1526
1527
	packet->op = BOOTREQUEST;
1528
	packet->htype = HTYPE_ETHER;
1529
	packet->hlen = ETHER_ADDR_LEN;
1530
	packet->hops = 0;
1531
	packet->xid = ifi->xid;
1532
	packet->secs = 0; /* filled in by send_discover. */
1533
	packet->flags = 0;
1534
1535
	packet->ciaddr.s_addr = INADDR_ANY;
1536
	packet->yiaddr.s_addr = INADDR_ANY;
1537
	packet->siaddr.s_addr = INADDR_ANY;
1538
	packet->giaddr.s_addr = INADDR_ANY;
1539
1540
	memcpy(&packet->chaddr, ifi->hw_address.ether_addr_octet,
1541
	    ETHER_ADDR_LEN);
1542
}
1543
1544
void
1545
make_request(struct interface_info *ifi, struct client_lease * lease)
1546
{
1547
	struct option_data	 options[DHO_COUNT];
1548
	struct dhcp_packet	*packet = &ifi->sent_packet;
1549
	unsigned char		 request = DHCPREQUEST;
1550
	int			 i;
1551
1552
	memset(options, 0, sizeof(options));
1553
	memset(packet, 0, sizeof(*packet));
1554
1555
	/* Set DHCP_MESSAGE_TYPE to DHCPREQUEST */
1556
	i = DHO_DHCP_MESSAGE_TYPE;
1557
	options[i].data = &request;
1558
	options[i].len = sizeof(request);
1559
1560
	/* Request the options we want */
1561
	i = DHO_DHCP_PARAMETER_REQUEST_LIST;
1562
	options[i].data = config->requested_options;
1563
	options[i].len = config->requested_option_count;
1564
1565
	/*
1566
	 * If we are requesting an address that hasn't yet been assigned
1567
	 * to us, use the DHCP Requested Address option.
1568
	 */
1569
	if (ifi->state == S_REQUESTING) {
1570
		/* Send back the server identifier. */
1571
		i = DHO_DHCP_SERVER_IDENTIFIER;
1572
		options[i].data = lease->options[i].data;
1573
		options[i].len = lease->options[i].len;
1574
	}
1575
	if (ifi->state == S_REQUESTING ||
1576
	    ifi->state == S_REBOOTING) {
1577
		ifi->requested_address = lease->address;
1578
		i = DHO_DHCP_REQUESTED_ADDRESS;
1579
		options[i].data = (char *)&lease->address.s_addr;
1580
		options[i].len = sizeof(lease->address.s_addr);
1581
	}
1582
1583
	/* Send any options requested in the config file. */
1584
	for (i = 0; i < DHO_COUNT; i++)
1585
		if (options[i].data == NULL &&
1586
		    config->send_options[i].data != NULL) {
1587
			options[i].data = config->send_options[i].data;
1588
			options[i].len = config->send_options[i].len;
1589
		}
1590
1591
	/*
1592
	 * Set up the option buffer to fit in a 576-byte UDP packet, which
1593
	 * RFC 791 says is the largest packet that *MUST* be accepted
1594
	 * by any host.
1595
	 */
1596
	i = pack_options(ifi->sent_packet.options, 576 - DHCP_FIXED_LEN,
1597
	    options);
1598
	if (i == -1 || packet->options[i] != DHO_END)
1599
		fatalx("options do not fit in DHCPREQUEST packet");
1600
	ifi->sent_packet_length = DHCP_FIXED_NON_UDP+i+1;
1601
	if (ifi->sent_packet_length < BOOTP_MIN_LEN)
1602
		ifi->sent_packet_length = BOOTP_MIN_LEN;
1603
1604
	packet->op = BOOTREQUEST;
1605
	packet->htype = HTYPE_ETHER;
1606
	packet->hlen = ETHER_ADDR_LEN;
1607
	packet->hops = 0;
1608
	packet->xid = ifi->xid;
1609
	packet->secs = 0; /* Filled in by send_request. */
1610
	packet->flags = 0;
1611
1612
	/*
1613
	 * If we own the address we're requesting, put it in ciaddr. Otherwise
1614
	 * set ciaddr to zero.
1615
	 */
1616
	if (ifi->state == S_BOUND ||
1617
	    ifi->state == S_RENEWING ||
1618
	    ifi->state == S_REBINDING)
1619
		packet->ciaddr.s_addr = lease->address.s_addr;
1620
	else
1621
		packet->ciaddr.s_addr = INADDR_ANY;
1622
1623
	packet->yiaddr.s_addr = INADDR_ANY;
1624
	packet->siaddr.s_addr = INADDR_ANY;
1625
	packet->giaddr.s_addr = INADDR_ANY;
1626
1627
	memcpy(&packet->chaddr, ifi->hw_address.ether_addr_octet,
1628
	    ETHER_ADDR_LEN);
1629
}
1630
1631
void
1632
make_decline(struct interface_info *ifi, struct client_lease *lease)
1633
{
1634
	struct option_data	 options[DHO_COUNT];
1635
	struct dhcp_packet	*packet = &ifi->sent_packet;
1636
	unsigned char		 decline = DHCPDECLINE;
1637
	int			 i;
1638
1639
	memset(options, 0, sizeof(options));
1640
	memset(packet, 0, sizeof(*packet));
1641
1642
	/* Set DHCP_MESSAGE_TYPE to DHCPDECLINE */
1643
	i = DHO_DHCP_MESSAGE_TYPE;
1644
	options[i].data = &decline;
1645
	options[i].len = sizeof(decline);
1646
1647
	/* Send back the server identifier. */
1648
	i = DHO_DHCP_SERVER_IDENTIFIER;
1649
	options[i].data = lease->options[i].data;
1650
	options[i].len = lease->options[i].len;
1651
1652
	/* Send back the address we're declining. */
1653
	i = DHO_DHCP_REQUESTED_ADDRESS;
1654
	options[i].data = (char *)&lease->address.s_addr;
1655
	options[i].len = sizeof(lease->address.s_addr);
1656
1657
	/* Send the uid if the user supplied one. */
1658
	i = DHO_DHCP_CLIENT_IDENTIFIER;
1659
	if (config->send_options[i].len != 0) {
1660
		options[i].data = config->send_options[i].data;
1661
		options[i].len = config->send_options[i].len;
1662
	}
1663
1664
	/*
1665
	 * Set up the option buffer to fit in a 576-byte UDP packet, which
1666
	 * RFC 791 says is the largest packet that *MUST* be accepted
1667
	 * by any host.
1668
	 */
1669
	i = pack_options(ifi->sent_packet.options, 576 - DHCP_FIXED_LEN,
1670
	    options);
1671
	if (i == -1 || packet->options[i] != DHO_END)
1672
		fatalx("options do not fit in DHCPDECLINE packet");
1673
	ifi->sent_packet_length = DHCP_FIXED_NON_UDP+i+1;
1674
	if (ifi->sent_packet_length < BOOTP_MIN_LEN)
1675
		ifi->sent_packet_length = BOOTP_MIN_LEN;
1676
1677
	packet->op = BOOTREQUEST;
1678
	packet->htype = HTYPE_ETHER;
1679
	packet->hlen = ETHER_ADDR_LEN;
1680
	packet->hops = 0;
1681
	packet->xid = ifi->xid;
1682
	packet->secs = 0;
1683
	packet->flags = 0;
1684
1685
	/* ciaddr must always be zero. */
1686
	packet->ciaddr.s_addr = INADDR_ANY;
1687
	packet->yiaddr.s_addr = INADDR_ANY;
1688
	packet->siaddr.s_addr = INADDR_ANY;
1689
	packet->giaddr.s_addr = INADDR_ANY;
1690
1691
	memcpy(&packet->chaddr, ifi->hw_address.ether_addr_octet,
1692
	    ETHER_ADDR_LEN);
1693
}
1694
1695
void
1696
free_client_lease(struct client_lease *lease)
1697
{
1698
	int	 i;
1699
1700
	/* Static leases are forever. */
1701
	if (lease == NULL || lease->is_static)
1702
		return;
1703
1704
	free(lease->server_name);
1705
	free(lease->filename);
1706
	for (i = 0; i < DHO_COUNT; i++)
1707
		free(lease->options[i].data);
1708
1709
	free(lease);
1710
}
1711
1712
void
1713
rewrite_client_leases(struct interface_info *ifi)
1714
{
1715
	struct client_lease	*lp;
1716
	char			*leasestr;
1717
	time_t			 cur_time;
1718
1719
	if (leaseFile == NULL)
1720
		fatalx("lease file not open");
1721
1722
	rewind(leaseFile);
1723
1724
	/*
1725
	 * The leases file is kept in chronological order, with the
1726
	 * most recently bound lease last. When the file was read
1727
	 * leases that were not expired were added to the head of the
1728
	 * TAILQ ifi->leases as they were read. Therefore write out
1729
	 * the leases in ifi->leases in reverse order to recreate
1730
	 * the chonological order required.
1731
	 */
1732
	time(&cur_time);
1733
	TAILQ_FOREACH_REVERSE(lp, &ifi->leases, client_lease_tq, next) {
1734
		/* Don't write out static leases from dhclient.conf. */
1735
		if (lp->is_static != 0)
1736
			continue;
1737
		if (lp->expiry <= cur_time)
1738
			continue;
1739
		leasestr = lease_as_string(ifi->name, "lease", lp);
1740
		if (leasestr != NULL)
1741
			fprintf(leaseFile, "%s", leasestr);
1742
		else
1743
			log_warnx("%s: cannot make lease into string",
1744
			    log_procname);
1745
	}
1746
1747
	fflush(leaseFile);
1748
	ftruncate(fileno(leaseFile), ftello(leaseFile));
1749
	fsync(fileno(leaseFile));
1750
}
1751
1752
void
1753
rewrite_option_db(char *name, struct client_lease *offered,
1754
    struct client_lease *effective)
1755
{
1756
	char	*leasestr;
1757
1758
	if (optionDB == NULL)
1759
		return;
1760
1761
	rewind(optionDB);
1762
1763
	leasestr = lease_as_string(name, "offered", offered);
1764
	if (leasestr != NULL)
1765
		fprintf(optionDB, "%s", leasestr);
1766
	else
1767
		log_warnx("%s: cannot make offered lease into string",
1768
		    log_procname);
1769
1770
	leasestr = lease_as_string(name, "effective", effective);
1771
	if (leasestr != NULL)
1772
		fprintf(optionDB, "%s", leasestr);
1773
	else
1774
		log_warnx("%s: cannot make effective lease into string",
1775
		    log_procname);
1776
1777
	fflush(optionDB);
1778
	ftruncate(fileno(optionDB), ftello(optionDB));
1779
	fsync(fileno(optionDB));
1780
}
1781
1782
void
1783
append_statement(char *string, size_t sz, char *s1, char *s2)
1784
{
1785
	strlcat(string, s1, sz);
1786
	strlcat(string, s2, sz);
1787
	strlcat(string, ";\n", sz);
1788
}
1789
1790
struct proposal *
1791
lease_as_proposal(struct client_lease *lease)
1792
{
1793
	struct proposal		*proposal;
1794
	struct option_data	*opt;
1795
	char			*buf;
1796
1797
	proposal = calloc(1, sizeof(*proposal));
1798
	if (proposal == NULL)
1799
		fatal("proposal");
1800
1801
	proposal->ifa = lease->address;
1802
	proposal->addrs |= RTA_IFA;
1803
1804
	opt = &lease->options[DHO_INTERFACE_MTU];
1805
	if (opt->len == sizeof(uint16_t)) {
1806
		memcpy(&proposal->mtu, opt->data, sizeof(proposal->mtu));
1807
		proposal->mtu = ntohs(proposal->mtu);
1808
		proposal->inits |= RTV_MTU;
1809
	}
1810
1811
	opt = &lease->options[DHO_SUBNET_MASK];
1812
	if (opt->len == sizeof(proposal->netmask)) {
1813
		proposal->addrs |= RTA_NETMASK;
1814
		proposal->netmask.s_addr =
1815
		    ((struct in_addr *)opt->data)->s_addr;
1816
	}
1817
1818
	if (lease->options[DHO_CLASSLESS_STATIC_ROUTES].len != 0) {
1819
		opt = &lease->options[DHO_CLASSLESS_STATIC_ROUTES];
1820
		/* XXX */
1821
		if (opt->len < sizeof(proposal->rtstatic)) {
1822
			proposal->rtstatic_len = opt->len;
1823
			memcpy(&proposal->rtstatic, opt->data, opt->len);
1824
			proposal->addrs |= RTA_STATIC;
1825
		} else
1826
			log_warnx("%s: CLASSLESS_STATIC_ROUTES too long",
1827
			    log_procname);
1828
	} else if (lease->options[DHO_CLASSLESS_MS_STATIC_ROUTES].len != 0) {
1829
		opt = &lease->options[DHO_CLASSLESS_MS_STATIC_ROUTES];
1830
		/* XXX */
1831
		if (opt->len < sizeof(proposal->rtstatic)) {
1832
			proposal->rtstatic_len = opt->len;
1833
			memcpy(&proposal->rtstatic[1], opt->data, opt->len);
1834
			proposal->addrs |= RTA_STATIC;
1835
		} else
1836
			log_warnx("%s: MS_CLASSLESS_STATIC_ROUTES too long",
1837
			    log_procname);
1838
	} else {
1839
		opt = &lease->options[DHO_ROUTERS];
1840
		if (opt->len >= sizeof(in_addr_t)) {
1841
			proposal->rtstatic_len = 1 + sizeof(in_addr_t);
1842
			proposal->rtstatic[0] = 0;
1843
			memcpy(&proposal->rtstatic[1], opt->data,
1844
			    sizeof(in_addr_t));
1845
			proposal->addrs |= RTA_STATIC;
1846
		}
1847
	}
1848
1849
	if (lease->options[DHO_DOMAIN_SEARCH].len != 0) {
1850
		opt = &lease->options[DHO_DOMAIN_SEARCH];
1851
		buf = pretty_print_domain_search(opt->data, opt->len);
1852
		if (buf == NULL )
1853
			log_warnx("%s: DOMAIN_SEARCH too long",
1854
			    log_procname);
1855
		else {
1856
			proposal->rtsearch_len = strlen(buf);
1857
			memcpy(proposal->rtsearch, buf, proposal->rtsearch_len);
1858
			proposal->addrs |= RTA_SEARCH;
1859
		}
1860
	} else if (lease->options[DHO_DOMAIN_NAME].len != 0) {
1861
		opt = &lease->options[DHO_DOMAIN_NAME];
1862
		if (opt->len < sizeof(proposal->rtsearch)) {
1863
			proposal->rtsearch_len = opt->len;
1864
			memcpy(proposal->rtsearch, opt->data, opt->len);
1865
			proposal->addrs |= RTA_SEARCH;
1866
		} else
1867
			log_warnx("%s: DOMAIN_NAME too long", log_procname);
1868
	}
1869
	if (lease->options[DHO_DOMAIN_NAME_SERVERS].len != 0) {
1870
		int servers;
1871
		opt = &lease->options[DHO_DOMAIN_NAME_SERVERS];
1872
		servers = opt->len / sizeof(in_addr_t);
1873
		if (servers > MAXNS)
1874
			servers = MAXNS;
1875
		if (servers > 0) {
1876
			proposal->addrs |= RTA_DNS;
1877
			proposal->rtdns_len = servers * sizeof(in_addr_t);
1878
			memcpy(proposal->rtdns, opt->data, proposal->rtdns_len);
1879
		}
1880
	}
1881
1882
	return proposal;
1883
}
1884
1885
char *
1886
lease_as_string(char *ifname, char *type, struct client_lease *lease)
1887
{
1888
	static char		 string[8192];
1889
	char			 timebuf[27];	/* 6 2017/04/08 05:47:50 UTC; */
1890
	struct option_data	*opt;
1891
	char			*buf, *name;
1892
	size_t			 rslt;
1893
	int			 i;
1894
1895
	memset(string, 0, sizeof(string));
1896
1897
	strlcat(string, type, sizeof(string));
1898
	strlcat(string, " {\n", sizeof(string));
1899
	strlcat(string, BOOTP_LEASE(lease) ? "  bootp;\n" : "", sizeof(string));
1900
1901
	buf = pretty_print_string(ifname, strlen(ifname), 1);
1902
	if (buf == NULL)
1903
		return NULL;
1904
	append_statement(string, sizeof(string), "  interface ", buf);
1905
1906
	append_statement(string, sizeof(string), "  fixed-address ",
1907
	    inet_ntoa(lease->address));
1908
	append_statement(string, sizeof(string), "  next-server ",
1909
	    inet_ntoa(lease->next_server));
1910
1911
	if (lease->filename != NULL) {
1912
		buf = pretty_print_string(lease->filename,
1913
		    strlen(lease->filename), 1);
1914
		if (buf == NULL)
1915
			return NULL;
1916
		append_statement(string, sizeof(string), "  filename ", buf);
1917
	}
1918
	if (lease->server_name != NULL) {
1919
		buf = pretty_print_string(lease->server_name,
1920
		    strlen(lease->server_name), 1);
1921
		if (buf == NULL)
1922
			return NULL;
1923
		append_statement(string, sizeof(string), "  server-name ",
1924
		    buf);
1925
	}
1926
	if (lease->ssid_len != 0) {
1927
		buf = pretty_print_string(lease->ssid, lease->ssid_len, 1);
1928
		if (buf == NULL)
1929
			return NULL;
1930
		append_statement(string, sizeof(string), "  ssid ", buf);
1931
	}
1932
1933
	for (i = 0; i < DHO_COUNT; i++) {
1934
		opt = &lease->options[i];
1935
		if (opt->len == 0)
1936
			continue;
1937
		name = code_to_name(i);
1938
1939
		buf = pretty_print_option(i, opt, 1);
1940
		if (buf == NULL)
1941
			return NULL;
1942
		strlcat(string, "  option ", sizeof(string));
1943
		strlcat(string, name, sizeof(string));
1944
		append_statement(string, sizeof(string), " ", buf);
1945
	}
1946
1947
	rslt = strftime(timebuf, sizeof(timebuf), DB_TIMEFMT,
1948
	    gmtime(&lease->renewal));
1949
	if (rslt == 0)
1950
		return NULL;
1951
	append_statement(string, sizeof(string), "  renew ", timebuf);
1952
1953
	rslt = strftime(timebuf, sizeof(timebuf), DB_TIMEFMT,
1954
	    gmtime(&lease->rebind));
1955
	if (rslt == 0)
1956
		return NULL;
1957
	append_statement(string, sizeof(string), "  rebind ", timebuf);
1958
1959
	rslt = strftime(timebuf, sizeof(timebuf), DB_TIMEFMT,
1960
	    gmtime(&lease->expiry));
1961
	if (rslt == 0)
1962
		return NULL;
1963
	append_statement(string, sizeof(string), "  expire ", timebuf);
1964
1965
	rslt = strlcat(string, "}\n", sizeof(string));
1966
	if (rslt >= sizeof(string))
1967
		return NULL;
1968
1969
	return string;
1970
}
1971
1972
void
1973
go_daemon(const char *name)
1974
{
1975
	static int	 state = 0;
1976
1977
	if (daemonize == 0 || state != 0)
1978
		return;
1979
1980
	state = 1;
1981
1982
	if (rdaemon(nullfd) == -1)
1983
		fatal("daemonize");
1984
1985
	/* Stop logging to stderr. */
1986
	log_perror = 0;
1987
	log_init(0, LOG_DAEMON);
1988
	log_procinit(log_procname);
1989
#ifdef DEBUG
1990
	log_setverbose(1);
1991
#else
1992
	log_setverbose(0);
1993
#endif	/* DEBUG */
1994
1995
	setproctitle("%s", log_procname);
1996
	signal(SIGHUP, sighdlr);
1997
	signal(SIGPIPE, SIG_IGN);
1998
}
1999
2000
int
2001
rdaemon(int devnull)
2002
{
2003
	if (devnull == -1) {
2004
		errno = EBADF;
2005
		return -1;
2006
	}
2007
	if (fcntl(devnull, F_GETFL) == -1)
2008
		return -1;
2009
2010
	switch (fork()) {
2011
	case -1:
2012
		return -1;
2013
	case 0:
2014
		break;
2015
	default:
2016
		_exit(0);
2017
	}
2018
2019
	if (setsid() == -1)
2020
		return -1;
2021
2022
	(void)dup2(devnull, STDIN_FILENO);
2023
	(void)dup2(devnull, STDOUT_FILENO);
2024
	(void)dup2(devnull, STDERR_FILENO);
2025
	if (devnull > 2)
2026
		(void)close(devnull);
2027
2028
	return 0;
2029
}
2030
2031
int
2032
res_hnok(const char *name)
2033
{
2034
	const char	*dn = name;
2035
	int		 pch = '.', ch = (unsigned char)*dn++;
2036
	int		 warn = 0;
2037
2038
	while (ch != '\0') {
2039
		int nch = (unsigned char)*dn++;
2040
2041
		if (ch == '.') {
2042
			;
2043
		} else if (pch == '.' || nch == '.' || nch == '\0') {
2044
			if (isalnum(ch) == 0)
2045
				return 0;
2046
		} else if (isalnum(ch) == 0 && ch != '-' && ch != '_') {
2047
			return 0;
2048
		} else if (ch == '_' && warn == 0) {
2049
			log_warnx("%s: warning: hostname %s contains an "
2050
			    "underscore which violates RFC 952", log_procname,
2051
			    name);
2052
			warn++;
2053
		}
2054
		pch = ch, ch = nch;
2055
	}
2056
	return 1;
2057
}
2058
2059
/*
2060
 * resolv_conf(5) says a max of DHCP_DOMAIN_SEARCH_CNT domains and total
2061
 * length of DHCP_DOMAIN_SEARCH_LEN bytes are acceptable for the 'search'
2062
 * statement.
2063
 */
2064
int
2065
res_hnok_list(const char *names)
2066
{
2067
	char	*dupnames, *hn, *inputstring;
2068
	int	 count;
2069
2070
	if (strlen(names) >= DHCP_DOMAIN_SEARCH_LEN)
2071
		return 0;
2072
2073
	dupnames = inputstring = strdup(names);
2074
	if (inputstring == NULL)
2075
		fatal("domain name list");
2076
2077
	count = 0;
2078
	while ((hn = strsep(&inputstring, " \t")) != NULL) {
2079
		if (strlen(hn) == 0)
2080
			continue;
2081
		if (res_hnok(hn) == 0)
2082
			break;
2083
		count++;
2084
		if (count > DHCP_DOMAIN_SEARCH_CNT)
2085
			break;
2086
	}
2087
2088
	free(dupnames);
2089
2090
	return count > 0 && count < 7 && hn == NULL;
2091
}
2092
2093
void
2094
fork_privchld(struct interface_info *ifi, int fd, int fd2)
2095
{
2096
	struct pollfd	 pfd[1];
2097
	struct imsgbuf	*priv_ibuf;
2098
	ssize_t		 n;
2099
	int		 ioctlfd, routefd, nfds, rslt;
2100
2101
	switch (fork()) {
2102
	case -1:
2103
		fatal("fork");
2104
		break;
2105
	case 0:
2106
		break;
2107
	default:
2108
		return;
2109
	}
2110
2111
	if (chdir("/") == -1)
2112
		fatal("chdir(\"/\")");
2113
2114
	go_daemon(ifi->name);
2115
2116
	if (log_procname != NULL)
2117
		free(log_procname);
2118
	rslt = asprintf(&log_procname, "%s [priv]", ifi->name);
2119
	if (rslt == -1)
2120
		fatal("log_procname");
2121
	setproctitle("%s", log_procname);
2122
	log_procinit(log_procname);
2123
2124
	close(fd2);
2125
2126
	if ((priv_ibuf = malloc(sizeof(*priv_ibuf))) == NULL)
2127
		fatal("priv_ibuf");
2128
2129
	imsg_init(priv_ibuf, fd);
2130
2131
	if ((ioctlfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
2132
		fatal("socket(AF_INET, SOCK_DGRAM)");
2133
	if ((routefd = socket(AF_ROUTE, SOCK_RAW, 0)) == -1)
2134
		fatal("socket(AF_ROUTE, SOCK_RAW)");
2135
2136
	while (quit == 0) {
2137
		pfd[0].fd = priv_ibuf->fd;
2138
		pfd[0].events = POLLIN;
2139
2140
		nfds = poll(pfd, 1, INFTIM);
2141
		if (nfds == -1) {
2142
			if (errno == EINTR)
2143
				continue;
2144
			log_warn("%s: poll(priv_ibuf)", log_procname);
2145
			quit = INTERNALSIG;
2146
			continue;
2147
		}
2148
		if ((pfd[0].revents & (POLLERR | POLLHUP | POLLNVAL)) != 0) {
2149
			quit = INTERNALSIG;
2150
			continue;
2151
		}
2152
		if (nfds == 0 || (pfd[0].revents & POLLIN) == 0)
2153
			continue;
2154
2155
		if ((n = imsg_read(priv_ibuf)) == -1 && errno != EAGAIN) {
2156
			log_warn("%s: imsg_read(priv_ibuf)", log_procname);
2157
			quit = INTERNALSIG;
2158
			continue;
2159
		}
2160
		if (n == 0) {
2161
			/* Connection closed - other end should log message. */
2162
			quit = INTERNALSIG;
2163
			continue;
2164
		}
2165
2166
		dispatch_imsg(ifi->name, ifi->rdomain, ioctlfd, routefd,
2167
		    priv_ibuf);
2168
	}
2169
	close(routefd);
2170
	close(ioctlfd);
2171
2172
	imsg_clear(priv_ibuf);
2173
	close(fd);
2174
2175
	if (quit == SIGHUP) {
2176
		log_warnx("%s: %s - restarting", log_procname, strsignal(quit));
2177
		signal(SIGHUP, SIG_IGN); /* will be restored after exec */
2178
		execvp(saved_argv[0], saved_argv);
2179
		fatal("execvp(%s)", saved_argv[0]);
2180
	}
2181
2182
	if (quit != INTERNALSIG)
2183
		fatalx("%s", strsignal(quit));
2184
2185
	exit(1);
2186
}
2187
2188
void
2189
get_ifname(struct interface_info *ifi, int ioctlfd, char *arg)
2190
{
2191
	struct ifgroupreq	 ifgr;
2192
	struct ifg_req		*ifg;
2193
	unsigned int		 len;
2194
2195
	if (strcmp(arg, "egress") == 0) {
2196
		memset(&ifgr, 0, sizeof(ifgr));
2197
		strlcpy(ifgr.ifgr_name, "egress", sizeof(ifgr.ifgr_name));
2198
		if (ioctl(ioctlfd, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1)
2199
			fatal("SIOCGIFGMEMB");
2200
		len = ifgr.ifgr_len;
2201
		if ((ifgr.ifgr_groups = calloc(1, len)) == NULL)
2202
			fatalx("ifgr_groups");
2203
		if (ioctl(ioctlfd, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1)
2204
			fatal("SIOCGIFGMEMB");
2205
2206
		arg = NULL;
2207
		for (ifg = ifgr.ifgr_groups; ifg && len >= sizeof(*ifg);
2208
		    ifg++) {
2209
			len -= sizeof(*ifg);
2210
			if (arg != NULL)
2211
				fatalx("too many interfaces in group egress");
2212
			arg = ifg->ifgrq_member;
2213
		}
2214
2215
		if (strlcpy(ifi->name, arg, IFNAMSIZ) >= IFNAMSIZ)
2216
			fatalx("interface name too long");
2217
2218
		free(ifgr.ifgr_groups);
2219
	} else if (strlcpy(ifi->name, arg, IFNAMSIZ) >= IFNAMSIZ)
2220
		fatalx("nterface name too long");
2221
}
2222
2223
struct client_lease *
2224
apply_defaults(struct client_lease *lease)
2225
{
2226
	struct client_lease	*newlease;
2227
	int			 i, j;
2228
2229
	newlease = clone_lease(lease);
2230
	if (newlease == NULL)
2231
		fatalx("unable to clone lease");
2232
2233
	if (config->filename != NULL) {
2234
		free(newlease->filename);
2235
		newlease->filename = strdup(config->filename);
2236
	}
2237
	if (config->server_name != NULL) {
2238
		free(newlease->server_name);
2239
		newlease->server_name = strdup(config->server_name);
2240
	}
2241
	if (config->address.s_addr != INADDR_ANY)
2242
		newlease->address.s_addr = config->address.s_addr;
2243
	if (config->next_server.s_addr != INADDR_ANY)
2244
		newlease->next_server.s_addr = config->next_server.s_addr;
2245
2246
	for (i = 0; i < DHO_COUNT; i++) {
2247
		for (j = 0; j < config->ignored_option_count; j++) {
2248
			if (config->ignored_options[j] == i) {
2249
				free(newlease->options[i].data);
2250
				newlease->options[i].data = NULL;
2251
				newlease->options[i].len = 0;
2252
				break;
2253
			}
2254
		}
2255
		if (j < config->ignored_option_count)
2256
			continue;
2257
2258
		switch (config->default_actions[i]) {
2259
		case ACTION_SUPERSEDE:
2260
			free(newlease->options[i].data);
2261
			newlease->options[i].len = config->defaults[i].len;
2262
			newlease->options[i].data = calloc(1,
2263
			    config->defaults[i].len);
2264
			if (newlease->options[i].data == NULL)
2265
				goto cleanup;
2266
			memcpy(newlease->options[i].data,
2267
			    config->defaults[i].data, config->defaults[i].len);
2268
			break;
2269
2270
		case ACTION_PREPEND:
2271
			free(newlease->options[i].data);
2272
			newlease->options[i].len = config->defaults[i].len +
2273
			    lease->options[i].len;
2274
			newlease->options[i].data = calloc(1,
2275
			    newlease->options[i].len);
2276
			if (newlease->options[i].data == NULL)
2277
				goto cleanup;
2278
			memcpy(newlease->options[i].data,
2279
			    config->defaults[i].data, config->defaults[i].len);
2280
			memcpy(newlease->options[i].data +
2281
			    config->defaults[i].len, lease->options[i].data,
2282
			    lease->options[i].len);
2283
			break;
2284
2285
		case ACTION_APPEND:
2286
			free(newlease->options[i].data);
2287
			newlease->options[i].len = config->defaults[i].len +
2288
			    lease->options[i].len;
2289
			newlease->options[i].data = calloc(1,
2290
			    newlease->options[i].len);
2291
			if (newlease->options[i].data == NULL)
2292
				goto cleanup;
2293
			memcpy(newlease->options[i].data,
2294
			    lease->options[i].data, lease->options[i].len);
2295
			memcpy(newlease->options[i].data +
2296
			    lease->options[i].len, config->defaults[i].data,
2297
			    config->defaults[i].len);
2298
			break;
2299
2300
		case ACTION_DEFAULT:
2301
			if ((newlease->options[i].len == 0) &&
2302
			    (config->defaults[i].len != 0)) {
2303
				newlease->options[i].len =
2304
				    config->defaults[i].len;
2305
				newlease->options[i].data = calloc(1,
2306
				    config->defaults[i].len);
2307
				if (newlease->options[i].data == NULL)
2308
					goto cleanup;
2309
				memcpy(newlease->options[i].data,
2310
				    config->defaults[i].data,
2311
				    config->defaults[i].len);
2312
			}
2313
			break;
2314
2315
		default:
2316
			break;
2317
		}
2318
	}
2319
2320
	if (newlease->options[DHO_STATIC_ROUTES].len != 0) {
2321
		log_warnx("%s: DHO_STATIC_ROUTES (option 33) not supported",
2322
		    log_procname);
2323
		free(newlease->options[DHO_STATIC_ROUTES].data);
2324
		newlease->options[DHO_STATIC_ROUTES].data = NULL;
2325
		newlease->options[DHO_STATIC_ROUTES].len = 0;
2326
	}
2327
2328
	/*
2329
	 * RFC 3442 says client *MUST* ignore DHO_ROUTERS
2330
	 * when DHO_CLASSLESS_[MS_]_ROUTES present.
2331
	 */
2332
	if ((newlease->options[DHO_CLASSLESS_MS_STATIC_ROUTES].len != 0) ||
2333
	    (newlease->options[DHO_CLASSLESS_STATIC_ROUTES].len != 0)) {
2334
		free(newlease->options[DHO_ROUTERS].data);
2335
		newlease->options[DHO_ROUTERS].data = NULL;
2336
		newlease->options[DHO_ROUTERS].len = 0;
2337
	}
2338
2339
	return newlease;
2340
2341
cleanup:
2342
	if (newlease != NULL) {
2343
		newlease->is_static = 0;
2344
		free_client_lease(newlease);
2345
	}
2346
2347
	fatalx("unable to apply defaults");
2348
	/* NOTREACHED */
2349
2350
	return NULL;
2351
}
2352
2353
struct client_lease *
2354
clone_lease(struct client_lease *oldlease)
2355
{
2356
	struct client_lease	*newlease;
2357
	int			 i;
2358
2359
	newlease = calloc(1, sizeof(*newlease));
2360
	if (newlease == NULL)
2361
		goto cleanup;
2362
2363
	newlease->expiry = oldlease->expiry;
2364
	newlease->renewal = oldlease->renewal;
2365
	newlease->rebind = oldlease->rebind;
2366
	newlease->is_static = oldlease->is_static;
2367
	newlease->address = oldlease->address;
2368
	newlease->next_server = oldlease->next_server;
2369
	memcpy(newlease->ssid, oldlease->ssid, sizeof(newlease->ssid));
2370
	newlease->ssid_len = oldlease->ssid_len;
2371
2372
	if (oldlease->server_name != NULL) {
2373
		newlease->server_name = strdup(oldlease->server_name);
2374
		if (newlease->server_name == NULL)
2375
			goto cleanup;
2376
	}
2377
	if (oldlease->filename != NULL) {
2378
		newlease->filename = strdup(oldlease->filename);
2379
		if (newlease->filename == NULL)
2380
			goto cleanup;
2381
	}
2382
2383
	for (i = 0; i < DHO_COUNT; i++) {
2384
		if (oldlease->options[i].len == 0)
2385
			continue;
2386
		newlease->options[i].len = oldlease->options[i].len;
2387
		newlease->options[i].data = calloc(1,
2388
		    newlease->options[i].len);
2389
		if (newlease->options[i].data == NULL)
2390
			goto cleanup;
2391
		memcpy(newlease->options[i].data, oldlease->options[i].data,
2392
		    newlease->options[i].len);
2393
	}
2394
2395
	return newlease;
2396
2397
cleanup:
2398
	if (newlease != NULL) {
2399
		newlease->is_static = 0;
2400
		free_client_lease(newlease);
2401
	}
2402
2403
	return NULL;
2404
}
2405
2406
/*
2407
 * Apply the list of options to be ignored that was provided on the
2408
 * command line. This will override any ignore list obtained from
2409
 * dhclient.conf.
2410
 */
2411
void
2412
apply_ignore_list(char *ignore_list)
2413
{
2414
	uint8_t		 list[DHO_COUNT];
2415
	char		*p;
2416
	int		 ix, i, j;
2417
2418
	memset(list, 0, sizeof(list));
2419
	ix = 0;
2420
2421
	for (p = strsep(&ignore_list, ", "); p != NULL;
2422
	    p = strsep(&ignore_list, ", ")) {
2423
		if (*p == '\0')
2424
			continue;
2425
2426
		i = name_to_code(p);
2427
		if (i == DHO_END) {
2428
			log_info("%s: invalid option name: '%s'", log_procname,
2429
			    p);
2430
			return;
2431
		}
2432
2433
		/* Avoid storing duplicate options in the list. */
2434
		for (j = 0; j < ix && list[j] != i; j++)
2435
			;
2436
		if (j == ix)
2437
			list[ix++] = i;
2438
	}
2439
2440
	config->ignored_option_count = ix;
2441
	memcpy(config->ignored_options, list, sizeof(config->ignored_options));
2442
}
2443
2444
void
2445
set_lease_times(struct client_lease *lease)
2446
{
2447
	time_t		 cur_time, time_max;
2448
	uint32_t	 uint32val;
2449
2450
	time(&cur_time);
2451
2452
	time_max = LLONG_MAX - cur_time;
2453
	if (time_max > UINT32_MAX)
2454
		time_max = UINT32_MAX;
2455
2456
	/*
2457
	 * Take the server-provided times if available.  Otherwise
2458
	 * figure them out according to the spec.
2459
	 *
2460
	 * expiry  == time to discard lease.
2461
	 * renewal == time to renew lease from server that provided it.
2462
	 * rebind  == time to renew lease from any server.
2463
	 *
2464
	 * 0 <= renewal <= rebind <= expiry <= time_max
2465
	 * &&
2466
	 * expiry >= MIN(time_max, 60)
2467
	 */
2468
2469
	lease->expiry = 43200;	/* Default to 12 hours */
2470
	if (lease->options[DHO_DHCP_LEASE_TIME].len == sizeof(uint32val)) {
2471
		memcpy(&uint32val, lease->options[DHO_DHCP_LEASE_TIME].data,
2472
		    sizeof(uint32val));
2473
		lease->expiry = ntohl(uint32val);
2474
		if (lease->expiry < 60)
2475
			lease->expiry = 60;
2476
	}
2477
	if (lease->expiry > time_max)
2478
		lease->expiry = time_max;
2479
2480
	lease->renewal = lease->expiry / 2;
2481
	if (lease->options[DHO_DHCP_RENEWAL_TIME].len == sizeof(uint32val)) {
2482
		memcpy(&uint32val, lease->options[DHO_DHCP_RENEWAL_TIME].data,
2483
		    sizeof(uint32val));
2484
		lease->renewal = ntohl(uint32val);
2485
		if (lease->renewal > lease->expiry)
2486
			lease->renewal = lease->expiry;
2487
	}
2488
2489
	lease->rebind = (lease->expiry * 7) / 8;
2490
	if (lease->options[DHO_DHCP_REBINDING_TIME].len == sizeof(uint32val)) {
2491
		memcpy(&uint32val,
2492
		    lease->options[DHO_DHCP_REBINDING_TIME].data,
2493
		    sizeof(uint32val));
2494
		lease->rebind = ntohl(uint32val);
2495
		if (lease->rebind > lease->expiry)
2496
			lease->rebind = lease->expiry;
2497
	}
2498
	if (lease->rebind < lease->renewal)
2499
		lease->rebind = lease->renewal;
2500
2501
	/* Convert lease lengths to times. */
2502
	lease->expiry += cur_time;
2503
	lease->renewal += cur_time;
2504
	lease->rebind += cur_time;
2505
}
2506
2507
void
2508
take_charge(struct interface_info *ifi, int routefd)
2509
{
2510
	struct pollfd		 fds[1];
2511
	struct rt_msghdr	 rtm;
2512
	time_t			 start_time, cur_time;
2513
	int			 nfds, retries;
2514
2515
	if (time(&start_time) == -1)
2516
		fatal("time");
2517
2518
	/*
2519
	 * Send RTM_PROPOSAL with RTF_PROTO3 set.
2520
	 *
2521
	 * When it comes back, we're in charge and other dhclients are
2522
	 * dead processes walking.
2523
	 */
2524
	memset(&rtm, 0, sizeof(rtm));
2525
2526
	rtm.rtm_version = RTM_VERSION;
2527
	rtm.rtm_type = RTM_PROPOSAL;
2528
	rtm.rtm_msglen = sizeof(rtm);
2529
	rtm.rtm_tableid = ifi->rdomain;
2530
	rtm.rtm_index = ifi->index;
2531
	rtm.rtm_seq = ifi->xid = arc4random();
2532
	rtm.rtm_priority = RTP_PROPOSAL_DHCLIENT;
2533
	rtm.rtm_addrs = 0;
2534
	rtm.rtm_flags = RTF_UP | RTF_PROTO3;
2535
2536
	retries = 0;
2537
	while ((ifi->flags & IFI_IN_CHARGE) == 0) {
2538
		if (write(routefd, &rtm, sizeof(rtm)) == -1)
2539
			fatal("write(routefd)");
2540
		time(&cur_time);
2541
		if ((cur_time - start_time) > 3) {
2542
			if (++retries <= 3) {
2543
				if (time(&start_time) == -1)
2544
					fatal("time");
2545
			} else {
2546
				fatalx("failed to take charge");
2547
			}
2548
		}
2549
		fds[0].fd = routefd;
2550
		fds[0].events = POLLIN;
2551
		nfds = poll(fds, 1, 3);
2552
		if (nfds == -1) {
2553
			if (errno == EINTR)
2554
				continue;
2555
			fatal("poll(routefd)");
2556
		}
2557
		if ((fds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) != 0)
2558
			fatal("routefd: ERR|HUP|NVAL");
2559
		if (nfds == 0 || (fds[0].revents & POLLIN) == 0)
2560
			continue;
2561
		routehandler(ifi, routefd);
2562
	}
2563
}
2564
2565
struct client_lease *
2566
get_recorded_lease(struct interface_info *ifi)
2567
{
2568
	char			 ifname[IF_NAMESIZE];
2569
	time_t			 cur_time;
2570
	struct client_lease	*lp;
2571
	int			 i;
2572
2573
	time(&cur_time);
2574
2575
	/* Run through the list of leases and see if one can be used. */
2576
	i = DHO_DHCP_CLIENT_IDENTIFIER;
2577
	TAILQ_FOREACH(lp, &ifi->leases, next) {
2578
		if (lp->ssid_len != ifi->ssid_len)
2579
			continue;
2580
		if (memcmp(lp->ssid, ifi->ssid, lp->ssid_len) != 0)
2581
			continue;
2582
		if ((lp->options[i].len != 0) && ((lp->options[i].len !=
2583
		    config->send_options[i].len) ||
2584
		    memcmp(lp->options[i].data, config->send_options[i].data,
2585
		    lp->options[i].len)))
2586
			continue;
2587
		if (addressinuse(ifi->name, lp->address, ifname) != 0 &&
2588
		    strncmp(ifname, ifi->name, IF_NAMESIZE) != 0)
2589
			continue;
2590
		if (lp->is_static == 0 && lp->expiry <= cur_time)
2591
			continue;
2592
2593
		if (lp->is_static != 0)
2594
			set_lease_times(lp);
2595
		break;
2596
	}
2597
2598
	return lp;
2599
}
2600
2601
void
2602
set_default_client_identifier(struct interface_info *ifi)
2603
{
2604
	struct option_data	*opt;
2605
2606
	/*
2607
	 * Check both len && data so
2608
	 *
2609
	 *     send dhcp-client-identifier "";
2610
	 *
2611
	 * can be used to suppress sending the default client
2612
	 * identifier.
2613
	 */
2614
	opt = &config->send_options[DHO_DHCP_CLIENT_IDENTIFIER];
2615
	if (opt->len == 0 && opt->data == NULL) {
2616
		opt->data = calloc(1, ETHER_ADDR_LEN + 1);
2617
		if (opt->data == NULL)
2618
			fatal("default client identifier");
2619
		opt->data[0] = HTYPE_ETHER;
2620
		memcpy(&opt->data[1], ifi->hw_address.ether_addr_octet,
2621
		    ETHER_ADDR_LEN);
2622
		opt->len = ETHER_ADDR_LEN + 1;
2623
	}
2624
}