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