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