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