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