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 if (arg != NULL && arg[0] != '\0') { 962 if (arg[0] == '4' || arg[1] == '4') 963 ifo->options |= DHCPCD_WAITIP4; 964 if (arg[0] == '6' || arg[1] == '6') 965 ifo->options |= DHCPCD_WAITIP6; 966 } 967 break; 968 case 'y': 969 ARG_REQUIRED; 970 ifo->reboot = (uint32_t)strtou(arg, NULL, 0, 0, UINT32_MAX, &e); 971 if (e) { 972 logerr("failed to convert reboot %s", arg); 973 return -1; 974 } 975 break; 976 case 'z': 977 ARG_REQUIRED; 978 if (!IN_CONFIG_BLOCK(ifo)) 979 ctx->ifav = splitv(&ctx->ifac, ctx->ifav, arg); 980 break; 981 case 'A': 982 ifo->options &= ~DHCPCD_ARP; 983 /* IPv4LL requires ARP */ 984 ifo->options &= ~DHCPCD_IPV4LL; 985 break; 986 case 'B': 987 ifo->options &= ~DHCPCD_DAEMONISE; 988 break; 989 case 'C': 990 ARG_REQUIRED; 991 /* Commas to spaces for shell */ 992 while ((p = strchr(arg, ','))) 993 *p = ' '; 994 dl = strlen("skip_hooks=") + strlen(arg) + 1; 995 p = malloc(sizeof(char) * dl); 996 if (p == NULL) { 997 logerr(__func__); 998 return -1; 999 } 1000 snprintf(p, dl, "skip_hooks=%s", arg); 1001 add_environ(&ifo->environ, p, 0); 1002 free(p); 1003 break; 1004 case 'D': 1005 ifo->options |= DHCPCD_CLIENTID | DHCPCD_DUID; 1006 if (ifname != NULL) /* duid type only a global option */ 1007 break; 1008 if (arg == NULL) 1009 ctx->duid_type = DUID_DEFAULT; 1010 else if (strcmp(arg, "ll") == 0) 1011 ctx->duid_type = DUID_LL; 1012 else if (strcmp(arg, "llt") == 0) 1013 ctx->duid_type = DUID_LLT; 1014 else if (strcmp(arg, "uuid") == 0) 1015 ctx->duid_type = DUID_UUID; 1016 else { 1017 dl = hwaddr_aton(NULL, arg); 1018 if (dl != 0) { 1019 no = realloc(ctx->duid, dl); 1020 if (no == NULL) 1021 logerrx(__func__); 1022 else { 1023 ctx->duid = no; 1024 ctx->duid_len = hwaddr_aton(no, arg); 1025 } 1026 } 1027 } 1028 break; 1029 case 'E': 1030 ifo->options |= DHCPCD_LASTLEASE; 1031 break; 1032 case 'F': 1033 if (!arg) { 1034 ifo->fqdn = FQDN_BOTH; 1035 break; 1036 } 1037 if (strcmp(arg, "none") == 0) 1038 ifo->fqdn = FQDN_NONE; 1039 else if (strcmp(arg, "ptr") == 0) 1040 ifo->fqdn = FQDN_PTR; 1041 else if (strcmp(arg, "both") == 0) 1042 ifo->fqdn = FQDN_BOTH; 1043 else if (strcmp(arg, "disable") == 0) 1044 ifo->fqdn = FQDN_DISABLE; 1045 else { 1046 logerrx("invalid FQDN value: %s", arg); 1047 return -1; 1048 } 1049 break; 1050 case 'G': 1051 ifo->options &= ~DHCPCD_GATEWAY; 1052 break; 1053 case 'H': 1054 ifo->options |= DHCPCD_XID_HWADDR; 1055 break; 1056 case 'I': 1057 /* Strings have a type of 0 */; 1058 ifo->clientid[1] = 0; 1059 if (arg) 1060 s = parse_hwaddr((char *)ifo->clientid + 1, 1061 CLIENTID_MAX_LEN, arg); 1062 else 1063 s = 0; 1064 if (s == -1) { 1065 logerr("clientid"); 1066 return -1; 1067 } 1068 ifo->options |= DHCPCD_CLIENTID; 1069 ifo->clientid[0] = (uint8_t)s; 1070 ifo->options &= ~DHCPCD_DUID; 1071 break; 1072 case 'J': 1073 ifo->options |= DHCPCD_BROADCAST; 1074 break; 1075 case 'K': 1076 ifo->options &= ~DHCPCD_LINK; 1077 break; 1078 case 'L': 1079 ifo->options &= ~DHCPCD_IPV4LL; 1080 break; 1081 case 'M': 1082 ifo->options |= DHCPCD_MANAGER; 1083 break; 1084 case 'O': 1085 ARG_REQUIRED; 1086 if (ctx->options & DHCPCD_PRINT_PIDFILE) 1087 break; 1088 set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo, 1089 &request, &require, &no, &reject); 1090 if (make_option_mask(d, dl, od, odl, request, arg, -1) != 0 || 1091 make_option_mask(d, dl, od, odl, require, arg, -1) != 0 || 1092 make_option_mask(d, dl, od, odl, no, arg, 1) != 0) 1093 { 1094 logerrx("unknown option: %s", arg); 1095 return -1; 1096 } 1097 break; 1098 case 'Q': 1099 ARG_REQUIRED; 1100 if (ctx->options & DHCPCD_PRINT_PIDFILE) 1101 break; 1102 set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo, 1103 &request, &require, &no, &reject); 1104 if (make_option_mask(d, dl, od, odl, require, arg, 1) != 0 || 1105 make_option_mask(d, dl, od, odl, request, arg, 1) != 0 || 1106 make_option_mask(d, dl, od, odl, no, arg, -1) != 0 || 1107 make_option_mask(d, dl, od, odl, reject, arg, -1) != 0) 1108 { 1109 logerrx("unknown option: %s", arg); 1110 return -1; 1111 } 1112 break; 1113 case 'S': 1114 ARG_REQUIRED; 1115 p = strchr(arg, '='); 1116 if (p == NULL) { 1117 logerrx("static assignment required"); 1118 return -1; 1119 } 1120 p = strskipwhite(++p); 1121 if (strncmp(arg, "ip_address=", strlen("ip_address=")) == 0) { 1122 if (p == NULL) { 1123 ifo->options &= ~DHCPCD_STATIC; 1124 ifo->req_addr.s_addr = INADDR_ANY; 1125 break; 1126 } 1127 if (parse_addr(&ifo->req_addr, 1128 ifo->req_mask.s_addr == 0 ? &ifo->req_mask : NULL, 1129 p) != 0) 1130 return -1; 1131 1132 ifo->options |= DHCPCD_STATIC; 1133 ifo->options &= ~DHCPCD_INFORM; 1134 } else if (strncmp(arg, "subnet_mask=", 1135 strlen("subnet_mask=")) == 0) 1136 { 1137 if (p == NULL) { 1138 ifo->req_mask.s_addr = INADDR_ANY; 1139 break; 1140 } 1141 if (parse_addr(&ifo->req_mask, NULL, p) != 0) 1142 return -1; 1143 } else if (strncmp(arg, "broadcast_address=", 1144 strlen("broadcast_address=")) == 0) 1145 { 1146 if (p == NULL) { 1147 ifo->req_brd.s_addr = INADDR_ANY; 1148 break; 1149 } 1150 if (parse_addr(&ifo->req_brd, NULL, p) != 0) 1151 return -1; 1152 } else if (strncmp(arg, "routes=", strlen("routes=")) == 0 || 1153 strncmp(arg, "static_routes=", 1154 strlen("static_routes=")) == 0 || 1155 strncmp(arg, "classless_static_routes=", 1156 strlen("classless_static_routes=")) == 0 || 1157 strncmp(arg, "ms_classless_static_routes=", 1158 strlen("ms_classless_static_routes=")) == 0) 1159 { 1160 struct in_addr addr3; 1161 1162 if (p == NULL) { 1163 rt_headclear(&ifo->routes, AF_INET); 1164 add_environ(&ifo->config, arg, 1); 1165 break; 1166 } 1167 1168 fp = np = strwhite(p); 1169 if (np == NULL) { 1170 logerrx("all routes need a gateway"); 1171 return -1; 1172 } 1173 *np++ = '\0'; 1174 np = strskipwhite(np); 1175 if (parse_addr(&addr, &addr2, p) == -1 || 1176 parse_addr(&addr3, NULL, np) == -1) 1177 { 1178 *fp = ' '; 1179 return -1; 1180 } 1181 *fp = ' '; 1182 if ((rt = rt_new0(ctx)) == NULL) 1183 return -1; 1184 sa_in_init(&rt->rt_dest, &addr); 1185 sa_in_init(&rt->rt_netmask, &addr2); 1186 sa_in_init(&rt->rt_gateway, &addr3); 1187 if (rt_proto_add_ctx(&ifo->routes, rt, ctx)) 1188 add_environ(&ifo->config, arg, 0); 1189 } else if (strncmp(arg, "routers=", strlen("routers=")) == 0) { 1190 if (p == NULL) { 1191 rt_headclear(&ifo->routes, AF_INET); 1192 add_environ(&ifo->config, arg, 1); 1193 break; 1194 } 1195 if (parse_addr(&addr, NULL, p) == -1) 1196 return -1; 1197 if ((rt = rt_new0(ctx)) == NULL) 1198 return -1; 1199 addr2.s_addr = INADDR_ANY; 1200 sa_in_init(&rt->rt_dest, &addr2); 1201 sa_in_init(&rt->rt_netmask, &addr2); 1202 sa_in_init(&rt->rt_gateway, &addr); 1203 if (rt_proto_add_ctx(&ifo->routes, rt, ctx)) 1204 add_environ(&ifo->config, arg, 0); 1205 } else if (strncmp(arg, "interface_mtu=", 1206 strlen("interface_mtu=")) == 0 || 1207 strncmp(arg, "mtu=", strlen("mtu=")) == 0) 1208 { 1209 if (p == NULL) 1210 break; 1211 ifo->mtu = (unsigned int)strtou(p, NULL, 0, 1212 MTU_MIN, MTU_MAX, &e); 1213 if (e) { 1214 logerrx("invalid MTU %s", p); 1215 return -1; 1216 } 1217 } else if (strncmp(arg, "ip6_address=", strlen("ip6_address=")) == 0) { 1218 if (p == NULL) { 1219 memset(&ifo->req_addr6, 0, 1220 sizeof(ifo->req_addr6)); 1221 break; 1222 } 1223 1224 np = strchr(p, '/'); 1225 if (np) 1226 *np++ = '\0'; 1227 if ((i = inet_pton(AF_INET6, p, &ifo->req_addr6)) == 1) { 1228 if (np) { 1229 ifo->req_prefix_len = (uint8_t)strtou(np, 1230 NULL, 0, 0, 128, &e); 1231 if (e) { 1232 logerrx("%s: failed to " 1233 "convert prefix len", 1234 ifname); 1235 return -1; 1236 } 1237 } else 1238 ifo->req_prefix_len = 128; 1239 } 1240 if (np) 1241 *(--np) = '\0'; 1242 if (i != 1) { 1243 logerrx("invalid AF_INET6: %s", p); 1244 memset(&ifo->req_addr6, 0, 1245 sizeof(ifo->req_addr6)); 1246 return -1; 1247 } 1248 } else 1249 add_environ(&ifo->config, arg, p == NULL ? 1 : 0); 1250 break; 1251 1252 case 'W': 1253 if (parse_addr(&addr, &addr2, arg) != 0) 1254 return -1; 1255 if (strchr(arg, '/') == NULL) 1256 addr2.s_addr = INADDR_BROADCAST; 1257 naddr = reallocarray(ifo->whitelist, 1258 ifo->whitelist_len + 2, sizeof(in_addr_t)); 1259 if (naddr == NULL) { 1260 logerr(__func__); 1261 return -1; 1262 } 1263 ifo->whitelist = naddr; 1264 ifo->whitelist[ifo->whitelist_len++] = addr.s_addr; 1265 ifo->whitelist[ifo->whitelist_len++] = addr2.s_addr; 1266 break; 1267 case 'X': 1268 if (parse_addr(&addr, &addr2, arg) != 0) 1269 return -1; 1270 if (strchr(arg, '/') == NULL) 1271 addr2.s_addr = INADDR_BROADCAST; 1272 naddr = reallocarray(ifo->blacklist, 1273 ifo->blacklist_len + 2, sizeof(in_addr_t)); 1274 if (naddr == NULL) { 1275 logerr(__func__); 1276 return -1; 1277 } 1278 ifo->blacklist = naddr; 1279 ifo->blacklist[ifo->blacklist_len++] = addr.s_addr; 1280 ifo->blacklist[ifo->blacklist_len++] = addr2.s_addr; 1281 break; 1282 case 'Z': 1283 ARG_REQUIRED; 1284 if (!IN_CONFIG_BLOCK(ifo)) 1285 ctx->ifdv = splitv(&ctx->ifdc, ctx->ifdv, arg); 1286 break; 1287 case '1': 1288 ifo->options |= DHCPCD_ONESHOT; 1289 break; 1290 case '4': 1291 #ifdef INET 1292 ifo->options &= ~DHCPCD_IPV6; 1293 ifo->options |= DHCPCD_IPV4; 1294 break; 1295 #else 1296 logerrx("INET has been compiled out"); 1297 return -1; 1298 #endif 1299 case '6': 1300 #ifdef INET6 1301 ifo->options &= ~DHCPCD_IPV4; 1302 ifo->options |= DHCPCD_IPV6; 1303 break; 1304 #else 1305 logerrx("INET6 has been compiled out"); 1306 return -1; 1307 #endif 1308 case O_IPV4: 1309 ifo->options |= DHCPCD_IPV4; 1310 break; 1311 case O_NOIPV4: 1312 ifo->options &= ~DHCPCD_IPV4; 1313 break; 1314 case O_IPV6: 1315 ifo->options |= DHCPCD_IPV6; 1316 break; 1317 case O_NOIPV6: 1318 ifo->options &= ~DHCPCD_IPV6; 1319 break; 1320 case O_ANONYMOUS: 1321 ifo->options |= DHCPCD_ANONYMOUS; 1322 ifo->options &= ~DHCPCD_HOSTNAME; 1323 ifo->fqdn = FQDN_DISABLE; 1324 1325 /* Block everything */ 1326 memset(ifo->nomask, 0xff, sizeof(ifo->nomask)); 1327 memset(ifo->nomask6, 0xff, sizeof(ifo->nomask6)); 1328 1329 /* Allow the bare minimum through */ 1330 #ifdef INET 1331 del_option_mask(ifo->nomask, DHO_SUBNETMASK); 1332 del_option_mask(ifo->nomask, DHO_CSR); 1333 del_option_mask(ifo->nomask, DHO_ROUTER); 1334 del_option_mask(ifo->nomask, DHO_DNSSERVER); 1335 del_option_mask(ifo->nomask, DHO_DNSDOMAIN); 1336 del_option_mask(ifo->nomask, DHO_BROADCAST); 1337 del_option_mask(ifo->nomask, DHO_STATICROUTE); 1338 del_option_mask(ifo->nomask, DHO_SERVERID); 1339 del_option_mask(ifo->nomask, DHO_RENEWALTIME); 1340 del_option_mask(ifo->nomask, DHO_REBINDTIME); 1341 del_option_mask(ifo->nomask, DHO_DNSSEARCH); 1342 #endif 1343 1344 #ifdef DHCP6 1345 del_option_mask(ifo->nomask6, D6_OPTION_DNS_SERVERS); 1346 del_option_mask(ifo->nomask6, D6_OPTION_DOMAIN_LIST); 1347 del_option_mask(ifo->nomask6, D6_OPTION_SOL_MAX_RT); 1348 del_option_mask(ifo->nomask6, D6_OPTION_INF_MAX_RT); 1349 #endif 1350 1351 break; 1352 case O_RANDOMISE_HWADDR: 1353 ifo->randomise_hwaddr = true; 1354 break; 1355 #ifdef INET 1356 case O_ARPING: 1357 while (arg != NULL) { 1358 fp = strwhite(arg); 1359 if (fp) 1360 *fp++ = '\0'; 1361 if (parse_addr(&addr, NULL, arg) != 0) 1362 return -1; 1363 naddr = reallocarray(ifo->arping, 1364 (size_t)ifo->arping_len + 1, sizeof(in_addr_t)); 1365 if (naddr == NULL) { 1366 logerr(__func__); 1367 return -1; 1368 } 1369 ifo->arping = naddr; 1370 ifo->arping[ifo->arping_len++] = addr.s_addr; 1371 arg = strskipwhite(fp); 1372 } 1373 break; 1374 case O_DESTINATION: 1375 ARG_REQUIRED; 1376 if (ctx->options & DHCPCD_PRINT_PIDFILE) 1377 break; 1378 set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo, 1379 &request, &require, &no, &reject); 1380 if (make_option_mask(d, dl, od, odl, 1381 ifo->dstmask, arg, 2) != 0) 1382 { 1383 if (errno == EINVAL) 1384 logerrx("option does not take" 1385 " an IPv4 address: %s", arg); 1386 else 1387 logerrx("unknown option: %s", arg); 1388 return -1; 1389 } 1390 break; 1391 case O_FALLBACK: 1392 ARG_REQUIRED; 1393 free(ifo->fallback); 1394 ifo->fallback = strdup(arg); 1395 if (ifo->fallback == NULL) { 1396 logerrx(__func__); 1397 return -1; 1398 } 1399 break; 1400 #endif 1401 case O_IAID: 1402 ARG_REQUIRED; 1403 if (ctx->options & DHCPCD_MANAGER && !IN_CONFIG_BLOCK(ifo)) { 1404 logerrx("IAID must belong in an interface block"); 1405 return -1; 1406 } 1407 if (parse_iaid(ifo->iaid, arg, sizeof(ifo->iaid)) == -1) { 1408 logerrx("invalid IAID %s", arg); 1409 return -1; 1410 } 1411 ifo->options |= DHCPCD_IAID; 1412 break; 1413 case O_IPV6RS: 1414 ifo->options |= DHCPCD_IPV6RS; 1415 break; 1416 case O_NOIPV6RS: 1417 ifo->options &= ~DHCPCD_IPV6RS; 1418 break; 1419 case O_IPV6RA_FORK: 1420 ifo->options &= ~DHCPCD_IPV6RA_REQRDNSS; 1421 break; 1422 case O_IPV6RA_AUTOCONF: 1423 ifo->options |= DHCPCD_IPV6RA_AUTOCONF; 1424 break; 1425 case O_IPV6RA_NOAUTOCONF: 1426 ifo->options &= ~DHCPCD_IPV6RA_AUTOCONF; 1427 break; 1428 case O_NOALIAS: 1429 ifo->options |= DHCPCD_NOALIAS; 1430 break; 1431 #ifdef DHCP6 1432 case O_IA_NA: 1433 i = D6_OPTION_IA_NA; 1434 /* FALLTHROUGH */ 1435 case O_IA_TA: 1436 if (i == 0) 1437 i = D6_OPTION_IA_TA; 1438 /* FALLTHROUGH */ 1439 case O_IA_PD: 1440 if (i == 0) { 1441 #ifdef SMALL 1442 logwarnx("%s: IA_PD not compiled in", ifname); 1443 return -1; 1444 #else 1445 if (ctx->options & DHCPCD_MANAGER && 1446 !IN_CONFIG_BLOCK(ifo)) 1447 { 1448 logerrx("IA PD must belong in an " 1449 "interface block"); 1450 return -1; 1451 } 1452 i = D6_OPTION_IA_PD; 1453 #endif 1454 } 1455 if (ctx->options & DHCPCD_MANAGER && 1456 !IN_CONFIG_BLOCK(ifo) && arg) 1457 { 1458 logerrx("IA with IAID must belong in an " 1459 "interface block"); 1460 return -1; 1461 } 1462 ifo->options |= DHCPCD_IA_FORCED; 1463 fp = strwhite(arg); 1464 if (fp) { 1465 *fp++ = '\0'; 1466 fp = strskipwhite(fp); 1467 } 1468 if (arg) { 1469 p = strchr(arg, '/'); 1470 if (p) 1471 *p++ = '\0'; 1472 if (parse_iaid(iaid, arg, sizeof(iaid)) == -1) { 1473 logerr("invalid IAID: %s", arg); 1474 return -1; 1475 } 1476 } 1477 ia = NULL; 1478 for (sl = 0; sl < ifo->ia_len; sl++) { 1479 if ((arg == NULL && !ifo->ia[sl].iaid_set) || 1480 (arg != NULL && ifo->ia[sl].iaid_set && 1481 ifo->ia[sl].ia_type == (uint16_t)i && 1482 ifo->ia[sl].iaid[0] == iaid[0] && 1483 ifo->ia[sl].iaid[1] == iaid[1] && 1484 ifo->ia[sl].iaid[2] == iaid[2] && 1485 ifo->ia[sl].iaid[3] == iaid[3])) 1486 { 1487 ia = &ifo->ia[sl]; 1488 break; 1489 } 1490 } 1491 if (ia == NULL) { 1492 ia = reallocarray(ifo->ia, 1493 ifo->ia_len + 1, sizeof(*ifo->ia)); 1494 if (ia == NULL) { 1495 logerr(__func__); 1496 return -1; 1497 } 1498 ifo->ia = ia; 1499 ia = &ifo->ia[ifo->ia_len++]; 1500 ia->ia_type = (uint16_t)i; 1501 if (arg) { 1502 ia->iaid[0] = iaid[0]; 1503 ia->iaid[1] = iaid[1]; 1504 ia->iaid[2] = iaid[2]; 1505 ia->iaid[3] = iaid[3]; 1506 ia->iaid_set = 1; 1507 } else 1508 ia->iaid_set = 0; 1509 if (!ia->iaid_set || 1510 p == NULL || 1511 ia->ia_type == D6_OPTION_IA_TA) 1512 { 1513 memset(&ia->addr, 0, sizeof(ia->addr)); 1514 ia->prefix_len = 0; 1515 } else { 1516 arg = p; 1517 p = strchr(arg, '/'); 1518 if (p) 1519 *p++ = '\0'; 1520 if (inet_pton(AF_INET6, arg, &ia->addr) != 1) { 1521 logerrx("invalid AF_INET6: %s", arg); 1522 memset(&ia->addr, 0, sizeof(ia->addr)); 1523 } 1524 if (p && ia->ia_type == D6_OPTION_IA_PD) { 1525 ia->prefix_len = (uint8_t)strtou(p, 1526 NULL, 0, 8, 120, &e); 1527 if (e) { 1528 logerrx("%s: failed to convert" 1529 " prefix len", 1530 p); 1531 ia->prefix_len = 0; 1532 } 1533 } 1534 } 1535 #ifndef SMALL 1536 ia->sla_max = 0; 1537 ia->sla_len = 0; 1538 ia->sla = NULL; 1539 #endif 1540 } 1541 1542 #ifdef SMALL 1543 break; 1544 #else 1545 if (ia->ia_type != D6_OPTION_IA_PD) 1546 break; 1547 1548 for (p = fp; p; p = fp) { 1549 fp = strwhite(p); 1550 if (fp) { 1551 *fp++ = '\0'; 1552 fp = strskipwhite(fp); 1553 } 1554 sla = reallocarray(ia->sla, 1555 ia->sla_len + 1, sizeof(*ia->sla)); 1556 if (sla == NULL) { 1557 logerr(__func__); 1558 return -1; 1559 } 1560 ia->sla = sla; 1561 sla = &ia->sla[ia->sla_len++]; 1562 np = strchr(p, '/'); 1563 if (np) 1564 *np++ = '\0'; 1565 if (strlcpy(sla->ifname, p, 1566 sizeof(sla->ifname)) >= sizeof(sla->ifname)) 1567 { 1568 logerrx("%s: interface name too long", arg); 1569 goto err_sla; 1570 } 1571 sla->sla_set = false; 1572 sla->prefix_len = 0; 1573 sla->suffix = 1; 1574 p = np; 1575 if (p) { 1576 np = strchr(p, '/'); 1577 if (np) 1578 *np++ = '\0'; 1579 if (*p != '\0') { 1580 sla->sla = (uint32_t)strtou(p, NULL, 1581 0, 0, UINT32_MAX, &e); 1582 sla->sla_set = true; 1583 if (e) { 1584 logerrx("%s: failed to convert " 1585 "sla", 1586 ifname); 1587 goto err_sla; 1588 } 1589 } 1590 p = np; 1591 } 1592 if (p) { 1593 np = strchr(p, '/'); 1594 if (np) 1595 *np++ = '\0'; 1596 if (*p != '\0') { 1597 sla->prefix_len = (uint8_t)strtou(p, 1598 NULL, 0, 0, 120, &e); 1599 if (e) { 1600 logerrx("%s: failed to " 1601 "convert prefix len", 1602 ifname); 1603 goto err_sla; 1604 } 1605 } 1606 p = np; 1607 } 1608 if (p) { 1609 np = strchr(p, '/'); 1610 if (np) 1611 *np = '\0'; 1612 if (*p != '\0') { 1613 sla->suffix = (uint64_t)strtou(p, NULL, 1614 0, 0, UINT64_MAX, &e); 1615 if (e) { 1616 logerrx("%s: failed to " 1617 "convert suffix", 1618 ifname); 1619 goto err_sla; 1620 } 1621 } 1622 } 1623 /* Sanity check */ 1624 for (sl = 0; sl < ia->sla_len - 1; sl++) { 1625 slap = &ia->sla[sl]; 1626 if (slap->sla_set != sla->sla_set) { 1627 logerrx("%s: cannot mix automatic " 1628 "and fixed SLA", 1629 sla->ifname); 1630 goto err_sla; 1631 } 1632 if (ia->prefix_len && 1633 (sla->prefix_len == ia->prefix_len || 1634 slap->prefix_len == ia->prefix_len)) 1635 { 1636 logerrx("%s: cannot delegte the same" 1637 "prefix length more than once", 1638 sla->ifname); 1639 goto err_sla; 1640 } 1641 if (!sla->sla_set && 1642 strcmp(slap->ifname, sla->ifname) == 0) 1643 { 1644 logwarnx("%s: cannot specify the " 1645 "same interface twice with " 1646 "an automatic SLA", 1647 sla->ifname); 1648 goto err_sla; 1649 } 1650 if (slap->sla_set && sla->sla_set && 1651 slap->sla == sla->sla) 1652 { 1653 logerrx("%s: cannot" 1654 " assign the same SLA %u" 1655 " more than once", 1656 sla->ifname, sla->sla); 1657 goto err_sla; 1658 } 1659 } 1660 if (sla->sla_set && sla->sla > ia->sla_max) 1661 ia->sla_max = sla->sla; 1662 } 1663 break; 1664 err_sla: 1665 ia->sla_len--; 1666 return -1; 1667 #endif 1668 #endif 1669 case O_HOSTNAME_SHORT: 1670 ifo->options |= DHCPCD_HOSTNAME | DHCPCD_HOSTNAME_SHORT; 1671 break; 1672 case O_DEV: 1673 ARG_REQUIRED; 1674 #ifdef PLUGIN_DEV 1675 if (ctx->dev_load) 1676 free(ctx->dev_load); 1677 ctx->dev_load = strdup(arg); 1678 #endif 1679 break; 1680 case O_NODEV: 1681 ifo->options &= ~DHCPCD_DEV; 1682 break; 1683 case O_DEFINE: 1684 dop = &ifo->dhcp_override; 1685 dop_len = &ifo->dhcp_override_len; 1686 /* FALLTHROUGH */ 1687 case O_DEFINEND: 1688 if (dop == NULL) { 1689 dop = &ifo->nd_override; 1690 dop_len = &ifo->nd_override_len; 1691 } 1692 /* FALLTHROUGH */ 1693 case O_DEFINE6: 1694 if (dop == NULL) { 1695 dop = &ifo->dhcp6_override; 1696 dop_len = &ifo->dhcp6_override_len; 1697 } 1698 /* FALLTHROUGH */ 1699 case O_VENDOPT: 1700 if (dop == NULL) { 1701 dop = &ifo->vivso_override; 1702 dop_len = &ifo->vivso_override_len; 1703 } 1704 *edop = *ldop = NULL; 1705 /* FALLTHROUGH */ 1706 case O_EMBED: 1707 if (dop == NULL) { 1708 if (*edop) { 1709 dop = &(*edop)->embopts; 1710 dop_len = &(*edop)->embopts_len; 1711 } else if (ldop) { 1712 dop = &(*ldop)->embopts; 1713 dop_len = &(*ldop)->embopts_len; 1714 } else { 1715 logerrx("embed must be after a define " 1716 "or encap"); 1717 return -1; 1718 } 1719 } 1720 /* FALLTHROUGH */ 1721 case O_ENCAP: 1722 ARG_REQUIRED; 1723 if (dop == NULL) { 1724 if (*ldop == NULL) { 1725 logerrx("encap must be after a define"); 1726 return -1; 1727 } 1728 dop = &(*ldop)->encopts; 1729 dop_len = &(*ldop)->encopts_len; 1730 } 1731 1732 /* Shared code for define, define6, embed and encap */ 1733 1734 /* code */ 1735 if (opt == O_EMBED) /* Embedded options don't have codes */ 1736 u = 0; 1737 else { 1738 fp = strwhite(arg); 1739 if (fp == NULL) { 1740 logerrx("invalid syntax: %s", arg); 1741 return -1; 1742 } 1743 *fp++ = '\0'; 1744 u = (uint32_t)strtou(arg, NULL, 0, 0, UINT32_MAX, &e); 1745 if (e) { 1746 logerrx("invalid code: %s", arg); 1747 return -1; 1748 } 1749 arg = strskipwhite(fp); 1750 if (arg == NULL) { 1751 logerrx("invalid syntax"); 1752 return -1; 1753 } 1754 } 1755 /* type */ 1756 fp = strwhite(arg); 1757 if (fp) 1758 *fp++ = '\0'; 1759 np = strchr(arg, ':'); 1760 /* length */ 1761 if (np) { 1762 *np++ = '\0'; 1763 bp = NULL; /* No bitflag */ 1764 l = (long)strtou(np, NULL, 0, 0, LONG_MAX, &e); 1765 if (e) { 1766 logerrx("failed to convert length"); 1767 return -1; 1768 } 1769 } else { 1770 l = 0; 1771 bp = strchr(arg, '='); /* bitflag assignment */ 1772 if (bp) 1773 *bp++ = '\0'; 1774 } 1775 t = 0; 1776 if (strcasecmp(arg, "request") == 0) { 1777 t |= OT_REQUEST; 1778 arg = strskipwhite(fp); 1779 fp = strwhite(arg); 1780 if (fp == NULL) { 1781 logerrx("incomplete request type"); 1782 return -1; 1783 } 1784 *fp++ = '\0'; 1785 } else if (strcasecmp(arg, "norequest") == 0) { 1786 t |= OT_NOREQ; 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 } 1795 if (strcasecmp(arg, "optional") == 0) { 1796 t |= OT_OPTIONAL; 1797 arg = strskipwhite(fp); 1798 fp = strwhite(arg); 1799 if (fp == NULL) { 1800 logerrx("incomplete optional type"); 1801 return -1; 1802 } 1803 *fp++ = '\0'; 1804 } 1805 if (strcasecmp(arg, "index") == 0) { 1806 t |= OT_INDEX; 1807 arg = strskipwhite(fp); 1808 fp = strwhite(arg); 1809 if (fp == NULL) { 1810 logerrx("incomplete index type"); 1811 return -1; 1812 } 1813 *fp++ = '\0'; 1814 } 1815 if (strcasecmp(arg, "array") == 0) { 1816 t |= OT_ARRAY; 1817 arg = strskipwhite(fp); 1818 fp = strwhite(arg); 1819 if (fp == NULL) { 1820 logerrx("incomplete array type"); 1821 return -1; 1822 } 1823 *fp++ = '\0'; 1824 } 1825 if (strcasecmp(arg, "ipaddress") == 0) 1826 t |= OT_ADDRIPV4; 1827 else if (strcasecmp(arg, "ip6address") == 0) 1828 t |= OT_ADDRIPV6; 1829 else if (strcasecmp(arg, "string") == 0) 1830 t |= OT_STRING; 1831 else if (strcasecmp(arg, "byte") == 0) 1832 t |= OT_UINT8; 1833 else if (strcasecmp(arg, "bitflags") == 0) 1834 t |= OT_BITFLAG; 1835 else if (strcasecmp(arg, "uint8") == 0) 1836 t |= OT_UINT8; 1837 else if (strcasecmp(arg, "int8") == 0) 1838 t |= OT_INT8; 1839 else if (strcasecmp(arg, "uint16") == 0) 1840 t |= OT_UINT16; 1841 else if (strcasecmp(arg, "int16") == 0) 1842 t |= OT_INT16; 1843 else if (strcasecmp(arg, "uint32") == 0) 1844 t |= OT_UINT32; 1845 else if (strcasecmp(arg, "int32") == 0) 1846 t |= OT_INT32; 1847 else if (strcasecmp(arg, "flag") == 0) 1848 t |= OT_FLAG; 1849 else if (strcasecmp(arg, "raw") == 0) 1850 t |= OT_STRING | OT_RAW; 1851 else if (strcasecmp(arg, "ascii") == 0) 1852 t |= OT_STRING | OT_ASCII; 1853 else if (strcasecmp(arg, "domain") == 0) 1854 t |= OT_STRING | OT_DOMAIN | OT_RFC1035; 1855 else if (strcasecmp(arg, "dname") == 0) 1856 t |= OT_STRING | OT_DOMAIN; 1857 else if (strcasecmp(arg, "binhex") == 0) 1858 t |= OT_STRING | OT_BINHEX; 1859 else if (strcasecmp(arg, "embed") == 0) 1860 t |= OT_EMBED; 1861 else if (strcasecmp(arg, "encap") == 0) 1862 t |= OT_ENCAP; 1863 else if (strcasecmp(arg, "rfc3361") ==0) 1864 t |= OT_STRING | OT_RFC3361; 1865 else if (strcasecmp(arg, "rfc3442") ==0) 1866 t |= OT_STRING | OT_RFC3442; 1867 else if (strcasecmp(arg, "option") == 0) 1868 t |= OT_OPTION; 1869 else { 1870 logerrx("unknown type: %s", arg); 1871 return -1; 1872 } 1873 if (l && !(t & (OT_STRING | OT_BINHEX))) { 1874 logwarnx("ignoring length for type: %s", arg); 1875 l = 0; 1876 } 1877 if (t & OT_ARRAY && t & (OT_STRING | OT_BINHEX) && 1878 !(t & (OT_RFC1035 | OT_DOMAIN))) 1879 { 1880 logwarnx("ignoring array for strings"); 1881 t &= ~OT_ARRAY; 1882 } 1883 if (t & OT_BITFLAG) { 1884 if (bp == NULL) 1885 logwarnx("missing bitflag assignment"); 1886 } 1887 /* variable */ 1888 if (!fp) { 1889 if (!(t & OT_OPTION)) { 1890 logerrx("type %s requires a variable name", 1891 arg); 1892 return -1; 1893 } 1894 np = NULL; 1895 } else { 1896 arg = strskipwhite(fp); 1897 fp = strwhite(arg); 1898 if (fp) 1899 *fp++ = '\0'; 1900 if (strcasecmp(arg, "reserved")) { 1901 np = strdup(arg); 1902 if (np == NULL) { 1903 logerr(__func__); 1904 return -1; 1905 } 1906 } else { 1907 np = NULL; 1908 t |= OT_RESERVED; 1909 } 1910 } 1911 if (opt != O_EMBED) { 1912 for (dl = 0, ndop = *dop; dl < *dop_len; dl++, ndop++) 1913 { 1914 /* type 0 seems freshly malloced struct 1915 * for us to use */ 1916 if (ndop->option == u || ndop->type == 0) 1917 break; 1918 } 1919 if (dl == *dop_len) 1920 ndop = NULL; 1921 } else 1922 ndop = NULL; 1923 if (ndop == NULL) { 1924 ndop = reallocarray(*dop, *dop_len + 1, sizeof(**dop)); 1925 if (ndop == NULL) { 1926 logerr(__func__); 1927 free(np); 1928 return -1; 1929 } 1930 *dop = ndop; 1931 ndop = &(*dop)[(*dop_len)++]; 1932 ndop->embopts = NULL; 1933 ndop->embopts_len = 0; 1934 ndop->encopts = NULL; 1935 ndop->encopts_len = 0; 1936 } else 1937 free_dhcp_opt_embenc(ndop); 1938 ndop->option = (uint32_t)u; /* could have been 0 */ 1939 ndop->type = t; 1940 ndop->len = (size_t)l; 1941 ndop->var = np; 1942 if (bp) { 1943 dl = strlen(bp); 1944 memcpy(ndop->bitflags, bp, dl); 1945 memset(ndop->bitflags + dl, 0, 1946 sizeof(ndop->bitflags) - dl); 1947 } else 1948 memset(ndop->bitflags, 0, sizeof(ndop->bitflags)); 1949 /* Save the define for embed and encap options */ 1950 switch (opt) { 1951 case O_DEFINE: 1952 case O_DEFINEND: 1953 case O_DEFINE6: 1954 case O_VENDOPT: 1955 *ldop = ndop; 1956 break; 1957 case O_ENCAP: 1958 *edop = ndop; 1959 break; 1960 } 1961 break; 1962 case O_VENDCLASS: 1963 ARG_REQUIRED; 1964 fp = strwhite(arg); 1965 if (fp) 1966 *fp++ = '\0'; 1967 u = (uint32_t)strtou(arg, NULL, 0, 0, UINT32_MAX, &e); 1968 if (e) { 1969 logerrx("invalid code: %s", arg); 1970 return -1; 1971 } 1972 fp = strskipwhite(fp); 1973 if (fp) { 1974 s = parse_string(NULL, 0, fp); 1975 if (s == -1) { 1976 logerr(__func__); 1977 return -1; 1978 } 1979 dl = (size_t)s; 1980 if (dl + (sizeof(uint16_t) * 2) > UINT16_MAX) { 1981 logerrx("vendor class is too big"); 1982 return -1; 1983 } 1984 np = malloc(dl); 1985 if (np == NULL) { 1986 logerr(__func__); 1987 return -1; 1988 } 1989 parse_string(np, dl, fp); 1990 } else { 1991 dl = 0; 1992 np = NULL; 1993 } 1994 vivco = reallocarray(ifo->vivco, 1995 ifo->vivco_len + 1, sizeof(*ifo->vivco)); 1996 if (vivco == NULL) { 1997 logerr( __func__); 1998 free(np); 1999 return -1; 2000 } 2001 ifo->vivco = vivco; 2002 ifo->vivco_en = (uint32_t)u; 2003 vivco = &ifo->vivco[ifo->vivco_len++]; 2004 vivco->len = dl; 2005 vivco->data = (uint8_t *)np; 2006 break; 2007 case O_AUTHPROTOCOL: 2008 ARG_REQUIRED; 2009 #ifdef AUTH 2010 fp = strwhite(arg); 2011 if (fp) 2012 *fp++ = '\0'; 2013 if (strcasecmp(arg, "token") == 0) 2014 ifo->auth.protocol = AUTH_PROTO_TOKEN; 2015 else if (strcasecmp(arg, "delayed") == 0) 2016 ifo->auth.protocol = AUTH_PROTO_DELAYED; 2017 else if (strcasecmp(arg, "delayedrealm") == 0) 2018 ifo->auth.protocol = AUTH_PROTO_DELAYEDREALM; 2019 else { 2020 logerrx("%s: unsupported protocol", arg); 2021 return -1; 2022 } 2023 arg = strskipwhite(fp); 2024 fp = strwhite(arg); 2025 if (arg == NULL) { 2026 ifo->auth.options |= DHCPCD_AUTH_SEND; 2027 if (ifo->auth.protocol == AUTH_PROTO_TOKEN) 2028 ifo->auth.protocol = AUTH_ALG_NONE; 2029 else 2030 ifo->auth.algorithm = AUTH_ALG_HMAC_MD5; 2031 ifo->auth.rdm = AUTH_RDM_MONOTONIC; 2032 break; 2033 } 2034 if (fp) 2035 *fp++ = '\0'; 2036 if (ifo->auth.protocol == AUTH_PROTO_TOKEN) { 2037 np = strchr(arg, '/'); 2038 if (np) { 2039 if (fp == NULL || np < fp) 2040 *np++ = '\0'; 2041 else 2042 np = NULL; 2043 } 2044 if (parse_uint32(&ifo->auth.token_snd_secretid, 2045 arg) == -1) 2046 logerrx("%s: not a number", arg); 2047 else 2048 ifo->auth.token_rcv_secretid = 2049 ifo->auth.token_snd_secretid; 2050 if (np && 2051 parse_uint32(&ifo->auth.token_rcv_secretid, 2052 np) == -1) 2053 logerrx("%s: not a number", arg); 2054 } else { 2055 if (strcasecmp(arg, "hmacmd5") == 0 || 2056 strcasecmp(arg, "hmac-md5") == 0) 2057 ifo->auth.algorithm = AUTH_ALG_HMAC_MD5; 2058 else { 2059 logerrx("%s: unsupported algorithm", arg); 2060 return 1; 2061 } 2062 } 2063 arg = fp; 2064 if (arg == NULL) { 2065 ifo->auth.options |= DHCPCD_AUTH_SEND; 2066 ifo->auth.rdm = AUTH_RDM_MONOTONIC; 2067 break; 2068 } 2069 if (strcasecmp(arg, "monocounter") == 0) { 2070 ifo->auth.rdm = AUTH_RDM_MONOTONIC; 2071 ifo->auth.options |= DHCPCD_AUTH_RDM_COUNTER; 2072 } else if (strcasecmp(arg, "monotonic") ==0 || 2073 strcasecmp(arg, "monotime") == 0) 2074 ifo->auth.rdm = AUTH_RDM_MONOTONIC; 2075 else { 2076 logerrx("%s: unsupported RDM", arg); 2077 return -1; 2078 } 2079 ifo->auth.options |= DHCPCD_AUTH_SEND; 2080 break; 2081 #else 2082 logerrx("no authentication support"); 2083 return -1; 2084 #endif 2085 case O_AUTHTOKEN: 2086 ARG_REQUIRED; 2087 #ifdef AUTH 2088 fp = strwhite(arg); 2089 if (fp == NULL) { 2090 logerrx("authtoken requires a realm"); 2091 return -1; 2092 } 2093 *fp++ = '\0'; 2094 token = calloc(1, sizeof(*token)); 2095 if (token == NULL) { 2096 logerr(__func__); 2097 return -1; 2098 } 2099 if (parse_uint32(&token->secretid, arg) == -1) { 2100 logerrx("%s: not a number", arg); 2101 goto invalid_token; 2102 } 2103 arg = fp; 2104 fp = strend(arg); 2105 if (fp == NULL) { 2106 logerrx("authtoken requires a realm"); 2107 goto invalid_token; 2108 } 2109 *fp++ = '\0'; 2110 s = parse_string(NULL, 0, arg); 2111 if (s == -1) { 2112 logerr("realm_len"); 2113 goto invalid_token; 2114 } 2115 if (s != 0) { 2116 token->realm_len = (size_t)s; 2117 token->realm = malloc(token->realm_len); 2118 if (token->realm == NULL) { 2119 logerr(__func__); 2120 goto invalid_token; 2121 } 2122 parse_string((char *)token->realm, token->realm_len, 2123 arg); 2124 } 2125 arg = fp; 2126 fp = strend(arg); 2127 if (fp == NULL) { 2128 logerrx("authtoken requies an expiry date"); 2129 goto invalid_token; 2130 } 2131 *fp++ = '\0'; 2132 if (*arg == '"') { 2133 arg++; 2134 np = strchr(arg, '"'); 2135 if (np) 2136 *np = '\0'; 2137 } 2138 if (strcmp(arg, "0") == 0 || strcasecmp(arg, "forever") == 0) 2139 token->expire =0; 2140 else { 2141 struct tm tm; 2142 2143 memset(&tm, 0, sizeof(tm)); 2144 if (strptime(arg, "%Y-%m-%d %H:%M", &tm) == NULL) { 2145 logerrx("%s: invalid date time", arg); 2146 goto invalid_token; 2147 } 2148 if ((token->expire = mktime(&tm)) == (time_t)-1) { 2149 logerr("%s: mktime", __func__); 2150 goto invalid_token; 2151 } 2152 } 2153 arg = fp; 2154 s = parse_string(NULL, 0, arg); 2155 if (s == -1 || s == 0) { 2156 if (s == -1) 2157 logerr("token_len"); 2158 else 2159 logerrx("authtoken requires a key"); 2160 goto invalid_token; 2161 } 2162 token->key_len = (size_t)s; 2163 token->key = malloc(token->key_len); 2164 if (token->key == NULL) { 2165 logerr(__func__); 2166 goto invalid_token; 2167 } 2168 parse_string((char *)token->key, token->key_len, arg); 2169 TAILQ_INSERT_TAIL(&ifo->auth.tokens, token, next); 2170 break; 2171 2172 invalid_token: 2173 free(token->realm); 2174 free(token); 2175 #else 2176 logerrx("no authentication support"); 2177 #endif 2178 return -1; 2179 case O_AUTHNOTREQUIRED: 2180 ifo->auth.options &= ~DHCPCD_AUTH_REQUIRE; 2181 break; 2182 case O_DHCP: 2183 ifo->options |= DHCPCD_DHCP | DHCPCD_WANTDHCP | DHCPCD_IPV4; 2184 break; 2185 case O_NODHCP: 2186 ifo->options &= ~DHCPCD_DHCP; 2187 break; 2188 case O_DHCP6: 2189 ifo->options |= DHCPCD_DHCP6 | DHCPCD_IPV6; 2190 break; 2191 case O_NODHCP6: 2192 ifo->options &= ~DHCPCD_DHCP6; 2193 break; 2194 case O_CONTROLGRP: 2195 ARG_REQUIRED; 2196 #ifdef PRIVSEP 2197 /* Control group is already set by this point. 2198 * We don't need to pledge getpw either with this. */ 2199 if (IN_PRIVSEP(ctx)) 2200 break; 2201 #endif 2202 #ifdef _REENTRANT 2203 l = sysconf(_SC_GETGR_R_SIZE_MAX); 2204 if (l == -1) 2205 dl = 1024; 2206 else 2207 dl = (size_t)l; 2208 p = malloc(dl); 2209 if (p == NULL) { 2210 logerr(__func__); 2211 return -1; 2212 } 2213 while ((i = getgrnam_r(arg, &grpbuf, p, dl, &grp)) == 2214 ERANGE) 2215 { 2216 size_t nl = dl * 2; 2217 if (nl < dl) { 2218 logerrx("control_group: out of buffer"); 2219 free(p); 2220 return -1; 2221 } 2222 dl = nl; 2223 np = realloc(p, dl); 2224 if (np == NULL) { 2225 logerr(__func__); 2226 free(p); 2227 return -1; 2228 } 2229 p = np; 2230 } 2231 if (i != 0) { 2232 errno = i; 2233 logerr("getgrnam_r"); 2234 free(p); 2235 return -1; 2236 } 2237 if (grp == NULL) { 2238 if (!ctx->control_group) 2239 logerrx("controlgroup: %s: not found", arg); 2240 free(p); 2241 return -1; 2242 } 2243 ctx->control_group = grp->gr_gid; 2244 free(p); 2245 #else 2246 grp = getgrnam(arg); 2247 if (grp == NULL) { 2248 if (!ctx->control_group) 2249 logerrx("controlgroup: %s: not found", arg); 2250 return -1; 2251 } 2252 ctx->control_group = grp->gr_gid; 2253 #endif 2254 break; 2255 case O_GATEWAY: 2256 ifo->options |= DHCPCD_GATEWAY; 2257 break; 2258 case O_NOUP: 2259 ifo->options &= ~DHCPCD_IF_UP; 2260 break; 2261 case O_SLAAC: 2262 ARG_REQUIRED; 2263 np = strwhite(arg); 2264 if (np != NULL) { 2265 *np++ = '\0'; 2266 np = strskipwhite(np); 2267 } 2268 if (strcmp(arg, "private") == 0 || 2269 strcmp(arg, "stableprivate") == 0 || 2270 strcmp(arg, "stable") == 0) 2271 ifo->options |= DHCPCD_SLAACPRIVATE; 2272 else 2273 ifo->options &= ~DHCPCD_SLAACPRIVATE; 2274 #ifdef INET6 2275 if (strcmp(arg, "token") == 0) { 2276 if (np == NULL) { 2277 logerrx("slaac token: no token specified"); 2278 return -1; 2279 } 2280 arg = np; 2281 np = strwhite(np); 2282 if (np != NULL) { 2283 *np++ = '\0'; 2284 np = strskipwhite(np); 2285 } 2286 if (inet_pton(AF_INET6, arg, &ifo->token) != 1) { 2287 logerrx("slaac token: invalid token"); 2288 return -1; 2289 } 2290 } 2291 #endif 2292 if (np != NULL && 2293 (strcmp(np, "temp") == 0 || strcmp(np, "temporary") == 0)) 2294 ifo->options |= DHCPCD_SLAACTEMP; 2295 break; 2296 case O_BOOTP: 2297 ifo->options |= DHCPCD_BOOTP; 2298 break; 2299 case O_NODELAY: 2300 ifo->options &= ~DHCPCD_INITIAL_DELAY; 2301 break; 2302 case O_LASTLEASE_EXTEND: 2303 ifo->options |= DHCPCD_LASTLEASE | DHCPCD_LASTLEASE_EXTEND; 2304 break; 2305 case O_INACTIVE: 2306 ifo->options |= DHCPCD_INACTIVE; 2307 break; 2308 case O_MUDURL: 2309 ARG_REQUIRED; 2310 s = parse_string((char *)ifo->mudurl + 1, MUDURL_MAX_LEN, arg); 2311 if (s == -1) { 2312 logerr("mudurl"); 2313 return -1; 2314 } 2315 *ifo->mudurl = (uint8_t)s; 2316 break; 2317 case O_LINK_RCVBUF: 2318 #ifndef SMALL 2319 ARG_REQUIRED; 2320 ctx->link_rcvbuf = (int)strtoi(arg, NULL, 0, 0, INT32_MAX, &e); 2321 if (e) { 2322 logerrx("failed to convert link_rcvbuf %s", arg); 2323 return -1; 2324 } 2325 #endif 2326 break; 2327 case O_CONFIGURE: 2328 ifo->options |= DHCPCD_CONFIGURE; 2329 break; 2330 case O_NOCONFIGURE: 2331 ifo->options &= ~DHCPCD_CONFIGURE; 2332 break; 2333 default: 2334 return 0; 2335 } 2336 2337 return 1; 2338 2339 #ifdef ARG_REQUIRED 2340 arg_required: 2341 logerrx("option %d requires an argument", opt); 2342 return -1; 2343 #undef ARG_REQUIRED 2344 #endif 2345 } 2346 2347 static int 2348 parse_config_line(struct dhcpcd_ctx *ctx, const char *ifname, 2349 struct if_options *ifo, const char *opt, char *line, 2350 struct dhcp_opt **ldop, struct dhcp_opt **edop) 2351 { 2352 unsigned int i; 2353 2354 for (i = 0; i < sizeof(cf_options) / sizeof(cf_options[0]); i++) { 2355 if (!cf_options[i].name || 2356 strcmp(cf_options[i].name, opt) != 0) 2357 continue; 2358 2359 if (cf_options[i].has_arg == required_argument && !line) { 2360 logerrx("option requires an argument -- %s", opt); 2361 return -1; 2362 } 2363 2364 return parse_option(ctx, ifname, ifo, cf_options[i].val, line, 2365 ldop, edop); 2366 } 2367 2368 if (!(ctx->options & DHCPCD_PRINT_PIDFILE)) 2369 logerrx("unknown option: %s", opt); 2370 return -1; 2371 } 2372 2373 static void 2374 finish_config(struct if_options *ifo) 2375 { 2376 2377 /* Terminate the encapsulated options */ 2378 if (ifo->vendor[0] && !(ifo->options & DHCPCD_VENDORRAW)) { 2379 ifo->vendor[0]++; 2380 ifo->vendor[ifo->vendor[0]] = DHO_END; 2381 /* We are called twice. 2382 * This should be fixed, but in the meantime, this 2383 * guard should suffice */ 2384 ifo->options |= DHCPCD_VENDORRAW; 2385 } 2386 2387 if (!(ifo->options & DHCPCD_ARP) || 2388 ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC)) 2389 ifo->options &= ~DHCPCD_IPV4LL; 2390 2391 if (!(ifo->options & DHCPCD_IPV4)) 2392 ifo->options &= ~(DHCPCD_DHCP | DHCPCD_IPV4LL | DHCPCD_WAITIP4); 2393 2394 if (!(ifo->options & DHCPCD_IPV6)) 2395 ifo->options &= 2396 ~(DHCPCD_IPV6RS | DHCPCD_DHCP6 | DHCPCD_WAITIP6); 2397 2398 if (!(ifo->options & DHCPCD_IPV6RS)) 2399 ifo->options &= 2400 ~(DHCPCD_IPV6RA_AUTOCONF | DHCPCD_IPV6RA_REQRDNSS); 2401 } 2402 2403 struct if_options * 2404 default_config(struct dhcpcd_ctx *ctx) 2405 { 2406 struct if_options *ifo; 2407 2408 /* Seed our default options */ 2409 if ((ifo = calloc(1, sizeof(*ifo))) == NULL) { 2410 logerr(__func__); 2411 return NULL; 2412 } 2413 ifo->options |= DHCPCD_IF_UP | DHCPCD_LINK | DHCPCD_INITIAL_DELAY; 2414 ifo->timeout = DEFAULT_TIMEOUT; 2415 ifo->reboot = DEFAULT_REBOOT; 2416 ifo->metric = -1; 2417 ifo->auth.options |= DHCPCD_AUTH_REQUIRE; 2418 rb_tree_init(&ifo->routes, &rt_compare_list_ops); 2419 #ifdef AUTH 2420 TAILQ_INIT(&ifo->auth.tokens); 2421 #endif 2422 2423 /* Inherit some global defaults */ 2424 if (ctx->options & DHCPCD_CONFIGURE) 2425 ifo->options |= DHCPCD_CONFIGURE; 2426 if (ctx->options & DHCPCD_PERSISTENT) 2427 ifo->options |= DHCPCD_PERSISTENT; 2428 if (ctx->options & DHCPCD_SLAACPRIVATE) 2429 ifo->options |= DHCPCD_SLAACPRIVATE; 2430 2431 return ifo; 2432 } 2433 2434 struct if_options * 2435 read_config(struct dhcpcd_ctx *ctx, 2436 const char *ifname, const char *ssid, const char *profile) 2437 { 2438 struct if_options *ifo; 2439 char buf[UDPLEN_MAX], *bp; /* 64k max config file size */ 2440 char *line, *option, *p; 2441 ssize_t buflen; 2442 size_t vlen; 2443 int skip, have_profile, new_block, had_block; 2444 #if !defined(INET) || !defined(INET6) 2445 size_t i; 2446 struct dhcp_opt *opt; 2447 #endif 2448 struct dhcp_opt *ldop, *edop; 2449 2450 /* Seed our default options */ 2451 if ((ifo = default_config(ctx)) == NULL) 2452 return NULL; 2453 if (default_options == 0) { 2454 default_options |= DHCPCD_CONFIGURE | DHCPCD_DAEMONISE | 2455 DHCPCD_GATEWAY; 2456 #ifdef INET 2457 skip = socket(PF_INET, SOCK_DGRAM, 0); 2458 if (skip != -1) { 2459 close(skip); 2460 default_options |= DHCPCD_IPV4 | DHCPCD_ARP | 2461 DHCPCD_DHCP | DHCPCD_IPV4LL; 2462 } 2463 #endif 2464 #ifdef INET6 2465 skip = socket(PF_INET6, SOCK_DGRAM, 0); 2466 if (skip != -1) { 2467 close(skip); 2468 default_options |= DHCPCD_IPV6 | DHCPCD_IPV6RS | 2469 DHCPCD_IPV6RA_AUTOCONF | DHCPCD_IPV6RA_REQRDNSS | 2470 DHCPCD_DHCP6; 2471 } 2472 #endif 2473 #ifdef PLUGIN_DEV 2474 default_options |= DHCPCD_DEV; 2475 #endif 2476 } 2477 ifo->options |= default_options; 2478 2479 CLEAR_CONFIG_BLOCK(ifo); 2480 2481 vlen = strlcpy((char *)ifo->vendorclassid + 1, ctx->vendor, 2482 sizeof(ifo->vendorclassid) - 1); 2483 ifo->vendorclassid[0] = (uint8_t)(vlen > 255 ? 0 : vlen); 2484 2485 /* Reset route order */ 2486 ctx->rt_order = 0; 2487 2488 /* Parse our embedded options file */ 2489 if (ifname == NULL && !(ctx->options & DHCPCD_PRINT_PIDFILE)) { 2490 /* Space for initial estimates */ 2491 #if defined(INET) && defined(INITDEFINES) 2492 ifo->dhcp_override = 2493 calloc(INITDEFINES, sizeof(*ifo->dhcp_override)); 2494 if (ifo->dhcp_override == NULL) 2495 logerr(__func__); 2496 else 2497 ifo->dhcp_override_len = INITDEFINES; 2498 #endif 2499 2500 #if defined(INET6) && defined(INITDEFINENDS) 2501 ifo->nd_override = 2502 calloc(INITDEFINENDS, sizeof(*ifo->nd_override)); 2503 if (ifo->nd_override == NULL) 2504 logerr(__func__); 2505 else 2506 ifo->nd_override_len = INITDEFINENDS; 2507 #endif 2508 #if defined(INET6) && defined(INITDEFINE6S) 2509 ifo->dhcp6_override = 2510 calloc(INITDEFINE6S, sizeof(*ifo->dhcp6_override)); 2511 if (ifo->dhcp6_override == NULL) 2512 logerr(__func__); 2513 else 2514 ifo->dhcp6_override_len = INITDEFINE6S; 2515 #endif 2516 2517 /* Now load our embedded config */ 2518 #ifdef EMBEDDED_CONFIG 2519 buflen = dhcp_readfile(ctx, EMBEDDED_CONFIG, buf, sizeof(buf)); 2520 if (buflen == -1) { 2521 logerr("%s: %s", __func__, EMBEDDED_CONFIG); 2522 return ifo; 2523 } 2524 if (buf[buflen - 1] != '\0') { 2525 if ((size_t)buflen < sizeof(buf) - 1) 2526 buflen++; 2527 buf[buflen - 1] = '\0'; 2528 } 2529 #else 2530 buflen = (ssize_t)strlcpy(buf, dhcpcd_embedded_conf, 2531 sizeof(buf)); 2532 if ((size_t)buflen >= sizeof(buf)) { 2533 logerrx("%s: embedded config too big", __func__); 2534 return ifo; 2535 } 2536 /* Our embedded config is NULL terminated */ 2537 #endif 2538 bp = buf; 2539 while ((line = get_line(&bp, &buflen)) != NULL) { 2540 option = strsep(&line, " \t"); 2541 if (line) 2542 line = strskipwhite(line); 2543 /* Trim trailing whitespace */ 2544 if (line) { 2545 p = line + strlen(line) - 1; 2546 while (p != line && 2547 (*p == ' ' || *p == '\t') && 2548 *(p - 1) != '\\') 2549 *p-- = '\0'; 2550 } 2551 parse_config_line(ctx, NULL, ifo, option, line, 2552 &ldop, &edop); 2553 } 2554 2555 #ifdef INET 2556 ctx->dhcp_opts = ifo->dhcp_override; 2557 ctx->dhcp_opts_len = ifo->dhcp_override_len; 2558 #else 2559 for (i = 0, opt = ifo->dhcp_override; 2560 i < ifo->dhcp_override_len; 2561 i++, opt++) 2562 free_dhcp_opt_embenc(opt); 2563 free(ifo->dhcp_override); 2564 #endif 2565 ifo->dhcp_override = NULL; 2566 ifo->dhcp_override_len = 0; 2567 2568 #ifdef INET6 2569 ctx->nd_opts = ifo->nd_override; 2570 ctx->nd_opts_len = ifo->nd_override_len; 2571 #ifdef DHCP6 2572 ctx->dhcp6_opts = ifo->dhcp6_override; 2573 ctx->dhcp6_opts_len = ifo->dhcp6_override_len; 2574 #endif 2575 #else 2576 for (i = 0, opt = ifo->nd_override; 2577 i < ifo->nd_override_len; 2578 i++, opt++) 2579 free_dhcp_opt_embenc(opt); 2580 free(ifo->nd_override); 2581 for (i = 0, opt = ifo->dhcp6_override; 2582 i < ifo->dhcp6_override_len; 2583 i++, opt++) 2584 free_dhcp_opt_embenc(opt); 2585 free(ifo->dhcp6_override); 2586 #endif 2587 ifo->nd_override = NULL; 2588 ifo->nd_override_len = 0; 2589 ifo->dhcp6_override = NULL; 2590 ifo->dhcp6_override_len = 0; 2591 2592 ctx->vivso = ifo->vivso_override; 2593 ctx->vivso_len = ifo->vivso_override_len; 2594 ifo->vivso_override = NULL; 2595 ifo->vivso_override_len = 0; 2596 } 2597 2598 /* Parse our options file */ 2599 buflen = dhcp_readfile(ctx, ctx->cffile, buf, sizeof(buf)); 2600 if (buflen == -1) { 2601 /* dhcpcd can continue without it, but no DNS options 2602 * would be requested ... */ 2603 logerr("%s: %s", __func__, ctx->cffile); 2604 return ifo; 2605 } 2606 if (buf[buflen - 1] != '\0') { 2607 if ((size_t)buflen < sizeof(buf) - 1) 2608 buflen++; 2609 buf[buflen - 1] = '\0'; 2610 } 2611 dhcp_filemtime(ctx, ctx->cffile, &ifo->mtime); 2612 2613 ldop = edop = NULL; 2614 skip = have_profile = new_block = 0; 2615 had_block = ifname == NULL ? 1 : 0; 2616 bp = buf; 2617 while ((line = get_line(&bp, &buflen)) != NULL) { 2618 option = strsep(&line, " \t"); 2619 if (line) 2620 line = strskipwhite(line); 2621 /* Trim trailing whitespace */ 2622 if (line) { 2623 p = line + strlen(line) - 1; 2624 while (p != line && 2625 (*p == ' ' || *p == '\t') && 2626 *(p - 1) != '\\') 2627 *p-- = '\0'; 2628 } 2629 if (skip == 0 && new_block) { 2630 had_block = 1; 2631 new_block = 0; 2632 ifo->options &= ~DHCPCD_WAITOPTS; 2633 SET_CONFIG_BLOCK(ifo); 2634 } 2635 2636 /* Start of an interface block, skip if not ours */ 2637 if (strcmp(option, "interface") == 0) { 2638 char **n; 2639 2640 new_block = 1; 2641 if (line == NULL) { 2642 /* No interface given */ 2643 skip = 1; 2644 continue; 2645 } 2646 if (ifname && strcmp(line, ifname) == 0) 2647 skip = 0; 2648 else 2649 skip = 1; 2650 if (ifname) 2651 continue; 2652 2653 n = reallocarray(ctx->ifcv, 2654 (size_t)ctx->ifcc + 1, sizeof(char *)); 2655 if (n == NULL) { 2656 logerr(__func__); 2657 continue; 2658 } 2659 ctx->ifcv = n; 2660 ctx->ifcv[ctx->ifcc] = strdup(line); 2661 if (ctx->ifcv[ctx->ifcc] == NULL) { 2662 logerr(__func__); 2663 continue; 2664 } 2665 ctx->ifcc++; 2666 continue; 2667 } 2668 /* Start of an ssid block, skip if not ours */ 2669 if (strcmp(option, "ssid") == 0) { 2670 new_block = 1; 2671 if (ssid && line && strcmp(line, ssid) == 0) 2672 skip = 0; 2673 else 2674 skip = 1; 2675 continue; 2676 } 2677 /* Start of a profile block, skip if not ours */ 2678 if (strcmp(option, "profile") == 0) { 2679 new_block = 1; 2680 if (profile && line && strcmp(line, profile) == 0) { 2681 skip = 0; 2682 have_profile = 1; 2683 } else 2684 skip = 1; 2685 continue; 2686 } 2687 /* Skip arping if we have selected a profile but not parsing 2688 * one. */ 2689 if (profile && !have_profile && strcmp(option, "arping") == 0) 2690 continue; 2691 if (skip) 2692 continue; 2693 2694 parse_config_line(ctx, ifname, ifo, option, line, &ldop, &edop); 2695 } 2696 2697 if (profile && !have_profile) { 2698 free_options(ctx, ifo); 2699 errno = ENOENT; 2700 return NULL; 2701 } 2702 2703 if (!had_block) 2704 ifo->options &= ~DHCPCD_WAITOPTS; 2705 CLEAR_CONFIG_BLOCK(ifo); 2706 finish_config(ifo); 2707 return ifo; 2708 } 2709 2710 int 2711 add_options(struct dhcpcd_ctx *ctx, const char *ifname, 2712 struct if_options *ifo, int argc, char **argv) 2713 { 2714 int oi, opt, r; 2715 unsigned long long wait_opts; 2716 2717 if (argc == 0) 2718 return 1; 2719 2720 optind = 0; 2721 r = 1; 2722 /* Don't apply the command line wait options to each interface, 2723 * only use the dhcpcd.conf entry for that. */ 2724 if (ifname != NULL) 2725 wait_opts = ifo->options & DHCPCD_WAITOPTS; 2726 while ((opt = getopt_long(argc, argv, 2727 ctx->options & DHCPCD_PRINT_PIDFILE ? NOERR_IF_OPTS : IF_OPTS, 2728 cf_options, &oi)) != -1) 2729 { 2730 r = parse_option(ctx, ifname, ifo, opt, optarg, NULL, NULL); 2731 if (r != 1) 2732 break; 2733 } 2734 if (ifname != NULL) { 2735 ifo->options &= ~DHCPCD_WAITOPTS; 2736 ifo->options |= wait_opts; 2737 } 2738 2739 finish_config(ifo); 2740 return r; 2741 } 2742 2743 void 2744 free_options(struct dhcpcd_ctx *ctx, struct if_options *ifo) 2745 { 2746 size_t i; 2747 #ifdef RT_FREE_ROUTE_TABLE 2748 struct interface *ifp; 2749 struct rt *rt; 2750 #endif 2751 struct dhcp_opt *opt; 2752 struct vivco *vo; 2753 #ifdef AUTH 2754 struct token *token; 2755 #endif 2756 2757 if (ifo == NULL) 2758 return; 2759 2760 if (ifo->environ) { 2761 i = 0; 2762 while (ifo->environ[i]) 2763 free(ifo->environ[i++]); 2764 free(ifo->environ); 2765 } 2766 if (ifo->config) { 2767 i = 0; 2768 while (ifo->config[i]) 2769 free(ifo->config[i++]); 2770 free(ifo->config); 2771 } 2772 2773 #ifdef RT_FREE_ROUTE_TABLE 2774 /* Stupidly, we don't know the interface when creating the options. 2775 * As such, make sure each route has one so they can goto the 2776 * free list. */ 2777 ifp = ctx->ifaces != NULL ? TAILQ_FIRST(ctx->ifaces) : NULL; 2778 if (ifp != NULL) { 2779 RB_TREE_FOREACH(rt, &ifo->routes) { 2780 if (rt->rt_ifp == NULL) 2781 rt->rt_ifp = ifp; 2782 } 2783 } 2784 #endif 2785 rt_headclear0(ctx, &ifo->routes, AF_UNSPEC); 2786 2787 free(ifo->arping); 2788 free(ifo->blacklist); 2789 free(ifo->fallback); 2790 2791 for (opt = ifo->dhcp_override; 2792 ifo->dhcp_override_len > 0; 2793 opt++, ifo->dhcp_override_len--) 2794 free_dhcp_opt_embenc(opt); 2795 free(ifo->dhcp_override); 2796 for (opt = ifo->nd_override; 2797 ifo->nd_override_len > 0; 2798 opt++, ifo->nd_override_len--) 2799 free_dhcp_opt_embenc(opt); 2800 free(ifo->nd_override); 2801 for (opt = ifo->dhcp6_override; 2802 ifo->dhcp6_override_len > 0; 2803 opt++, ifo->dhcp6_override_len--) 2804 free_dhcp_opt_embenc(opt); 2805 free(ifo->dhcp6_override); 2806 for (vo = ifo->vivco; 2807 ifo->vivco_len > 0; 2808 vo++, ifo->vivco_len--) 2809 free(vo->data); 2810 free(ifo->vivco); 2811 for (opt = ifo->vivso_override; 2812 ifo->vivso_override_len > 0; 2813 opt++, ifo->vivso_override_len--) 2814 free_dhcp_opt_embenc(opt); 2815 free(ifo->vivso_override); 2816 2817 #if defined(INET6) && !defined(SMALL) 2818 for (; ifo->ia_len > 0; ifo->ia_len--) 2819 free(ifo->ia[ifo->ia_len - 1].sla); 2820 #endif 2821 free(ifo->ia); 2822 2823 #ifdef AUTH 2824 while ((token = TAILQ_FIRST(&ifo->auth.tokens))) { 2825 TAILQ_REMOVE(&ifo->auth.tokens, token, next); 2826 if (token->realm_len) 2827 free(token->realm); 2828 free(token->key); 2829 free(token); 2830 } 2831 #endif 2832 free(ifo); 2833 } 2834