GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: sbin/dhclient/dhclient.c Lines: 0 1273 0.0 %
Date: 2017-11-13 Branches: 0 809 0.0 %

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