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 fp = strskipwhite(fp); 1854 if (fp) { 1855 s = parse_string(NULL, 0, fp); 1856 if (s == -1) { 1857 logerr(__func__); 1858 return -1; 1859 } 1860 dl = (size_t)s; 1861 if (dl + (sizeof(uint16_t) * 2) > UINT16_MAX) { 1862 logerrx("vendor class is too big"); 1863 return -1; 1864 } 1865 np = malloc(dl); 1866 if (np == NULL) { 1867 logerr(__func__); 1868 return -1; 1869 } 1870 parse_string(np, dl, fp); 1871 } else { 1872 dl = 0; 1873 np = NULL; 1874 } 1875 vivco = reallocarray(ifo->vivco, 1876 ifo->vivco_len + 1, sizeof(*ifo->vivco)); 1877 if (vivco == NULL) { 1878 logerr( __func__); 1879 return -1; 1880 } 1881 ifo->vivco = vivco; 1882 ifo->vivco_en = (uint32_t)u; 1883 vivco = &ifo->vivco[ifo->vivco_len++]; 1884 vivco->len = dl; 1885 vivco->data = (uint8_t *)np; 1886 break; 1887 case O_AUTHPROTOCOL: 1888 ARG_REQUIRED; 1889 #ifdef AUTH 1890 fp = strwhite(arg); 1891 if (fp) 1892 *fp++ = '\0'; 1893 if (strcasecmp(arg, "token") == 0) 1894 ifo->auth.protocol = AUTH_PROTO_TOKEN; 1895 else if (strcasecmp(arg, "delayed") == 0) 1896 ifo->auth.protocol = AUTH_PROTO_DELAYED; 1897 else if (strcasecmp(arg, "delayedrealm") == 0) 1898 ifo->auth.protocol = AUTH_PROTO_DELAYEDREALM; 1899 else { 1900 logerrx("%s: unsupported protocol", arg); 1901 return -1; 1902 } 1903 arg = strskipwhite(fp); 1904 fp = strwhite(arg); 1905 if (arg == NULL) { 1906 ifo->auth.options |= DHCPCD_AUTH_SEND; 1907 if (ifo->auth.protocol == AUTH_PROTO_TOKEN) 1908 ifo->auth.protocol = AUTH_ALG_NONE; 1909 else 1910 ifo->auth.algorithm = AUTH_ALG_HMAC_MD5; 1911 ifo->auth.rdm = AUTH_RDM_MONOTONIC; 1912 break; 1913 } 1914 if (fp) 1915 *fp++ = '\0'; 1916 if (ifo->auth.protocol == AUTH_PROTO_TOKEN) { 1917 np = strchr(arg, '/'); 1918 if (np) { 1919 if (fp == NULL || np < fp) 1920 *np++ = '\0'; 1921 else 1922 np = NULL; 1923 } 1924 if (parse_uint32(&ifo->auth.token_snd_secretid, 1925 arg) == -1) 1926 logerrx("%s: not a number", arg); 1927 else 1928 ifo->auth.token_rcv_secretid = 1929 ifo->auth.token_snd_secretid; 1930 if (np && 1931 parse_uint32(&ifo->auth.token_rcv_secretid, 1932 np) == -1) 1933 logerrx("%s: not a number", arg); 1934 } else { 1935 if (strcasecmp(arg, "hmacmd5") == 0 || 1936 strcasecmp(arg, "hmac-md5") == 0) 1937 ifo->auth.algorithm = AUTH_ALG_HMAC_MD5; 1938 else { 1939 logerrx("%s: unsupported algorithm", arg); 1940 return 1; 1941 } 1942 } 1943 arg = fp; 1944 if (arg == NULL) { 1945 ifo->auth.options |= DHCPCD_AUTH_SEND; 1946 ifo->auth.rdm = AUTH_RDM_MONOTONIC; 1947 break; 1948 } 1949 if (strcasecmp(arg, "monocounter") == 0) { 1950 ifo->auth.rdm = AUTH_RDM_MONOTONIC; 1951 ifo->auth.options |= DHCPCD_AUTH_RDM_COUNTER; 1952 } else if (strcasecmp(arg, "monotonic") ==0 || 1953 strcasecmp(arg, "monotime") == 0) 1954 ifo->auth.rdm = AUTH_RDM_MONOTONIC; 1955 else { 1956 logerrx("%s: unsupported RDM", arg); 1957 return -1; 1958 } 1959 ifo->auth.options |= DHCPCD_AUTH_SEND; 1960 break; 1961 #else 1962 logerrx("no authentication support"); 1963 return -1; 1964 #endif 1965 case O_AUTHTOKEN: 1966 ARG_REQUIRED; 1967 #ifdef AUTH 1968 fp = strwhite(arg); 1969 if (fp == NULL) { 1970 logerrx("authtoken requires a realm"); 1971 return -1; 1972 } 1973 *fp++ = '\0'; 1974 token = malloc(sizeof(*token)); 1975 if (token == NULL) { 1976 logerr(__func__); 1977 free(token); 1978 return -1; 1979 } 1980 if (parse_uint32(&token->secretid, arg) == -1) { 1981 logerrx("%s: not a number", arg); 1982 free(token); 1983 return -1; 1984 } 1985 arg = fp; 1986 fp = strend(arg); 1987 if (fp == NULL) { 1988 logerrx("authtoken requies an a key"); 1989 free(token); 1990 return -1; 1991 } 1992 *fp++ = '\0'; 1993 s = parse_string(NULL, 0, arg); 1994 if (s == -1) { 1995 logerr("realm_len"); 1996 free(token); 1997 return -1; 1998 } 1999 if (s) { 2000 token->realm_len = (size_t)s; 2001 token->realm = malloc(token->realm_len); 2002 if (token->realm == NULL) { 2003 logerr(__func__); 2004 free(token); 2005 return -1; 2006 } 2007 parse_string((char *)token->realm, token->realm_len, 2008 arg); 2009 } else { 2010 token->realm_len = 0; 2011 token->realm = NULL; 2012 } 2013 arg = fp; 2014 fp = strend(arg); 2015 if (fp == NULL) { 2016 logerrx("authtoken requies an an expiry date"); 2017 free(token->realm); 2018 free(token); 2019 return -1; 2020 } 2021 *fp++ = '\0'; 2022 if (*arg == '"') { 2023 arg++; 2024 np = strchr(arg, '"'); 2025 if (np) 2026 *np = '\0'; 2027 } 2028 if (strcmp(arg, "0") == 0 || strcasecmp(arg, "forever") == 0) 2029 token->expire =0; 2030 else { 2031 struct tm tm; 2032 2033 memset(&tm, 0, sizeof(tm)); 2034 if (strptime(arg, "%Y-%m-%d %H:%M", &tm) == NULL) { 2035 logerrx("%s: invalid date time", arg); 2036 free(token->realm); 2037 free(token); 2038 return -1; 2039 } 2040 if ((token->expire = mktime(&tm)) == (time_t)-1) { 2041 logerr("%s: mktime", __func__); 2042 free(token->realm); 2043 free(token); 2044 return -1; 2045 } 2046 } 2047 arg = fp; 2048 s = parse_string(NULL, 0, arg); 2049 if (s == -1 || s == 0) { 2050 if (s == -1) 2051 logerr("token_len"); 2052 else 2053 logerrx("authtoken needs a key"); 2054 free(token->realm); 2055 free(token); 2056 return -1; 2057 } 2058 token->key_len = (size_t)s; 2059 token->key = malloc(token->key_len); 2060 parse_string((char *)token->key, token->key_len, arg); 2061 TAILQ_INSERT_TAIL(&ifo->auth.tokens, token, next); 2062 #else 2063 logerrx("no authentication support"); 2064 return -1; 2065 #endif 2066 break; 2067 case O_AUTHNOTREQUIRED: 2068 ifo->auth.options &= ~DHCPCD_AUTH_REQUIRE; 2069 break; 2070 case O_DHCP: 2071 ifo->options |= DHCPCD_DHCP | DHCPCD_IPV4; 2072 break; 2073 case O_NODHCP: 2074 ifo->options &= ~DHCPCD_DHCP; 2075 break; 2076 case O_DHCP6: 2077 ifo->options |= DHCPCD_DHCP6 | DHCPCD_IPV6; 2078 break; 2079 case O_NODHCP6: 2080 ifo->options &= ~DHCPCD_DHCP6; 2081 break; 2082 case O_CONTROLGRP: 2083 ARG_REQUIRED; 2084 #ifdef _REENTRANT 2085 l = sysconf(_SC_GETGR_R_SIZE_MAX); 2086 if (l == -1) 2087 dl = 1024; 2088 else 2089 dl = (size_t)l; 2090 p = malloc(dl); 2091 if (p == NULL) { 2092 logerr(__func__); 2093 return -1; 2094 } 2095 while ((i = getgrnam_r(arg, &grpbuf, p, (size_t)l, &grp)) == 2096 ERANGE) 2097 { 2098 size_t nl = dl * 2; 2099 if (nl < dl) { 2100 logerrx("control_group: out of buffer"); 2101 free(p); 2102 return -1; 2103 } 2104 dl = nl; 2105 np = realloc(p, dl); 2106 if (np == NULL) { 2107 logerr(__func__); 2108 free(p); 2109 return -1; 2110 } 2111 p = np; 2112 } 2113 if (i != 0) { 2114 errno = i; 2115 logerr("getgrnam_r"); 2116 free(p); 2117 return -1; 2118 } 2119 if (grp == NULL) { 2120 logerrx("controlgroup: %s: not found", arg); 2121 free(p); 2122 return -1; 2123 } 2124 ctx->control_group = grp->gr_gid; 2125 free(p); 2126 #else 2127 grp = getgrnam(arg); 2128 if (grp == NULL) { 2129 logerrx("controlgroup: %s: not found", arg); 2130 return -1; 2131 } 2132 ctx->control_group = grp->gr_gid; 2133 #endif 2134 break; 2135 case O_GATEWAY: 2136 ifo->options |= DHCPCD_GATEWAY; 2137 break; 2138 case O_NOUP: 2139 ifo->options &= ~DHCPCD_IF_UP; 2140 break; 2141 case O_SLAAC: 2142 ARG_REQUIRED; 2143 if (strcmp(arg, "private") == 0 || 2144 strcmp(arg, "stableprivate") == 0 || 2145 strcmp(arg, "stable") == 0) 2146 ifo->options |= DHCPCD_SLAACPRIVATE; 2147 else 2148 ifo->options &= ~DHCPCD_SLAACPRIVATE; 2149 break; 2150 case O_BOOTP: 2151 ifo->options |= DHCPCD_BOOTP; 2152 break; 2153 case O_NODELAY: 2154 ifo->options &= ~DHCPCD_INITIAL_DELAY; 2155 break; 2156 case O_LASTLEASE_EXTEND: 2157 ifo->options |= DHCPCD_LASTLEASE | DHCPCD_LASTLEASE_EXTEND; 2158 break; 2159 case O_INACTIVE: 2160 ifo->options |= DHCPCD_INACTIVE; 2161 break; 2162 case O_MUDURL: 2163 ARG_REQUIRED; 2164 s = parse_string((char *)ifo->mudurl + 1, MUDURL_MAX_LEN, arg); 2165 if (s == -1) { 2166 logerr("mudurl"); 2167 return -1; 2168 } 2169 *ifo->mudurl = (uint8_t)s; 2170 break; 2171 default: 2172 return 0; 2173 } 2174 2175 return 1; 2176 2177 #ifdef ARG_REQUIRED 2178 arg_required: 2179 logerrx("option %d requires an argument", opt); 2180 return -1; 2181 #undef ARG_REQUIRED 2182 #endif 2183 } 2184 2185 static int 2186 parse_config_line(struct dhcpcd_ctx *ctx, const char *ifname, 2187 struct if_options *ifo, const char *opt, char *line, 2188 struct dhcp_opt **ldop, struct dhcp_opt **edop) 2189 { 2190 unsigned int i; 2191 2192 for (i = 0; i < sizeof(cf_options) / sizeof(cf_options[0]); i++) { 2193 if (!cf_options[i].name || 2194 strcmp(cf_options[i].name, opt) != 0) 2195 continue; 2196 2197 if (cf_options[i].has_arg == required_argument && !line) { 2198 logerrx("option requires an argument -- %s", opt); 2199 return -1; 2200 } 2201 2202 return parse_option(ctx, ifname, ifo, cf_options[i].val, line, 2203 ldop, edop); 2204 } 2205 2206 logerrx("unknown option: %s", opt); 2207 return -1; 2208 } 2209 2210 static void 2211 finish_config(struct if_options *ifo) 2212 { 2213 2214 /* Terminate the encapsulated options */ 2215 if (ifo->vendor[0] && !(ifo->options & DHCPCD_VENDORRAW)) { 2216 ifo->vendor[0]++; 2217 ifo->vendor[ifo->vendor[0]] = DHO_END; 2218 /* We are called twice. 2219 * This should be fixed, but in the meantime, this 2220 * guard should suffice */ 2221 ifo->options |= DHCPCD_VENDORRAW; 2222 } 2223 } 2224 2225 /* Handy routine to read very long lines in text files. 2226 * This means we read the whole line and avoid any nasty buffer overflows. 2227 * We strip leading space and avoid comment lines, making the code that calls 2228 * us smaller. */ 2229 static char * 2230 get_line(char ** __restrict buf, size_t * __restrict buflen, 2231 FILE * __restrict fp) 2232 { 2233 char *p, *c; 2234 ssize_t bytes; 2235 int quoted; 2236 2237 do { 2238 bytes = getline(buf, buflen, fp); 2239 if (bytes == -1) 2240 return NULL; 2241 for (p = *buf; *p == ' ' || *p == '\t'; p++) 2242 ; 2243 } while (*p == '\0' || *p == '\n' || *p == '#' || *p == ';'); 2244 if ((*buf)[--bytes] == '\n') 2245 (*buf)[bytes] = '\0'; 2246 2247 /* Strip embedded comments unless in a quoted string or escaped */ 2248 quoted = 0; 2249 for (c = p; *c != '\0'; c++) { 2250 if (*c == '\\') { 2251 c++; /* escaped */ 2252 continue; 2253 } 2254 if (*c == '"') 2255 quoted = !quoted; 2256 else if (*c == '#' && !quoted) { 2257 *c = '\0'; 2258 break; 2259 } 2260 } 2261 return p; 2262 } 2263 2264 struct if_options * 2265 default_config(struct dhcpcd_ctx *ctx) 2266 { 2267 struct if_options *ifo; 2268 2269 /* Seed our default options */ 2270 if ((ifo = calloc(1, sizeof(*ifo))) == NULL) { 2271 logerr(__func__); 2272 return NULL; 2273 } 2274 ifo->options |= DHCPCD_IF_UP | DHCPCD_LINK | DHCPCD_INITIAL_DELAY; 2275 ifo->timeout = DEFAULT_TIMEOUT; 2276 ifo->reboot = DEFAULT_REBOOT; 2277 ifo->metric = -1; 2278 ifo->auth.options |= DHCPCD_AUTH_REQUIRE; 2279 TAILQ_INIT(&ifo->routes); 2280 #ifdef AUTH 2281 TAILQ_INIT(&ifo->auth.tokens); 2282 #endif 2283 2284 /* Inherit some global defaults */ 2285 if (ctx->options & DHCPCD_PERSISTENT) 2286 ifo->options |= DHCPCD_PERSISTENT; 2287 if (ctx->options & DHCPCD_SLAACPRIVATE) 2288 ifo->options |= DHCPCD_SLAACPRIVATE; 2289 2290 return ifo; 2291 } 2292 2293 struct if_options * 2294 read_config(struct dhcpcd_ctx *ctx, 2295 const char *ifname, const char *ssid, const char *profile) 2296 { 2297 struct if_options *ifo; 2298 FILE *fp; 2299 struct stat sb; 2300 char *line, *buf, *option, *p; 2301 size_t buflen; 2302 ssize_t vlen; 2303 int skip, have_profile, new_block, had_block; 2304 #ifndef EMBEDDED_CONFIG 2305 const char * const *e; 2306 size_t ol; 2307 #endif 2308 #if !defined(INET) || !defined(INET6) 2309 size_t i; 2310 struct dhcp_opt *opt; 2311 #endif 2312 struct dhcp_opt *ldop, *edop; 2313 2314 /* Seed our default options */ 2315 if ((ifo = default_config(ctx)) == NULL) 2316 return NULL; 2317 ifo->options |= DHCPCD_DAEMONISE | DHCPCD_GATEWAY; 2318 #ifdef PLUGIN_DEV 2319 ifo->options |= DHCPCD_DEV; 2320 #endif 2321 #ifdef INET 2322 ifo->options |= DHCPCD_IPV4 | DHCPCD_ARP | DHCPCD_DHCP | DHCPCD_IPV4LL; 2323 #endif 2324 #ifdef INET6 2325 ifo->options |= DHCPCD_IPV6 | DHCPCD_IPV6RS; 2326 ifo->options |= DHCPCD_IPV6RA_AUTOCONF | DHCPCD_IPV6RA_REQRDNSS; 2327 ifo->options |= DHCPCD_DHCP6; 2328 #endif 2329 2330 vlen = dhcp_vendor((char *)ifo->vendorclassid + 1, 2331 sizeof(ifo->vendorclassid) - 1); 2332 ifo->vendorclassid[0] = (uint8_t)(vlen == -1 ? 0 : vlen); 2333 2334 buf = NULL; 2335 buflen = 0; 2336 2337 /* Parse our embedded options file */ 2338 if (ifname == NULL && !(ctx->options & DHCPCD_PRINT_PIDFILE)) { 2339 /* Space for initial estimates */ 2340 #if defined(INET) && defined(INITDEFINES) 2341 ifo->dhcp_override = 2342 calloc(INITDEFINES, sizeof(*ifo->dhcp_override)); 2343 if (ifo->dhcp_override == NULL) 2344 logerr(__func__); 2345 else 2346 ifo->dhcp_override_len = INITDEFINES; 2347 #endif 2348 2349 #if defined(INET6) && defined(INITDEFINENDS) 2350 ifo->nd_override = 2351 calloc(INITDEFINENDS, sizeof(*ifo->nd_override)); 2352 if (ifo->nd_override == NULL) 2353 logerr(__func__); 2354 else 2355 ifo->nd_override_len = INITDEFINENDS; 2356 #endif 2357 #if defined(INET6) && defined(INITDEFINE6S) 2358 ifo->dhcp6_override = 2359 calloc(INITDEFINE6S, sizeof(*ifo->dhcp6_override)); 2360 if (ifo->dhcp6_override == NULL) 2361 logerr(__func__); 2362 else 2363 ifo->dhcp6_override_len = INITDEFINE6S; 2364 #endif 2365 2366 /* Now load our embedded config */ 2367 #ifdef EMBEDDED_CONFIG 2368 fp = fopen(EMBEDDED_CONFIG, "r"); 2369 if (fp == NULL) 2370 logerr("%s: fopen `%s'", __func__, EMBEDDED_CONFIG); 2371 2372 while (fp && (line = get_line(&buf, &buflen, fp))) { 2373 #else 2374 buflen = 80; 2375 buf = malloc(buflen); 2376 if (buf == NULL) { 2377 logerr(__func__); 2378 free_options(ctx, ifo); 2379 return NULL; 2380 } 2381 ldop = edop = NULL; 2382 for (e = dhcpcd_embedded_conf; *e; e++) { 2383 ol = strlen(*e) + 1; 2384 if (ol > buflen) { 2385 char *nbuf; 2386 2387 buflen = ol; 2388 nbuf = realloc(buf, buflen); 2389 if (nbuf == NULL) { 2390 logerr(__func__); 2391 free(buf); 2392 free_options(ctx, ifo); 2393 return NULL; 2394 } 2395 buf = nbuf; 2396 } 2397 memcpy(buf, *e, ol); 2398 line = buf; 2399 #endif 2400 option = strsep(&line, " \t"); 2401 if (line) 2402 line = strskipwhite(line); 2403 /* Trim trailing whitespace */ 2404 if (line) { 2405 p = line + strlen(line) - 1; 2406 while (p != line && 2407 (*p == ' ' || *p == '\t') && 2408 *(p - 1) != '\\') 2409 *p-- = '\0'; 2410 } 2411 parse_config_line(ctx, NULL, ifo, option, line, 2412 &ldop, &edop); 2413 2414 } 2415 2416 #ifdef EMBEDDED_CONFIG 2417 if (fp) 2418 fclose(fp); 2419 #endif 2420 #ifdef INET 2421 ctx->dhcp_opts = ifo->dhcp_override; 2422 ctx->dhcp_opts_len = ifo->dhcp_override_len; 2423 #else 2424 for (i = 0, opt = ifo->dhcp_override; 2425 i < ifo->dhcp_override_len; 2426 i++, opt++) 2427 free_dhcp_opt_embenc(opt); 2428 free(ifo->dhcp_override); 2429 #endif 2430 ifo->dhcp_override = NULL; 2431 ifo->dhcp_override_len = 0; 2432 2433 #ifdef INET6 2434 ctx->nd_opts = ifo->nd_override; 2435 ctx->nd_opts_len = ifo->nd_override_len; 2436 ctx->dhcp6_opts = ifo->dhcp6_override; 2437 ctx->dhcp6_opts_len = ifo->dhcp6_override_len; 2438 #else 2439 for (i = 0, opt = ifo->nd_override; 2440 i < ifo->nd_override_len; 2441 i++, opt++) 2442 free_dhcp_opt_embenc(opt); 2443 free(ifo->nd_override); 2444 for (i = 0, opt = ifo->dhcp6_override; 2445 i < ifo->dhcp6_override_len; 2446 i++, opt++) 2447 free_dhcp_opt_embenc(opt); 2448 free(ifo->dhcp6_override); 2449 #endif 2450 ifo->nd_override = NULL; 2451 ifo->nd_override_len = 0; 2452 ifo->dhcp6_override = NULL; 2453 ifo->dhcp6_override_len = 0; 2454 2455 ctx->vivso = ifo->vivso_override; 2456 ctx->vivso_len = ifo->vivso_override_len; 2457 ifo->vivso_override = NULL; 2458 ifo->vivso_override_len = 0; 2459 } 2460 2461 /* Parse our options file */ 2462 fp = fopen(ctx->cffile, "r"); 2463 if (fp == NULL) { 2464 /* dhcpcd can continue without it, but no DNS options 2465 * would be requested ... */ 2466 logwarn("%s: fopen `%s'", __func__, ctx->cffile); 2467 free(buf); 2468 return ifo; 2469 } 2470 if (stat(ctx->cffile, &sb) == 0) 2471 ifo->mtime = sb.st_mtime; 2472 2473 ldop = edop = NULL; 2474 skip = have_profile = new_block = 0; 2475 had_block = ifname == NULL ? 1 : 0; 2476 while ((line = get_line(&buf, &buflen, fp))) { 2477 option = strsep(&line, " \t"); 2478 if (line) 2479 line = strskipwhite(line); 2480 /* Trim trailing whitespace */ 2481 if (line) { 2482 p = line + strlen(line) - 1; 2483 while (p != line && 2484 (*p == ' ' || *p == '\t') && 2485 *(p - 1) != '\\') 2486 *p-- = '\0'; 2487 } 2488 if (skip == 0 && new_block) { 2489 had_block = 1; 2490 new_block = 0; 2491 ifo->options &= ~DHCPCD_WAITOPTS; 2492 } 2493 /* Start of an interface block, skip if not ours */ 2494 if (strcmp(option, "interface") == 0) { 2495 char **n; 2496 2497 new_block = 1; 2498 if (line == NULL) { 2499 /* No interface given */ 2500 skip = 1; 2501 continue; 2502 } 2503 if (ifname && strcmp(line, ifname) == 0) 2504 skip = 0; 2505 else 2506 skip = 1; 2507 if (ifname) 2508 continue; 2509 2510 n = reallocarray(ctx->ifcv, 2511 (size_t)ctx->ifcc + 1, sizeof(char *)); 2512 if (n == NULL) { 2513 logerr(__func__); 2514 continue; 2515 } 2516 ctx->ifcv = n; 2517 ctx->ifcv[ctx->ifcc] = strdup(line); 2518 if (ctx->ifcv[ctx->ifcc] == NULL) { 2519 logerr(__func__); 2520 continue; 2521 } 2522 ctx->ifcc++; 2523 continue; 2524 } 2525 /* Start of an ssid block, skip if not ours */ 2526 if (strcmp(option, "ssid") == 0) { 2527 new_block = 1; 2528 if (ssid && line && strcmp(line, ssid) == 0) 2529 skip = 0; 2530 else 2531 skip = 1; 2532 continue; 2533 } 2534 /* Start of a profile block, skip if not ours */ 2535 if (strcmp(option, "profile") == 0) { 2536 new_block = 1; 2537 if (profile && line && strcmp(line, profile) == 0) { 2538 skip = 0; 2539 have_profile = 1; 2540 } else 2541 skip = 1; 2542 continue; 2543 } 2544 /* Skip arping if we have selected a profile but not parsing 2545 * one. */ 2546 if (profile && !have_profile && strcmp(option, "arping") == 0) 2547 continue; 2548 if (skip) 2549 continue; 2550 parse_config_line(ctx, ifname, ifo, option, line, &ldop, &edop); 2551 } 2552 fclose(fp); 2553 free(buf); 2554 2555 if (profile && !have_profile) { 2556 free_options(ctx, ifo); 2557 errno = ENOENT; 2558 return NULL; 2559 } 2560 2561 if (!had_block) 2562 ifo->options &= ~DHCPCD_WAITOPTS; 2563 finish_config(ifo); 2564 return ifo; 2565 } 2566 2567 int 2568 add_options(struct dhcpcd_ctx *ctx, const char *ifname, 2569 struct if_options *ifo, int argc, char **argv) 2570 { 2571 int oi, opt, r; 2572 unsigned long long wait_opts; 2573 2574 if (argc == 0) 2575 return 1; 2576 2577 optind = 0; 2578 r = 1; 2579 /* Don't apply the command line wait options to each interface, 2580 * only use the dhcpcd.conf entry for that. */ 2581 if (ifname != NULL) 2582 wait_opts = ifo->options & DHCPCD_WAITOPTS; 2583 while ((opt = getopt_long(argc, argv, 2584 ctx->options & DHCPCD_PRINT_PIDFILE ? NOERR_IF_OPTS : IF_OPTS, 2585 cf_options, &oi)) != -1) 2586 { 2587 r = parse_option(ctx, ifname, ifo, opt, optarg, NULL, NULL); 2588 if (r != 1) 2589 break; 2590 } 2591 if (ifname != NULL) { 2592 ifo->options &= ~DHCPCD_WAITOPTS; 2593 ifo->options |= wait_opts; 2594 } 2595 2596 finish_config(ifo); 2597 return r; 2598 } 2599 2600 void 2601 free_options(struct dhcpcd_ctx *ctx, struct if_options *ifo) 2602 { 2603 size_t i; 2604 struct dhcp_opt *opt; 2605 struct vivco *vo; 2606 #ifdef AUTH 2607 struct token *token; 2608 #endif 2609 2610 if (ifo) { 2611 if (ifo->environ) { 2612 i = 0; 2613 while (ifo->environ[i]) 2614 free(ifo->environ[i++]); 2615 free(ifo->environ); 2616 } 2617 if (ifo->config) { 2618 i = 0; 2619 while (ifo->config[i]) 2620 free(ifo->config[i++]); 2621 free(ifo->config); 2622 } 2623 rt_headclear0(ctx, &ifo->routes, AF_UNSPEC); 2624 free(ifo->script); 2625 free(ifo->arping); 2626 free(ifo->blacklist); 2627 free(ifo->fallback); 2628 2629 for (opt = ifo->dhcp_override; 2630 ifo->dhcp_override_len > 0; 2631 opt++, ifo->dhcp_override_len--) 2632 free_dhcp_opt_embenc(opt); 2633 free(ifo->dhcp_override); 2634 for (opt = ifo->nd_override; 2635 ifo->nd_override_len > 0; 2636 opt++, ifo->nd_override_len--) 2637 free_dhcp_opt_embenc(opt); 2638 free(ifo->nd_override); 2639 for (opt = ifo->dhcp6_override; 2640 ifo->dhcp6_override_len > 0; 2641 opt++, ifo->dhcp6_override_len--) 2642 free_dhcp_opt_embenc(opt); 2643 free(ifo->dhcp6_override); 2644 for (vo = ifo->vivco; 2645 ifo->vivco_len > 0; 2646 vo++, ifo->vivco_len--) 2647 free(vo->data); 2648 free(ifo->vivco); 2649 for (opt = ifo->vivso_override; 2650 ifo->vivso_override_len > 0; 2651 opt++, ifo->vivso_override_len--) 2652 free_dhcp_opt_embenc(opt); 2653 free(ifo->vivso_override); 2654 2655 #if defined(INET6) && !defined(SMALL) 2656 for (; ifo->ia_len > 0; ifo->ia_len--) 2657 free(ifo->ia[ifo->ia_len - 1].sla); 2658 #endif 2659 free(ifo->ia); 2660 2661 #ifdef AUTH 2662 while ((token = TAILQ_FIRST(&ifo->auth.tokens))) { 2663 TAILQ_REMOVE(&ifo->auth.tokens, token, next); 2664 if (token->realm_len) 2665 free(token->realm); 2666 free(token->key); 2667 free(token); 2668 } 2669 #endif 2670 free(ifo); 2671 } 2672 } 2673