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