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