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