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