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