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