xref: /dragonfly/contrib/dhcpcd/src/if-options.c (revision 54175cef)
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * dhcpcd - DHCP client daemon
4  * Copyright (c) 2006-2023 Roy Marples <roy@marples.name>
5  * All rights reserved
6 
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include <sys/param.h>
30 #include <sys/types.h>
31 
32 #include <arpa/inet.h>
33 
34 #include <ctype.h>
35 #include <errno.h>
36 #include <getopt.h>
37 #include <grp.h>
38 #include <inttypes.h>
39 #include <limits.h>
40 #include <paths.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <unistd.h>
45 #include <time.h>
46 
47 #include "config.h"
48 #include "common.h"
49 #include "dhcp.h"
50 #include "dhcp6.h"
51 #include "dhcpcd-embedded.h"
52 #include "duid.h"
53 #include "if.h"
54 #include "if-options.h"
55 #include "ipv4.h"
56 #include "logerr.h"
57 #include "sa.h"
58 
59 #define	IN_CONFIG_BLOCK(ifo)	((ifo)->options & DHCPCD_FORKED)
60 #define	SET_CONFIG_BLOCK(ifo)	((ifo)->options |= DHCPCD_FORKED)
61 #define	CLEAR_CONFIG_BLOCK(ifo)	((ifo)->options &= ~DHCPCD_FORKED)
62 
63 static unsigned long long default_options;
64 
65 const struct option cf_options[] = {
66 	{"background",      no_argument,       NULL, 'b'},
67 	{"script",          required_argument, NULL, 'c'},
68 	{"debug",           no_argument,       NULL, 'd'},
69 	{"env",             required_argument, NULL, 'e'},
70 	{"config",          required_argument, NULL, 'f'},
71 	{"reconfigure",     no_argument,       NULL, 'g'},
72 	{"hostname",        optional_argument, NULL, 'h'},
73 	{"vendorclassid",   optional_argument, NULL, 'i'},
74 	{"logfile",         required_argument, NULL, 'j'},
75 	{"release",         no_argument,       NULL, 'k'},
76 	{"leasetime",       required_argument, NULL, 'l'},
77 	{"metric",          required_argument, NULL, 'm'},
78 	{"rebind",          no_argument,       NULL, 'n'},
79 	{"option",          required_argument, NULL, 'o'},
80 	{"persistent",      no_argument,       NULL, 'p'},
81 	{"quiet",           no_argument,       NULL, 'q'},
82 	{"request",         optional_argument, NULL, 'r'},
83 	{"inform",          optional_argument, NULL, 's'},
84 	{"inform6",         optional_argument, NULL, O_INFORM6},
85 	{"timeout",         required_argument, NULL, 't'},
86 	{"userclass",       required_argument, NULL, 'u'},
87 #ifndef SMALL
88 	{"msuserclass",     required_argument, NULL, O_MSUSERCLASS},
89 #endif
90 	{"vendor",          required_argument, NULL, 'v'},
91 	{"waitip",          optional_argument, NULL, 'w'},
92 	{"exit",            no_argument,       NULL, 'x'},
93 	{"allowinterfaces", required_argument, NULL, 'z'},
94 	{"reboot",          required_argument, NULL, 'y'},
95 	{"noarp",           no_argument,       NULL, 'A'},
96 	{"nobackground",    no_argument,       NULL, 'B'},
97 	{"nohook",          required_argument, NULL, 'C'},
98 	{"duid",            optional_argument, NULL, 'D'},
99 	{"lastlease",       no_argument,       NULL, 'E'},
100 	{"fqdn",            optional_argument, NULL, 'F'},
101 	{"nogateway",       no_argument,       NULL, 'G'},
102 	{"xidhwaddr",       no_argument,       NULL, 'H'},
103 	{"clientid",        optional_argument, NULL, 'I'},
104 	{"broadcast",       no_argument,       NULL, 'J'},
105 	{"nolink",          no_argument,       NULL, 'K'},
106 	{"noipv4ll",        no_argument,       NULL, 'L'},
107 	{"manager",         no_argument,       NULL, 'M'},
108 	{"renew",           no_argument,       NULL, 'N'},
109 	{"nooption",        required_argument, NULL, 'O'},
110 	{"printpidfile",    no_argument,       NULL, 'P'},
111 	{"require",         required_argument, NULL, 'Q'},
112 	{"static",          required_argument, NULL, 'S'},
113 	{"test",            no_argument,       NULL, 'T'},
114 	{"dumplease",       no_argument,       NULL, 'U'},
115 	{"variables",       no_argument,       NULL, 'V'},
116 	{"whitelist",       required_argument, NULL, 'W'},
117 	{"blacklist",       required_argument, NULL, 'X'},
118 	{"denyinterfaces",  required_argument, NULL, 'Z'},
119 	{"oneshot",         no_argument,       NULL, '1'},
120 	{"ipv4only",        no_argument,       NULL, '4'},
121 	{"ipv6only",        no_argument,       NULL, '6'},
122 	{"anonymous",       no_argument,       NULL, O_ANONYMOUS},
123 	{"randomise_hwaddr",no_argument,       NULL, O_RANDOMISE_HWADDR},
124 	{"arping",          required_argument, NULL, O_ARPING},
125 	{"destination",     required_argument, NULL, O_DESTINATION},
126 	{"fallback",        required_argument, NULL, O_FALLBACK},
127 	{"ipv6rs",          no_argument,       NULL, O_IPV6RS},
128 	{"noipv6rs",        no_argument,       NULL, O_NOIPV6RS},
129 	{"ipv6ra_autoconf", no_argument,       NULL, O_IPV6RA_AUTOCONF},
130 	{"ipv6ra_noautoconf", no_argument,     NULL, O_IPV6RA_NOAUTOCONF},
131 	{"ipv6ra_fork",     no_argument,       NULL, O_IPV6RA_FORK},
132 	{"ipv4",            no_argument,       NULL, O_IPV4},
133 	{"noipv4",          no_argument,       NULL, O_NOIPV4},
134 	{"ipv6",            no_argument,       NULL, O_IPV6},
135 	{"noipv6",          no_argument,       NULL, O_NOIPV6},
136 	{"noalias",         no_argument,       NULL, O_NOALIAS},
137 	{"iaid",            required_argument, NULL, O_IAID},
138 	{"ia_na",           optional_argument, NULL, O_IA_NA},
139 	{"ia_ta",           optional_argument, NULL, O_IA_TA},
140 	{"ia_pd",           optional_argument, NULL, O_IA_PD},
141 	{"hostname_short",  no_argument,       NULL, O_HOSTNAME_SHORT},
142 	{"dev",             required_argument, NULL, O_DEV},
143 	{"nodev",           no_argument,       NULL, O_NODEV},
144 	{"define",          required_argument, NULL, O_DEFINE},
145 	{"definend",        required_argument, NULL, O_DEFINEND},
146 	{"define6",         required_argument, NULL, O_DEFINE6},
147 	{"embed",           required_argument, NULL, O_EMBED},
148 	{"encap",           required_argument, NULL, O_ENCAP},
149 	{"vendopt",         required_argument, NULL, O_VENDOPT},
150 	{"vendclass",       required_argument, NULL, O_VENDCLASS},
151 	{"authprotocol",    required_argument, NULL, O_AUTHPROTOCOL},
152 	{"authtoken",       required_argument, NULL, O_AUTHTOKEN},
153 	{"noauthrequired",  no_argument,       NULL, O_AUTHNOTREQUIRED},
154 	{"dhcp",            no_argument,       NULL, O_DHCP},
155 	{"nodhcp",          no_argument,       NULL, O_NODHCP},
156 	{"dhcp6",           no_argument,       NULL, O_DHCP6},
157 	{"nodhcp6",         no_argument,       NULL, O_NODHCP6},
158 	{"controlgroup",    required_argument, NULL, O_CONTROLGRP},
159 	{"slaac",           required_argument, NULL, O_SLAAC},
160 	{"gateway",         no_argument,       NULL, O_GATEWAY},
161 	{"reject",          required_argument, NULL, O_REJECT},
162 	{"bootp",           no_argument,       NULL, O_BOOTP},
163 	{"nodelay",         no_argument,       NULL, O_NODELAY},
164 	{"noup",            no_argument,       NULL, O_NOUP},
165 	{"lastleaseextend", no_argument,       NULL, O_LASTLEASE_EXTEND},
166 	{"inactive",        no_argument,       NULL, O_INACTIVE},
167 	{"mudurl",          required_argument, NULL, O_MUDURL},
168 	{"link_rcvbuf",     required_argument, NULL, O_LINK_RCVBUF},
169 	{"configure",       no_argument,       NULL, O_CONFIGURE},
170 	{"noconfigure",     no_argument,       NULL, O_NOCONFIGURE},
171 	{"arp_persistdefence", no_argument,    NULL, O_ARP_PERSISTDEFENCE},
172 	{"request_time",    required_argument, NULL, O_REQUEST_TIME},
173 	{"fallback_time",   required_argument, NULL, O_FALLBACK_TIME},
174 	{"ipv4ll_time",     required_argument, NULL, O_IPV4LL_TIME},
175 	{NULL,              0,                 NULL, '\0'}
176 };
177 
178 static char *
add_environ(char *** array,const char * value,int uniq)179 add_environ(char ***array, const char *value, int uniq)
180 {
181 	char **newlist, **list = *array;
182 	size_t i = 0, l, lv;
183 	char *match = NULL, *p, *n;
184 
185 	match = strdup(value);
186 	if (match == NULL) {
187 		logerr(__func__);
188 		return NULL;
189 	}
190 	p = strchr(match, '=');
191 	if (p == NULL) {
192 		logerrx("%s: no assignment: %s", __func__, value);
193 		free(match);
194 		return NULL;
195 	}
196 	*p++ = '\0';
197 	l = strlen(match);
198 
199 	while (list && list[i]) {
200 		/* We know that it must contain '=' due to the above test */
201 		size_t listl = (size_t)(strchr(list[i], '=') - list[i]);
202 
203 		if (l == listl && strncmp(list[i], match, l) == 0) {
204 			if (uniq) {
205 				n = strdup(value);
206 				if (n == NULL) {
207 					logerr(__func__);
208 					free(match);
209 					return NULL;
210 				}
211 				free(list[i]);
212 				list[i] = n;
213 			} else {
214 				/* Append a space and the value to it */
215 				l = strlen(list[i]);
216 				lv = strlen(p);
217 				n = realloc(list[i], l + lv + 2);
218 				if (n == NULL) {
219 					logerr(__func__);
220 					free(match);
221 					return NULL;
222 				}
223 				list[i] = n;
224 				list[i][l] = ' ';
225 				memcpy(list[i] + l + 1, p, lv);
226 				list[i][l + lv + 1] = '\0';
227 			}
228 			free(match);
229 			return list[i];
230 		}
231 		i++;
232 	}
233 
234 	free(match);
235 	n = strdup(value);
236 	if (n == NULL) {
237 		logerr(__func__);
238 		return NULL;
239 	}
240 	newlist = reallocarray(list, i + 2, sizeof(char *));
241 	if (newlist == NULL) {
242 		logerr(__func__);
243 		free(n);
244 		return NULL;
245 	}
246 	newlist[i] = n;
247 	newlist[i + 1] = NULL;
248 	*array = newlist;
249 	return newlist[i];
250 }
251 
252 #define PARSE_STRING		0
253 #define PARSE_STRING_NULL	1
254 #define PARSE_HWADDR		2
255 #define parse_string(a, b, c) parse_str((a), (b), (c), PARSE_STRING)
256 #define parse_nstring(a, b, c) parse_str((a), (b), (c), PARSE_STRING_NULL)
257 #define parse_hwaddr(a, b, c) parse_str((a), (b), (c), PARSE_HWADDR)
258 static ssize_t
parse_str(char * sbuf,size_t slen,const char * str,int flags)259 parse_str(char *sbuf, size_t slen, const char *str, int flags)
260 {
261 	size_t l;
262 	const char *p, *end;
263 	int i;
264 	char c[4], cmd;
265 
266 	end = str + strlen(str);
267 	/* If surrounded by quotes then it's a string */
268 	if (*str == '"') {
269 		p = end - 1;
270 		if (*p == '"') {
271 			str++;
272 			end = p;
273 		}
274 	} else {
275 		l = (size_t)hwaddr_aton(NULL, str);
276 		if (l > 0) {
277 			if ((ssize_t)l == -1) {
278 				errno = ENOBUFS;
279 				return -1;
280 			}
281 			if (sbuf == NULL)
282 				return (ssize_t)l;
283 			if (l > slen) {
284 				errno = ENOBUFS;
285 				return -1;
286 			}
287 			hwaddr_aton((uint8_t *)sbuf, str);
288 			return (ssize_t)l;
289 		}
290 	}
291 
292 	/* Process escapes */
293 	l = 0;
294 	/* If processing a string on the clientid, first byte should be
295 	 * 0 to indicate a non hardware type */
296 	if (flags == PARSE_HWADDR && *str) {
297 		if (sbuf)
298 			*sbuf++ = 0;
299 		l++;
300 	}
301 	c[3] = '\0';
302 	while (str < end) {
303 		if (++l > slen && sbuf) {
304 			errno = ENOBUFS;
305 			return -1;
306 		}
307 		if (*str == '\\') {
308 			str++;
309 			switch((cmd = *str++)) {
310 			case '\0':
311 				str--;
312 				break;
313 			case 'b':
314 				if (sbuf)
315 					*sbuf++ = '\b';
316 				break;
317 			case 'n':
318 				if (sbuf)
319 					*sbuf++ = '\n';
320 				break;
321 			case 'r':
322 				if (sbuf)
323 					*sbuf++ = '\r';
324 				break;
325 			case 't':
326 				if (sbuf)
327 					*sbuf++ = '\t';
328 				break;
329 			case 'x':
330 				/* Grab a hex code */
331 				c[1] = '\0';
332 				for (i = 0; i < 2; i++) {
333 					if (isxdigit((unsigned char)*str) == 0)
334 						break;
335 					c[i] = *str++;
336 				}
337 				if (c[1] != '\0') {
338 					c[2] = '\0';
339 					if (sbuf)
340 						*sbuf++ = (char)strtol(c, NULL, 16);
341 				} else
342 					l--;
343 				break;
344 			case '0':
345 				/* Grab an octal code */
346 				c[2] = '\0';
347 				for (i = 0; i < 3; i++) {
348 					if (*str < '0' || *str > '7')
349 						break;
350 					c[i] = *str++;
351 				}
352 				if (c[2] != '\0') {
353 					i = (int)strtol(c, NULL, 8);
354 					if (i > 255)
355 						i = 255;
356 					if (sbuf)
357 						*sbuf++ = (char)i;
358 				} else
359 					l--;
360 				break;
361 			default:
362 				if (sbuf)
363 					*sbuf++ = cmd;
364 				break;
365 			}
366 		} else {
367 			if (sbuf)
368 				*sbuf++ = *str;
369 			str++;
370 		}
371 	}
372 	if (flags == PARSE_STRING_NULL) {
373 		l++;
374 		if (sbuf != NULL) {
375 			if (l > slen) {
376 				errno = ENOBUFS;
377 				return -1;
378 			}
379 			*sbuf = '\0';
380 		}
381 	}
382 	return (ssize_t)l;
383 }
384 
385 static int
parse_iaid1(uint8_t * iaid,const char * arg,size_t len,int n)386 parse_iaid1(uint8_t *iaid, const char *arg, size_t len, int n)
387 {
388 	int e;
389 	uint32_t narg;
390 	ssize_t s;
391 
392 	narg = (uint32_t)strtou(arg, NULL, 0, 0, UINT32_MAX, &e);
393 	if (e == 0) {
394 		if (n)
395 			narg = htonl(narg);
396 		memcpy(iaid, &narg, sizeof(narg));
397 		return 0;
398 	}
399 
400 	if ((s = parse_string((char *)iaid, len, arg)) < 1)
401 		return -1;
402 	if (s < 4)
403 		iaid[3] = '\0';
404 	if (s < 3)
405 		iaid[2] = '\0';
406 	if (s < 2)
407 		iaid[1] = '\0';
408 	return 0;
409 }
410 
411 static int
parse_iaid(uint8_t * iaid,const char * arg,size_t len)412 parse_iaid(uint8_t *iaid, const char *arg, size_t len)
413 {
414 
415 	return parse_iaid1(iaid, arg, len, 1);
416 }
417 
418 #ifdef AUTH
419 static int
parse_uint32(uint32_t * i,const char * arg)420 parse_uint32(uint32_t *i, const char *arg)
421 {
422 
423 	return parse_iaid1((uint8_t *)i, arg, sizeof(uint32_t), 0);
424 }
425 #endif
426 
427 static char **
splitv(int * argc,char ** argv,const char * arg)428 splitv(int *argc, char **argv, const char *arg)
429 {
430 	char **n, **v = argv;
431 	char *o = strdup(arg), *p, *t, *nt;
432 
433 	if (o == NULL) {
434 		logerr(__func__);
435 		return v;
436 	}
437 	p = o;
438 	while ((t = strsep(&p, ", "))) {
439 		nt = strdup(t);
440 		if (nt == NULL) {
441 			logerr(__func__);
442 			free(o);
443 			return v;
444 		}
445 		n = reallocarray(v, (size_t)(*argc) + 1, sizeof(char *));
446 		if (n == NULL) {
447 			logerr(__func__);
448 			free(o);
449 			free(nt);
450 			return v;
451 		}
452 		v = n;
453 		v[(*argc)++] = nt;
454 	}
455 	free(o);
456 	return v;
457 }
458 
459 #ifdef INET
460 static int
parse_addr(struct in_addr * addr,struct in_addr * net,const char * arg)461 parse_addr(struct in_addr *addr, struct in_addr *net, const char *arg)
462 {
463 	char *p;
464 
465 	if (arg == NULL || *arg == '\0') {
466 		if (addr != NULL)
467 			addr->s_addr = 0;
468 		if (net != NULL)
469 			net->s_addr = 0;
470 		return 0;
471 	}
472 	if ((p = strchr(arg, '/')) != NULL) {
473 		int e;
474 		intmax_t i;
475 
476 		*p++ = '\0';
477 		i = strtoi(p, NULL, 10, 0, 32, &e);
478 		if (e != 0 ||
479 		    (net != NULL && inet_cidrtoaddr((int)i, net) != 0))
480 		{
481 			logerrx("invalid CIDR: %s", p);
482 			return -1;
483 		}
484 	}
485 
486 	if (addr != NULL && inet_aton(arg, addr) == 0) {
487 		logerrx("invalid IP address: %s", arg);
488 		return -1;
489 	}
490 	if (p != NULL)
491 		*--p = '/';
492 	else if (net != NULL && addr != NULL)
493 		net->s_addr = ipv4_getnetmask(addr->s_addr);
494 	return 0;
495 }
496 #else
497 static int
parse_addr(__unused struct in_addr * addr,__unused struct in_addr * net,__unused const char * arg)498 parse_addr(__unused struct in_addr *addr, __unused struct in_addr *net,
499     __unused const char *arg)
500 {
501 
502 	logerrx("No IPv4 support");
503 	return -1;
504 }
505 #endif
506 
507 static void
set_option_space(struct dhcpcd_ctx * ctx,const char * arg,const struct dhcp_opt ** d,size_t * dl,const struct dhcp_opt ** od,size_t * odl,struct if_options * ifo,uint8_t * request[],uint8_t * require[],uint8_t * no[],uint8_t * reject[])508 set_option_space(struct dhcpcd_ctx *ctx,
509     const char *arg,
510     const struct dhcp_opt **d, size_t *dl,
511     const struct dhcp_opt **od, size_t *odl,
512     struct if_options *ifo,
513     uint8_t *request[], uint8_t *require[], uint8_t *no[], uint8_t *reject[])
514 {
515 
516 #if !defined(INET) && !defined(INET6)
517 	UNUSED(ctx);
518 #endif
519 
520 #ifdef INET6
521 	if (strncmp(arg, "nd_", strlen("nd_")) == 0) {
522 		*d = ctx->nd_opts;
523 		*dl = ctx->nd_opts_len;
524 		*od = ifo->nd_override;
525 		*odl = ifo->nd_override_len;
526 		*request = ifo->requestmasknd;
527 		*require = ifo->requiremasknd;
528 		*no = ifo->nomasknd;
529 		*reject = ifo->rejectmasknd;
530 		return;
531 	}
532 
533 #ifdef DHCP6
534 	if (strncmp(arg, "dhcp6_", strlen("dhcp6_")) == 0) {
535 		*d = ctx->dhcp6_opts;
536 		*dl = ctx->dhcp6_opts_len;
537 		*od = ifo->dhcp6_override;
538 		*odl = ifo->dhcp6_override_len;
539 		*request = ifo->requestmask6;
540 		*require = ifo->requiremask6;
541 		*no = ifo->nomask6;
542 		*reject = ifo->rejectmask6;
543 		return;
544 	}
545 #endif
546 #else
547 	UNUSED(arg);
548 #endif
549 
550 #ifdef INET
551 	*d = ctx->dhcp_opts;
552 	*dl = ctx->dhcp_opts_len;
553 	*od = ifo->dhcp_override;
554 	*odl = ifo->dhcp_override_len;
555 #else
556 	*d = NULL;
557 	*dl = 0;
558 	*od = NULL;
559 	*odl = 0;
560 #endif
561 	*request = ifo->requestmask;
562 	*require = ifo->requiremask;
563 	*no = ifo->nomask;
564 	*reject = ifo->rejectmask;
565 }
566 
567 void
free_dhcp_opt_embenc(struct dhcp_opt * opt)568 free_dhcp_opt_embenc(struct dhcp_opt *opt)
569 {
570 	size_t i;
571 	struct dhcp_opt *o;
572 
573 	free(opt->var);
574 
575 	for (i = 0, o = opt->embopts; i < opt->embopts_len; i++, o++)
576 		free_dhcp_opt_embenc(o);
577 	free(opt->embopts);
578 	opt->embopts_len = 0;
579 	opt->embopts = NULL;
580 
581 	for (i = 0, o = opt->encopts; i < opt->encopts_len; i++, o++)
582 		free_dhcp_opt_embenc(o);
583 	free(opt->encopts);
584 	opt->encopts_len = 0;
585 	opt->encopts = NULL;
586 }
587 
588 static char *
strwhite(const char * s)589 strwhite(const char *s)
590 {
591 
592 	if (s == NULL)
593 		return NULL;
594 	while (*s != ' ' && *s != '\t') {
595 		if (*s == '\0')
596 			return NULL;
597 		s++;
598 	}
599 	return UNCONST(s);
600 }
601 
602 static char *
strskipwhite(const char * s)603 strskipwhite(const char *s)
604 {
605 
606 	if (s == NULL || *s == '\0')
607 		return NULL;
608 	while (*s == ' ' || *s == '\t') {
609 		s++;
610 		if (*s == '\0')
611 			return NULL;
612 	}
613 	return UNCONST(s);
614 }
615 
616 #ifdef AUTH
617 /* Find the end pointer of a string. */
618 static char *
strend(const char * s)619 strend(const char *s)
620 {
621 
622 	s = strskipwhite(s);
623 	if (s == NULL)
624 		return NULL;
625 	if (*s != '"')
626 		return strchr(s, ' ');
627 	s++;
628 	for (; *s != '"' ; s++) {
629 		if (*s == '\0')
630 			return NULL;
631 		if (*s == '\\') {
632 			if (*(++s) == '\0')
633 				return NULL;
634 		}
635 	}
636 	return UNCONST(++s);
637 }
638 #endif
639 
640 static int
parse_option(struct dhcpcd_ctx * ctx,const char * ifname,struct if_options * ifo,int opt,const char * arg,struct dhcp_opt ** ldop,struct dhcp_opt ** edop)641 parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo,
642     int opt, const char *arg, struct dhcp_opt **ldop, struct dhcp_opt **edop)
643 {
644 	int e, i, t;
645 	long l;
646 	unsigned long u;
647 	char *p = NULL, *bp, *fp, *np;
648 	ssize_t s;
649 	struct in_addr addr, addr2;
650 	in_addr_t *naddr;
651 	struct rt *rt;
652 	const struct dhcp_opt *d, *od;
653 	uint8_t *request, *require, *no, *reject;
654 	struct dhcp_opt **dop, *ndop;
655 	size_t *dop_len, dl, odl;
656 	struct vivco *vivco;
657 	struct group *grp;
658 #ifdef AUTH
659 	struct token *token;
660 #endif
661 #ifdef _REENTRANT
662 	struct group grpbuf;
663 #endif
664 #ifdef DHCP6
665 	size_t sl;
666 	struct if_ia *ia;
667 	uint8_t iaid[4];
668 #ifndef SMALL
669 	struct if_sla *sla, *slap;
670 #endif
671 #endif
672 
673 	dop = NULL;
674 	dop_len = NULL;
675 #ifdef INET6
676 	i = 0;
677 #endif
678 
679 /* Add a guard for static analysers.
680  * This should not be needed really because of the argument_required option
681  * in the options declaration above. */
682 #define ARG_REQUIRED if (arg == NULL) goto arg_required
683 
684 	switch(opt) {
685 	case 'f': /* FALLTHROUGH */
686 	case 'g': /* FALLTHROUGH */
687 	case 'n': /* FALLTHROUGH */
688 	case 'q': /* FALLTHROUGH */
689 	case 'x': /* FALLTHROUGH */
690 	case 'N': /* FALLTHROUGH */
691 	case 'P': /* FALLTHROUGH */
692 	case 'T': /* FALLTHROUGH */
693 	case 'U': /* FALLTHROUGH */
694 	case 'V': /* We need to handle non interface options */
695 		break;
696 	case 'b':
697 		ifo->options |= DHCPCD_BACKGROUND;
698 		break;
699 	case 'c':
700 		ARG_REQUIRED;
701 		if (IN_CONFIG_BLOCK(ifo)) {
702 			logerrx("%s: per interface scripts"
703 			    " are no longer supported",
704 			    ifname);
705 			return -1;
706 		}
707 		if (ctx->script != dhcpcd_default_script)
708 			free(ctx->script);
709 		s = parse_nstring(NULL, 0, arg);
710 		if (s == 0) {
711 			ctx->script = NULL;
712 			break;
713 		}
714 		dl = (size_t)s;
715 		if (s == -1 || (ctx->script = malloc(dl)) == NULL) {
716 			ctx->script = NULL;
717 			logerr(__func__);
718 			return -1;
719 		}
720 		s = parse_nstring(ctx->script, dl, arg);
721 		if (s == -1 ||
722 		    ctx->script[0] == '\0' ||
723 		    strcmp(ctx->script, "/dev/null") == 0)
724 		{
725 			free(ctx->script);
726 			ctx->script = NULL;
727 		}
728 		break;
729 	case 'd':
730 		ifo->options |= DHCPCD_DEBUG;
731 		break;
732 	case 'e':
733 		ARG_REQUIRED;
734 		add_environ(&ifo->environ, arg, 1);
735 		break;
736 	case 'h':
737 		if (!arg) {
738 			ifo->options |= DHCPCD_HOSTNAME;
739 			break;
740 		}
741 		s = parse_nstring(ifo->hostname, sizeof(ifo->hostname), arg);
742 		if (s == -1) {
743 			logerr("%s: hostname", __func__);
744 			return -1;
745 		}
746 		if (s != 0 && ifo->hostname[0] == '.') {
747 			logerrx("hostname cannot begin with .");
748 			return -1;
749 		}
750 		if (ifo->hostname[0] == '\0')
751 			ifo->options &= ~DHCPCD_HOSTNAME;
752 		else
753 			ifo->options |= DHCPCD_HOSTNAME;
754 		break;
755 	case 'i':
756 		if (arg)
757 			s = parse_string((char *)ifo->vendorclassid + 1,
758 			    VENDORCLASSID_MAX_LEN, arg);
759 		else
760 			s = 0;
761 		if (s == -1) {
762 			logerr("vendorclassid");
763 			return -1;
764 		}
765 		*ifo->vendorclassid = (uint8_t)s;
766 		break;
767 	case 'j':
768 		ARG_REQUIRED;
769 		/* per interface logging is not supported
770 		 * don't want to overide the commandline */
771 		if (!IN_CONFIG_BLOCK(ifo) && ctx->logfile == NULL) {
772 			logclose();
773 			ctx->logfile = strdup(arg);
774 			logopen(ctx->logfile);
775 		}
776 		break;
777 	case 'k':
778 		ifo->options |= DHCPCD_RELEASE;
779 		break;
780 	case 'l':
781 		ARG_REQUIRED;
782 		if (strcmp(arg, "-1") == 0) {
783 			ifo->leasetime = DHCP_INFINITE_LIFETIME;
784 			break;
785 		}
786 		ifo->leasetime = (uint32_t)strtou(arg, NULL,
787 		    0, 0, UINT32_MAX, &e);
788 		if (e) {
789 			logerrx("failed to convert leasetime %s", arg);
790 			return -1;
791 		}
792 		break;
793 	case 'm':
794 		ARG_REQUIRED;
795 		ifo->metric = (int)strtoi(arg, NULL, 0, 0, INT32_MAX, &e);
796 		if (e) {
797 			logerrx("failed to convert metric %s", arg);
798 			return -1;
799 		}
800 		break;
801 	case 'o':
802 		ARG_REQUIRED;
803 		if (ctx->options & DHCPCD_PRINT_PIDFILE)
804 			break;
805 		set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo,
806 		    &request, &require, &no, &reject);
807 		if (make_option_mask(d, dl, od, odl, request, arg, 1) != 0 ||
808 		    make_option_mask(d, dl, od, odl, no, arg, -1) != 0 ||
809 		    make_option_mask(d, dl, od, odl, reject, arg, -1) != 0)
810 		{
811 			logerrx("unknown option: %s", arg);
812 			return -1;
813 		}
814 		break;
815 	case O_REJECT:
816 		ARG_REQUIRED;
817 		if (ctx->options & DHCPCD_PRINT_PIDFILE)
818 			break;
819 		set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo,
820 		    &request, &require, &no, &reject);
821 		if (make_option_mask(d, dl, od, odl, reject, arg, 1) != 0 ||
822 		    make_option_mask(d, dl, od, odl, request, arg, -1) != 0 ||
823 		    make_option_mask(d, dl, od, odl, require, arg, -1) != 0)
824 		{
825 			logerrx("unknown option: %s", arg);
826 			return -1;
827 		}
828 		break;
829 	case 'p':
830 		ifo->options |= DHCPCD_PERSISTENT;
831 		break;
832 	case 'r':
833 		if (parse_addr(&ifo->req_addr, NULL, arg) != 0)
834 			return -1;
835 		ifo->options |= DHCPCD_REQUEST;
836 		ifo->req_mask.s_addr = 0;
837 		break;
838 	case 's':
839 		if (arg && *arg != '\0') {
840 			/* Strip out a broadcast address */
841 			p = strchr(arg, '/');
842 			if (p != NULL) {
843 				p = strchr(p + 1, '/');
844 				if (p != NULL)
845 					*p = '\0';
846 			}
847 			i = parse_addr(&ifo->req_addr, &ifo->req_mask, arg);
848 			if (p != NULL) {
849 				/* Ensure the original string is preserved */
850 				*p++ = '/';
851 				if (i == 0)
852 					i = parse_addr(&ifo->req_brd, NULL, p);
853 			}
854 			if (i != 0)
855 				return -1;
856 		} else {
857 			ifo->req_addr.s_addr = 0;
858 			ifo->req_mask.s_addr = 0;
859 		}
860 		ifo->options |= DHCPCD_INFORM | DHCPCD_PERSISTENT;
861 		ifo->options &= ~DHCPCD_STATIC;
862 		break;
863 	case O_INFORM6:
864 		ifo->options |= DHCPCD_INFORM6;
865 		break;
866 	case 't':
867 		ARG_REQUIRED;
868 		ifo->timeout = (uint32_t)strtou(arg, NULL, 0, 0, UINT32_MAX, &e);
869 		if (e) {
870 			logerrx("failed to convert timeout %s", arg);
871 			return -1;
872 		}
873 		break;
874 	case 'u':
875 		dl = sizeof(ifo->userclass) - ifo->userclass[0] - 1;
876 		s = parse_string((char *)ifo->userclass +
877 		    ifo->userclass[0] + 2, dl, arg);
878 		if (s == -1) {
879 			logerr("userclass");
880 			return -1;
881 		}
882 		if (s != 0) {
883 			ifo->userclass[ifo->userclass[0] + 1] = (uint8_t)s;
884 			ifo->userclass[0] = (uint8_t)(ifo->userclass[0] + s +1);
885 		}
886 		break;
887 #ifndef SMALL
888 	case O_MSUSERCLASS:
889 		/* Some Microsoft DHCP servers expect userclass to be an
890 		 * opaque blob. This is not RFC 3004 compliant. */
891 		s = parse_string((char *)ifo->userclass + 1,
892 		    sizeof(ifo->userclass) - 1, arg);
893 		if (s == -1) {
894 			logerr("msuserclass");
895 			return -1;
896 		}
897 		ifo->userclass[0] = (uint8_t)s;
898 		break;
899 #endif
900 	case 'v':
901 		ARG_REQUIRED;
902 		p = strchr(arg, ',');
903 		if (!p || !p[1]) {
904 			logerrx("invalid vendor format: %s", arg);
905 			return -1;
906 		}
907 
908 		/* If vendor starts with , then it is not encapsulated */
909 		if (p == arg) {
910 			arg++;
911 			s = parse_string((char *)ifo->vendor + 1,
912 			    VENDOR_MAX_LEN, arg);
913 			if (s == -1) {
914 				logerr("vendor");
915 				return -1;
916 			}
917 			ifo->vendor[0] = (uint8_t)s;
918 			ifo->options |= DHCPCD_VENDORRAW;
919 			break;
920 		}
921 
922 		/* Encapsulated vendor options */
923 		if (ifo->options & DHCPCD_VENDORRAW) {
924 			ifo->options &= ~DHCPCD_VENDORRAW;
925 			ifo->vendor[0] = 0;
926 		}
927 
928 		/* Strip and preserve the comma */
929 		*p = '\0';
930 		i = (int)strtoi(arg, NULL, 0, 1, 254, &e);
931 		*p = ',';
932 		if (e) {
933 			logerrx("vendor option should be between"
934 			    " 1 and 254 inclusive");
935 			return -1;
936 		}
937 
938 		arg = p + 1;
939 		s = VENDOR_MAX_LEN - ifo->vendor[0] - 2;
940 		if (inet_aton(arg, &addr) == 1) {
941 			if (s < 6) {
942 				s = -1;
943 				errno = ENOBUFS;
944 			} else {
945 				memcpy(ifo->vendor + ifo->vendor[0] + 3,
946 				    &addr.s_addr, sizeof(addr.s_addr));
947 				s = sizeof(addr.s_addr);
948 			}
949 		} else {
950 			s = parse_string((char *)ifo->vendor +
951 			    ifo->vendor[0] + 3, (size_t)s, arg);
952 		}
953 		if (s == -1) {
954 			logerr("vendor");
955 			return -1;
956 		}
957 		if (s != 0) {
958 			ifo->vendor[ifo->vendor[0] + 1] = (uint8_t)i;
959 			ifo->vendor[ifo->vendor[0] + 2] = (uint8_t)s;
960 			ifo->vendor[0] = (uint8_t)(ifo->vendor[0] + s + 2);
961 		}
962 		break;
963 	case 'w':
964 		ifo->options |= DHCPCD_WAITIP;
965 		p = UNCONST(arg);
966 		// Generally it's --waitip=46, but some expect
967 		// --waitip="4 6" to work as well.
968 		// It's easier to allow it rather than have confusing docs.
969 		while (p != NULL && p[0] != '\0') {
970 			if (p[0] == '4' || p[1] == '4')
971 				ifo->options |= DHCPCD_WAITIP4;
972 			if (p[0] == '6' || p[1] == '6')
973 				ifo->options |= DHCPCD_WAITIP6;
974 			p = strskipwhite(++p);
975 		}
976 		break;
977 	case 'y':
978 		ARG_REQUIRED;
979 		ifo->reboot = (uint32_t)strtou(arg, NULL, 0, 0, UINT32_MAX, &e);
980 		if (e) {
981 			logerr("failed to convert reboot %s", arg);
982 			return -1;
983 		}
984 		break;
985 	case 'z':
986 		ARG_REQUIRED;
987 		if (!IN_CONFIG_BLOCK(ifo))
988 			ctx->ifav = splitv(&ctx->ifac, ctx->ifav, arg);
989 		break;
990 	case 'A':
991 		ifo->options &= ~DHCPCD_ARP;
992 		/* IPv4LL requires ARP */
993 		ifo->options &= ~DHCPCD_IPV4LL;
994 		break;
995 	case 'B':
996 		ifo->options &= ~DHCPCD_DAEMONISE;
997 		break;
998 	case 'C':
999 		ARG_REQUIRED;
1000 		/* Commas to spaces for shell */
1001 		while ((p = strchr(arg, ',')))
1002 			*p = ' ';
1003 		dl = strlen("skip_hooks=") + strlen(arg) + 1;
1004 		p = malloc(sizeof(char) * dl);
1005 		if (p == NULL) {
1006 			logerr(__func__);
1007 			return -1;
1008 		}
1009 		snprintf(p, dl, "skip_hooks=%s", arg);
1010 		add_environ(&ifo->environ, p, 0);
1011 		free(p);
1012 		break;
1013 	case 'D':
1014 		ifo->options |= DHCPCD_CLIENTID | DHCPCD_DUID;
1015 		if (ifname != NULL) /* duid type only a global option */
1016 			break;
1017 		if (arg == NULL)
1018 			ctx->duid_type = DUID_DEFAULT;
1019 		else if (strcmp(arg, "ll") == 0)
1020 			ctx->duid_type = DUID_LL;
1021 		else if (strcmp(arg, "llt") == 0)
1022 			ctx->duid_type = DUID_LLT;
1023 		else if (strcmp(arg, "uuid") == 0)
1024 			ctx->duid_type = DUID_UUID;
1025 		else {
1026 			dl = hwaddr_aton(NULL, arg);
1027 			if (dl != 0) {
1028 				no = realloc(ctx->duid, dl);
1029 				if (no == NULL)
1030 					logerrx(__func__);
1031 				else {
1032 					ctx->duid = no;
1033 					ctx->duid_len = hwaddr_aton(no, arg);
1034 				}
1035 			}
1036 		}
1037 		break;
1038 	case 'E':
1039 		ifo->options |= DHCPCD_LASTLEASE;
1040 		break;
1041 	case 'F':
1042 		if (!arg) {
1043 			ifo->fqdn = FQDN_BOTH;
1044 			break;
1045 		}
1046 		if (strcmp(arg, "none") == 0)
1047 			ifo->fqdn = FQDN_NONE;
1048 		else if (strcmp(arg, "ptr") == 0)
1049 			ifo->fqdn = FQDN_PTR;
1050 		else if (strcmp(arg, "both") == 0)
1051 			ifo->fqdn = FQDN_BOTH;
1052 		else if (strcmp(arg, "disable") == 0)
1053 			ifo->fqdn = FQDN_DISABLE;
1054 		else {
1055 			logerrx("invalid FQDN value: %s", arg);
1056 			return -1;
1057 		}
1058 		break;
1059 	case 'G':
1060 		ifo->options &= ~DHCPCD_GATEWAY;
1061 		break;
1062 	case 'H':
1063 		ifo->options |= DHCPCD_XID_HWADDR;
1064 		break;
1065 	case 'I':
1066 		/* Strings have a type of 0 */;
1067 		ifo->clientid[1] = 0;
1068 		if (arg)
1069 			s = parse_hwaddr((char *)ifo->clientid + 1,
1070 			    CLIENTID_MAX_LEN, arg);
1071 		else
1072 			s = 0;
1073 		if (s == -1) {
1074 			logerr("clientid");
1075 			return -1;
1076 		}
1077 		ifo->options |= DHCPCD_CLIENTID;
1078 		ifo->clientid[0] = (uint8_t)s;
1079 		ifo->options &= ~DHCPCD_DUID;
1080 		break;
1081 	case 'J':
1082 		ifo->options |= DHCPCD_BROADCAST;
1083 		break;
1084 	case 'K':
1085 		ifo->options &= ~DHCPCD_LINK;
1086 		break;
1087 	case 'L':
1088 		ifo->options &= ~DHCPCD_IPV4LL;
1089 		break;
1090 	case 'M':
1091 		ifo->options |= DHCPCD_MANAGER;
1092 		break;
1093 	case 'O':
1094 		ARG_REQUIRED;
1095 		if (ctx->options & DHCPCD_PRINT_PIDFILE)
1096 			break;
1097 		set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo,
1098 		    &request, &require, &no, &reject);
1099 		if (make_option_mask(d, dl, od, odl, request, arg, -1) != 0 ||
1100 		    make_option_mask(d, dl, od, odl, require, arg, -1) != 0 ||
1101 		    make_option_mask(d, dl, od, odl, no, arg, 1) != 0)
1102 		{
1103 			logerrx("unknown option: %s", arg);
1104 			return -1;
1105 		}
1106 		break;
1107 	case 'Q':
1108 		ARG_REQUIRED;
1109 		if (ctx->options & DHCPCD_PRINT_PIDFILE)
1110 			break;
1111 		set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo,
1112 		    &request, &require, &no, &reject);
1113 		if (make_option_mask(d, dl, od, odl, require, arg, 1) != 0 ||
1114 		    make_option_mask(d, dl, od, odl, request, arg, 1) != 0 ||
1115 		    make_option_mask(d, dl, od, odl, no, arg, -1) != 0 ||
1116 		    make_option_mask(d, dl, od, odl, reject, arg, -1) != 0)
1117 		{
1118 			logerrx("unknown option: %s", arg);
1119 			return -1;
1120 		}
1121 		break;
1122 	case 'S':
1123 		ARG_REQUIRED;
1124 		p = strchr(arg, '=');
1125 		if (p == NULL) {
1126 			logerrx("static assignment required");
1127 			return -1;
1128 		}
1129 		p = strskipwhite(++p);
1130 		if (strncmp(arg, "ip_address=", strlen("ip_address=")) == 0) {
1131 			if (p == NULL) {
1132 				ifo->options &= ~DHCPCD_STATIC;
1133 				ifo->req_addr.s_addr = INADDR_ANY;
1134 				break;
1135 			}
1136 			if (parse_addr(&ifo->req_addr,
1137 			    ifo->req_mask.s_addr == 0 ? &ifo->req_mask : NULL,
1138 			    p) != 0)
1139 				return -1;
1140 
1141 			ifo->options |= DHCPCD_STATIC;
1142 			ifo->options &= ~DHCPCD_INFORM;
1143 		} else if (strncmp(arg, "subnet_mask=",
1144 		    strlen("subnet_mask=")) == 0)
1145 		{
1146 			if (p == NULL) {
1147 				ifo->req_mask.s_addr = INADDR_ANY;
1148 				break;
1149 			}
1150 			if (parse_addr(&ifo->req_mask, NULL, p) != 0)
1151 				return -1;
1152 		} else if (strncmp(arg, "broadcast_address=",
1153 		    strlen("broadcast_address=")) == 0)
1154 		{
1155 			if (p == NULL) {
1156 				ifo->req_brd.s_addr = INADDR_ANY;
1157 				break;
1158 			}
1159 			if (parse_addr(&ifo->req_brd, NULL, p) != 0)
1160 				return -1;
1161 		} else if (strncmp(arg, "routes=", strlen("routes=")) == 0 ||
1162 		    strncmp(arg, "static_routes=",
1163 		        strlen("static_routes=")) == 0 ||
1164 		    strncmp(arg, "classless_static_routes=",
1165 		        strlen("classless_static_routes=")) == 0 ||
1166 		    strncmp(arg, "ms_classless_static_routes=",
1167 		        strlen("ms_classless_static_routes=")) == 0)
1168 		{
1169 			struct in_addr addr3;
1170 
1171 			if (p == NULL) {
1172 				rt_headclear(&ifo->routes, AF_INET);
1173 				add_environ(&ifo->config, arg, 1);
1174 				break;
1175 			}
1176 
1177 			fp = np = strwhite(p);
1178 			if (np == NULL) {
1179 				logerrx("all routes need a gateway");
1180 				return -1;
1181 			}
1182 			*np++ = '\0';
1183 			np = strskipwhite(np);
1184 			if (parse_addr(&addr, &addr2, p) == -1 ||
1185 			    parse_addr(&addr3, NULL, np) == -1)
1186 			{
1187 				*fp = ' ';
1188 				return -1;
1189 			}
1190 			*fp = ' ';
1191 			if ((rt = rt_new0(ctx)) == NULL)
1192 				return -1;
1193 			sa_in_init(&rt->rt_dest, &addr);
1194 			sa_in_init(&rt->rt_netmask, &addr2);
1195 			sa_in_init(&rt->rt_gateway, &addr3);
1196 			if (rt_proto_add_ctx(&ifo->routes, rt, ctx))
1197 				add_environ(&ifo->config, arg, 0);
1198 		} else if (strncmp(arg, "routers=", strlen("routers=")) == 0) {
1199 			if (p == NULL) {
1200 				rt_headclear(&ifo->routes, AF_INET);
1201 				add_environ(&ifo->config, arg, 1);
1202 				break;
1203 			}
1204 			if (parse_addr(&addr, NULL, p) == -1)
1205 				return -1;
1206 			if ((rt = rt_new0(ctx)) == NULL)
1207 				return -1;
1208 			addr2.s_addr = INADDR_ANY;
1209 			sa_in_init(&rt->rt_dest, &addr2);
1210 			sa_in_init(&rt->rt_netmask, &addr2);
1211 			sa_in_init(&rt->rt_gateway, &addr);
1212 			if (rt_proto_add_ctx(&ifo->routes, rt, ctx))
1213 				add_environ(&ifo->config, arg, 0);
1214 		} else if (strncmp(arg, "interface_mtu=",
1215 		    strlen("interface_mtu=")) == 0 ||
1216 		    strncmp(arg, "mtu=", strlen("mtu=")) == 0)
1217 		{
1218 			if (p == NULL)
1219 				break;
1220 			ifo->mtu = (unsigned int)strtou(p, NULL, 0,
1221 			    MTU_MIN, MTU_MAX, &e);
1222 			if (e) {
1223 				logerrx("invalid MTU %s", p);
1224 				return -1;
1225 			}
1226 		} else if (strncmp(arg, "ip6_address=", strlen("ip6_address=")) == 0) {
1227 			if (p == NULL) {
1228 				memset(&ifo->req_addr6, 0,
1229 				    sizeof(ifo->req_addr6));
1230 				break;
1231 			}
1232 
1233 			np = strchr(p, '/');
1234 			if (np)
1235 				*np++ = '\0';
1236 			if ((i = inet_pton(AF_INET6, p, &ifo->req_addr6)) == 1) {
1237 				if (np) {
1238 					ifo->req_prefix_len = (uint8_t)strtou(np,
1239 					    NULL, 0, 0, 128, &e);
1240 					if (e) {
1241 						logerrx("%s: failed to "
1242 						    "convert prefix len",
1243 						    ifname);
1244 						return -1;
1245 					}
1246 				} else
1247 					ifo->req_prefix_len = 128;
1248 			}
1249 			if (np)
1250 				*(--np) = '\0';
1251 			if (i != 1) {
1252 				logerrx("invalid AF_INET6: %s", p);
1253 				memset(&ifo->req_addr6, 0,
1254 				    sizeof(ifo->req_addr6));
1255 				return -1;
1256 			}
1257 		} else
1258 			add_environ(&ifo->config, arg, p == NULL ? 1 : 0);
1259 		break;
1260 
1261 	case 'W':
1262 		if (parse_addr(&addr, &addr2, arg) != 0)
1263 			return -1;
1264 		if (strchr(arg, '/') == NULL)
1265 			addr2.s_addr = INADDR_BROADCAST;
1266 		naddr = reallocarray(ifo->whitelist,
1267 		    ifo->whitelist_len + 2, sizeof(in_addr_t));
1268 		if (naddr == NULL) {
1269 			logerr(__func__);
1270 			return -1;
1271 		}
1272 		ifo->whitelist = naddr;
1273 		ifo->whitelist[ifo->whitelist_len++] = addr.s_addr;
1274 		ifo->whitelist[ifo->whitelist_len++] = addr2.s_addr;
1275 		break;
1276 	case 'X':
1277 		if (parse_addr(&addr, &addr2, arg) != 0)
1278 			return -1;
1279 		if (strchr(arg, '/') == NULL)
1280 			addr2.s_addr = INADDR_BROADCAST;
1281 		naddr = reallocarray(ifo->blacklist,
1282 		    ifo->blacklist_len + 2, sizeof(in_addr_t));
1283 		if (naddr == NULL) {
1284 			logerr(__func__);
1285 			return -1;
1286 		}
1287 		ifo->blacklist = naddr;
1288 		ifo->blacklist[ifo->blacklist_len++] = addr.s_addr;
1289 		ifo->blacklist[ifo->blacklist_len++] = addr2.s_addr;
1290 		break;
1291 	case 'Z':
1292 		ARG_REQUIRED;
1293 		if (!IN_CONFIG_BLOCK(ifo))
1294 			ctx->ifdv = splitv(&ctx->ifdc, ctx->ifdv, arg);
1295 		break;
1296 	case '1':
1297 		ifo->options |= DHCPCD_ONESHOT;
1298 		break;
1299 	case '4':
1300 #ifdef INET
1301 		ifo->options &= ~DHCPCD_IPV6;
1302 		ifo->options |= DHCPCD_IPV4;
1303 		break;
1304 #else
1305 		logerrx("INET has been compiled out");
1306 		return -1;
1307 #endif
1308 	case '6':
1309 #ifdef INET6
1310 		ifo->options &= ~DHCPCD_IPV4;
1311 		ifo->options |= DHCPCD_IPV6;
1312 		break;
1313 #else
1314 		logerrx("INET6 has been compiled out");
1315 		return -1;
1316 #endif
1317 	case O_IPV4:
1318 		ifo->options |= DHCPCD_IPV4;
1319 		break;
1320 	case O_NOIPV4:
1321 		ifo->options &= ~DHCPCD_IPV4;
1322 		break;
1323 	case O_IPV6:
1324 		ifo->options |= DHCPCD_IPV6;
1325 		break;
1326 	case O_NOIPV6:
1327 		ifo->options &= ~DHCPCD_IPV6;
1328 		break;
1329 	case O_ANONYMOUS:
1330 		ifo->options |= DHCPCD_ANONYMOUS;
1331 		ifo->options &= ~DHCPCD_HOSTNAME;
1332 		ifo->fqdn = FQDN_DISABLE;
1333 
1334 		/* Block everything */
1335 		memset(ifo->nomask, 0xff, sizeof(ifo->nomask));
1336 		memset(ifo->nomask6, 0xff, sizeof(ifo->nomask6));
1337 
1338 		/* Allow the bare minimum through */
1339 #ifdef INET
1340 		del_option_mask(ifo->nomask, DHO_SUBNETMASK);
1341 		del_option_mask(ifo->nomask, DHO_CSR);
1342 		del_option_mask(ifo->nomask, DHO_ROUTER);
1343 		del_option_mask(ifo->nomask, DHO_DNSSERVER);
1344 		del_option_mask(ifo->nomask, DHO_DNSDOMAIN);
1345 		del_option_mask(ifo->nomask, DHO_BROADCAST);
1346 		del_option_mask(ifo->nomask, DHO_STATICROUTE);
1347 		del_option_mask(ifo->nomask, DHO_SERVERID);
1348 		del_option_mask(ifo->nomask, DHO_RENEWALTIME);
1349 		del_option_mask(ifo->nomask, DHO_REBINDTIME);
1350 		del_option_mask(ifo->nomask, DHO_DNSSEARCH);
1351 #endif
1352 
1353 #ifdef DHCP6
1354 		del_option_mask(ifo->nomask6, D6_OPTION_DNS_SERVERS);
1355 		del_option_mask(ifo->nomask6, D6_OPTION_DOMAIN_LIST);
1356 		del_option_mask(ifo->nomask6, D6_OPTION_SOL_MAX_RT);
1357 		del_option_mask(ifo->nomask6, D6_OPTION_INF_MAX_RT);
1358 #endif
1359 
1360 		break;
1361 	case O_RANDOMISE_HWADDR:
1362 		ifo->randomise_hwaddr = true;
1363 		break;
1364 #ifdef INET
1365 	case O_ARPING:
1366 		while (arg != NULL) {
1367 			fp = strwhite(arg);
1368 			if (fp)
1369 				*fp++ = '\0';
1370 			if (parse_addr(&addr, NULL, arg) != 0)
1371 				return -1;
1372 			naddr = reallocarray(ifo->arping,
1373 			    (size_t)ifo->arping_len + 1, sizeof(in_addr_t));
1374 			if (naddr == NULL) {
1375 				logerr(__func__);
1376 				return -1;
1377 			}
1378 			ifo->arping = naddr;
1379 			ifo->arping[ifo->arping_len++] = addr.s_addr;
1380 			arg = strskipwhite(fp);
1381 		}
1382 		break;
1383 	case O_DESTINATION:
1384 		ARG_REQUIRED;
1385 		if (ctx->options & DHCPCD_PRINT_PIDFILE)
1386 			break;
1387 		set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo,
1388 		    &request, &require, &no, &reject);
1389 		if (make_option_mask(d, dl, od, odl,
1390 		    ifo->dstmask, arg, 2) != 0)
1391 		{
1392 			if (errno == EINVAL)
1393 				logerrx("option does not take"
1394 				    " an IPv4 address: %s", arg);
1395 			else
1396 				logerrx("unknown option: %s", arg);
1397 			return -1;
1398 		}
1399 		break;
1400 	case O_FALLBACK:
1401 		ARG_REQUIRED;
1402 		free(ifo->fallback);
1403 		ifo->fallback = strdup(arg);
1404 		if (ifo->fallback == NULL) {
1405 			logerrx(__func__);
1406 			return -1;
1407 		}
1408 		break;
1409 #endif
1410 	case O_IAID:
1411 		ARG_REQUIRED;
1412 		if (ctx->options & DHCPCD_MANAGER && !IN_CONFIG_BLOCK(ifo)) {
1413 			logerrx("IAID must belong in an interface block");
1414 			return -1;
1415 		}
1416 		if (parse_iaid(ifo->iaid, arg, sizeof(ifo->iaid)) == -1) {
1417 			logerrx("invalid IAID %s", arg);
1418 			return -1;
1419 		}
1420 		ifo->options |= DHCPCD_IAID;
1421 		break;
1422 	case O_IPV6RS:
1423 		ifo->options |= DHCPCD_IPV6RS;
1424 		break;
1425 	case O_NOIPV6RS:
1426 		ifo->options &= ~DHCPCD_IPV6RS;
1427 		break;
1428 	case O_IPV6RA_FORK:
1429 		ifo->options &= ~DHCPCD_IPV6RA_REQRDNSS;
1430 		break;
1431 	case O_IPV6RA_AUTOCONF:
1432 		ifo->options |= DHCPCD_IPV6RA_AUTOCONF;
1433 		break;
1434 	case O_IPV6RA_NOAUTOCONF:
1435 		ifo->options &= ~DHCPCD_IPV6RA_AUTOCONF;
1436 		break;
1437 	case O_NOALIAS:
1438 		ifo->options |= DHCPCD_NOALIAS;
1439 		break;
1440 #ifdef DHCP6
1441 	case O_IA_NA:
1442 		i = D6_OPTION_IA_NA;
1443 		/* FALLTHROUGH */
1444 	case O_IA_TA:
1445 		if (i == 0)
1446 			i = D6_OPTION_IA_TA;
1447 		/* FALLTHROUGH */
1448 	case O_IA_PD:
1449 		if (i == 0) {
1450 #ifdef SMALL
1451 			logwarnx("%s: IA_PD not compiled in", ifname);
1452 			return -1;
1453 #else
1454 			if (ctx->options & DHCPCD_MANAGER &&
1455 			    !IN_CONFIG_BLOCK(ifo))
1456 			{
1457 				logerrx("IA PD must belong in an "
1458 				    "interface block");
1459 				return -1;
1460 			}
1461 			i = D6_OPTION_IA_PD;
1462 #endif
1463 		}
1464 		if (ctx->options & DHCPCD_MANAGER &&
1465 		    !IN_CONFIG_BLOCK(ifo) && arg)
1466 		{
1467 			logerrx("IA with IAID must belong in an "
1468 			    "interface block");
1469 			return -1;
1470 		}
1471 		ifo->options |= DHCPCD_IA_FORCED;
1472 		fp = strwhite(arg);
1473 		if (fp) {
1474 			*fp++ = '\0';
1475 			fp = strskipwhite(fp);
1476 		}
1477 		if (arg) {
1478 			p = strchr(arg, '/');
1479 			if (p)
1480 				*p++ = '\0';
1481 			if (parse_iaid(iaid, arg, sizeof(iaid)) == -1) {
1482 				logerr("invalid IAID: %s", arg);
1483 				return -1;
1484 			}
1485 		}
1486 		ia = NULL;
1487 		for (sl = 0; sl < ifo->ia_len; sl++) {
1488 			if ((arg == NULL && !ifo->ia[sl].iaid_set) ||
1489 			    (arg != NULL && ifo->ia[sl].iaid_set &&
1490 			    ifo->ia[sl].ia_type == (uint16_t)i &&
1491 			    ifo->ia[sl].iaid[0] == iaid[0] &&
1492 			    ifo->ia[sl].iaid[1] == iaid[1] &&
1493 			    ifo->ia[sl].iaid[2] == iaid[2] &&
1494 			    ifo->ia[sl].iaid[3] == iaid[3]))
1495 			{
1496 			        ia = &ifo->ia[sl];
1497 				break;
1498 			}
1499 		}
1500 		if (ia == NULL) {
1501 			ia = reallocarray(ifo->ia,
1502 			    ifo->ia_len + 1, sizeof(*ifo->ia));
1503 			if (ia == NULL) {
1504 				logerr(__func__);
1505 				return -1;
1506 			}
1507 			ifo->ia = ia;
1508 			ia = &ifo->ia[ifo->ia_len++];
1509 			ia->ia_type = (uint16_t)i;
1510 			if (arg) {
1511 				ia->iaid[0] = iaid[0];
1512 				ia->iaid[1] = iaid[1];
1513 				ia->iaid[2] = iaid[2];
1514 				ia->iaid[3] = iaid[3];
1515 				ia->iaid_set = 1;
1516 			} else
1517 				ia->iaid_set = 0;
1518 			if (!ia->iaid_set ||
1519 			    p == NULL ||
1520 			    ia->ia_type == D6_OPTION_IA_TA)
1521 			{
1522 				memset(&ia->addr, 0, sizeof(ia->addr));
1523 				ia->prefix_len = 0;
1524 			} else {
1525 				arg = p;
1526 				p = strchr(arg, '/');
1527 				if (p)
1528 					*p++ = '\0';
1529 				if (inet_pton(AF_INET6, arg, &ia->addr) != 1) {
1530 					logerrx("invalid AF_INET6: %s", arg);
1531 					memset(&ia->addr, 0, sizeof(ia->addr));
1532 				}
1533 				if (p && ia->ia_type == D6_OPTION_IA_PD) {
1534 					ia->prefix_len = (uint8_t)strtou(p,
1535 					    NULL, 0, 8, 120, &e);
1536 					if (e) {
1537 						logerrx("%s: failed to convert"
1538 						    " prefix len",
1539 						    p);
1540 						ia->prefix_len = 0;
1541 					}
1542 				}
1543 			}
1544 #ifndef SMALL
1545 			ia->sla_max = 0;
1546 			ia->sla_len = 0;
1547 			ia->sla = NULL;
1548 #endif
1549 		}
1550 
1551 #ifdef SMALL
1552 		break;
1553 #else
1554 		if (ia->ia_type != D6_OPTION_IA_PD)
1555 			break;
1556 
1557 		for (p = fp; p; p = fp) {
1558 			fp = strwhite(p);
1559 			if (fp) {
1560 				*fp++ = '\0';
1561 				fp = strskipwhite(fp);
1562 			}
1563 			sla = reallocarray(ia->sla,
1564 			    ia->sla_len + 1, sizeof(*ia->sla));
1565 			if (sla == NULL) {
1566 				logerr(__func__);
1567 				return -1;
1568 			}
1569 			ia->sla = sla;
1570 			sla = &ia->sla[ia->sla_len++];
1571 			np = strchr(p, '/');
1572 			if (np)
1573 				*np++ = '\0';
1574 			if (strlcpy(sla->ifname, p,
1575 			    sizeof(sla->ifname)) >= sizeof(sla->ifname))
1576 			{
1577 				logerrx("%s: interface name too long", arg);
1578 				goto err_sla;
1579 			}
1580 			sla->sla_set = false;
1581 			sla->prefix_len = 0;
1582 			sla->suffix = 1;
1583 			p = np;
1584 			if (p) {
1585 				np = strchr(p, '/');
1586 				if (np)
1587 					*np++ = '\0';
1588 				if (*p != '\0') {
1589 					sla->sla = (uint32_t)strtou(p, NULL,
1590 					    0, 0, UINT32_MAX, &e);
1591 					sla->sla_set = true;
1592 					if (e) {
1593 						logerrx("%s: failed to convert "
1594 						    "sla",
1595 						    ifname);
1596 						goto err_sla;
1597 					}
1598 				}
1599 				p = np;
1600 			}
1601 			if (p) {
1602 				np = strchr(p, '/');
1603 				if (np)
1604 					*np++ = '\0';
1605 				if (*p != '\0') {
1606 					sla->prefix_len = (uint8_t)strtou(p,
1607 				    NULL, 0, 0, 120, &e);
1608 					if (e) {
1609 						logerrx("%s: failed to "
1610 						    "convert prefix len",
1611 						    ifname);
1612 						goto err_sla;
1613 					}
1614 				}
1615 				p = np;
1616 			}
1617 			if (p) {
1618 				np = strchr(p, '/');
1619 				if (np)
1620 					*np = '\0';
1621 				if (*p != '\0') {
1622 					sla->suffix = (uint64_t)strtou(p, NULL,
1623 					    0, 0, UINT64_MAX, &e);
1624 					if (e) {
1625 						logerrx("%s: failed to "
1626 						    "convert suffix",
1627 						    ifname);
1628 						goto err_sla;
1629 					}
1630 				}
1631 			}
1632 			/* Sanity check */
1633 			for (sl = 0; sl < ia->sla_len - 1; sl++) {
1634 				slap = &ia->sla[sl];
1635 				if (slap->sla_set != sla->sla_set) {
1636 					logerrx("%s: cannot mix automatic "
1637 					    "and fixed SLA",
1638 					    sla->ifname);
1639 					goto err_sla;
1640 				}
1641 				if (ia->prefix_len &&
1642 				    (sla->prefix_len == ia->prefix_len ||
1643 				    slap->prefix_len == ia->prefix_len))
1644 				{
1645 					logerrx("%s: cannot delegte the same"
1646 					    "prefix length more than once",
1647 					    sla->ifname);
1648 					goto err_sla;
1649 				}
1650 				if (!sla->sla_set &&
1651 				    strcmp(slap->ifname, sla->ifname) == 0)
1652 				{
1653 					logwarnx("%s: cannot specify the "
1654 					    "same interface twice with "
1655 					    "an automatic SLA",
1656 					    sla->ifname);
1657 					goto err_sla;
1658 				}
1659 				if (slap->sla_set && sla->sla_set &&
1660 				    slap->sla == sla->sla)
1661 				{
1662 					logerrx("%s: cannot"
1663 					    " assign the same SLA %u"
1664 					    " more than once",
1665 					    sla->ifname, sla->sla);
1666 					goto err_sla;
1667 				}
1668 			}
1669 			if (sla->sla_set && sla->sla > ia->sla_max)
1670 				ia->sla_max = sla->sla;
1671 		}
1672 		break;
1673 err_sla:
1674 		ia->sla_len--;
1675 		return -1;
1676 #endif
1677 #endif
1678 	case O_HOSTNAME_SHORT:
1679 		ifo->options |= DHCPCD_HOSTNAME | DHCPCD_HOSTNAME_SHORT;
1680 		break;
1681 	case O_DEV:
1682 		ARG_REQUIRED;
1683 #ifdef PLUGIN_DEV
1684 		if (ctx->dev_load)
1685 			free(ctx->dev_load);
1686 		ctx->dev_load = strdup(arg);
1687 #endif
1688 		break;
1689 	case O_NODEV:
1690 		ifo->options &= ~DHCPCD_DEV;
1691 		break;
1692 	case O_DEFINE:
1693 		dop = &ifo->dhcp_override;
1694 		dop_len = &ifo->dhcp_override_len;
1695 		/* FALLTHROUGH */
1696 	case O_DEFINEND:
1697 		if (dop == NULL) {
1698 			dop = &ifo->nd_override;
1699 			dop_len = &ifo->nd_override_len;
1700 		}
1701 		/* FALLTHROUGH */
1702 	case O_DEFINE6:
1703 		if (dop == NULL) {
1704 			dop = &ifo->dhcp6_override;
1705 			dop_len = &ifo->dhcp6_override_len;
1706 		}
1707 		/* FALLTHROUGH */
1708 	case O_VENDOPT:
1709 		if (dop == NULL) {
1710 			dop = &ifo->vivso_override;
1711 			dop_len = &ifo->vivso_override_len;
1712 		}
1713 		*edop = *ldop = NULL;
1714 		/* FALLTHROUGH */
1715 	case O_EMBED:
1716 		if (dop == NULL) {
1717 			if (*edop) {
1718 				dop = &(*edop)->embopts;
1719 				dop_len = &(*edop)->embopts_len;
1720 			} else if (ldop) {
1721 				dop = &(*ldop)->embopts;
1722 				dop_len = &(*ldop)->embopts_len;
1723 			} else {
1724 				logerrx("embed must be after a define "
1725 				    "or encap");
1726 				return -1;
1727 			}
1728 		}
1729 		/* FALLTHROUGH */
1730 	case O_ENCAP:
1731 		ARG_REQUIRED;
1732 		if (dop == NULL) {
1733 			if (*ldop == NULL) {
1734 				logerrx("encap must be after a define");
1735 				return -1;
1736 			}
1737 			dop = &(*ldop)->encopts;
1738 			dop_len = &(*ldop)->encopts_len;
1739 		}
1740 
1741 		/* Shared code for define, define6, embed and encap */
1742 
1743 		/* code */
1744 		if (opt == O_EMBED) /* Embedded options don't have codes */
1745 			u = 0;
1746 		else {
1747 			fp = strwhite(arg);
1748 			if (fp == NULL) {
1749 				logerrx("invalid syntax: %s", arg);
1750 				return -1;
1751 			}
1752 			*fp++ = '\0';
1753 			u = (uint32_t)strtou(arg, NULL, 0, 0, UINT32_MAX, &e);
1754 			if (e) {
1755 				logerrx("invalid code: %s", arg);
1756 				return -1;
1757 			}
1758 			arg = strskipwhite(fp);
1759 			if (arg == NULL) {
1760 				logerrx("invalid syntax");
1761 				return -1;
1762 			}
1763 		}
1764 		/* type */
1765 		fp = strwhite(arg);
1766 		if (fp)
1767 			*fp++ = '\0';
1768 		np = strchr(arg, ':');
1769 		/* length */
1770 		if (np) {
1771 			*np++ = '\0';
1772 			bp = NULL; /* No bitflag */
1773 			l = (long)strtou(np, NULL, 0, 0, LONG_MAX, &e);
1774 			if (e) {
1775 				logerrx("failed to convert length");
1776 				return -1;
1777 			}
1778 		} else {
1779 			l = 0;
1780 			bp = strchr(arg, '='); /* bitflag assignment */
1781 			if (bp)
1782 				*bp++ = '\0';
1783 		}
1784 		t = 0;
1785 		if (strcasecmp(arg, "request") == 0) {
1786 			t |= OT_REQUEST;
1787 			arg = strskipwhite(fp);
1788 			fp = strwhite(arg);
1789 			if (fp == NULL) {
1790 				logerrx("incomplete request type");
1791 				return -1;
1792 			}
1793 			*fp++ = '\0';
1794 		} else if (strcasecmp(arg, "norequest") == 0) {
1795 			t |= OT_NOREQ;
1796 			arg = strskipwhite(fp);
1797 			fp = strwhite(arg);
1798 			if (fp == NULL) {
1799 				logerrx("incomplete request type");
1800 				return -1;
1801 			}
1802 			*fp++ = '\0';
1803 		}
1804 		if (strcasecmp(arg, "optional") == 0) {
1805 			t |= OT_OPTIONAL;
1806 			arg = strskipwhite(fp);
1807 			fp = strwhite(arg);
1808 			if (fp == NULL) {
1809 				logerrx("incomplete optional type");
1810 				return -1;
1811 			}
1812 			*fp++ = '\0';
1813 		}
1814 		if (strcasecmp(arg, "index") == 0) {
1815 			t |= OT_INDEX;
1816 			arg = strskipwhite(fp);
1817 			fp = strwhite(arg);
1818 			if (fp == NULL) {
1819 				logerrx("incomplete index type");
1820 				return -1;
1821 			}
1822 			*fp++ = '\0';
1823 		}
1824 		if (strcasecmp(arg, "array") == 0) {
1825 			t |= OT_ARRAY;
1826 			arg = strskipwhite(fp);
1827 			fp = strwhite(arg);
1828 			if (fp == NULL) {
1829 				logerrx("incomplete array type");
1830 				return -1;
1831 			}
1832 			*fp++ = '\0';
1833 		}
1834 		if (strcasecmp(arg, "ipaddress") == 0)
1835 			t |= OT_ADDRIPV4;
1836 		else if (strcasecmp(arg, "ip6address") == 0)
1837 			t |= OT_ADDRIPV6;
1838 		else if (strcasecmp(arg, "string") == 0)
1839 			t |= OT_STRING;
1840 		else if (strcasecmp(arg, "uri") == 0)
1841 			t |= OT_URI;
1842 		else if (strcasecmp(arg, "byte") == 0)
1843 			t |= OT_UINT8;
1844 		else if (strcasecmp(arg, "bitflags") == 0)
1845 			t |= OT_BITFLAG;
1846 		else if (strcasecmp(arg, "uint8") == 0)
1847 			t |= OT_UINT8;
1848 		else if (strcasecmp(arg, "int8") == 0)
1849 			t |= OT_INT8;
1850 		else if (strcasecmp(arg, "uint16") == 0)
1851 			t |= OT_UINT16;
1852 		else if (strcasecmp(arg, "int16") == 0)
1853 			t |= OT_INT16;
1854 		else if (strcasecmp(arg, "uint32") == 0)
1855 			t |= OT_UINT32;
1856 		else if (strcasecmp(arg, "int32") == 0)
1857 			t |= OT_INT32;
1858 		else if (strcasecmp(arg, "flag") == 0)
1859 			t |= OT_FLAG;
1860 		else if (strcasecmp(arg, "raw") == 0)
1861 			t |= OT_STRING | OT_RAW;
1862 		else if (strcasecmp(arg, "ascii") == 0)
1863 			t |= OT_STRING | OT_ASCII;
1864 		else if (strcasecmp(arg, "domain") == 0)
1865 			t |= OT_STRING | OT_DOMAIN | OT_RFC1035;
1866 		else if (strcasecmp(arg, "dname") == 0)
1867 			t |= OT_STRING | OT_DOMAIN;
1868 		else if (strcasecmp(arg, "binhex") == 0)
1869 			t |= OT_STRING | OT_BINHEX;
1870 		else if (strcasecmp(arg, "embed") == 0)
1871 			t |= OT_EMBED;
1872 		else if (strcasecmp(arg, "encap") == 0)
1873 			t |= OT_ENCAP;
1874 		else if (strcasecmp(arg, "rfc3361") ==0)
1875 			t |= OT_STRING | OT_RFC3361;
1876 		else if (strcasecmp(arg, "rfc3442") ==0)
1877 			t |= OT_STRING | OT_RFC3442;
1878 		else if (strcasecmp(arg, "option") == 0)
1879 			t |= OT_OPTION;
1880 		else {
1881 			logerrx("unknown type: %s", arg);
1882 			return -1;
1883 		}
1884 		if (l && !(t & (OT_STRING | OT_BINHEX))) {
1885 			logwarnx("ignoring length for type: %s", arg);
1886 			l = 0;
1887 		}
1888 		if (t & OT_ARRAY && t & (OT_STRING | OT_BINHEX) &&
1889 		    !(t & (OT_RFC1035 | OT_DOMAIN)))
1890 		{
1891 			logwarnx("ignoring array for strings");
1892 			t &= ~OT_ARRAY;
1893 		}
1894 		if (t & OT_BITFLAG) {
1895 			if (bp == NULL)
1896 				logwarnx("missing bitflag assignment");
1897 		}
1898 		/* variable */
1899 		if (!fp) {
1900 			if (!(t & OT_OPTION)) {
1901 			        logerrx("type %s requires a variable name",
1902 				    arg);
1903 				return -1;
1904 			}
1905 			np = NULL;
1906 		} else {
1907 			arg = strskipwhite(fp);
1908 			fp = strwhite(arg);
1909 			if (fp)
1910 				*fp++ = '\0';
1911 			if (strcasecmp(arg, "reserved")) {
1912 				np = strdup(arg);
1913 				if (np == NULL) {
1914 					logerr(__func__);
1915 					return -1;
1916 				}
1917 			} else {
1918 				np = NULL;
1919 				t |= OT_RESERVED;
1920 			}
1921 		}
1922 		if (opt != O_EMBED) {
1923 			for (dl = 0, ndop = *dop; dl < *dop_len; dl++, ndop++)
1924 			{
1925 				/* type 0 seems freshly malloced struct
1926 				 * for us to use */
1927 				if (ndop->option == u || ndop->type == 0)
1928 					break;
1929 			}
1930 			if (dl == *dop_len)
1931 				ndop = NULL;
1932 		} else
1933 			ndop = NULL;
1934 		if (ndop == NULL) {
1935 			ndop = reallocarray(*dop, *dop_len + 1, sizeof(**dop));
1936 			if (ndop == NULL) {
1937 				logerr(__func__);
1938 				free(np);
1939 				return -1;
1940 			}
1941 			*dop = ndop;
1942 			ndop = &(*dop)[(*dop_len)++];
1943 			ndop->embopts = NULL;
1944 			ndop->embopts_len = 0;
1945 			ndop->encopts = NULL;
1946 			ndop->encopts_len = 0;
1947 		} else
1948 			free_dhcp_opt_embenc(ndop);
1949 		ndop->option = (uint32_t)u; /* could have been 0 */
1950 		ndop->type = t;
1951 		ndop->len = (size_t)l;
1952 		ndop->var = np;
1953 		if (bp) {
1954 			dl = strlen(bp);
1955 			memcpy(ndop->bitflags, bp, dl);
1956 			memset(ndop->bitflags + dl, 0,
1957 			    sizeof(ndop->bitflags) - dl);
1958 		} else
1959 			memset(ndop->bitflags, 0, sizeof(ndop->bitflags));
1960 		/* Save the define for embed and encap options */
1961 		switch (opt) {
1962 		case O_DEFINE:
1963 		case O_DEFINEND:
1964 		case O_DEFINE6:
1965 		case O_VENDOPT:
1966 			*ldop = ndop;
1967 			break;
1968 		case O_ENCAP:
1969 			*edop = ndop;
1970 			break;
1971 		}
1972 		break;
1973 	case O_VENDCLASS:
1974 		ARG_REQUIRED;
1975 		fp = strwhite(arg);
1976 		if (fp)
1977 			*fp++ = '\0';
1978 		u = (uint32_t)strtou(arg, NULL, 0, 0, UINT32_MAX, &e);
1979 		if (e) {
1980 			logerrx("invalid code: %s", arg);
1981 			return -1;
1982 		}
1983 		fp = strskipwhite(fp);
1984 		if (fp) {
1985 			s = parse_string(NULL, 0, fp);
1986 			if (s == -1) {
1987 				logerr(__func__);
1988 				return -1;
1989 			}
1990 			dl = (size_t)s;
1991 			if (dl + (sizeof(uint16_t) * 2) > UINT16_MAX) {
1992 				logerrx("vendor class is too big");
1993 				return -1;
1994 			}
1995 			np = malloc(dl);
1996 			if (np == NULL) {
1997 				logerr(__func__);
1998 				return -1;
1999 			}
2000 			parse_string(np, dl, fp);
2001 		} else {
2002 			dl = 0;
2003 			np = NULL;
2004 		}
2005 		vivco = reallocarray(ifo->vivco,
2006 		    ifo->vivco_len + 1, sizeof(*ifo->vivco));
2007 		if (vivco == NULL) {
2008 			logerr( __func__);
2009 			free(np);
2010 			return -1;
2011 		}
2012 		ifo->vivco = vivco;
2013 		ifo->vivco_en = (uint32_t)u;
2014 		vivco = &ifo->vivco[ifo->vivco_len++];
2015 		vivco->len = dl;
2016 		vivco->data = (uint8_t *)np;
2017 		break;
2018 	case O_AUTHPROTOCOL:
2019 		ARG_REQUIRED;
2020 #ifdef AUTH
2021 		fp = strwhite(arg);
2022 		if (fp)
2023 			*fp++ = '\0';
2024 		if (strcasecmp(arg, "token") == 0)
2025 			ifo->auth.protocol = AUTH_PROTO_TOKEN;
2026 		else if (strcasecmp(arg, "delayed") == 0)
2027 			ifo->auth.protocol = AUTH_PROTO_DELAYED;
2028 		else if (strcasecmp(arg, "delayedrealm") == 0)
2029 			ifo->auth.protocol = AUTH_PROTO_DELAYEDREALM;
2030 		else {
2031 			logerrx("%s: unsupported protocol", arg);
2032 			return -1;
2033 		}
2034 		arg = strskipwhite(fp);
2035 		fp = strwhite(arg);
2036 		if (arg == NULL) {
2037 			ifo->auth.options |= DHCPCD_AUTH_SEND;
2038 			if (ifo->auth.protocol == AUTH_PROTO_TOKEN)
2039 				ifo->auth.protocol = AUTH_ALG_NONE;
2040 			else
2041 				ifo->auth.algorithm = AUTH_ALG_HMAC_MD5;
2042 			ifo->auth.rdm = AUTH_RDM_MONOTONIC;
2043 			break;
2044 		}
2045 		if (fp)
2046 			*fp++ = '\0';
2047 		if (ifo->auth.protocol == AUTH_PROTO_TOKEN) {
2048 			np = strchr(arg, '/');
2049 			if (np) {
2050 				if (fp == NULL || np < fp)
2051 					*np++ = '\0';
2052 				else
2053 					np = NULL;
2054 			}
2055 			if (parse_uint32(&ifo->auth.token_snd_secretid,
2056 			    arg) == -1)
2057 				logerrx("%s: not a number", arg);
2058 			else
2059 				ifo->auth.token_rcv_secretid =
2060 				    ifo->auth.token_snd_secretid;
2061 			if (np &&
2062 			    parse_uint32(&ifo->auth.token_rcv_secretid,
2063 			    np) == -1)
2064 				logerrx("%s: not a number", arg);
2065 		} else {
2066 			if (strcasecmp(arg, "hmacmd5") == 0 ||
2067 			    strcasecmp(arg, "hmac-md5") == 0)
2068 				ifo->auth.algorithm = AUTH_ALG_HMAC_MD5;
2069 			else {
2070 				logerrx("%s: unsupported algorithm", arg);
2071 				return 1;
2072 			}
2073 		}
2074 		arg = fp;
2075 		if (arg == NULL) {
2076 			ifo->auth.options |= DHCPCD_AUTH_SEND;
2077 			ifo->auth.rdm = AUTH_RDM_MONOTONIC;
2078 			break;
2079 		}
2080 		if (strcasecmp(arg, "monocounter") == 0) {
2081 			ifo->auth.rdm = AUTH_RDM_MONOTONIC;
2082 			ifo->auth.options |= DHCPCD_AUTH_RDM_COUNTER;
2083 		} else if (strcasecmp(arg, "monotonic") ==0 ||
2084 		    strcasecmp(arg, "monotime") == 0)
2085 			ifo->auth.rdm = AUTH_RDM_MONOTONIC;
2086 		else {
2087 			logerrx("%s: unsupported RDM", arg);
2088 			return -1;
2089 		}
2090 		ifo->auth.options |= DHCPCD_AUTH_SEND;
2091 		break;
2092 #else
2093 		logerrx("no authentication support");
2094 		return -1;
2095 #endif
2096 	case O_AUTHTOKEN:
2097 		ARG_REQUIRED;
2098 #ifdef AUTH
2099 		fp = strwhite(arg);
2100 		if (fp == NULL) {
2101 			logerrx("authtoken requires a realm");
2102 			return -1;
2103 		}
2104 		*fp++ = '\0';
2105 		token = calloc(1, sizeof(*token));
2106 		if (token == NULL) {
2107 			logerr(__func__);
2108 			return -1;
2109 		}
2110 		if (parse_uint32(&token->secretid, arg) == -1) {
2111 			logerrx("%s: not a number", arg);
2112 			goto invalid_token;
2113 		}
2114 		arg = fp;
2115 		fp = strend(arg);
2116 		if (fp == NULL) {
2117 			logerrx("authtoken requires a realm");
2118 			goto invalid_token;
2119 		}
2120 		*fp++ = '\0';
2121 		s = parse_string(NULL, 0, arg);
2122 		if (s == -1) {
2123 			logerr("realm_len");
2124 			goto invalid_token;
2125 		}
2126 		if (s != 0) {
2127 			token->realm_len = (size_t)s;
2128 			token->realm = malloc(token->realm_len);
2129 			if (token->realm == NULL) {
2130 				logerr(__func__);
2131 				goto invalid_token;
2132 			}
2133 			parse_string((char *)token->realm, token->realm_len,
2134 			    arg);
2135 		}
2136 		arg = fp;
2137 		fp = strend(arg);
2138 		if (fp == NULL) {
2139 			logerrx("authtoken requies an expiry date");
2140 			goto invalid_token;
2141 		}
2142 		*fp++ = '\0';
2143 		if (*arg == '"') {
2144 			arg++;
2145 			np = strchr(arg, '"');
2146 			if (np)
2147 				*np = '\0';
2148 		}
2149 		if (strcmp(arg, "0") == 0 || strcasecmp(arg, "forever") == 0)
2150 			token->expire =0;
2151 		else {
2152 			struct tm tm;
2153 
2154 			memset(&tm, 0, sizeof(tm));
2155 			if (strptime(arg, "%Y-%m-%d %H:%M", &tm) == NULL) {
2156 				logerrx("%s: invalid date time", arg);
2157 				goto invalid_token;
2158 			}
2159 			if ((token->expire = mktime(&tm)) == (time_t)-1) {
2160 				logerr("%s: mktime", __func__);
2161 				goto invalid_token;
2162 			}
2163 		}
2164 		arg = fp;
2165 		s = parse_string(NULL, 0, arg);
2166 		if (s == -1 || s == 0) {
2167 			if (s == -1)
2168 				logerr("token_len");
2169 			else
2170 				logerrx("authtoken requires a key");
2171 			goto invalid_token;
2172 		}
2173 		token->key_len = (size_t)s;
2174 		token->key = malloc(token->key_len);
2175 		if (token->key == NULL) {
2176 			logerr(__func__);
2177 			goto invalid_token;
2178 		}
2179 		parse_string((char *)token->key, token->key_len, arg);
2180 		TAILQ_INSERT_TAIL(&ifo->auth.tokens, token, next);
2181 		break;
2182 
2183 invalid_token:
2184 		free(token->realm);
2185 		free(token);
2186 #else
2187 		logerrx("no authentication support");
2188 #endif
2189 		return -1;
2190 	case O_AUTHNOTREQUIRED:
2191 		ifo->auth.options &= ~DHCPCD_AUTH_REQUIRE;
2192 		break;
2193 	case O_DHCP:
2194 		ifo->options |= DHCPCD_DHCP | DHCPCD_WANTDHCP | DHCPCD_IPV4;
2195 		break;
2196 	case O_NODHCP:
2197 		ifo->options &= ~DHCPCD_DHCP;
2198 		break;
2199 	case O_DHCP6:
2200 		ifo->options |= DHCPCD_DHCP6 | DHCPCD_IPV6;
2201 		break;
2202 	case O_NODHCP6:
2203 		ifo->options &= ~DHCPCD_DHCP6;
2204 		break;
2205 	case O_CONTROLGRP:
2206 		ARG_REQUIRED;
2207 #ifdef PRIVSEP
2208 		/* Control group is already set by this point.
2209 		 * We don't need to pledge getpw either with this. */
2210 		if (IN_PRIVSEP(ctx))
2211 			break;
2212 #endif
2213 #ifdef _REENTRANT
2214 		l = sysconf(_SC_GETGR_R_SIZE_MAX);
2215 		if (l == -1)
2216 			dl = 1024;
2217 		else
2218 			dl = (size_t)l;
2219 		p = malloc(dl);
2220 		if (p == NULL) {
2221 			logerr(__func__);
2222 			return -1;
2223 		}
2224 		while ((i = getgrnam_r(arg, &grpbuf, p, dl, &grp)) ==
2225 		    ERANGE)
2226 		{
2227 			size_t nl = dl * 2;
2228 			if (nl < dl) {
2229 				logerrx("control_group: out of buffer");
2230 				free(p);
2231 				return -1;
2232 			}
2233 			dl = nl;
2234 			np = realloc(p, dl);
2235 			if (np == NULL) {
2236 				logerr(__func__);
2237 				free(p);
2238 				return -1;
2239 			}
2240 			p = np;
2241 		}
2242 		if (i != 0) {
2243 			errno = i;
2244 			logerr("getgrnam_r");
2245 			free(p);
2246 			return -1;
2247 		}
2248 		if (grp == NULL) {
2249 			if (!ctx->control_group)
2250 				logerrx("controlgroup: %s: not found", arg);
2251 			free(p);
2252 			return -1;
2253 		}
2254 		ctx->control_group = grp->gr_gid;
2255 		free(p);
2256 #else
2257 		grp = getgrnam(arg);
2258 		if (grp == NULL) {
2259 			if (!ctx->control_group)
2260 				logerrx("controlgroup: %s: not found", arg);
2261 			return -1;
2262 		}
2263 		ctx->control_group = grp->gr_gid;
2264 #endif
2265 		break;
2266 	case O_GATEWAY:
2267 		ifo->options |= DHCPCD_GATEWAY;
2268 		break;
2269 	case O_NOUP:
2270 		ifo->options &= ~DHCPCD_IF_UP;
2271 		break;
2272 	case O_SLAAC:
2273 		ARG_REQUIRED;
2274 		np = strwhite(arg);
2275 		if (np != NULL) {
2276 			*np++ = '\0';
2277 			np = strskipwhite(np);
2278 		}
2279 		if (strcmp(arg, "private") == 0 ||
2280 		    strcmp(arg, "stableprivate") == 0 ||
2281 		    strcmp(arg, "stable") == 0)
2282 			ifo->options |= DHCPCD_SLAACPRIVATE;
2283 		else
2284 			ifo->options &= ~DHCPCD_SLAACPRIVATE;
2285 #ifdef INET6
2286 		if (strcmp(arg, "token") == 0) {
2287 			if (np == NULL) {
2288 				logerrx("slaac token: no token specified");
2289 				return -1;
2290 			}
2291 			arg = np;
2292 			np = strwhite(np);
2293 			if (np != NULL) {
2294 				*np++ = '\0';
2295 				np = strskipwhite(np);
2296 			}
2297 			if (inet_pton(AF_INET6, arg, &ifo->token) != 1) {
2298 				logerrx("slaac token: invalid token");
2299 				return -1;
2300 			}
2301 		}
2302 #endif
2303 		if (np != NULL &&
2304 		    (strcmp(np, "temp") == 0 || strcmp(np, "temporary") == 0))
2305 			ifo->options |= DHCPCD_SLAACTEMP;
2306 		break;
2307 	case O_BOOTP:
2308 		ifo->options |= DHCPCD_BOOTP;
2309 		break;
2310 	case O_NODELAY:
2311 		ifo->options &= ~DHCPCD_INITIAL_DELAY;
2312 		break;
2313 	case O_LASTLEASE_EXTEND:
2314 		ifo->options |= DHCPCD_LASTLEASE | DHCPCD_LASTLEASE_EXTEND;
2315 		break;
2316 	case O_INACTIVE:
2317 		ifo->options |= DHCPCD_INACTIVE;
2318 		break;
2319 	case O_MUDURL:
2320 		ARG_REQUIRED;
2321 		s = parse_string((char *)ifo->mudurl + 1, MUDURL_MAX_LEN, arg);
2322 		if (s == -1) {
2323 			logerr("mudurl");
2324 			return -1;
2325 		}
2326 		*ifo->mudurl = (uint8_t)s;
2327 		break;
2328 	case O_LINK_RCVBUF:
2329 #ifndef SMALL
2330 		ARG_REQUIRED;
2331 		ctx->link_rcvbuf = (int)strtoi(arg, NULL, 0, 0, INT32_MAX, &e);
2332 		if (e) {
2333 			logerrx("failed to convert link_rcvbuf %s", arg);
2334 			return -1;
2335 		}
2336 #endif
2337 		break;
2338 	case O_CONFIGURE:
2339 		ifo->options |= DHCPCD_CONFIGURE;
2340 		break;
2341 	case O_NOCONFIGURE:
2342 		ifo->options &= ~DHCPCD_CONFIGURE;
2343 		break;
2344 	case O_ARP_PERSISTDEFENCE:
2345 		ifo->options |= DHCPCD_ARP_PERSISTDEFENCE;
2346 		break;
2347 	case O_REQUEST_TIME:
2348 		ARG_REQUIRED;
2349 		ifo->request_time =
2350 		    (uint32_t)strtou(arg, NULL, 0, 0, UINT32_MAX, &e);
2351 		if (e) {
2352 			logerrx("invalid request time: %s", arg);
2353 			return -1;
2354 		}
2355 		break;
2356 #ifdef INET
2357 	case O_FALLBACK_TIME:
2358 		ARG_REQUIRED;
2359 		ifo->request_time =
2360 		    (uint32_t)strtou(arg, NULL, 0, 0, UINT32_MAX, &e);
2361 		if (e) {
2362 			logerrx("invalid fallback time: %s", arg);
2363 			return -1;
2364 		}
2365 		break;
2366 	case O_IPV4LL_TIME:
2367 		ARG_REQUIRED;
2368 		ifo->ipv4ll_time =
2369 		    (uint32_t)strtou(arg, NULL, 0, 0, UINT32_MAX, &e);
2370 		if (e) {
2371 			logerrx("invalid ipv4ll time: %s", arg);
2372 			return -1;
2373 		}
2374 		break;
2375 #endif
2376 	default:
2377 		return 0;
2378 	}
2379 
2380 	return 1;
2381 
2382 #ifdef ARG_REQUIRED
2383 arg_required:
2384 	logerrx("option %d requires an argument", opt);
2385 	return -1;
2386 #undef ARG_REQUIRED
2387 #endif
2388 }
2389 
2390 static int
parse_config_line(struct dhcpcd_ctx * ctx,const char * ifname,struct if_options * ifo,const char * opt,char * line,struct dhcp_opt ** ldop,struct dhcp_opt ** edop)2391 parse_config_line(struct dhcpcd_ctx *ctx, const char *ifname,
2392     struct if_options *ifo, const char *opt, char *line,
2393     struct dhcp_opt **ldop, struct dhcp_opt **edop)
2394 {
2395 	unsigned int i;
2396 
2397 	for (i = 0; i < sizeof(cf_options) / sizeof(cf_options[0]); i++) {
2398 		if (!cf_options[i].name ||
2399 		    strcmp(cf_options[i].name, opt) != 0)
2400 			continue;
2401 
2402 		if (cf_options[i].has_arg == required_argument && !line) {
2403 			logerrx("option requires an argument -- %s", opt);
2404 			return -1;
2405 		}
2406 
2407 		return parse_option(ctx, ifname, ifo, cf_options[i].val, line,
2408 		    ldop, edop);
2409 	}
2410 
2411 	if (!(ctx->options & DHCPCD_PRINT_PIDFILE))
2412 		logerrx("unknown option: %s", opt);
2413 	return -1;
2414 }
2415 
2416 static void
finish_config(struct if_options * ifo)2417 finish_config(struct if_options *ifo)
2418 {
2419 
2420 	/* Terminate the encapsulated options */
2421 	if (ifo->vendor[0] && !(ifo->options & DHCPCD_VENDORRAW)) {
2422 		ifo->vendor[0]++;
2423 		ifo->vendor[ifo->vendor[0]] = DHO_END;
2424 		/* We are called twice.
2425 		 * This should be fixed, but in the meantime, this
2426 		 * guard should suffice */
2427 		ifo->options |= DHCPCD_VENDORRAW;
2428 	}
2429 
2430 	if (!(ifo->options & DHCPCD_ARP) ||
2431 	    ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC))
2432 		ifo->options &= ~DHCPCD_IPV4LL;
2433 
2434 	if (!(ifo->options & DHCPCD_IPV4))
2435 		ifo->options &= ~(DHCPCD_DHCP | DHCPCD_IPV4LL | DHCPCD_WAITIP4);
2436 
2437 	if (!(ifo->options & DHCPCD_IPV6))
2438 		ifo->options &=
2439 		    ~(DHCPCD_IPV6RS | DHCPCD_DHCP6 | DHCPCD_WAITIP6);
2440 
2441 	if (!(ifo->options & DHCPCD_IPV6RS))
2442 		ifo->options &=
2443 		    ~(DHCPCD_IPV6RA_AUTOCONF | DHCPCD_IPV6RA_REQRDNSS);
2444 }
2445 
2446 static struct if_options *
default_config(struct dhcpcd_ctx * ctx)2447 default_config(struct dhcpcd_ctx *ctx)
2448 {
2449 	struct if_options *ifo;
2450 
2451 	/* Seed our default options */
2452 	if ((ifo = calloc(1, sizeof(*ifo))) == NULL) {
2453 		logerr(__func__);
2454 		return NULL;
2455 	}
2456 	ifo->options |= DHCPCD_IF_UP | DHCPCD_LINK | DHCPCD_INITIAL_DELAY;
2457 	ifo->timeout = DEFAULT_TIMEOUT;
2458 	ifo->reboot = DEFAULT_REBOOT;
2459 	ifo->request_time = DEFAULT_REQUEST;
2460 #ifdef INET
2461 	ifo->fallback_time = DEFAULT_FALLBACK;
2462 	ifo->ipv4ll_time = DEFAULT_IPV4LL;
2463 #endif
2464 	ifo->metric = -1;
2465 	ifo->auth.options |= DHCPCD_AUTH_REQUIRE;
2466 	rb_tree_init(&ifo->routes, &rt_compare_list_ops);
2467 #ifdef AUTH
2468 	TAILQ_INIT(&ifo->auth.tokens);
2469 #endif
2470 
2471 	/* Inherit some global defaults */
2472 	if (ctx->options & DHCPCD_CONFIGURE)
2473 		ifo->options |= DHCPCD_CONFIGURE;
2474 	if (ctx->options & DHCPCD_PERSISTENT)
2475 		ifo->options |= DHCPCD_PERSISTENT;
2476 	if (ctx->options & DHCPCD_SLAACPRIVATE)
2477 		ifo->options |= DHCPCD_SLAACPRIVATE;
2478 
2479 	return ifo;
2480 }
2481 
2482 struct if_options *
read_config(struct dhcpcd_ctx * ctx,const char * ifname,const char * ssid,const char * profile)2483 read_config(struct dhcpcd_ctx *ctx,
2484     const char *ifname, const char *ssid, const char *profile)
2485 {
2486 	struct if_options *ifo;
2487 	char buf[UDPLEN_MAX], *bp; /* 64k max config file size */
2488 	char *line, *option, *p;
2489 	ssize_t buflen;
2490 	size_t vlen;
2491 	int skip, have_profile, new_block, had_block;
2492 #if !defined(INET) || !defined(INET6)
2493 	size_t i;
2494 	struct dhcp_opt *opt;
2495 #endif
2496 	struct dhcp_opt *ldop, *edop;
2497 
2498 	/* Seed our default options */
2499 	if ((ifo = default_config(ctx)) == NULL)
2500 		return NULL;
2501 	if (default_options == 0) {
2502 		default_options |= DHCPCD_CONFIGURE | DHCPCD_DAEMONISE |
2503 		    DHCPCD_GATEWAY;
2504 #ifdef INET
2505 		skip = xsocket(PF_INET, SOCK_DGRAM, 0);
2506 		if (skip != -1) {
2507 			close(skip);
2508 			default_options |= DHCPCD_IPV4 | DHCPCD_ARP |
2509 			    DHCPCD_DHCP | DHCPCD_IPV4LL;
2510 		}
2511 #endif
2512 #ifdef INET6
2513 		skip = xsocket(PF_INET6, SOCK_DGRAM, 0);
2514 		if (skip != -1) {
2515 			close(skip);
2516 			default_options |= DHCPCD_IPV6 | DHCPCD_IPV6RS |
2517 			    DHCPCD_IPV6RA_AUTOCONF | DHCPCD_IPV6RA_REQRDNSS |
2518 			    DHCPCD_DHCP6;
2519 		}
2520 #endif
2521 #ifdef PLUGIN_DEV
2522 		default_options |= DHCPCD_DEV;
2523 #endif
2524 	}
2525 	ifo->options |= default_options;
2526 
2527 	CLEAR_CONFIG_BLOCK(ifo);
2528 
2529 	vlen = strlcpy((char *)ifo->vendorclassid + 1, ctx->vendor,
2530 	    sizeof(ifo->vendorclassid) - 1);
2531 	ifo->vendorclassid[0] = (uint8_t)(vlen > 255 ? 0 : vlen);
2532 
2533 	/* Reset route order */
2534 	ctx->rt_order = 0;
2535 
2536 	/* Parse our embedded options file */
2537 	if (ifname == NULL && !(ctx->options & DHCPCD_PRINT_PIDFILE)) {
2538 		/* Space for initial estimates */
2539 #if defined(INET) && defined(INITDEFINES)
2540 		ifo->dhcp_override =
2541 		    calloc(INITDEFINES, sizeof(*ifo->dhcp_override));
2542 		if (ifo->dhcp_override == NULL)
2543 			logerr(__func__);
2544 		else
2545 			ifo->dhcp_override_len = INITDEFINES;
2546 #endif
2547 
2548 #if defined(INET6) && defined(INITDEFINENDS)
2549 		ifo->nd_override =
2550 		    calloc(INITDEFINENDS, sizeof(*ifo->nd_override));
2551 		if (ifo->nd_override == NULL)
2552 			logerr(__func__);
2553 		else
2554 			ifo->nd_override_len = INITDEFINENDS;
2555 #endif
2556 #if defined(INET6) && defined(INITDEFINE6S)
2557 		ifo->dhcp6_override =
2558 		    calloc(INITDEFINE6S, sizeof(*ifo->dhcp6_override));
2559 		if (ifo->dhcp6_override == NULL)
2560 			logerr(__func__);
2561 		else
2562 			ifo->dhcp6_override_len = INITDEFINE6S;
2563 #endif
2564 
2565 		/* Now load our embedded config */
2566 #ifdef EMBEDDED_CONFIG
2567 		buflen = dhcp_readfile(ctx, EMBEDDED_CONFIG, buf, sizeof(buf));
2568 		if (buflen == -1) {
2569 			logerr("%s: %s", __func__, EMBEDDED_CONFIG);
2570 			return ifo;
2571 		}
2572 		if (buf[buflen - 1] != '\0') {
2573 			if ((size_t)buflen < sizeof(buf) - 1)
2574 				buflen++;
2575 			buf[buflen - 1] = '\0';
2576 		}
2577 #else
2578 		buflen = (ssize_t)strlcpy(buf, dhcpcd_embedded_conf,
2579 		    sizeof(buf));
2580 		if ((size_t)buflen >= sizeof(buf)) {
2581 			logerrx("%s: embedded config too big", __func__);
2582 			return ifo;
2583 		}
2584 		/* Our embedded config is NULL terminated */
2585 #endif
2586 		bp = buf;
2587 		while ((line = get_line(&bp, &buflen)) != NULL) {
2588 			option = strsep(&line, " \t");
2589 			if (line)
2590 				line = strskipwhite(line);
2591 			/* Trim trailing whitespace */
2592 			if (line) {
2593 				p = line + strlen(line) - 1;
2594 				while (p != line &&
2595 				    (*p == ' ' || *p == '\t') &&
2596 				    *(p - 1) != '\\')
2597 					*p-- = '\0';
2598 			}
2599 			parse_config_line(ctx, NULL, ifo, option, line,
2600 			    &ldop, &edop);
2601 		}
2602 
2603 #ifdef INET
2604 		ctx->dhcp_opts = ifo->dhcp_override;
2605 		ctx->dhcp_opts_len = ifo->dhcp_override_len;
2606 #else
2607 		for (i = 0, opt = ifo->dhcp_override;
2608 		    i < ifo->dhcp_override_len;
2609 		    i++, opt++)
2610 			free_dhcp_opt_embenc(opt);
2611 		free(ifo->dhcp_override);
2612 #endif
2613 		ifo->dhcp_override = NULL;
2614 		ifo->dhcp_override_len = 0;
2615 
2616 #ifdef INET6
2617 		ctx->nd_opts = ifo->nd_override;
2618 		ctx->nd_opts_len = ifo->nd_override_len;
2619 #ifdef DHCP6
2620 		ctx->dhcp6_opts = ifo->dhcp6_override;
2621 		ctx->dhcp6_opts_len = ifo->dhcp6_override_len;
2622 #endif
2623 #else
2624 		for (i = 0, opt = ifo->nd_override;
2625 		    i < ifo->nd_override_len;
2626 		    i++, opt++)
2627 			free_dhcp_opt_embenc(opt);
2628 		free(ifo->nd_override);
2629 		for (i = 0, opt = ifo->dhcp6_override;
2630 		    i < ifo->dhcp6_override_len;
2631 		    i++, opt++)
2632 			free_dhcp_opt_embenc(opt);
2633 		free(ifo->dhcp6_override);
2634 #endif
2635 		ifo->nd_override = NULL;
2636 		ifo->nd_override_len = 0;
2637 		ifo->dhcp6_override = NULL;
2638 		ifo->dhcp6_override_len = 0;
2639 
2640 		ctx->vivso = ifo->vivso_override;
2641 		ctx->vivso_len = ifo->vivso_override_len;
2642 		ifo->vivso_override = NULL;
2643 		ifo->vivso_override_len = 0;
2644 	}
2645 
2646 	/* Parse our options file */
2647 	buflen = dhcp_readfile(ctx, ctx->cffile, buf, sizeof(buf));
2648 	if (buflen == -1) {
2649 		/* dhcpcd can continue without it, but no DNS options
2650 		 * would be requested ... */
2651 		logerr("%s: %s", __func__, ctx->cffile);
2652 		return ifo;
2653 	}
2654 	if (buf[buflen - 1] != '\0') {
2655 		if ((size_t)buflen < sizeof(buf) - 1)
2656 			buflen++;
2657 		buf[buflen - 1] = '\0';
2658 	}
2659 	dhcp_filemtime(ctx, ctx->cffile, &ifo->mtime);
2660 
2661 	ldop = edop = NULL;
2662 	skip = have_profile = new_block = 0;
2663 	had_block = ifname == NULL ? 1 : 0;
2664 	bp = buf;
2665 	while ((line = get_line(&bp, &buflen)) != NULL) {
2666 		option = strsep(&line, " \t");
2667 		if (line)
2668 			line = strskipwhite(line);
2669 		/* Trim trailing whitespace */
2670 		if (line) {
2671 			p = line + strlen(line) - 1;
2672 			while (p != line &&
2673 			    (*p == ' ' || *p == '\t') &&
2674 			    *(p - 1) != '\\')
2675 				*p-- = '\0';
2676 		}
2677 		if (skip == 0 && new_block) {
2678 			had_block = 1;
2679 			new_block = 0;
2680 			ifo->options &= ~DHCPCD_WAITOPTS;
2681 			SET_CONFIG_BLOCK(ifo);
2682 		}
2683 
2684 		/* Start of an interface block, skip if not ours */
2685 		if (strcmp(option, "interface") == 0) {
2686 			char **n;
2687 
2688 			new_block = 1;
2689 			if (line == NULL) {
2690 				/* No interface given */
2691 				skip = 1;
2692 				continue;
2693 			}
2694 			if (ifname && strcmp(line, ifname) == 0)
2695 				skip = 0;
2696 			else
2697 				skip = 1;
2698 			if (ifname)
2699 				continue;
2700 
2701 			n = reallocarray(ctx->ifcv,
2702 			    (size_t)ctx->ifcc + 1, sizeof(char *));
2703 			if (n == NULL) {
2704 				logerr(__func__);
2705 				continue;
2706 			}
2707 			ctx->ifcv = n;
2708 			ctx->ifcv[ctx->ifcc] = strdup(line);
2709 			if (ctx->ifcv[ctx->ifcc] == NULL) {
2710 				logerr(__func__);
2711 				continue;
2712 			}
2713 			ctx->ifcc++;
2714 			continue;
2715 		}
2716 		/* Start of an ssid block, skip if not ours */
2717 		if (strcmp(option, "ssid") == 0) {
2718 			new_block = 1;
2719 			if (ssid && line && strcmp(line, ssid) == 0)
2720 				skip = 0;
2721 			else
2722 				skip = 1;
2723 			continue;
2724 		}
2725 		/* Start of a profile block, skip if not ours */
2726 		if (strcmp(option, "profile") == 0) {
2727 			new_block = 1;
2728 			if (profile && line && strcmp(line, profile) == 0) {
2729 				skip = 0;
2730 				have_profile = 1;
2731 			} else
2732 				skip = 1;
2733 			continue;
2734 		}
2735 		/* Skip arping if we have selected a profile but not parsing
2736 		 * one. */
2737 		if (profile && !have_profile && strcmp(option, "arping") == 0)
2738 			continue;
2739 		if (skip)
2740 			continue;
2741 
2742 		parse_config_line(ctx, ifname, ifo, option, line, &ldop, &edop);
2743 	}
2744 
2745 	if (profile && !have_profile) {
2746 		free_options(ctx, ifo);
2747 		errno = ENOENT;
2748 		return NULL;
2749 	}
2750 
2751 	if (!had_block)
2752 		ifo->options &= ~DHCPCD_WAITOPTS;
2753 	CLEAR_CONFIG_BLOCK(ifo);
2754 	finish_config(ifo);
2755 	return ifo;
2756 }
2757 
2758 int
add_options(struct dhcpcd_ctx * ctx,const char * ifname,struct if_options * ifo,int argc,char ** argv)2759 add_options(struct dhcpcd_ctx *ctx, const char *ifname,
2760     struct if_options *ifo, int argc, char **argv)
2761 {
2762 	int oi, opt, r;
2763 	unsigned long long wait_opts;
2764 
2765 	if (argc == 0)
2766 		return 1;
2767 
2768 	optind = 0;
2769 	r = 1;
2770 	/* Don't apply the command line wait options to each interface,
2771 	 * only use the dhcpcd.conf entry for that. */
2772 	if (ifname != NULL)
2773 		wait_opts = ifo->options & DHCPCD_WAITOPTS;
2774 	while ((opt = getopt_long(argc, argv,
2775 	    ctx->options & DHCPCD_PRINT_PIDFILE ? NOERR_IF_OPTS : IF_OPTS,
2776 	    cf_options, &oi)) != -1)
2777 	{
2778 		r = parse_option(ctx, ifname, ifo, opt, optarg, NULL, NULL);
2779 		if (r != 1)
2780 			break;
2781 	}
2782 	if (ifname != NULL) {
2783 		ifo->options &= ~DHCPCD_WAITOPTS;
2784 		ifo->options |= wait_opts;
2785 	}
2786 
2787 	finish_config(ifo);
2788 	return r;
2789 }
2790 
2791 void
free_options(struct dhcpcd_ctx * ctx,struct if_options * ifo)2792 free_options(struct dhcpcd_ctx *ctx, struct if_options *ifo)
2793 {
2794 	size_t i;
2795 #ifdef RT_FREE_ROUTE_TABLE
2796 	struct interface *ifp;
2797 	struct rt *rt;
2798 #endif
2799 	struct dhcp_opt *opt;
2800 	struct vivco *vo;
2801 #ifdef AUTH
2802 	struct token *token;
2803 #endif
2804 
2805 	if (ifo == NULL)
2806 		return;
2807 
2808 	if (ifo->environ) {
2809 		i = 0;
2810 		while (ifo->environ[i])
2811 			free(ifo->environ[i++]);
2812 		free(ifo->environ);
2813 	}
2814 	if (ifo->config) {
2815 		i = 0;
2816 		while (ifo->config[i])
2817 			free(ifo->config[i++]);
2818 		free(ifo->config);
2819 	}
2820 
2821 #ifdef RT_FREE_ROUTE_TABLE
2822 	/* Stupidly, we don't know the interface when creating the options.
2823 	 * As such, make sure each route has one so they can goto the
2824 	 * free list. */
2825 	ifp = ctx->ifaces != NULL ? TAILQ_FIRST(ctx->ifaces) : NULL;
2826 	if (ifp != NULL) {
2827 		RB_TREE_FOREACH(rt, &ifo->routes) {
2828 			if (rt->rt_ifp == NULL)
2829 				rt->rt_ifp = ifp;
2830 		}
2831 	}
2832 #endif
2833 	rt_headclear0(ctx, &ifo->routes, AF_UNSPEC);
2834 
2835 	free(ifo->arping);
2836 	free(ifo->blacklist);
2837 	free(ifo->fallback);
2838 
2839 	for (opt = ifo->dhcp_override;
2840 	    ifo->dhcp_override_len > 0;
2841 	    opt++, ifo->dhcp_override_len--)
2842 		free_dhcp_opt_embenc(opt);
2843 	free(ifo->dhcp_override);
2844 	for (opt = ifo->nd_override;
2845 	    ifo->nd_override_len > 0;
2846 	    opt++, ifo->nd_override_len--)
2847 		free_dhcp_opt_embenc(opt);
2848 	free(ifo->nd_override);
2849 	for (opt = ifo->dhcp6_override;
2850 	    ifo->dhcp6_override_len > 0;
2851 	    opt++, ifo->dhcp6_override_len--)
2852 		free_dhcp_opt_embenc(opt);
2853 	free(ifo->dhcp6_override);
2854 	for (vo = ifo->vivco;
2855 	    ifo->vivco_len > 0;
2856 	    vo++, ifo->vivco_len--)
2857 		free(vo->data);
2858 	free(ifo->vivco);
2859 	for (opt = ifo->vivso_override;
2860 	    ifo->vivso_override_len > 0;
2861 	    opt++, ifo->vivso_override_len--)
2862 		free_dhcp_opt_embenc(opt);
2863 	free(ifo->vivso_override);
2864 
2865 #if defined(INET6) && !defined(SMALL)
2866 	for (; ifo->ia_len > 0; ifo->ia_len--)
2867 		free(ifo->ia[ifo->ia_len - 1].sla);
2868 #endif
2869 	free(ifo->ia);
2870 
2871 #ifdef AUTH
2872 	while ((token = TAILQ_FIRST(&ifo->auth.tokens))) {
2873 		TAILQ_REMOVE(&ifo->auth.tokens, token, next);
2874 		if (token->realm_len)
2875 			free(token->realm);
2876 		free(token->key);
2877 		free(token);
2878 	}
2879 #endif
2880 	free(ifo);
2881 }
2882