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, "byte") == 0) 1837 t |= OT_UINT8; 1838 else if (strcasecmp(arg, "bitflags") == 0) 1839 t |= OT_BITFLAG; 1840 else if (strcasecmp(arg, "uint8") == 0) 1841 t |= OT_UINT8; 1842 else if (strcasecmp(arg, "int8") == 0) 1843 t |= OT_INT8; 1844 else if (strcasecmp(arg, "uint16") == 0) 1845 t |= OT_UINT16; 1846 else if (strcasecmp(arg, "int16") == 0) 1847 t |= OT_INT16; 1848 else if (strcasecmp(arg, "uint32") == 0) 1849 t |= OT_UINT32; 1850 else if (strcasecmp(arg, "int32") == 0) 1851 t |= OT_INT32; 1852 else if (strcasecmp(arg, "flag") == 0) 1853 t |= OT_FLAG; 1854 else if (strcasecmp(arg, "raw") == 0) 1855 t |= OT_STRING | OT_RAW; 1856 else if (strcasecmp(arg, "ascii") == 0) 1857 t |= OT_STRING | OT_ASCII; 1858 else if (strcasecmp(arg, "domain") == 0) 1859 t |= OT_STRING | OT_DOMAIN | OT_RFC1035; 1860 else if (strcasecmp(arg, "dname") == 0) 1861 t |= OT_STRING | OT_DOMAIN; 1862 else if (strcasecmp(arg, "binhex") == 0) 1863 t |= OT_STRING | OT_BINHEX; 1864 else if (strcasecmp(arg, "embed") == 0) 1865 t |= OT_EMBED; 1866 else if (strcasecmp(arg, "encap") == 0) 1867 t |= OT_ENCAP; 1868 else if (strcasecmp(arg, "rfc3361") ==0) 1869 t |= OT_STRING | OT_RFC3361; 1870 else if (strcasecmp(arg, "rfc3442") ==0) 1871 t |= OT_STRING | OT_RFC3442; 1872 else if (strcasecmp(arg, "option") == 0) 1873 t |= OT_OPTION; 1874 else { 1875 logerrx("unknown type: %s", arg); 1876 return -1; 1877 } 1878 if (l && !(t & (OT_STRING | OT_BINHEX))) { 1879 logwarnx("ignoring length for type: %s", arg); 1880 l = 0; 1881 } 1882 if (t & OT_ARRAY && t & (OT_STRING | OT_BINHEX) && 1883 !(t & (OT_RFC1035 | OT_DOMAIN))) 1884 { 1885 logwarnx("ignoring array for strings"); 1886 t &= ~OT_ARRAY; 1887 } 1888 if (t & OT_BITFLAG) { 1889 if (bp == NULL) 1890 logwarnx("missing bitflag assignment"); 1891 } 1892 /* variable */ 1893 if (!fp) { 1894 if (!(t & OT_OPTION)) { 1895 logerrx("type %s requires a variable name", 1896 arg); 1897 return -1; 1898 } 1899 np = NULL; 1900 } else { 1901 arg = strskipwhite(fp); 1902 fp = strwhite(arg); 1903 if (fp) 1904 *fp++ = '\0'; 1905 if (strcasecmp(arg, "reserved")) { 1906 np = strdup(arg); 1907 if (np == NULL) { 1908 logerr(__func__); 1909 return -1; 1910 } 1911 } else { 1912 np = NULL; 1913 t |= OT_RESERVED; 1914 } 1915 } 1916 if (opt != O_EMBED) { 1917 for (dl = 0, ndop = *dop; dl < *dop_len; dl++, ndop++) 1918 { 1919 /* type 0 seems freshly malloced struct 1920 * for us to use */ 1921 if (ndop->option == u || ndop->type == 0) 1922 break; 1923 } 1924 if (dl == *dop_len) 1925 ndop = NULL; 1926 } else 1927 ndop = NULL; 1928 if (ndop == NULL) { 1929 ndop = reallocarray(*dop, *dop_len + 1, sizeof(**dop)); 1930 if (ndop == NULL) { 1931 logerr(__func__); 1932 free(np); 1933 return -1; 1934 } 1935 *dop = ndop; 1936 ndop = &(*dop)[(*dop_len)++]; 1937 ndop->embopts = NULL; 1938 ndop->embopts_len = 0; 1939 ndop->encopts = NULL; 1940 ndop->encopts_len = 0; 1941 } else 1942 free_dhcp_opt_embenc(ndop); 1943 ndop->option = (uint32_t)u; /* could have been 0 */ 1944 ndop->type = t; 1945 ndop->len = (size_t)l; 1946 ndop->var = np; 1947 if (bp) { 1948 dl = strlen(bp); 1949 memcpy(ndop->bitflags, bp, dl); 1950 memset(ndop->bitflags + dl, 0, 1951 sizeof(ndop->bitflags) - dl); 1952 } else 1953 memset(ndop->bitflags, 0, sizeof(ndop->bitflags)); 1954 /* Save the define for embed and encap options */ 1955 switch (opt) { 1956 case O_DEFINE: 1957 case O_DEFINEND: 1958 case O_DEFINE6: 1959 case O_VENDOPT: 1960 *ldop = ndop; 1961 break; 1962 case O_ENCAP: 1963 *edop = ndop; 1964 break; 1965 } 1966 break; 1967 case O_VENDCLASS: 1968 ARG_REQUIRED; 1969 fp = strwhite(arg); 1970 if (fp) 1971 *fp++ = '\0'; 1972 u = (uint32_t)strtou(arg, NULL, 0, 0, UINT32_MAX, &e); 1973 if (e) { 1974 logerrx("invalid code: %s", arg); 1975 return -1; 1976 } 1977 fp = strskipwhite(fp); 1978 if (fp) { 1979 s = parse_string(NULL, 0, fp); 1980 if (s == -1) { 1981 logerr(__func__); 1982 return -1; 1983 } 1984 dl = (size_t)s; 1985 if (dl + (sizeof(uint16_t) * 2) > UINT16_MAX) { 1986 logerrx("vendor class is too big"); 1987 return -1; 1988 } 1989 np = malloc(dl); 1990 if (np == NULL) { 1991 logerr(__func__); 1992 return -1; 1993 } 1994 parse_string(np, dl, fp); 1995 } else { 1996 dl = 0; 1997 np = NULL; 1998 } 1999 vivco = reallocarray(ifo->vivco, 2000 ifo->vivco_len + 1, sizeof(*ifo->vivco)); 2001 if (vivco == NULL) { 2002 logerr( __func__); 2003 free(np); 2004 return -1; 2005 } 2006 ifo->vivco = vivco; 2007 ifo->vivco_en = (uint32_t)u; 2008 vivco = &ifo->vivco[ifo->vivco_len++]; 2009 vivco->len = dl; 2010 vivco->data = (uint8_t *)np; 2011 break; 2012 case O_AUTHPROTOCOL: 2013 ARG_REQUIRED; 2014 #ifdef AUTH 2015 fp = strwhite(arg); 2016 if (fp) 2017 *fp++ = '\0'; 2018 if (strcasecmp(arg, "token") == 0) 2019 ifo->auth.protocol = AUTH_PROTO_TOKEN; 2020 else if (strcasecmp(arg, "delayed") == 0) 2021 ifo->auth.protocol = AUTH_PROTO_DELAYED; 2022 else if (strcasecmp(arg, "delayedrealm") == 0) 2023 ifo->auth.protocol = AUTH_PROTO_DELAYEDREALM; 2024 else { 2025 logerrx("%s: unsupported protocol", arg); 2026 return -1; 2027 } 2028 arg = strskipwhite(fp); 2029 fp = strwhite(arg); 2030 if (arg == NULL) { 2031 ifo->auth.options |= DHCPCD_AUTH_SEND; 2032 if (ifo->auth.protocol == AUTH_PROTO_TOKEN) 2033 ifo->auth.protocol = AUTH_ALG_NONE; 2034 else 2035 ifo->auth.algorithm = AUTH_ALG_HMAC_MD5; 2036 ifo->auth.rdm = AUTH_RDM_MONOTONIC; 2037 break; 2038 } 2039 if (fp) 2040 *fp++ = '\0'; 2041 if (ifo->auth.protocol == AUTH_PROTO_TOKEN) { 2042 np = strchr(arg, '/'); 2043 if (np) { 2044 if (fp == NULL || np < fp) 2045 *np++ = '\0'; 2046 else 2047 np = NULL; 2048 } 2049 if (parse_uint32(&ifo->auth.token_snd_secretid, 2050 arg) == -1) 2051 logerrx("%s: not a number", arg); 2052 else 2053 ifo->auth.token_rcv_secretid = 2054 ifo->auth.token_snd_secretid; 2055 if (np && 2056 parse_uint32(&ifo->auth.token_rcv_secretid, 2057 np) == -1) 2058 logerrx("%s: not a number", arg); 2059 } else { 2060 if (strcasecmp(arg, "hmacmd5") == 0 || 2061 strcasecmp(arg, "hmac-md5") == 0) 2062 ifo->auth.algorithm = AUTH_ALG_HMAC_MD5; 2063 else { 2064 logerrx("%s: unsupported algorithm", arg); 2065 return 1; 2066 } 2067 } 2068 arg = fp; 2069 if (arg == NULL) { 2070 ifo->auth.options |= DHCPCD_AUTH_SEND; 2071 ifo->auth.rdm = AUTH_RDM_MONOTONIC; 2072 break; 2073 } 2074 if (strcasecmp(arg, "monocounter") == 0) { 2075 ifo->auth.rdm = AUTH_RDM_MONOTONIC; 2076 ifo->auth.options |= DHCPCD_AUTH_RDM_COUNTER; 2077 } else if (strcasecmp(arg, "monotonic") ==0 || 2078 strcasecmp(arg, "monotime") == 0) 2079 ifo->auth.rdm = AUTH_RDM_MONOTONIC; 2080 else { 2081 logerrx("%s: unsupported RDM", arg); 2082 return -1; 2083 } 2084 ifo->auth.options |= DHCPCD_AUTH_SEND; 2085 break; 2086 #else 2087 logerrx("no authentication support"); 2088 return -1; 2089 #endif 2090 case O_AUTHTOKEN: 2091 ARG_REQUIRED; 2092 #ifdef AUTH 2093 fp = strwhite(arg); 2094 if (fp == NULL) { 2095 logerrx("authtoken requires a realm"); 2096 return -1; 2097 } 2098 *fp++ = '\0'; 2099 token = calloc(1, sizeof(*token)); 2100 if (token == NULL) { 2101 logerr(__func__); 2102 return -1; 2103 } 2104 if (parse_uint32(&token->secretid, arg) == -1) { 2105 logerrx("%s: not a number", arg); 2106 goto invalid_token; 2107 } 2108 arg = fp; 2109 fp = strend(arg); 2110 if (fp == NULL) { 2111 logerrx("authtoken requires a realm"); 2112 goto invalid_token; 2113 } 2114 *fp++ = '\0'; 2115 s = parse_string(NULL, 0, arg); 2116 if (s == -1) { 2117 logerr("realm_len"); 2118 goto invalid_token; 2119 } 2120 if (s != 0) { 2121 token->realm_len = (size_t)s; 2122 token->realm = malloc(token->realm_len); 2123 if (token->realm == NULL) { 2124 logerr(__func__); 2125 goto invalid_token; 2126 } 2127 parse_string((char *)token->realm, token->realm_len, 2128 arg); 2129 } 2130 arg = fp; 2131 fp = strend(arg); 2132 if (fp == NULL) { 2133 logerrx("authtoken requies an expiry date"); 2134 goto invalid_token; 2135 } 2136 *fp++ = '\0'; 2137 if (*arg == '"') { 2138 arg++; 2139 np = strchr(arg, '"'); 2140 if (np) 2141 *np = '\0'; 2142 } 2143 if (strcmp(arg, "0") == 0 || strcasecmp(arg, "forever") == 0) 2144 token->expire =0; 2145 else { 2146 struct tm tm; 2147 2148 memset(&tm, 0, sizeof(tm)); 2149 if (strptime(arg, "%Y-%m-%d %H:%M", &tm) == NULL) { 2150 logerrx("%s: invalid date time", arg); 2151 goto invalid_token; 2152 } 2153 if ((token->expire = mktime(&tm)) == (time_t)-1) { 2154 logerr("%s: mktime", __func__); 2155 goto invalid_token; 2156 } 2157 } 2158 arg = fp; 2159 s = parse_string(NULL, 0, arg); 2160 if (s == -1 || s == 0) { 2161 if (s == -1) 2162 logerr("token_len"); 2163 else 2164 logerrx("authtoken requires a key"); 2165 goto invalid_token; 2166 } 2167 token->key_len = (size_t)s; 2168 token->key = malloc(token->key_len); 2169 if (token->key == NULL) { 2170 logerr(__func__); 2171 goto invalid_token; 2172 } 2173 parse_string((char *)token->key, token->key_len, arg); 2174 TAILQ_INSERT_TAIL(&ifo->auth.tokens, token, next); 2175 break; 2176 2177 invalid_token: 2178 free(token->realm); 2179 free(token); 2180 #else 2181 logerrx("no authentication support"); 2182 #endif 2183 return -1; 2184 case O_AUTHNOTREQUIRED: 2185 ifo->auth.options &= ~DHCPCD_AUTH_REQUIRE; 2186 break; 2187 case O_DHCP: 2188 ifo->options |= DHCPCD_DHCP | DHCPCD_WANTDHCP | DHCPCD_IPV4; 2189 break; 2190 case O_NODHCP: 2191 ifo->options &= ~DHCPCD_DHCP; 2192 break; 2193 case O_DHCP6: 2194 ifo->options |= DHCPCD_DHCP6 | DHCPCD_IPV6; 2195 break; 2196 case O_NODHCP6: 2197 ifo->options &= ~DHCPCD_DHCP6; 2198 break; 2199 case O_CONTROLGRP: 2200 ARG_REQUIRED; 2201 #ifdef PRIVSEP 2202 /* Control group is already set by this point. 2203 * We don't need to pledge getpw either with this. */ 2204 if (IN_PRIVSEP(ctx)) 2205 break; 2206 #endif 2207 #ifdef _REENTRANT 2208 l = sysconf(_SC_GETGR_R_SIZE_MAX); 2209 if (l == -1) 2210 dl = 1024; 2211 else 2212 dl = (size_t)l; 2213 p = malloc(dl); 2214 if (p == NULL) { 2215 logerr(__func__); 2216 return -1; 2217 } 2218 while ((i = getgrnam_r(arg, &grpbuf, p, dl, &grp)) == 2219 ERANGE) 2220 { 2221 size_t nl = dl * 2; 2222 if (nl < dl) { 2223 logerrx("control_group: out of buffer"); 2224 free(p); 2225 return -1; 2226 } 2227 dl = nl; 2228 np = realloc(p, dl); 2229 if (np == NULL) { 2230 logerr(__func__); 2231 free(p); 2232 return -1; 2233 } 2234 p = np; 2235 } 2236 if (i != 0) { 2237 errno = i; 2238 logerr("getgrnam_r"); 2239 free(p); 2240 return -1; 2241 } 2242 if (grp == NULL) { 2243 if (!ctx->control_group) 2244 logerrx("controlgroup: %s: not found", arg); 2245 free(p); 2246 return -1; 2247 } 2248 ctx->control_group = grp->gr_gid; 2249 free(p); 2250 #else 2251 grp = getgrnam(arg); 2252 if (grp == NULL) { 2253 if (!ctx->control_group) 2254 logerrx("controlgroup: %s: not found", arg); 2255 return -1; 2256 } 2257 ctx->control_group = grp->gr_gid; 2258 #endif 2259 break; 2260 case O_GATEWAY: 2261 ifo->options |= DHCPCD_GATEWAY; 2262 break; 2263 case O_NOUP: 2264 ifo->options &= ~DHCPCD_IF_UP; 2265 break; 2266 case O_SLAAC: 2267 ARG_REQUIRED; 2268 np = strwhite(arg); 2269 if (np != NULL) { 2270 *np++ = '\0'; 2271 np = strskipwhite(np); 2272 } 2273 if (strcmp(arg, "private") == 0 || 2274 strcmp(arg, "stableprivate") == 0 || 2275 strcmp(arg, "stable") == 0) 2276 ifo->options |= DHCPCD_SLAACPRIVATE; 2277 else 2278 ifo->options &= ~DHCPCD_SLAACPRIVATE; 2279 #ifdef INET6 2280 if (strcmp(arg, "token") == 0) { 2281 if (np == NULL) { 2282 logerrx("slaac token: no token specified"); 2283 return -1; 2284 } 2285 arg = np; 2286 np = strwhite(np); 2287 if (np != NULL) { 2288 *np++ = '\0'; 2289 np = strskipwhite(np); 2290 } 2291 if (inet_pton(AF_INET6, arg, &ifo->token) != 1) { 2292 logerrx("slaac token: invalid token"); 2293 return -1; 2294 } 2295 } 2296 #endif 2297 if (np != NULL && 2298 (strcmp(np, "temp") == 0 || strcmp(np, "temporary") == 0)) 2299 ifo->options |= DHCPCD_SLAACTEMP; 2300 break; 2301 case O_BOOTP: 2302 ifo->options |= DHCPCD_BOOTP; 2303 break; 2304 case O_NODELAY: 2305 ifo->options &= ~DHCPCD_INITIAL_DELAY; 2306 break; 2307 case O_LASTLEASE_EXTEND: 2308 ifo->options |= DHCPCD_LASTLEASE | DHCPCD_LASTLEASE_EXTEND; 2309 break; 2310 case O_INACTIVE: 2311 ifo->options |= DHCPCD_INACTIVE; 2312 break; 2313 case O_MUDURL: 2314 ARG_REQUIRED; 2315 s = parse_string((char *)ifo->mudurl + 1, MUDURL_MAX_LEN, arg); 2316 if (s == -1) { 2317 logerr("mudurl"); 2318 return -1; 2319 } 2320 *ifo->mudurl = (uint8_t)s; 2321 break; 2322 case O_LINK_RCVBUF: 2323 #ifndef SMALL 2324 ARG_REQUIRED; 2325 ctx->link_rcvbuf = (int)strtoi(arg, NULL, 0, 0, INT32_MAX, &e); 2326 if (e) { 2327 logerrx("failed to convert link_rcvbuf %s", arg); 2328 return -1; 2329 } 2330 #endif 2331 break; 2332 case O_CONFIGURE: 2333 ifo->options |= DHCPCD_CONFIGURE; 2334 break; 2335 case O_NOCONFIGURE: 2336 ifo->options &= ~DHCPCD_CONFIGURE; 2337 break; 2338 default: 2339 return 0; 2340 } 2341 2342 return 1; 2343 2344 #ifdef ARG_REQUIRED 2345 arg_required: 2346 logerrx("option %d requires an argument", opt); 2347 return -1; 2348 #undef ARG_REQUIRED 2349 #endif 2350 } 2351 2352 static int 2353 parse_config_line(struct dhcpcd_ctx *ctx, const char *ifname, 2354 struct if_options *ifo, const char *opt, char *line, 2355 struct dhcp_opt **ldop, struct dhcp_opt **edop) 2356 { 2357 unsigned int i; 2358 2359 for (i = 0; i < sizeof(cf_options) / sizeof(cf_options[0]); i++) { 2360 if (!cf_options[i].name || 2361 strcmp(cf_options[i].name, opt) != 0) 2362 continue; 2363 2364 if (cf_options[i].has_arg == required_argument && !line) { 2365 logerrx("option requires an argument -- %s", opt); 2366 return -1; 2367 } 2368 2369 return parse_option(ctx, ifname, ifo, cf_options[i].val, line, 2370 ldop, edop); 2371 } 2372 2373 if (!(ctx->options & DHCPCD_PRINT_PIDFILE)) 2374 logerrx("unknown option: %s", opt); 2375 return -1; 2376 } 2377 2378 static void 2379 finish_config(struct if_options *ifo) 2380 { 2381 2382 /* Terminate the encapsulated options */ 2383 if (ifo->vendor[0] && !(ifo->options & DHCPCD_VENDORRAW)) { 2384 ifo->vendor[0]++; 2385 ifo->vendor[ifo->vendor[0]] = DHO_END; 2386 /* We are called twice. 2387 * This should be fixed, but in the meantime, this 2388 * guard should suffice */ 2389 ifo->options |= DHCPCD_VENDORRAW; 2390 } 2391 2392 if (!(ifo->options & DHCPCD_ARP) || 2393 ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC)) 2394 ifo->options &= ~DHCPCD_IPV4LL; 2395 2396 if (!(ifo->options & DHCPCD_IPV4)) 2397 ifo->options &= ~(DHCPCD_DHCP | DHCPCD_IPV4LL | DHCPCD_WAITIP4); 2398 2399 if (!(ifo->options & DHCPCD_IPV6)) 2400 ifo->options &= 2401 ~(DHCPCD_IPV6RS | DHCPCD_DHCP6 | DHCPCD_WAITIP6); 2402 2403 if (!(ifo->options & DHCPCD_IPV6RS)) 2404 ifo->options &= 2405 ~(DHCPCD_IPV6RA_AUTOCONF | DHCPCD_IPV6RA_REQRDNSS); 2406 } 2407 2408 struct if_options * 2409 default_config(struct dhcpcd_ctx *ctx) 2410 { 2411 struct if_options *ifo; 2412 2413 /* Seed our default options */ 2414 if ((ifo = calloc(1, sizeof(*ifo))) == NULL) { 2415 logerr(__func__); 2416 return NULL; 2417 } 2418 ifo->options |= DHCPCD_IF_UP | DHCPCD_LINK | DHCPCD_INITIAL_DELAY; 2419 ifo->timeout = DEFAULT_TIMEOUT; 2420 ifo->reboot = DEFAULT_REBOOT; 2421 ifo->metric = -1; 2422 ifo->auth.options |= DHCPCD_AUTH_REQUIRE; 2423 rb_tree_init(&ifo->routes, &rt_compare_list_ops); 2424 #ifdef AUTH 2425 TAILQ_INIT(&ifo->auth.tokens); 2426 #endif 2427 2428 /* Inherit some global defaults */ 2429 if (ctx->options & DHCPCD_CONFIGURE) 2430 ifo->options |= DHCPCD_CONFIGURE; 2431 if (ctx->options & DHCPCD_PERSISTENT) 2432 ifo->options |= DHCPCD_PERSISTENT; 2433 if (ctx->options & DHCPCD_SLAACPRIVATE) 2434 ifo->options |= DHCPCD_SLAACPRIVATE; 2435 2436 return ifo; 2437 } 2438 2439 struct if_options * 2440 read_config(struct dhcpcd_ctx *ctx, 2441 const char *ifname, const char *ssid, const char *profile) 2442 { 2443 struct if_options *ifo; 2444 char buf[UDPLEN_MAX], *bp; /* 64k max config file size */ 2445 char *line, *option, *p; 2446 ssize_t buflen; 2447 size_t vlen; 2448 int skip, have_profile, new_block, had_block; 2449 #if !defined(INET) || !defined(INET6) 2450 size_t i; 2451 struct dhcp_opt *opt; 2452 #endif 2453 struct dhcp_opt *ldop, *edop; 2454 2455 /* Seed our default options */ 2456 if ((ifo = default_config(ctx)) == NULL) 2457 return NULL; 2458 if (default_options == 0) { 2459 default_options |= DHCPCD_CONFIGURE | DHCPCD_DAEMONISE | 2460 DHCPCD_GATEWAY; 2461 #ifdef INET 2462 skip = socket(PF_INET, SOCK_DGRAM, 0); 2463 if (skip != -1) { 2464 close(skip); 2465 default_options |= DHCPCD_IPV4 | DHCPCD_ARP | 2466 DHCPCD_DHCP | DHCPCD_IPV4LL; 2467 } 2468 #endif 2469 #ifdef INET6 2470 skip = socket(PF_INET6, SOCK_DGRAM, 0); 2471 if (skip != -1) { 2472 close(skip); 2473 default_options |= DHCPCD_IPV6 | DHCPCD_IPV6RS | 2474 DHCPCD_IPV6RA_AUTOCONF | DHCPCD_IPV6RA_REQRDNSS | 2475 DHCPCD_DHCP6; 2476 } 2477 #endif 2478 #ifdef PLUGIN_DEV 2479 default_options |= DHCPCD_DEV; 2480 #endif 2481 } 2482 ifo->options |= default_options; 2483 2484 CLEAR_CONFIG_BLOCK(ifo); 2485 2486 vlen = strlcpy((char *)ifo->vendorclassid + 1, ctx->vendor, 2487 sizeof(ifo->vendorclassid) - 1); 2488 ifo->vendorclassid[0] = (uint8_t)(vlen > 255 ? 0 : vlen); 2489 2490 /* Reset route order */ 2491 ctx->rt_order = 0; 2492 2493 /* Parse our embedded options file */ 2494 if (ifname == NULL && !(ctx->options & DHCPCD_PRINT_PIDFILE)) { 2495 /* Space for initial estimates */ 2496 #if defined(INET) && defined(INITDEFINES) 2497 ifo->dhcp_override = 2498 calloc(INITDEFINES, sizeof(*ifo->dhcp_override)); 2499 if (ifo->dhcp_override == NULL) 2500 logerr(__func__); 2501 else 2502 ifo->dhcp_override_len = INITDEFINES; 2503 #endif 2504 2505 #if defined(INET6) && defined(INITDEFINENDS) 2506 ifo->nd_override = 2507 calloc(INITDEFINENDS, sizeof(*ifo->nd_override)); 2508 if (ifo->nd_override == NULL) 2509 logerr(__func__); 2510 else 2511 ifo->nd_override_len = INITDEFINENDS; 2512 #endif 2513 #if defined(INET6) && defined(INITDEFINE6S) 2514 ifo->dhcp6_override = 2515 calloc(INITDEFINE6S, sizeof(*ifo->dhcp6_override)); 2516 if (ifo->dhcp6_override == NULL) 2517 logerr(__func__); 2518 else 2519 ifo->dhcp6_override_len = INITDEFINE6S; 2520 #endif 2521 2522 /* Now load our embedded config */ 2523 #ifdef EMBEDDED_CONFIG 2524 buflen = dhcp_readfile(ctx, EMBEDDED_CONFIG, buf, sizeof(buf)); 2525 if (buflen == -1) { 2526 logerr("%s: %s", __func__, EMBEDDED_CONFIG); 2527 return ifo; 2528 } 2529 if (buf[buflen - 1] != '\0') { 2530 if ((size_t)buflen < sizeof(buf) - 1) 2531 buflen++; 2532 buf[buflen - 1] = '\0'; 2533 } 2534 #else 2535 buflen = (ssize_t)strlcpy(buf, dhcpcd_embedded_conf, 2536 sizeof(buf)); 2537 if ((size_t)buflen >= sizeof(buf)) { 2538 logerrx("%s: embedded config too big", __func__); 2539 return ifo; 2540 } 2541 /* Our embedded config is NULL terminated */ 2542 #endif 2543 bp = buf; 2544 while ((line = get_line(&bp, &buflen)) != NULL) { 2545 option = strsep(&line, " \t"); 2546 if (line) 2547 line = strskipwhite(line); 2548 /* Trim trailing whitespace */ 2549 if (line) { 2550 p = line + strlen(line) - 1; 2551 while (p != line && 2552 (*p == ' ' || *p == '\t') && 2553 *(p - 1) != '\\') 2554 *p-- = '\0'; 2555 } 2556 parse_config_line(ctx, NULL, ifo, option, line, 2557 &ldop, &edop); 2558 } 2559 2560 #ifdef INET 2561 ctx->dhcp_opts = ifo->dhcp_override; 2562 ctx->dhcp_opts_len = ifo->dhcp_override_len; 2563 #else 2564 for (i = 0, opt = ifo->dhcp_override; 2565 i < ifo->dhcp_override_len; 2566 i++, opt++) 2567 free_dhcp_opt_embenc(opt); 2568 free(ifo->dhcp_override); 2569 #endif 2570 ifo->dhcp_override = NULL; 2571 ifo->dhcp_override_len = 0; 2572 2573 #ifdef INET6 2574 ctx->nd_opts = ifo->nd_override; 2575 ctx->nd_opts_len = ifo->nd_override_len; 2576 #ifdef DHCP6 2577 ctx->dhcp6_opts = ifo->dhcp6_override; 2578 ctx->dhcp6_opts_len = ifo->dhcp6_override_len; 2579 #endif 2580 #else 2581 for (i = 0, opt = ifo->nd_override; 2582 i < ifo->nd_override_len; 2583 i++, opt++) 2584 free_dhcp_opt_embenc(opt); 2585 free(ifo->nd_override); 2586 for (i = 0, opt = ifo->dhcp6_override; 2587 i < ifo->dhcp6_override_len; 2588 i++, opt++) 2589 free_dhcp_opt_embenc(opt); 2590 free(ifo->dhcp6_override); 2591 #endif 2592 ifo->nd_override = NULL; 2593 ifo->nd_override_len = 0; 2594 ifo->dhcp6_override = NULL; 2595 ifo->dhcp6_override_len = 0; 2596 2597 ctx->vivso = ifo->vivso_override; 2598 ctx->vivso_len = ifo->vivso_override_len; 2599 ifo->vivso_override = NULL; 2600 ifo->vivso_override_len = 0; 2601 } 2602 2603 /* Parse our options file */ 2604 buflen = dhcp_readfile(ctx, ctx->cffile, buf, sizeof(buf)); 2605 if (buflen == -1) { 2606 /* dhcpcd can continue without it, but no DNS options 2607 * would be requested ... */ 2608 logerr("%s: %s", __func__, ctx->cffile); 2609 return ifo; 2610 } 2611 if (buf[buflen - 1] != '\0') { 2612 if ((size_t)buflen < sizeof(buf) - 1) 2613 buflen++; 2614 buf[buflen - 1] = '\0'; 2615 } 2616 dhcp_filemtime(ctx, ctx->cffile, &ifo->mtime); 2617 2618 ldop = edop = NULL; 2619 skip = have_profile = new_block = 0; 2620 had_block = ifname == NULL ? 1 : 0; 2621 bp = buf; 2622 while ((line = get_line(&bp, &buflen)) != NULL) { 2623 option = strsep(&line, " \t"); 2624 if (line) 2625 line = strskipwhite(line); 2626 /* Trim trailing whitespace */ 2627 if (line) { 2628 p = line + strlen(line) - 1; 2629 while (p != line && 2630 (*p == ' ' || *p == '\t') && 2631 *(p - 1) != '\\') 2632 *p-- = '\0'; 2633 } 2634 if (skip == 0 && new_block) { 2635 had_block = 1; 2636 new_block = 0; 2637 ifo->options &= ~DHCPCD_WAITOPTS; 2638 SET_CONFIG_BLOCK(ifo); 2639 } 2640 2641 /* Start of an interface block, skip if not ours */ 2642 if (strcmp(option, "interface") == 0) { 2643 char **n; 2644 2645 new_block = 1; 2646 if (line == NULL) { 2647 /* No interface given */ 2648 skip = 1; 2649 continue; 2650 } 2651 if (ifname && strcmp(line, ifname) == 0) 2652 skip = 0; 2653 else 2654 skip = 1; 2655 if (ifname) 2656 continue; 2657 2658 n = reallocarray(ctx->ifcv, 2659 (size_t)ctx->ifcc + 1, sizeof(char *)); 2660 if (n == NULL) { 2661 logerr(__func__); 2662 continue; 2663 } 2664 ctx->ifcv = n; 2665 ctx->ifcv[ctx->ifcc] = strdup(line); 2666 if (ctx->ifcv[ctx->ifcc] == NULL) { 2667 logerr(__func__); 2668 continue; 2669 } 2670 ctx->ifcc++; 2671 continue; 2672 } 2673 /* Start of an ssid block, skip if not ours */ 2674 if (strcmp(option, "ssid") == 0) { 2675 new_block = 1; 2676 if (ssid && line && strcmp(line, ssid) == 0) 2677 skip = 0; 2678 else 2679 skip = 1; 2680 continue; 2681 } 2682 /* Start of a profile block, skip if not ours */ 2683 if (strcmp(option, "profile") == 0) { 2684 new_block = 1; 2685 if (profile && line && strcmp(line, profile) == 0) { 2686 skip = 0; 2687 have_profile = 1; 2688 } else 2689 skip = 1; 2690 continue; 2691 } 2692 /* Skip arping if we have selected a profile but not parsing 2693 * one. */ 2694 if (profile && !have_profile && strcmp(option, "arping") == 0) 2695 continue; 2696 if (skip) 2697 continue; 2698 2699 parse_config_line(ctx, ifname, ifo, option, line, &ldop, &edop); 2700 } 2701 2702 if (profile && !have_profile) { 2703 free_options(ctx, ifo); 2704 errno = ENOENT; 2705 return NULL; 2706 } 2707 2708 if (!had_block) 2709 ifo->options &= ~DHCPCD_WAITOPTS; 2710 CLEAR_CONFIG_BLOCK(ifo); 2711 finish_config(ifo); 2712 return ifo; 2713 } 2714 2715 int 2716 add_options(struct dhcpcd_ctx *ctx, const char *ifname, 2717 struct if_options *ifo, int argc, char **argv) 2718 { 2719 int oi, opt, r; 2720 unsigned long long wait_opts; 2721 2722 if (argc == 0) 2723 return 1; 2724 2725 optind = 0; 2726 r = 1; 2727 /* Don't apply the command line wait options to each interface, 2728 * only use the dhcpcd.conf entry for that. */ 2729 if (ifname != NULL) 2730 wait_opts = ifo->options & DHCPCD_WAITOPTS; 2731 while ((opt = getopt_long(argc, argv, 2732 ctx->options & DHCPCD_PRINT_PIDFILE ? NOERR_IF_OPTS : IF_OPTS, 2733 cf_options, &oi)) != -1) 2734 { 2735 r = parse_option(ctx, ifname, ifo, opt, optarg, NULL, NULL); 2736 if (r != 1) 2737 break; 2738 } 2739 if (ifname != NULL) { 2740 ifo->options &= ~DHCPCD_WAITOPTS; 2741 ifo->options |= wait_opts; 2742 } 2743 2744 finish_config(ifo); 2745 return r; 2746 } 2747 2748 void 2749 free_options(struct dhcpcd_ctx *ctx, struct if_options *ifo) 2750 { 2751 size_t i; 2752 #ifdef RT_FREE_ROUTE_TABLE 2753 struct interface *ifp; 2754 struct rt *rt; 2755 #endif 2756 struct dhcp_opt *opt; 2757 struct vivco *vo; 2758 #ifdef AUTH 2759 struct token *token; 2760 #endif 2761 2762 if (ifo == NULL) 2763 return; 2764 2765 if (ifo->environ) { 2766 i = 0; 2767 while (ifo->environ[i]) 2768 free(ifo->environ[i++]); 2769 free(ifo->environ); 2770 } 2771 if (ifo->config) { 2772 i = 0; 2773 while (ifo->config[i]) 2774 free(ifo->config[i++]); 2775 free(ifo->config); 2776 } 2777 2778 #ifdef RT_FREE_ROUTE_TABLE 2779 /* Stupidly, we don't know the interface when creating the options. 2780 * As such, make sure each route has one so they can goto the 2781 * free list. */ 2782 ifp = ctx->ifaces != NULL ? TAILQ_FIRST(ctx->ifaces) : NULL; 2783 if (ifp != NULL) { 2784 RB_TREE_FOREACH(rt, &ifo->routes) { 2785 if (rt->rt_ifp == NULL) 2786 rt->rt_ifp = ifp; 2787 } 2788 } 2789 #endif 2790 rt_headclear0(ctx, &ifo->routes, AF_UNSPEC); 2791 2792 free(ifo->arping); 2793 free(ifo->blacklist); 2794 free(ifo->fallback); 2795 2796 for (opt = ifo->dhcp_override; 2797 ifo->dhcp_override_len > 0; 2798 opt++, ifo->dhcp_override_len--) 2799 free_dhcp_opt_embenc(opt); 2800 free(ifo->dhcp_override); 2801 for (opt = ifo->nd_override; 2802 ifo->nd_override_len > 0; 2803 opt++, ifo->nd_override_len--) 2804 free_dhcp_opt_embenc(opt); 2805 free(ifo->nd_override); 2806 for (opt = ifo->dhcp6_override; 2807 ifo->dhcp6_override_len > 0; 2808 opt++, ifo->dhcp6_override_len--) 2809 free_dhcp_opt_embenc(opt); 2810 free(ifo->dhcp6_override); 2811 for (vo = ifo->vivco; 2812 ifo->vivco_len > 0; 2813 vo++, ifo->vivco_len--) 2814 free(vo->data); 2815 free(ifo->vivco); 2816 for (opt = ifo->vivso_override; 2817 ifo->vivso_override_len > 0; 2818 opt++, ifo->vivso_override_len--) 2819 free_dhcp_opt_embenc(opt); 2820 free(ifo->vivso_override); 2821 2822 #if defined(INET6) && !defined(SMALL) 2823 for (; ifo->ia_len > 0; ifo->ia_len--) 2824 free(ifo->ia[ifo->ia_len - 1].sla); 2825 #endif 2826 free(ifo->ia); 2827 2828 #ifdef AUTH 2829 while ((token = TAILQ_FIRST(&ifo->auth.tokens))) { 2830 TAILQ_REMOVE(&ifo->auth.tokens, token, next); 2831 if (token->realm_len) 2832 free(token->realm); 2833 free(token->key); 2834 free(token); 2835 } 2836 #endif 2837 free(ifo); 2838 } 2839