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