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].ia_type == (uint16_t)i && 1364 ifo->ia[sl].iaid[0] == iaid[0] && 1365 ifo->ia[sl].iaid[1] == iaid[1] && 1366 ifo->ia[sl].iaid[2] == iaid[2] && 1367 ifo->ia[sl].iaid[3] == iaid[3])) 1368 { 1369 ia = &ifo->ia[sl]; 1370 break; 1371 } 1372 } 1373 if (ia == NULL) { 1374 ia = reallocarray(ifo->ia, 1375 ifo->ia_len + 1, sizeof(*ifo->ia)); 1376 if (ia == NULL) { 1377 logerr(__func__); 1378 return -1; 1379 } 1380 ifo->ia = ia; 1381 ia = &ifo->ia[ifo->ia_len++]; 1382 ia->ia_type = (uint16_t)i; 1383 if (arg) { 1384 ia->iaid[0] = iaid[0]; 1385 ia->iaid[1] = iaid[1]; 1386 ia->iaid[2] = iaid[2]; 1387 ia->iaid[3] = iaid[3]; 1388 ia->iaid_set = 1; 1389 } else 1390 ia->iaid_set = 0; 1391 if (!ia->iaid_set || 1392 p == NULL || 1393 ia->ia_type == D6_OPTION_IA_TA) 1394 { 1395 memset(&ia->addr, 0, sizeof(ia->addr)); 1396 ia->prefix_len = 0; 1397 } else { 1398 arg = p; 1399 p = strchr(arg, '/'); 1400 if (p) 1401 *p++ = '\0'; 1402 if (inet_pton(AF_INET6, arg, &ia->addr) == -1) { 1403 logerr("%s", arg); 1404 memset(&ia->addr, 0, sizeof(ia->addr)); 1405 } 1406 if (p && ia->ia_type == D6_OPTION_IA_PD) { 1407 ia->prefix_len = (uint8_t)strtou(p, 1408 NULL, 0, 8, 120, &e); 1409 if (e) { 1410 logerrx("%s: failed to convert" 1411 " prefix len", 1412 p); 1413 ia->prefix_len = 0; 1414 } 1415 } 1416 } 1417 #ifndef SMALL 1418 ia->sla_max = 0; 1419 ia->sla_len = 0; 1420 ia->sla = NULL; 1421 #endif 1422 } 1423 if (ia->ia_type != D6_OPTION_IA_PD) 1424 break; 1425 #ifndef SMALL 1426 for (p = fp; p; p = fp) { 1427 fp = strwhite(p); 1428 if (fp) { 1429 *fp++ = '\0'; 1430 fp = strskipwhite(fp); 1431 } 1432 sla = reallocarray(ia->sla, 1433 ia->sla_len + 1, sizeof(*ia->sla)); 1434 if (sla == NULL) { 1435 logerr(__func__); 1436 return -1; 1437 } 1438 ia->sla = sla; 1439 sla = &ia->sla[ia->sla_len++]; 1440 np = strchr(p, '/'); 1441 if (np) 1442 *np++ = '\0'; 1443 if (strlcpy(sla->ifname, p, 1444 sizeof(sla->ifname)) >= sizeof(sla->ifname)) 1445 { 1446 logerrx("%s: interface name too long", arg); 1447 goto err_sla; 1448 } 1449 sla->sla_set = 0; 1450 sla->prefix_len = 0; 1451 sla->suffix = 1; 1452 p = np; 1453 if (p) { 1454 np = strchr(p, '/'); 1455 if (np) 1456 *np++ = '\0'; 1457 if (*p != '\0') { 1458 sla->sla = (uint32_t)strtou(p, NULL, 1459 0, 0, UINT32_MAX, &e); 1460 sla->sla_set = 1; 1461 if (e) { 1462 logerrx("%s: failed to convert " 1463 "sla", 1464 ifname); 1465 goto err_sla; 1466 } 1467 } 1468 p = np; 1469 } 1470 if (p) { 1471 np = strchr(p, '/'); 1472 if (np) 1473 *np++ = '\0'; 1474 if (*p != '\0') { 1475 sla->prefix_len = (uint8_t)strtou(p, 1476 NULL, 0, 0, 120, &e); 1477 if (e) { 1478 logerrx("%s: failed to " 1479 "convert prefix len", 1480 ifname); 1481 goto err_sla; 1482 } 1483 } 1484 p = np; 1485 } 1486 if (p) { 1487 np = strchr(p, '/'); 1488 if (np) 1489 *np = '\0'; 1490 if (*p != '\0') { 1491 sla->suffix = (uint64_t)strtou(p, NULL, 1492 0, 0, UINT64_MAX, &e); 1493 if (e) { 1494 logerrx("%s: failed to " 1495 "convert suffix", 1496 ifname); 1497 goto err_sla; 1498 } 1499 } 1500 } 1501 /* Sanity check */ 1502 for (sl = 0; sl < ia->sla_len - 1; sl++) { 1503 slap = &ia->sla[sl]; 1504 if (slap->sla_set != sla->sla_set) { 1505 logerrx("%s: cannot mix automatic " 1506 "and fixed SLA", 1507 sla->ifname); 1508 goto err_sla; 1509 } 1510 if (ia->prefix_len && 1511 (sla->prefix_len == ia->prefix_len || 1512 slap->prefix_len == ia->prefix_len)) 1513 { 1514 logerrx("%s: cannot delegte the same" 1515 "prefix length more than once", 1516 sla->ifname); 1517 goto err_sla; 1518 } 1519 if (sla->sla_set == 0 && 1520 strcmp(slap->ifname, sla->ifname) == 0) 1521 { 1522 logwarnx("%s: cannot specify the " 1523 "same interface twice with " 1524 "an automatic SLA", 1525 sla->ifname); 1526 goto err_sla; 1527 } 1528 if (slap->sla_set && sla->sla_set && 1529 slap->sla == sla->sla) 1530 { 1531 logerrx("%s: cannot" 1532 " assign the same SLA %u" 1533 " more than once", 1534 sla->ifname, sla->sla); 1535 goto err_sla; 1536 } 1537 } 1538 if (sla->sla_set && sla->sla > ia->sla_max) 1539 ia->sla_max = sla->sla; 1540 } 1541 break; 1542 err_sla: 1543 ia->sla_len--; 1544 return -1; 1545 #endif 1546 #endif 1547 case O_HOSTNAME_SHORT: 1548 ifo->options |= DHCPCD_HOSTNAME | DHCPCD_HOSTNAME_SHORT; 1549 break; 1550 case O_DEV: 1551 ARG_REQUIRED; 1552 #ifdef PLUGIN_DEV 1553 if (ctx->dev_load) 1554 free(ctx->dev_load); 1555 ctx->dev_load = strdup(arg); 1556 #endif 1557 break; 1558 case O_NODEV: 1559 ifo->options &= ~DHCPCD_DEV; 1560 break; 1561 case O_DEFINE: 1562 dop = &ifo->dhcp_override; 1563 dop_len = &ifo->dhcp_override_len; 1564 /* FALLTHROUGH */ 1565 case O_DEFINEND: 1566 if (dop == NULL) { 1567 dop = &ifo->nd_override; 1568 dop_len = &ifo->nd_override_len; 1569 } 1570 /* FALLTHROUGH */ 1571 case O_DEFINE6: 1572 if (dop == NULL) { 1573 dop = &ifo->dhcp6_override; 1574 dop_len = &ifo->dhcp6_override_len; 1575 } 1576 /* FALLTHROUGH */ 1577 case O_VENDOPT: 1578 if (dop == NULL) { 1579 dop = &ifo->vivso_override; 1580 dop_len = &ifo->vivso_override_len; 1581 } 1582 *edop = *ldop = NULL; 1583 /* FALLTHROUGH */ 1584 case O_EMBED: 1585 if (dop == NULL) { 1586 if (*edop) { 1587 dop = &(*edop)->embopts; 1588 dop_len = &(*edop)->embopts_len; 1589 } else if (ldop) { 1590 dop = &(*ldop)->embopts; 1591 dop_len = &(*ldop)->embopts_len; 1592 } else { 1593 logerrx("embed must be after a define " 1594 "or encap"); 1595 return -1; 1596 } 1597 } 1598 /* FALLTHROUGH */ 1599 case O_ENCAP: 1600 ARG_REQUIRED; 1601 if (dop == NULL) { 1602 if (*ldop == NULL) { 1603 logerrx("encap must be after a define"); 1604 return -1; 1605 } 1606 dop = &(*ldop)->encopts; 1607 dop_len = &(*ldop)->encopts_len; 1608 } 1609 1610 /* Shared code for define, define6, embed and encap */ 1611 1612 /* code */ 1613 if (opt == O_EMBED) /* Embedded options don't have codes */ 1614 u = 0; 1615 else { 1616 fp = strwhite(arg); 1617 if (fp == NULL) { 1618 logerrx("invalid syntax: %s", arg); 1619 return -1; 1620 } 1621 *fp++ = '\0'; 1622 u = (uint32_t)strtou(arg, NULL, 0, 0, UINT32_MAX, &e); 1623 if (e) { 1624 logerrx("invalid code: %s", arg); 1625 return -1; 1626 } 1627 arg = strskipwhite(fp); 1628 if (arg == NULL) { 1629 logerrx("invalid syntax"); 1630 return -1; 1631 } 1632 } 1633 /* type */ 1634 fp = strwhite(arg); 1635 if (fp) 1636 *fp++ = '\0'; 1637 np = strchr(arg, ':'); 1638 /* length */ 1639 if (np) { 1640 *np++ = '\0'; 1641 bp = NULL; /* No bitflag */ 1642 l = (long)strtou(np, NULL, 0, 0, LONG_MAX, &e); 1643 if (e) { 1644 logerrx("failed to convert length"); 1645 return -1; 1646 } 1647 } else { 1648 l = 0; 1649 bp = strchr(arg, '='); /* bitflag assignment */ 1650 if (bp) 1651 *bp++ = '\0'; 1652 } 1653 t = 0; 1654 if (strcasecmp(arg, "request") == 0) { 1655 t |= OT_REQUEST; 1656 arg = strskipwhite(fp); 1657 fp = strwhite(arg); 1658 if (fp == NULL) { 1659 logerrx("incomplete request type"); 1660 return -1; 1661 } 1662 *fp++ = '\0'; 1663 } else if (strcasecmp(arg, "norequest") == 0) { 1664 t |= OT_NOREQ; 1665 arg = strskipwhite(fp); 1666 fp = strwhite(arg); 1667 if (fp == NULL) { 1668 logerrx("incomplete request type"); 1669 return -1; 1670 } 1671 *fp++ = '\0'; 1672 } 1673 if (strcasecmp(arg, "optional") == 0) { 1674 t |= OT_OPTIONAL; 1675 arg = strskipwhite(fp); 1676 fp = strwhite(arg); 1677 if (fp == NULL) { 1678 logerrx("incomplete optional type"); 1679 return -1; 1680 } 1681 *fp++ = '\0'; 1682 } 1683 if (strcasecmp(arg, "index") == 0) { 1684 t |= OT_INDEX; 1685 arg = strskipwhite(fp); 1686 fp = strwhite(arg); 1687 if (fp == NULL) { 1688 logerrx("incomplete index type"); 1689 return -1; 1690 } 1691 *fp++ = '\0'; 1692 } 1693 if (strcasecmp(arg, "array") == 0) { 1694 t |= OT_ARRAY; 1695 arg = strskipwhite(fp); 1696 fp = strwhite(arg); 1697 if (fp == NULL) { 1698 logerrx("incomplete array type"); 1699 return -1; 1700 } 1701 *fp++ = '\0'; 1702 } 1703 if (strcasecmp(arg, "ipaddress") == 0) 1704 t |= OT_ADDRIPV4; 1705 else if (strcasecmp(arg, "ip6address") == 0) 1706 t |= OT_ADDRIPV6; 1707 else if (strcasecmp(arg, "string") == 0) 1708 t |= OT_STRING; 1709 else if (strcasecmp(arg, "byte") == 0) 1710 t |= OT_UINT8; 1711 else if (strcasecmp(arg, "bitflags") == 0) 1712 t |= OT_BITFLAG; 1713 else if (strcasecmp(arg, "uint8") == 0) 1714 t |= OT_UINT8; 1715 else if (strcasecmp(arg, "int8") == 0) 1716 t |= OT_INT8; 1717 else if (strcasecmp(arg, "uint16") == 0) 1718 t |= OT_UINT16; 1719 else if (strcasecmp(arg, "int16") == 0) 1720 t |= OT_INT16; 1721 else if (strcasecmp(arg, "uint32") == 0) 1722 t |= OT_UINT32; 1723 else if (strcasecmp(arg, "int32") == 0) 1724 t |= OT_INT32; 1725 else if (strcasecmp(arg, "flag") == 0) 1726 t |= OT_FLAG; 1727 else if (strcasecmp(arg, "raw") == 0) 1728 t |= OT_STRING | OT_RAW; 1729 else if (strcasecmp(arg, "ascii") == 0) 1730 t |= OT_STRING | OT_ASCII; 1731 else if (strcasecmp(arg, "domain") == 0) 1732 t |= OT_STRING | OT_DOMAIN | OT_RFC1035; 1733 else if (strcasecmp(arg, "dname") == 0) 1734 t |= OT_STRING | OT_DOMAIN; 1735 else if (strcasecmp(arg, "binhex") == 0) 1736 t |= OT_STRING | OT_BINHEX; 1737 else if (strcasecmp(arg, "embed") == 0) 1738 t |= OT_EMBED; 1739 else if (strcasecmp(arg, "encap") == 0) 1740 t |= OT_ENCAP; 1741 else if (strcasecmp(arg, "rfc3361") ==0) 1742 t |= OT_STRING | OT_RFC3361; 1743 else if (strcasecmp(arg, "rfc3442") ==0) 1744 t |= OT_STRING | OT_RFC3442; 1745 else if (strcasecmp(arg, "option") == 0) 1746 t |= OT_OPTION; 1747 else { 1748 logerrx("unknown type: %s", arg); 1749 return -1; 1750 } 1751 if (l && !(t & (OT_STRING | OT_BINHEX))) { 1752 logwarnx("ignoring length for type `%s'", arg); 1753 l = 0; 1754 } 1755 if (t & OT_ARRAY && t & (OT_STRING | OT_BINHEX) && 1756 !(t & (OT_RFC1035 | OT_DOMAIN))) 1757 { 1758 logwarnx("ignoring array for strings"); 1759 t &= ~OT_ARRAY; 1760 } 1761 if (t & OT_BITFLAG) { 1762 if (bp == NULL) 1763 logwarnx("missing bitflag assignment"); 1764 } 1765 /* variable */ 1766 if (!fp) { 1767 if (!(t & OT_OPTION)) { 1768 logerrx("type %s requires a variable name", 1769 arg); 1770 return -1; 1771 } 1772 np = NULL; 1773 } else { 1774 arg = strskipwhite(fp); 1775 fp = strwhite(arg); 1776 if (fp) 1777 *fp++ = '\0'; 1778 if (strcasecmp(arg, "reserved")) { 1779 np = strdup(arg); 1780 if (np == NULL) { 1781 logerr(__func__); 1782 return -1; 1783 } 1784 } else { 1785 np = NULL; 1786 t |= OT_RESERVED; 1787 } 1788 } 1789 if (opt != O_EMBED) { 1790 for (dl = 0, ndop = *dop; dl < *dop_len; dl++, ndop++) 1791 { 1792 /* type 0 seems freshly malloced struct 1793 * for us to use */ 1794 if (ndop->option == u || ndop->type == 0) 1795 break; 1796 } 1797 if (dl == *dop_len) 1798 ndop = NULL; 1799 } else 1800 ndop = NULL; 1801 if (ndop == NULL) { 1802 ndop = reallocarray(*dop, *dop_len + 1, sizeof(**dop)); 1803 if (ndop == NULL) { 1804 logerr(__func__); 1805 free(np); 1806 return -1; 1807 } 1808 *dop = ndop; 1809 ndop = &(*dop)[(*dop_len)++]; 1810 ndop->embopts = NULL; 1811 ndop->embopts_len = 0; 1812 ndop->encopts = NULL; 1813 ndop->encopts_len = 0; 1814 } else 1815 free_dhcp_opt_embenc(ndop); 1816 ndop->option = (uint32_t)u; /* could have been 0 */ 1817 ndop->type = t; 1818 ndop->len = (size_t)l; 1819 ndop->var = np; 1820 if (bp) { 1821 dl = strlen(bp); 1822 memcpy(ndop->bitflags, bp, dl); 1823 memset(ndop->bitflags + dl, 0, 1824 sizeof(ndop->bitflags) - dl); 1825 } else 1826 memset(ndop->bitflags, 0, sizeof(ndop->bitflags)); 1827 /* Save the define for embed and encap options */ 1828 switch (opt) { 1829 case O_DEFINE: 1830 case O_DEFINEND: 1831 case O_DEFINE6: 1832 case O_VENDOPT: 1833 *ldop = ndop; 1834 break; 1835 case O_ENCAP: 1836 *edop = ndop; 1837 break; 1838 } 1839 break; 1840 case O_VENDCLASS: 1841 ARG_REQUIRED; 1842 fp = strwhite(arg); 1843 if (fp) 1844 *fp++ = '\0'; 1845 u = (uint32_t)strtou(arg, NULL, 0, 0, UINT32_MAX, &e); 1846 if (e) { 1847 logerrx("invalid code: %s", arg); 1848 return -1; 1849 } 1850 fp = strskipwhite(fp); 1851 if (fp) { 1852 s = parse_string(NULL, 0, fp); 1853 if (s == -1) { 1854 logerr(__func__); 1855 return -1; 1856 } 1857 dl = (size_t)s; 1858 if (dl + (sizeof(uint16_t) * 2) > UINT16_MAX) { 1859 logerrx("vendor class is too big"); 1860 return -1; 1861 } 1862 np = malloc(dl); 1863 if (np == NULL) { 1864 logerr(__func__); 1865 return -1; 1866 } 1867 parse_string(np, dl, fp); 1868 } else { 1869 dl = 0; 1870 np = NULL; 1871 } 1872 vivco = reallocarray(ifo->vivco, 1873 ifo->vivco_len + 1, sizeof(*ifo->vivco)); 1874 if (vivco == NULL) { 1875 logerr( __func__); 1876 return -1; 1877 } 1878 ifo->vivco = vivco; 1879 ifo->vivco_en = (uint32_t)u; 1880 vivco = &ifo->vivco[ifo->vivco_len++]; 1881 vivco->len = dl; 1882 vivco->data = (uint8_t *)np; 1883 break; 1884 case O_AUTHPROTOCOL: 1885 ARG_REQUIRED; 1886 #ifdef AUTH 1887 fp = strwhite(arg); 1888 if (fp) 1889 *fp++ = '\0'; 1890 if (strcasecmp(arg, "token") == 0) 1891 ifo->auth.protocol = AUTH_PROTO_TOKEN; 1892 else if (strcasecmp(arg, "delayed") == 0) 1893 ifo->auth.protocol = AUTH_PROTO_DELAYED; 1894 else if (strcasecmp(arg, "delayedrealm") == 0) 1895 ifo->auth.protocol = AUTH_PROTO_DELAYEDREALM; 1896 else { 1897 logerrx("%s: unsupported protocol", arg); 1898 return -1; 1899 } 1900 arg = strskipwhite(fp); 1901 fp = strwhite(arg); 1902 if (arg == NULL) { 1903 ifo->auth.options |= DHCPCD_AUTH_SEND; 1904 if (ifo->auth.protocol == AUTH_PROTO_TOKEN) 1905 ifo->auth.protocol = AUTH_ALG_NONE; 1906 else 1907 ifo->auth.algorithm = AUTH_ALG_HMAC_MD5; 1908 ifo->auth.rdm = AUTH_RDM_MONOTONIC; 1909 break; 1910 } 1911 if (fp) 1912 *fp++ = '\0'; 1913 if (ifo->auth.protocol == AUTH_PROTO_TOKEN) { 1914 np = strchr(arg, '/'); 1915 if (np) { 1916 if (fp == NULL || np < fp) 1917 *np++ = '\0'; 1918 else 1919 np = NULL; 1920 } 1921 if (parse_uint32(&ifo->auth.token_snd_secretid, 1922 arg) == -1) 1923 logerrx("%s: not a number", arg); 1924 else 1925 ifo->auth.token_rcv_secretid = 1926 ifo->auth.token_snd_secretid; 1927 if (np && 1928 parse_uint32(&ifo->auth.token_rcv_secretid, 1929 np) == -1) 1930 logerrx("%s: not a number", arg); 1931 } else { 1932 if (strcasecmp(arg, "hmacmd5") == 0 || 1933 strcasecmp(arg, "hmac-md5") == 0) 1934 ifo->auth.algorithm = AUTH_ALG_HMAC_MD5; 1935 else { 1936 logerrx("%s: unsupported algorithm", arg); 1937 return 1; 1938 } 1939 } 1940 arg = fp; 1941 if (arg == NULL) { 1942 ifo->auth.options |= DHCPCD_AUTH_SEND; 1943 ifo->auth.rdm = AUTH_RDM_MONOTONIC; 1944 break; 1945 } 1946 if (strcasecmp(arg, "monocounter") == 0) { 1947 ifo->auth.rdm = AUTH_RDM_MONOTONIC; 1948 ifo->auth.options |= DHCPCD_AUTH_RDM_COUNTER; 1949 } else if (strcasecmp(arg, "monotonic") ==0 || 1950 strcasecmp(arg, "monotime") == 0) 1951 ifo->auth.rdm = AUTH_RDM_MONOTONIC; 1952 else { 1953 logerrx("%s: unsupported RDM", arg); 1954 return -1; 1955 } 1956 ifo->auth.options |= DHCPCD_AUTH_SEND; 1957 break; 1958 #else 1959 logerrx("no authentication support"); 1960 return -1; 1961 #endif 1962 case O_AUTHTOKEN: 1963 ARG_REQUIRED; 1964 #ifdef AUTH 1965 fp = strwhite(arg); 1966 if (fp == NULL) { 1967 logerrx("authtoken requires a realm"); 1968 return -1; 1969 } 1970 *fp++ = '\0'; 1971 token = malloc(sizeof(*token)); 1972 if (token == NULL) { 1973 logerr(__func__); 1974 free(token); 1975 return -1; 1976 } 1977 if (parse_uint32(&token->secretid, arg) == -1) { 1978 logerrx("%s: not a number", arg); 1979 free(token); 1980 return -1; 1981 } 1982 arg = fp; 1983 fp = strend(arg); 1984 if (fp == NULL) { 1985 logerrx("authtoken requies an a key"); 1986 free(token); 1987 return -1; 1988 } 1989 *fp++ = '\0'; 1990 s = parse_string(NULL, 0, arg); 1991 if (s == -1) { 1992 logerr("realm_len"); 1993 free(token); 1994 return -1; 1995 } 1996 if (s) { 1997 token->realm_len = (size_t)s; 1998 token->realm = malloc(token->realm_len); 1999 if (token->realm == NULL) { 2000 logerr(__func__); 2001 free(token); 2002 return -1; 2003 } 2004 parse_string((char *)token->realm, token->realm_len, 2005 arg); 2006 } else { 2007 token->realm_len = 0; 2008 token->realm = NULL; 2009 } 2010 arg = fp; 2011 fp = strend(arg); 2012 if (fp == NULL) { 2013 logerrx("authtoken requies an an expiry date"); 2014 free(token->realm); 2015 free(token); 2016 return -1; 2017 } 2018 *fp++ = '\0'; 2019 if (*arg == '"') { 2020 arg++; 2021 np = strchr(arg, '"'); 2022 if (np) 2023 *np = '\0'; 2024 } 2025 if (strcmp(arg, "0") == 0 || strcasecmp(arg, "forever") == 0) 2026 token->expire =0; 2027 else { 2028 struct tm tm; 2029 2030 memset(&tm, 0, sizeof(tm)); 2031 if (strptime(arg, "%Y-%m-%d %H:%M", &tm) == NULL) { 2032 logerrx("%s: invalid date time", arg); 2033 free(token->realm); 2034 free(token); 2035 return -1; 2036 } 2037 if ((token->expire = mktime(&tm)) == (time_t)-1) { 2038 logerr("%s: mktime", __func__); 2039 free(token->realm); 2040 free(token); 2041 return -1; 2042 } 2043 } 2044 arg = fp; 2045 s = parse_string(NULL, 0, arg); 2046 if (s == -1 || s == 0) { 2047 if (s == -1) 2048 logerr("token_len"); 2049 else 2050 logerrx("authtoken needs a key"); 2051 free(token->realm); 2052 free(token); 2053 return -1; 2054 } 2055 token->key_len = (size_t)s; 2056 token->key = malloc(token->key_len); 2057 parse_string((char *)token->key, token->key_len, arg); 2058 TAILQ_INSERT_TAIL(&ifo->auth.tokens, token, next); 2059 #else 2060 logerrx("no authentication support"); 2061 return -1; 2062 #endif 2063 break; 2064 case O_AUTHNOTREQUIRED: 2065 ifo->auth.options &= ~DHCPCD_AUTH_REQUIRE; 2066 break; 2067 case O_DHCP: 2068 ifo->options |= DHCPCD_DHCP | DHCPCD_IPV4; 2069 break; 2070 case O_NODHCP: 2071 ifo->options &= ~DHCPCD_DHCP; 2072 break; 2073 case O_DHCP6: 2074 ifo->options |= DHCPCD_DHCP6 | DHCPCD_IPV6; 2075 break; 2076 case O_NODHCP6: 2077 ifo->options &= ~DHCPCD_DHCP6; 2078 break; 2079 case O_CONTROLGRP: 2080 ARG_REQUIRED; 2081 #ifdef _REENTRANT 2082 l = sysconf(_SC_GETGR_R_SIZE_MAX); 2083 if (l == -1) 2084 dl = 1024; 2085 else 2086 dl = (size_t)l; 2087 p = malloc(dl); 2088 if (p == NULL) { 2089 logerr(__func__); 2090 return -1; 2091 } 2092 while ((i = getgrnam_r(arg, &grpbuf, p, (size_t)l, &grp)) == 2093 ERANGE) 2094 { 2095 size_t nl = dl * 2; 2096 if (nl < dl) { 2097 logerrx("control_group: out of buffer"); 2098 free(p); 2099 return -1; 2100 } 2101 dl = nl; 2102 np = realloc(p, dl); 2103 if (np == NULL) { 2104 logerr(__func__); 2105 free(p); 2106 return -1; 2107 } 2108 p = np; 2109 } 2110 if (i != 0) { 2111 errno = i; 2112 logerr("getgrnam_r"); 2113 free(p); 2114 return -1; 2115 } 2116 if (grp == NULL) { 2117 logerrx("controlgroup: %s: not found", arg); 2118 free(p); 2119 return -1; 2120 } 2121 ctx->control_group = grp->gr_gid; 2122 free(p); 2123 #else 2124 grp = getgrnam(arg); 2125 if (grp == NULL) { 2126 logerrx("controlgroup: %s: not found", arg); 2127 return -1; 2128 } 2129 ctx->control_group = grp->gr_gid; 2130 #endif 2131 break; 2132 case O_GATEWAY: 2133 ifo->options |= DHCPCD_GATEWAY; 2134 break; 2135 case O_NOUP: 2136 ifo->options &= ~DHCPCD_IF_UP; 2137 break; 2138 case O_SLAAC: 2139 ARG_REQUIRED; 2140 if (strcmp(arg, "private") == 0 || 2141 strcmp(arg, "stableprivate") == 0 || 2142 strcmp(arg, "stable") == 0) 2143 ifo->options |= DHCPCD_SLAACPRIVATE; 2144 else 2145 ifo->options &= ~DHCPCD_SLAACPRIVATE; 2146 break; 2147 case O_BOOTP: 2148 ifo->options |= DHCPCD_BOOTP; 2149 break; 2150 case O_NODELAY: 2151 ifo->options &= ~DHCPCD_INITIAL_DELAY; 2152 break; 2153 case O_LASTLEASE_EXTEND: 2154 ifo->options |= DHCPCD_LASTLEASE | DHCPCD_LASTLEASE_EXTEND; 2155 break; 2156 case O_INACTIVE: 2157 ifo->options |= DHCPCD_INACTIVE; 2158 break; 2159 case O_MUDURL: 2160 ARG_REQUIRED; 2161 s = parse_string((char *)ifo->mudurl + 1, MUDURL_MAX_LEN, arg); 2162 if (s == -1) { 2163 logerr("mudurl"); 2164 return -1; 2165 } 2166 *ifo->mudurl = (uint8_t)s; 2167 break; 2168 default: 2169 return 0; 2170 } 2171 2172 return 1; 2173 2174 #ifdef ARG_REQUIRED 2175 arg_required: 2176 logerrx("option %d requires an argument", opt); 2177 return -1; 2178 #undef ARG_REQUIRED 2179 #endif 2180 } 2181 2182 static int 2183 parse_config_line(struct dhcpcd_ctx *ctx, const char *ifname, 2184 struct if_options *ifo, const char *opt, char *line, 2185 struct dhcp_opt **ldop, struct dhcp_opt **edop) 2186 { 2187 unsigned int i; 2188 2189 for (i = 0; i < sizeof(cf_options) / sizeof(cf_options[0]); i++) { 2190 if (!cf_options[i].name || 2191 strcmp(cf_options[i].name, opt) != 0) 2192 continue; 2193 2194 if (cf_options[i].has_arg == required_argument && !line) { 2195 logerrx("option requires an argument -- %s", opt); 2196 return -1; 2197 } 2198 2199 return parse_option(ctx, ifname, ifo, cf_options[i].val, line, 2200 ldop, edop); 2201 } 2202 2203 logerrx("unknown option: %s", opt); 2204 return -1; 2205 } 2206 2207 static void 2208 finish_config(struct if_options *ifo) 2209 { 2210 2211 /* Terminate the encapsulated options */ 2212 if (ifo->vendor[0] && !(ifo->options & DHCPCD_VENDORRAW)) { 2213 ifo->vendor[0]++; 2214 ifo->vendor[ifo->vendor[0]] = DHO_END; 2215 /* We are called twice. 2216 * This should be fixed, but in the meantime, this 2217 * guard should suffice */ 2218 ifo->options |= DHCPCD_VENDORRAW; 2219 } 2220 } 2221 2222 /* Handy routine to read very long lines in text files. 2223 * This means we read the whole line and avoid any nasty buffer overflows. 2224 * We strip leading space and avoid comment lines, making the code that calls 2225 * us smaller. */ 2226 static char * 2227 get_line(char ** __restrict buf, size_t * __restrict buflen, 2228 FILE * __restrict fp) 2229 { 2230 char *p, *c; 2231 ssize_t bytes; 2232 int quoted; 2233 2234 do { 2235 bytes = getline(buf, buflen, fp); 2236 if (bytes == -1) 2237 return NULL; 2238 for (p = *buf; *p == ' ' || *p == '\t'; p++) 2239 ; 2240 } while (*p == '\0' || *p == '\n' || *p == '#' || *p == ';'); 2241 if ((*buf)[--bytes] == '\n') 2242 (*buf)[bytes] = '\0'; 2243 2244 /* Strip embedded comments unless in a quoted string or escaped */ 2245 quoted = 0; 2246 for (c = p; *c != '\0'; c++) { 2247 if (*c == '\\') { 2248 c++; /* escaped */ 2249 continue; 2250 } 2251 if (*c == '"') 2252 quoted = !quoted; 2253 else if (*c == '#' && !quoted) { 2254 *c = '\0'; 2255 break; 2256 } 2257 } 2258 return p; 2259 } 2260 2261 struct if_options * 2262 default_config(struct dhcpcd_ctx *ctx) 2263 { 2264 struct if_options *ifo; 2265 2266 /* Seed our default options */ 2267 if ((ifo = calloc(1, sizeof(*ifo))) == NULL) { 2268 logerr(__func__); 2269 return NULL; 2270 } 2271 ifo->options |= DHCPCD_IF_UP | DHCPCD_LINK | DHCPCD_INITIAL_DELAY; 2272 ifo->timeout = DEFAULT_TIMEOUT; 2273 ifo->reboot = DEFAULT_REBOOT; 2274 ifo->metric = -1; 2275 ifo->auth.options |= DHCPCD_AUTH_REQUIRE; 2276 TAILQ_INIT(&ifo->routes); 2277 #ifdef AUTH 2278 TAILQ_INIT(&ifo->auth.tokens); 2279 #endif 2280 2281 /* Inherit some global defaults */ 2282 if (ctx->options & DHCPCD_PERSISTENT) 2283 ifo->options |= DHCPCD_PERSISTENT; 2284 if (ctx->options & DHCPCD_SLAACPRIVATE) 2285 ifo->options |= DHCPCD_SLAACPRIVATE; 2286 2287 return ifo; 2288 } 2289 2290 struct if_options * 2291 read_config(struct dhcpcd_ctx *ctx, 2292 const char *ifname, const char *ssid, const char *profile) 2293 { 2294 struct if_options *ifo; 2295 FILE *fp; 2296 struct stat sb; 2297 char *line, *buf, *option, *p; 2298 size_t buflen; 2299 ssize_t vlen; 2300 int skip, have_profile, new_block, had_block; 2301 #ifndef EMBEDDED_CONFIG 2302 const char * const *e; 2303 size_t ol; 2304 #endif 2305 #if !defined(INET) || !defined(INET6) 2306 size_t i; 2307 struct dhcp_opt *opt; 2308 #endif 2309 struct dhcp_opt *ldop, *edop; 2310 2311 /* Seed our default options */ 2312 if ((ifo = default_config(ctx)) == NULL) 2313 return NULL; 2314 ifo->options |= DHCPCD_DAEMONISE | DHCPCD_GATEWAY; 2315 #ifdef PLUGIN_DEV 2316 ifo->options |= DHCPCD_DEV; 2317 #endif 2318 #ifdef INET 2319 ifo->options |= DHCPCD_IPV4 | DHCPCD_ARP | DHCPCD_DHCP | DHCPCD_IPV4LL; 2320 #endif 2321 #ifdef INET6 2322 ifo->options |= DHCPCD_IPV6 | DHCPCD_IPV6RS; 2323 ifo->options |= DHCPCD_IPV6RA_AUTOCONF | DHCPCD_IPV6RA_REQRDNSS; 2324 ifo->options |= DHCPCD_DHCP6; 2325 #endif 2326 2327 vlen = dhcp_vendor((char *)ifo->vendorclassid + 1, 2328 sizeof(ifo->vendorclassid) - 1); 2329 ifo->vendorclassid[0] = (uint8_t)(vlen == -1 ? 0 : vlen); 2330 2331 buf = NULL; 2332 buflen = 0; 2333 2334 /* Parse our embedded options file */ 2335 if (ifname == NULL && !(ctx->options & DHCPCD_PRINT_PIDFILE)) { 2336 /* Space for initial estimates */ 2337 #if defined(INET) && defined(INITDEFINES) 2338 ifo->dhcp_override = 2339 calloc(INITDEFINES, sizeof(*ifo->dhcp_override)); 2340 if (ifo->dhcp_override == NULL) 2341 logerr(__func__); 2342 else 2343 ifo->dhcp_override_len = INITDEFINES; 2344 #endif 2345 2346 #if defined(INET6) && defined(INITDEFINENDS) 2347 ifo->nd_override = 2348 calloc(INITDEFINENDS, sizeof(*ifo->nd_override)); 2349 if (ifo->nd_override == NULL) 2350 logerr(__func__); 2351 else 2352 ifo->nd_override_len = INITDEFINENDS; 2353 #endif 2354 #if defined(INET6) && defined(INITDEFINE6S) 2355 ifo->dhcp6_override = 2356 calloc(INITDEFINE6S, sizeof(*ifo->dhcp6_override)); 2357 if (ifo->dhcp6_override == NULL) 2358 logerr(__func__); 2359 else 2360 ifo->dhcp6_override_len = INITDEFINE6S; 2361 #endif 2362 2363 /* Now load our embedded config */ 2364 #ifdef EMBEDDED_CONFIG 2365 fp = fopen(EMBEDDED_CONFIG, "r"); 2366 if (fp == NULL) 2367 logerr("%s: fopen `%s'", __func__, EMBEDDED_CONFIG); 2368 2369 while (fp && (line = get_line(&buf, &buflen, fp))) { 2370 #else 2371 buflen = 80; 2372 buf = malloc(buflen); 2373 if (buf == NULL) { 2374 logerr(__func__); 2375 free_options(ctx, ifo); 2376 return NULL; 2377 } 2378 ldop = edop = NULL; 2379 for (e = dhcpcd_embedded_conf; *e; e++) { 2380 ol = strlen(*e) + 1; 2381 if (ol > buflen) { 2382 char *nbuf; 2383 2384 buflen = ol; 2385 nbuf = realloc(buf, buflen); 2386 if (nbuf == NULL) { 2387 logerr(__func__); 2388 free(buf); 2389 free_options(ctx, ifo); 2390 return NULL; 2391 } 2392 buf = nbuf; 2393 } 2394 memcpy(buf, *e, ol); 2395 line = buf; 2396 #endif 2397 option = strsep(&line, " \t"); 2398 if (line) 2399 line = strskipwhite(line); 2400 /* Trim trailing whitespace */ 2401 if (line) { 2402 p = line + strlen(line) - 1; 2403 while (p != line && 2404 (*p == ' ' || *p == '\t') && 2405 *(p - 1) != '\\') 2406 *p-- = '\0'; 2407 } 2408 parse_config_line(ctx, NULL, ifo, option, line, 2409 &ldop, &edop); 2410 2411 } 2412 2413 #ifdef EMBEDDED_CONFIG 2414 if (fp) 2415 fclose(fp); 2416 #endif 2417 #ifdef INET 2418 ctx->dhcp_opts = ifo->dhcp_override; 2419 ctx->dhcp_opts_len = ifo->dhcp_override_len; 2420 #else 2421 for (i = 0, opt = ifo->dhcp_override; 2422 i < ifo->dhcp_override_len; 2423 i++, opt++) 2424 free_dhcp_opt_embenc(opt); 2425 free(ifo->dhcp_override); 2426 #endif 2427 ifo->dhcp_override = NULL; 2428 ifo->dhcp_override_len = 0; 2429 2430 #ifdef INET6 2431 ctx->nd_opts = ifo->nd_override; 2432 ctx->nd_opts_len = ifo->nd_override_len; 2433 ctx->dhcp6_opts = ifo->dhcp6_override; 2434 ctx->dhcp6_opts_len = ifo->dhcp6_override_len; 2435 #else 2436 for (i = 0, opt = ifo->nd_override; 2437 i < ifo->nd_override_len; 2438 i++, opt++) 2439 free_dhcp_opt_embenc(opt); 2440 free(ifo->nd_override); 2441 for (i = 0, opt = ifo->dhcp6_override; 2442 i < ifo->dhcp6_override_len; 2443 i++, opt++) 2444 free_dhcp_opt_embenc(opt); 2445 free(ifo->dhcp6_override); 2446 #endif 2447 ifo->nd_override = NULL; 2448 ifo->nd_override_len = 0; 2449 ifo->dhcp6_override = NULL; 2450 ifo->dhcp6_override_len = 0; 2451 2452 ctx->vivso = ifo->vivso_override; 2453 ctx->vivso_len = ifo->vivso_override_len; 2454 ifo->vivso_override = NULL; 2455 ifo->vivso_override_len = 0; 2456 } 2457 2458 /* Parse our options file */ 2459 fp = fopen(ctx->cffile, "r"); 2460 if (fp == NULL) { 2461 /* dhcpcd can continue without it, but no DNS options 2462 * would be requested ... */ 2463 logwarn("%s: fopen `%s'", __func__, ctx->cffile); 2464 free(buf); 2465 return ifo; 2466 } 2467 if (stat(ctx->cffile, &sb) == 0) 2468 ifo->mtime = sb.st_mtime; 2469 2470 ldop = edop = NULL; 2471 skip = have_profile = new_block = 0; 2472 had_block = ifname == NULL ? 1 : 0; 2473 while ((line = get_line(&buf, &buflen, fp))) { 2474 option = strsep(&line, " \t"); 2475 if (line) 2476 line = strskipwhite(line); 2477 /* Trim trailing whitespace */ 2478 if (line) { 2479 p = line + strlen(line) - 1; 2480 while (p != line && 2481 (*p == ' ' || *p == '\t') && 2482 *(p - 1) != '\\') 2483 *p-- = '\0'; 2484 } 2485 if (skip == 0 && new_block) { 2486 had_block = 1; 2487 new_block = 0; 2488 ifo->options &= ~DHCPCD_WAITOPTS; 2489 } 2490 /* Start of an interface block, skip if not ours */ 2491 if (strcmp(option, "interface") == 0) { 2492 char **n; 2493 2494 new_block = 1; 2495 if (line == NULL) { 2496 /* No interface given */ 2497 skip = 1; 2498 continue; 2499 } 2500 if (ifname && strcmp(line, ifname) == 0) 2501 skip = 0; 2502 else 2503 skip = 1; 2504 if (ifname) 2505 continue; 2506 2507 n = reallocarray(ctx->ifcv, 2508 (size_t)ctx->ifcc + 1, sizeof(char *)); 2509 if (n == NULL) { 2510 logerr(__func__); 2511 continue; 2512 } 2513 ctx->ifcv = n; 2514 ctx->ifcv[ctx->ifcc] = strdup(line); 2515 if (ctx->ifcv[ctx->ifcc] == NULL) { 2516 logerr(__func__); 2517 continue; 2518 } 2519 ctx->ifcc++; 2520 continue; 2521 } 2522 /* Start of an ssid block, skip if not ours */ 2523 if (strcmp(option, "ssid") == 0) { 2524 new_block = 1; 2525 if (ssid && line && strcmp(line, ssid) == 0) 2526 skip = 0; 2527 else 2528 skip = 1; 2529 continue; 2530 } 2531 /* Start of a profile block, skip if not ours */ 2532 if (strcmp(option, "profile") == 0) { 2533 new_block = 1; 2534 if (profile && line && strcmp(line, profile) == 0) { 2535 skip = 0; 2536 have_profile = 1; 2537 } else 2538 skip = 1; 2539 continue; 2540 } 2541 /* Skip arping if we have selected a profile but not parsing 2542 * one. */ 2543 if (profile && !have_profile && strcmp(option, "arping") == 0) 2544 continue; 2545 if (skip) 2546 continue; 2547 parse_config_line(ctx, ifname, ifo, option, line, &ldop, &edop); 2548 } 2549 fclose(fp); 2550 free(buf); 2551 2552 if (profile && !have_profile) { 2553 free_options(ctx, ifo); 2554 errno = ENOENT; 2555 return NULL; 2556 } 2557 2558 if (!had_block) 2559 ifo->options &= ~DHCPCD_WAITOPTS; 2560 finish_config(ifo); 2561 return ifo; 2562 } 2563 2564 int 2565 add_options(struct dhcpcd_ctx *ctx, const char *ifname, 2566 struct if_options *ifo, int argc, char **argv) 2567 { 2568 int oi, opt, r; 2569 unsigned long long wait_opts; 2570 2571 if (argc == 0) 2572 return 1; 2573 2574 optind = 0; 2575 r = 1; 2576 /* Don't apply the command line wait options to each interface, 2577 * only use the dhcpcd.conf entry for that. */ 2578 if (ifname != NULL) 2579 wait_opts = ifo->options & DHCPCD_WAITOPTS; 2580 while ((opt = getopt_long(argc, argv, 2581 ctx->options & DHCPCD_PRINT_PIDFILE ? NOERR_IF_OPTS : IF_OPTS, 2582 cf_options, &oi)) != -1) 2583 { 2584 r = parse_option(ctx, ifname, ifo, opt, optarg, NULL, NULL); 2585 if (r != 1) 2586 break; 2587 } 2588 if (ifname != NULL) { 2589 ifo->options &= ~DHCPCD_WAITOPTS; 2590 ifo->options |= wait_opts; 2591 } 2592 2593 finish_config(ifo); 2594 return r; 2595 } 2596 2597 void 2598 free_options(struct dhcpcd_ctx *ctx, struct if_options *ifo) 2599 { 2600 size_t i; 2601 struct dhcp_opt *opt; 2602 struct vivco *vo; 2603 #ifdef AUTH 2604 struct token *token; 2605 #endif 2606 2607 if (ifo) { 2608 if (ifo->environ) { 2609 i = 0; 2610 while (ifo->environ[i]) 2611 free(ifo->environ[i++]); 2612 free(ifo->environ); 2613 } 2614 if (ifo->config) { 2615 i = 0; 2616 while (ifo->config[i]) 2617 free(ifo->config[i++]); 2618 free(ifo->config); 2619 } 2620 rt_headclear0(ctx, &ifo->routes, AF_UNSPEC); 2621 free(ifo->script); 2622 free(ifo->arping); 2623 free(ifo->blacklist); 2624 free(ifo->fallback); 2625 2626 for (opt = ifo->dhcp_override; 2627 ifo->dhcp_override_len > 0; 2628 opt++, ifo->dhcp_override_len--) 2629 free_dhcp_opt_embenc(opt); 2630 free(ifo->dhcp_override); 2631 for (opt = ifo->nd_override; 2632 ifo->nd_override_len > 0; 2633 opt++, ifo->nd_override_len--) 2634 free_dhcp_opt_embenc(opt); 2635 free(ifo->nd_override); 2636 for (opt = ifo->dhcp6_override; 2637 ifo->dhcp6_override_len > 0; 2638 opt++, ifo->dhcp6_override_len--) 2639 free_dhcp_opt_embenc(opt); 2640 free(ifo->dhcp6_override); 2641 for (vo = ifo->vivco; 2642 ifo->vivco_len > 0; 2643 vo++, ifo->vivco_len--) 2644 free(vo->data); 2645 free(ifo->vivco); 2646 for (opt = ifo->vivso_override; 2647 ifo->vivso_override_len > 0; 2648 opt++, ifo->vivso_override_len--) 2649 free_dhcp_opt_embenc(opt); 2650 free(ifo->vivso_override); 2651 2652 #if defined(INET6) && !defined(SMALL) 2653 for (; ifo->ia_len > 0; ifo->ia_len--) 2654 free(ifo->ia[ifo->ia_len - 1].sla); 2655 #endif 2656 free(ifo->ia); 2657 2658 #ifdef AUTH 2659 while ((token = TAILQ_FIRST(&ifo->auth.tokens))) { 2660 TAILQ_REMOVE(&ifo->auth.tokens, token, next); 2661 if (token->realm_len) 2662 free(token->realm); 2663 free(token->key); 2664 free(token); 2665 } 2666 #endif 2667 free(ifo); 2668 } 2669 } 2670