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