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