1 /* SPDX-License-Identifier: BSD-2-Clause */ 2 /* 3 * dhcpcd - DHCP client daemon 4 * Copyright (c) 2006-2023 Roy Marples <roy@marples.name> 5 * All rights reserved 6 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 static const char dhcpcd_copyright[] = "Copyright (c) 2006-2023 Roy Marples"; 30 31 #include <sys/file.h> 32 #include <sys/ioctl.h> 33 #include <sys/socket.h> 34 #include <sys/stat.h> 35 #include <sys/time.h> 36 #include <sys/types.h> 37 #include <sys/uio.h> 38 #include <sys/wait.h> 39 40 #include <ctype.h> 41 #include <errno.h> 42 #include <fcntl.h> 43 #include <getopt.h> 44 #include <limits.h> 45 #include <paths.h> 46 #include <signal.h> 47 #include <stdio.h> 48 #include <stdlib.h> 49 #include <string.h> 50 #include <syslog.h> 51 #include <unistd.h> 52 #include <time.h> 53 54 #include "config.h" 55 #include "arp.h" 56 #include "common.h" 57 #include "control.h" 58 #include "dev.h" 59 #include "dhcp-common.h" 60 #include "dhcpcd.h" 61 #include "dhcp.h" 62 #include "dhcp6.h" 63 #include "duid.h" 64 #include "eloop.h" 65 #include "if.h" 66 #include "if-options.h" 67 #include "ipv4.h" 68 #include "ipv4ll.h" 69 #include "ipv6.h" 70 #include "ipv6nd.h" 71 #include "logerr.h" 72 #include "privsep.h" 73 #include "script.h" 74 75 #ifdef HAVE_CAPSICUM 76 #include <sys/capsicum.h> 77 #endif 78 #ifdef HAVE_OPENSSL 79 #include <openssl/crypto.h> 80 #endif 81 #ifdef HAVE_UTIL_H 82 #include <util.h> 83 #endif 84 85 #ifdef USE_SIGNALS 86 const int dhcpcd_signals[] = { 87 SIGTERM, 88 SIGINT, 89 SIGALRM, 90 SIGHUP, 91 SIGUSR1, 92 SIGUSR2, 93 SIGCHLD, 94 }; 95 const size_t dhcpcd_signals_len = __arraycount(dhcpcd_signals); 96 97 const int dhcpcd_signals_ignore[] = { 98 SIGPIPE, 99 }; 100 const size_t dhcpcd_signals_ignore_len = __arraycount(dhcpcd_signals_ignore); 101 #endif 102 103 const char *dhcpcd_default_script = SCRIPT; 104 105 static void 106 usage(void) 107 { 108 109 printf("usage: "PACKAGE"\t[-146ABbDdEGgHJKLMNPpqTV]\n" 110 "\t\t[-C, --nohook hook] [-c, --script script]\n" 111 "\t\t[-e, --env value] [-F, --fqdn FQDN] [-f, --config file]\n" 112 "\t\t[-h, --hostname hostname] [-I, --clientid clientid]\n" 113 "\t\t[-i, --vendorclassid vendorclassid] [-j, --logfile logfile]\n" 114 "\t\t[-l, --leasetime seconds] [-m, --metric metric]\n" 115 "\t\t[-O, --nooption option] [-o, --option option]\n" 116 "\t\t[-Q, --require option] [-r, --request address]\n" 117 "\t\t[-S, --static value]\n" 118 "\t\t[-s, --inform address[/cidr[/broadcast_address]]]\n [--inform6]" 119 "\t\t[-t, --timeout seconds] [-u, --userclass class]\n" 120 "\t\t[-v, --vendor code, value] [-W, --whitelist address[/cidr]] [-w]\n" 121 "\t\t[--waitip [4 | 6]] [-y, --reboot seconds]\n" 122 "\t\t[-X, --blacklist address[/cidr]] [-Z, --denyinterfaces pattern]\n" 123 "\t\t[-z, --allowinterfaces pattern] [--inactive] [interface] [...]\n" 124 " "PACKAGE"\t-n, --rebind [interface]\n" 125 " "PACKAGE"\t-k, --release [interface]\n" 126 " "PACKAGE"\t-U, --dumplease interface\n" 127 " "PACKAGE"\t--version\n" 128 " "PACKAGE"\t-x, --exit [interface]\n"); 129 } 130 131 static void 132 free_globals(struct dhcpcd_ctx *ctx) 133 { 134 struct dhcp_opt *opt; 135 136 if (ctx->ifac) { 137 for (; ctx->ifac > 0; ctx->ifac--) 138 free(ctx->ifav[ctx->ifac - 1]); 139 free(ctx->ifav); 140 ctx->ifav = NULL; 141 } 142 if (ctx->ifdc) { 143 for (; ctx->ifdc > 0; ctx->ifdc--) 144 free(ctx->ifdv[ctx->ifdc - 1]); 145 free(ctx->ifdv); 146 ctx->ifdv = NULL; 147 } 148 if (ctx->ifcc) { 149 for (; ctx->ifcc > 0; ctx->ifcc--) 150 free(ctx->ifcv[ctx->ifcc - 1]); 151 free(ctx->ifcv); 152 ctx->ifcv = NULL; 153 } 154 155 #ifdef INET 156 if (ctx->dhcp_opts) { 157 for (opt = ctx->dhcp_opts; 158 ctx->dhcp_opts_len > 0; 159 opt++, ctx->dhcp_opts_len--) 160 free_dhcp_opt_embenc(opt); 161 free(ctx->dhcp_opts); 162 ctx->dhcp_opts = NULL; 163 } 164 #endif 165 #ifdef INET6 166 if (ctx->nd_opts) { 167 for (opt = ctx->nd_opts; 168 ctx->nd_opts_len > 0; 169 opt++, ctx->nd_opts_len--) 170 free_dhcp_opt_embenc(opt); 171 free(ctx->nd_opts); 172 ctx->nd_opts = NULL; 173 } 174 #ifdef DHCP6 175 if (ctx->dhcp6_opts) { 176 for (opt = ctx->dhcp6_opts; 177 ctx->dhcp6_opts_len > 0; 178 opt++, ctx->dhcp6_opts_len--) 179 free_dhcp_opt_embenc(opt); 180 free(ctx->dhcp6_opts); 181 ctx->dhcp6_opts = NULL; 182 } 183 #endif 184 #endif 185 if (ctx->vivso) { 186 for (opt = ctx->vivso; 187 ctx->vivso_len > 0; 188 opt++, ctx->vivso_len--) 189 free_dhcp_opt_embenc(opt); 190 free(ctx->vivso); 191 ctx->vivso = NULL; 192 } 193 } 194 195 static void 196 handle_exit_timeout(void *arg) 197 { 198 struct dhcpcd_ctx *ctx; 199 200 ctx = arg; 201 logerrx("timed out"); 202 if (!(ctx->options & DHCPCD_MANAGER)) { 203 struct interface *ifp; 204 205 TAILQ_FOREACH(ifp, ctx->ifaces, next) { 206 if (ifp->active == IF_ACTIVE_USER) 207 script_runreason(ifp, "STOPPED"); 208 } 209 eloop_exit(ctx->eloop, EXIT_FAILURE); 210 return; 211 } 212 ctx->options |= DHCPCD_NOWAITIP; 213 dhcpcd_daemonise(ctx); 214 } 215 216 static const char * 217 dhcpcd_af(int af) 218 { 219 220 switch (af) { 221 case AF_UNSPEC: 222 return "IP"; 223 case AF_INET: 224 return "IPv4"; 225 case AF_INET6: 226 return "IPv6"; 227 default: 228 return NULL; 229 } 230 } 231 232 int 233 dhcpcd_ifafwaiting(const struct interface *ifp) 234 { 235 unsigned long long opts; 236 bool foundany = false; 237 238 if (ifp->active != IF_ACTIVE_USER) 239 return AF_MAX; 240 241 #define DHCPCD_WAITALL (DHCPCD_WAITIP4 | DHCPCD_WAITIP6) 242 opts = ifp->options->options; 243 #ifdef INET 244 if (opts & DHCPCD_WAITIP4 || 245 (opts & DHCPCD_WAITIP && !(opts & DHCPCD_WAITALL))) 246 { 247 bool foundaddr = ipv4_hasaddr(ifp); 248 249 if (opts & DHCPCD_WAITIP4 && !foundaddr) 250 return AF_INET; 251 if (foundaddr) 252 foundany = true; 253 } 254 #endif 255 #ifdef INET6 256 if (opts & DHCPCD_WAITIP6 || 257 (opts & DHCPCD_WAITIP && !(opts & DHCPCD_WAITALL))) 258 { 259 bool foundaddr = ipv6_hasaddr(ifp); 260 261 if (opts & DHCPCD_WAITIP6 && !foundaddr) 262 return AF_INET6; 263 if (foundaddr) 264 foundany = true; 265 } 266 #endif 267 268 if (opts & DHCPCD_WAITIP && !(opts & DHCPCD_WAITALL) && !foundany) 269 return AF_UNSPEC; 270 return AF_MAX; 271 } 272 273 int 274 dhcpcd_afwaiting(const struct dhcpcd_ctx *ctx) 275 { 276 unsigned long long opts; 277 const struct interface *ifp; 278 int af; 279 280 if (!(ctx->options & DHCPCD_WAITOPTS)) 281 return AF_MAX; 282 283 opts = ctx->options; 284 TAILQ_FOREACH(ifp, ctx->ifaces, next) { 285 #ifdef INET 286 if (opts & (DHCPCD_WAITIP | DHCPCD_WAITIP4) && 287 ipv4_hasaddr(ifp)) 288 opts &= ~(DHCPCD_WAITIP | DHCPCD_WAITIP4); 289 #endif 290 #ifdef INET6 291 if (opts & (DHCPCD_WAITIP | DHCPCD_WAITIP6) && 292 ipv6_hasaddr(ifp)) 293 opts &= ~(DHCPCD_WAITIP | DHCPCD_WAITIP6); 294 #endif 295 if (!(opts & DHCPCD_WAITOPTS)) 296 break; 297 } 298 if (opts & DHCPCD_WAITIP) 299 af = AF_UNSPEC; 300 else if (opts & DHCPCD_WAITIP4) 301 af = AF_INET; 302 else if (opts & DHCPCD_WAITIP6) 303 af = AF_INET6; 304 else 305 return AF_MAX; 306 return af; 307 } 308 309 static int 310 dhcpcd_ipwaited(struct dhcpcd_ctx *ctx) 311 { 312 struct interface *ifp; 313 int af; 314 315 TAILQ_FOREACH(ifp, ctx->ifaces, next) { 316 if ((af = dhcpcd_ifafwaiting(ifp)) != AF_MAX) { 317 logdebugx("%s: waiting for an %s address", 318 ifp->name, dhcpcd_af(af)); 319 return 0; 320 } 321 } 322 323 if ((af = dhcpcd_afwaiting(ctx)) != AF_MAX) { 324 logdebugx("waiting for an %s address", 325 dhcpcd_af(af)); 326 return 0; 327 } 328 329 return 1; 330 } 331 332 #ifndef THERE_IS_NO_FORK 333 void 334 dhcpcd_daemonised(struct dhcpcd_ctx *ctx) 335 { 336 unsigned int logopts = loggetopts(); 337 338 /* 339 * Stop writing to stderr. 340 * On the happy path, only the manager process writes to stderr, 341 * so this just stops wasting fprintf calls to nowhere. 342 * All other calls - ie errors in privsep processes or script output, 343 * will error when printing. 344 * If we *really* want to fix that, then we need to suck 345 * stderr/stdout in the manager process and either discard it or pass 346 * it to the launcher process and then to stderr. 347 */ 348 logopts &= ~LOGERR_ERR; 349 logsetopts(logopts); 350 351 /* 352 * We need to do something with stdout/stderr to avoid SIGPIPE 353 * We know that stdin is already mapped to /dev/null 354 */ 355 dup2(STDIN_FILENO, STDOUT_FILENO); 356 dup2(STDIN_FILENO, STDERR_FILENO); 357 358 ctx->options |= DHCPCD_DAEMONISED; 359 } 360 #endif 361 362 /* Returns the pid of the child, otherwise 0. */ 363 void 364 dhcpcd_daemonise(struct dhcpcd_ctx *ctx) 365 { 366 #ifdef THERE_IS_NO_FORK 367 eloop_timeout_delete(ctx->eloop, handle_exit_timeout, ctx); 368 errno = ENOSYS; 369 return; 370 #else 371 int i; 372 unsigned int logopts = loggetopts(); 373 374 if (ctx->options & DHCPCD_DAEMONISE && 375 !(ctx->options & (DHCPCD_DAEMONISED | DHCPCD_NOWAITIP))) 376 { 377 if (!dhcpcd_ipwaited(ctx)) 378 return; 379 } 380 381 if (ctx->options & DHCPCD_ONESHOT) { 382 loginfox("exiting due to oneshot"); 383 eloop_exit(ctx->eloop, EXIT_SUCCESS); 384 return; 385 } 386 387 eloop_timeout_delete(ctx->eloop, handle_exit_timeout, ctx); 388 if (ctx->options & DHCPCD_DAEMONISED || 389 !(ctx->options & DHCPCD_DAEMONISE)) 390 return; 391 392 /* Don't use loginfo because this makes no sense in a log. */ 393 if (!(logopts & LOGERR_QUIET) && ctx->stderr_valid) 394 (void)fprintf(stderr, 395 "forked to background, child pid %d\n", getpid()); 396 397 #ifdef PRIVSEP 398 ps_daemonised(ctx); 399 #else 400 dhcpcd_daemonised(ctx); 401 #endif 402 403 i = EXIT_SUCCESS; 404 if (write(ctx->fork_fd, &i, sizeof(i)) == -1) 405 logerr("write"); 406 ctx->options |= DHCPCD_DAEMONISED; 407 eloop_event_delete(ctx->eloop, ctx->fork_fd); 408 close(ctx->fork_fd); 409 ctx->fork_fd = -1; 410 #endif 411 } 412 413 static void 414 dhcpcd_drop(struct interface *ifp, int stop) 415 { 416 417 #ifdef DHCP6 418 dhcp6_drop(ifp, stop ? NULL : "EXPIRE6"); 419 #endif 420 #ifdef INET6 421 ipv6nd_drop(ifp); 422 ipv6_drop(ifp); 423 #endif 424 #ifdef IPV4LL 425 ipv4ll_drop(ifp); 426 #endif 427 #ifdef INET 428 dhcp_drop(ifp, stop ? "STOP" : "EXPIRE"); 429 #endif 430 #ifdef ARP 431 arp_drop(ifp); 432 #endif 433 #if !defined(DHCP6) && !defined(DHCP) 434 UNUSED(stop); 435 #endif 436 } 437 438 static void 439 stop_interface(struct interface *ifp, const char *reason) 440 { 441 struct dhcpcd_ctx *ctx; 442 443 ctx = ifp->ctx; 444 loginfox("%s: removing interface", ifp->name); 445 ifp->options->options |= DHCPCD_STOPPING; 446 447 dhcpcd_drop(ifp, 1); 448 script_runreason(ifp, reason == NULL ? "STOPPED" : reason); 449 450 /* Delete all timeouts for the interfaces */ 451 eloop_q_timeout_delete(ctx->eloop, ELOOP_QUEUE_ALL, NULL, ifp); 452 453 /* De-activate the interface */ 454 ifp->active = IF_INACTIVE; 455 ifp->options->options &= ~DHCPCD_STOPPING; 456 457 if (!(ctx->options & (DHCPCD_MANAGER | DHCPCD_TEST))) 458 eloop_exit(ctx->eloop, EXIT_FAILURE); 459 } 460 461 static void 462 configure_interface1(struct interface *ifp) 463 { 464 struct if_options *ifo = ifp->options; 465 466 /* Do any platform specific configuration */ 467 if_conf(ifp); 468 469 /* If we want to release a lease, we can't really persist the 470 * address either. */ 471 if (ifo->options & DHCPCD_RELEASE) 472 ifo->options &= ~DHCPCD_PERSISTENT; 473 474 if (ifp->flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) { 475 ifo->options &= ~DHCPCD_ARP; 476 if (!(ifp->flags & IFF_MULTICAST)) 477 ifo->options &= ~DHCPCD_IPV6RS; 478 if (!(ifo->options & (DHCPCD_INFORM | DHCPCD_WANTDHCP))) 479 ifo->options |= DHCPCD_STATIC; 480 } 481 482 if (ifo->metric != -1) 483 ifp->metric = (unsigned int)ifo->metric; 484 485 #ifdef INET6 486 /* We want to setup INET6 on the interface as soon as possible. */ 487 if (ifp->active == IF_ACTIVE_USER && 488 ifo->options & DHCPCD_IPV6 && 489 !(ifp->ctx->options & (DHCPCD_DUMPLEASE | DHCPCD_TEST))) 490 { 491 /* If not doing any DHCP, disable the RDNSS requirement. */ 492 if (!(ifo->options & (DHCPCD_DHCP | DHCPCD_DHCP6))) 493 ifo->options &= ~DHCPCD_IPV6RA_REQRDNSS; 494 if_setup_inet6(ifp); 495 } 496 #endif 497 498 if (!(ifo->options & DHCPCD_IAID)) { 499 /* 500 * An IAID is for identifying a unqiue interface within 501 * the client. It is 4 bytes long. Working out a default 502 * value is problematic. 503 * 504 * Interface name and number are not stable 505 * between different OS's. Some OS's also cannot make 506 * up their mind what the interface should be called 507 * (yes, udev, I'm looking at you). 508 * Also, the name could be longer than 4 bytes. 509 * Also, with pluggable interfaces the name and index 510 * could easily get swapped per actual interface. 511 * 512 * The MAC address is 6 bytes long, the final 3 513 * being unique to the manufacturer and the initial 3 514 * being unique to the organisation which makes it. 515 * We could use the last 4 bytes of the MAC address 516 * as the IAID as it's the most stable part given the 517 * above, but equally it's not guaranteed to be 518 * unique. 519 * 520 * Given the above, and our need to reliably work 521 * between reboots without persitent storage, 522 * generating the IAID from the MAC address is the only 523 * logical default. 524 * Saying that, if a VLANID has been specified then we 525 * can use that. It's possible that different interfaces 526 * can have the same VLANID, but this is no worse than 527 * generating the IAID from the duplicate MAC address. 528 * 529 * dhclient uses the last 4 bytes of the MAC address. 530 * dibbler uses an increamenting counter. 531 * wide-dhcpv6 uses 0 or a configured value. 532 * odhcp6c uses 1. 533 * Windows 7 uses the first 3 bytes of the MAC address 534 * and an unknown byte. 535 * dhcpcd-6.1.0 and earlier used the interface name, 536 * falling back to interface index if name > 4. 537 */ 538 if (ifp->vlanid != 0) { 539 uint32_t vlanid; 540 541 /* Maximal VLANID is 4095, so prefix with 0xff 542 * so we don't conflict with an interface index. */ 543 vlanid = htonl(ifp->vlanid | 0xff000000); 544 memcpy(ifo->iaid, &vlanid, sizeof(vlanid)); 545 } else if (ifo->options & DHCPCD_ANONYMOUS) 546 memset(ifo->iaid, 0, sizeof(ifo->iaid)); 547 else if (ifp->hwlen >= sizeof(ifo->iaid)) { 548 memcpy(ifo->iaid, 549 ifp->hwaddr + ifp->hwlen - sizeof(ifo->iaid), 550 sizeof(ifo->iaid)); 551 } else { 552 uint32_t len; 553 554 len = (uint32_t)strlen(ifp->name); 555 if (len <= sizeof(ifo->iaid)) { 556 memcpy(ifo->iaid, ifp->name, len); 557 if (len < sizeof(ifo->iaid)) 558 memset(ifo->iaid + len, 0, 559 sizeof(ifo->iaid) - len); 560 } else { 561 /* IAID is the same size as a uint32_t */ 562 len = htonl(ifp->index); 563 memcpy(ifo->iaid, &len, sizeof(ifo->iaid)); 564 } 565 } 566 ifo->options |= DHCPCD_IAID; 567 } 568 569 #ifdef DHCP6 570 if (ifo->ia_len == 0 && ifo->options & DHCPCD_IPV6 && 571 ifp->name[0] != '\0') 572 { 573 ifo->ia = malloc(sizeof(*ifo->ia)); 574 if (ifo->ia == NULL) 575 logerr(__func__); 576 else { 577 ifo->ia_len = 1; 578 ifo->ia->ia_type = D6_OPTION_IA_NA; 579 memcpy(ifo->ia->iaid, ifo->iaid, sizeof(ifo->iaid)); 580 memset(&ifo->ia->addr, 0, sizeof(ifo->ia->addr)); 581 #ifndef SMALL 582 ifo->ia->sla = NULL; 583 ifo->ia->sla_len = 0; 584 #endif 585 } 586 } else { 587 size_t i; 588 589 for (i = 0; i < ifo->ia_len; i++) { 590 if (!ifo->ia[i].iaid_set) { 591 memcpy(&ifo->ia[i].iaid, ifo->iaid, 592 sizeof(ifo->ia[i].iaid)); 593 ifo->ia[i].iaid_set = 1; 594 } 595 } 596 } 597 #endif 598 599 /* If root is network mounted, we don't want to kill the connection 600 * if the DHCP server goes the way of the dodo OR dhcpcd is rebooting 601 * and the lease file has expired. */ 602 if (is_root_local() == 0) 603 ifo->options |= DHCPCD_LASTLEASE_EXTEND; 604 } 605 606 int 607 dhcpcd_selectprofile(struct interface *ifp, const char *profile) 608 { 609 struct if_options *ifo; 610 char pssid[PROFILE_LEN]; 611 612 if (ifp->ssid_len) { 613 ssize_t r; 614 615 r = print_string(pssid, sizeof(pssid), OT_ESCSTRING, 616 ifp->ssid, ifp->ssid_len); 617 if (r == -1) { 618 logerr(__func__); 619 pssid[0] = '\0'; 620 } 621 } else 622 pssid[0] = '\0'; 623 ifo = read_config(ifp->ctx, ifp->name, pssid, profile); 624 if (ifo == NULL) { 625 logdebugx("%s: no profile %s", ifp->name, profile); 626 return -1; 627 } 628 if (profile != NULL) { 629 strlcpy(ifp->profile, profile, sizeof(ifp->profile)); 630 loginfox("%s: selected profile %s", ifp->name, profile); 631 } else 632 *ifp->profile = '\0'; 633 634 free_options(ifp->ctx, ifp->options); 635 ifp->options = ifo; 636 if (profile) { 637 add_options(ifp->ctx, ifp->name, ifp->options, 638 ifp->ctx->argc, ifp->ctx->argv); 639 configure_interface1(ifp); 640 } 641 return 1; 642 } 643 644 static void 645 configure_interface(struct interface *ifp, int argc, char **argv, 646 unsigned long long options) 647 { 648 time_t old; 649 650 old = ifp->options ? ifp->options->mtime : 0; 651 dhcpcd_selectprofile(ifp, NULL); 652 if (ifp->options == NULL) { 653 /* dhcpcd cannot continue with this interface. */ 654 ifp->active = IF_INACTIVE; 655 return; 656 } 657 add_options(ifp->ctx, ifp->name, ifp->options, argc, argv); 658 ifp->options->options |= options; 659 configure_interface1(ifp); 660 661 /* If the mtime has changed drop any old lease */ 662 if (old != 0 && ifp->options->mtime != old) { 663 logwarnx("%s: config file changed, expiring leases", 664 ifp->name); 665 dhcpcd_drop(ifp, 0); 666 } 667 } 668 669 static void 670 dhcpcd_initstate2(struct interface *ifp, unsigned long long options) 671 { 672 struct if_options *ifo; 673 674 if (options) { 675 if ((ifo = default_config(ifp->ctx)) == NULL) { 676 logerr(__func__); 677 return; 678 } 679 ifo->options |= options; 680 free(ifp->options); 681 ifp->options = ifo; 682 } else 683 ifo = ifp->options; 684 685 #ifdef INET6 686 if (ifo->options & DHCPCD_IPV6 && ipv6_init(ifp->ctx) == -1) { 687 logerr(__func__); 688 ifo->options &= ~DHCPCD_IPV6; 689 } 690 #endif 691 } 692 693 static void 694 dhcpcd_initstate1(struct interface *ifp, int argc, char **argv, 695 unsigned long long options) 696 { 697 698 configure_interface(ifp, argc, argv, options); 699 if (ifp->active) 700 dhcpcd_initstate2(ifp, 0); 701 } 702 703 static void 704 dhcpcd_initstate(struct interface *ifp, unsigned long long options) 705 { 706 707 dhcpcd_initstate1(ifp, ifp->ctx->argc, ifp->ctx->argv, options); 708 } 709 710 static void 711 dhcpcd_reportssid(struct interface *ifp) 712 { 713 char pssid[IF_SSIDLEN * 4]; 714 715 if (print_string(pssid, sizeof(pssid), OT_ESCSTRING, 716 ifp->ssid, ifp->ssid_len) == -1) 717 { 718 logerr(__func__); 719 return; 720 } 721 722 loginfox("%s: connected to Access Point: %s", ifp->name, pssid); 723 } 724 725 static void 726 dhcpcd_nocarrier_roaming(struct interface *ifp) 727 { 728 729 loginfox("%s: carrier lost - roaming", ifp->name); 730 731 #ifdef ARP 732 arp_drop(ifp); 733 #endif 734 #ifdef INET 735 dhcp_abort(ifp); 736 #endif 737 #ifdef DHCP6 738 dhcp6_abort(ifp); 739 #endif 740 741 rt_build(ifp->ctx, AF_UNSPEC); 742 script_runreason(ifp, "NOCARRIER_ROAMING"); 743 } 744 745 void 746 dhcpcd_handlecarrier(struct interface *ifp, int carrier, unsigned int flags) 747 { 748 bool was_link_up = if_is_link_up(ifp); 749 bool was_roaming = if_roaming(ifp); 750 751 ifp->carrier = carrier; 752 ifp->flags = flags; 753 754 if (!if_is_link_up(ifp)) { 755 if (!ifp->active || (!was_link_up && !was_roaming)) 756 return; 757 758 /* 759 * If the interface is roaming (generally on wireless) 760 * then while we are not up, we are not down either. 761 * Preserve the network state until we either disconnect 762 * or re-connect. 763 */ 764 if (!ifp->options->randomise_hwaddr && if_roaming(ifp)) { 765 dhcpcd_nocarrier_roaming(ifp); 766 return; 767 } 768 769 loginfox("%s: carrier lost", ifp->name); 770 script_runreason(ifp, "NOCARRIER"); 771 dhcpcd_drop(ifp, 0); 772 773 if (ifp->options->randomise_hwaddr) { 774 bool is_up = ifp->flags & IFF_UP; 775 776 if (is_up) 777 if_down(ifp); 778 if (if_randomisemac(ifp) == -1 && errno != ENXIO) 779 logerr(__func__); 780 if (is_up) 781 if_up(ifp); 782 } 783 784 return; 785 } 786 787 /* 788 * At this point carrier is NOT DOWN and we have IFF_UP. 789 * We should treat LINK_UNKNOWN as up as the driver may not support 790 * link state changes. 791 * The consideration of any other information about carrier should 792 * be handled in the OS specific if_carrier() function. 793 */ 794 if (was_link_up) 795 return; 796 797 if (ifp->active) { 798 if (carrier == LINK_UNKNOWN) 799 loginfox("%s: carrier unknown, assuming up", ifp->name); 800 else 801 loginfox("%s: carrier acquired", ifp->name); 802 } 803 804 #if !defined(__linux__) && !defined(__NetBSD__) 805 /* BSD does not emit RTM_NEWADDR or RTM_CHGADDR when the 806 * hardware address changes so we have to go 807 * through the disovery process to work it out. */ 808 dhcpcd_handleinterface(ifp->ctx, 0, ifp->name); 809 #endif 810 811 if (ifp->wireless) { 812 uint8_t ossid[IF_SSIDLEN]; 813 size_t olen; 814 815 olen = ifp->ssid_len; 816 memcpy(ossid, ifp->ssid, ifp->ssid_len); 817 if_getssid(ifp); 818 819 /* If we changed SSID network, drop leases */ 820 if ((ifp->ssid_len != olen || 821 memcmp(ifp->ssid, ossid, ifp->ssid_len)) && ifp->active) 822 { 823 dhcpcd_reportssid(ifp); 824 dhcpcd_drop(ifp, 0); 825 #ifdef IPV4LL 826 ipv4ll_reset(ifp); 827 #endif 828 } 829 } 830 831 if (!ifp->active) 832 return; 833 834 dhcpcd_initstate(ifp, 0); 835 script_runreason(ifp, "CARRIER"); 836 837 #ifdef INET6 838 /* Set any IPv6 Routers we remembered to expire faster than they 839 * would normally as we maybe on a new network. */ 840 ipv6nd_startexpire(ifp); 841 #ifdef IPV6_MANAGETEMPADDR 842 /* RFC4941 Section 3.5 */ 843 ipv6_regentempaddrs(ifp); 844 #endif 845 #endif 846 847 dhcpcd_startinterface(ifp); 848 } 849 850 static void 851 warn_iaid_conflict(struct interface *ifp, uint16_t ia_type, uint8_t *iaid) 852 { 853 struct interface *ifn; 854 #ifdef INET6 855 size_t i; 856 struct if_ia *ia; 857 #endif 858 859 TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) { 860 if (ifn == ifp || !ifn->active) 861 continue; 862 if (ifn->options->options & DHCPCD_ANONYMOUS) 863 continue; 864 if (ia_type == 0 && 865 memcmp(ifn->options->iaid, iaid, 866 sizeof(ifn->options->iaid)) == 0) 867 break; 868 #ifdef INET6 869 for (i = 0; i < ifn->options->ia_len; i++) { 870 ia = &ifn->options->ia[i]; 871 if (ia->ia_type == ia_type && 872 memcmp(ia->iaid, iaid, sizeof(ia->iaid)) == 0) 873 break; 874 } 875 #endif 876 } 877 878 /* This is only a problem if the interfaces are on the same network. */ 879 if (ifn) 880 logerrx("%s: IAID conflicts with one assigned to %s", 881 ifp->name, ifn->name); 882 } 883 884 static void 885 dhcpcd_initduid(struct dhcpcd_ctx *ctx, struct interface *ifp) 886 { 887 char buf[DUID_LEN * 3]; 888 889 if (ctx->duid != NULL) { 890 if (ifp == NULL) 891 goto log; 892 return; 893 } 894 895 duid_init(ctx, ifp); 896 if (ctx->duid == NULL) 897 return; 898 899 log: 900 loginfox("DUID %s", 901 hwaddr_ntoa(ctx->duid, ctx->duid_len, buf, sizeof(buf))); 902 } 903 904 void 905 dhcpcd_startinterface(void *arg) 906 { 907 struct interface *ifp = arg; 908 struct if_options *ifo = ifp->options; 909 910 if (ifo->options & DHCPCD_LINK && !if_is_link_up(ifp)) { 911 loginfox("%s: waiting for carrier", ifp->name); 912 return; 913 } 914 915 if (ifo->options & (DHCPCD_DUID | DHCPCD_IPV6) && 916 !(ifo->options & DHCPCD_ANONYMOUS)) 917 { 918 char buf[sizeof(ifo->iaid) * 3]; 919 #ifdef INET6 920 size_t i; 921 struct if_ia *ia; 922 #endif 923 924 /* Try and init DUID from the interface hardware address */ 925 dhcpcd_initduid(ifp->ctx, ifp); 926 927 /* Report IAIDs */ 928 loginfox("%s: IAID %s", ifp->name, 929 hwaddr_ntoa(ifo->iaid, sizeof(ifo->iaid), 930 buf, sizeof(buf))); 931 warn_iaid_conflict(ifp, 0, ifo->iaid); 932 933 #ifdef INET6 934 for (i = 0; i < ifo->ia_len; i++) { 935 ia = &ifo->ia[i]; 936 if (memcmp(ifo->iaid, ia->iaid, sizeof(ifo->iaid))) { 937 loginfox("%s: IA type %u IAID %s", 938 ifp->name, ia->ia_type, 939 hwaddr_ntoa(ia->iaid, sizeof(ia->iaid), 940 buf, sizeof(buf))); 941 warn_iaid_conflict(ifp, ia->ia_type, ia->iaid); 942 } 943 } 944 #endif 945 } 946 947 #ifdef INET6 948 if (ifo->options & DHCPCD_IPV6 && ipv6_start(ifp) == -1) { 949 logerr("%s: ipv6_start", ifp->name); 950 ifo->options &= ~DHCPCD_IPV6; 951 } 952 953 if (ifo->options & DHCPCD_IPV6) { 954 if (ifp->active == IF_ACTIVE_USER) { 955 ipv6_startstatic(ifp); 956 957 if (ifo->options & DHCPCD_IPV6RS) 958 ipv6nd_startrs(ifp); 959 } 960 961 #ifdef DHCP6 962 /* DHCPv6 could be turned off, but the interface 963 * is still delegated to. */ 964 if (ifp->active) 965 dhcp6_find_delegates(ifp); 966 967 if (ifo->options & DHCPCD_DHCP6) { 968 if (ifp->active == IF_ACTIVE_USER) { 969 enum DH6S d6_state; 970 971 if (ifo->options & DHCPCD_IA_FORCED) 972 d6_state = DH6S_INIT; 973 else if (ifo->options & DHCPCD_INFORM6) 974 d6_state = DH6S_INFORM; 975 else 976 d6_state = DH6S_CONFIRM; 977 if (dhcp6_start(ifp, d6_state) == -1) 978 logerr("%s: dhcp6_start", ifp->name); 979 } 980 } 981 #endif 982 } 983 #endif 984 985 #ifdef INET 986 if (ifo->options & DHCPCD_IPV4 && ifp->active == IF_ACTIVE_USER) { 987 /* Ensure we have an IPv4 state before starting DHCP */ 988 if (ipv4_getstate(ifp) != NULL) 989 dhcp_start(ifp); 990 } 991 #endif 992 } 993 994 static void 995 dhcpcd_prestartinterface(void *arg) 996 { 997 struct interface *ifp = arg; 998 struct dhcpcd_ctx *ctx = ifp->ctx; 999 bool randmac_down; 1000 1001 if (ifp->carrier <= LINK_DOWN && 1002 ifp->options->randomise_hwaddr && 1003 ifp->flags & IFF_UP) 1004 { 1005 if_down(ifp); 1006 randmac_down = true; 1007 } else 1008 randmac_down = false; 1009 1010 if ((!(ctx->options & DHCPCD_MANAGER) || 1011 ifp->options->options & DHCPCD_IF_UP || randmac_down) && 1012 !(ifp->flags & IFF_UP)) 1013 { 1014 if (ifp->options->randomise_hwaddr && 1015 if_randomisemac(ifp) == -1) 1016 logerr(__func__); 1017 if (if_up(ifp) == -1) 1018 logerr(__func__); 1019 } 1020 1021 dhcpcd_startinterface(ifp); 1022 } 1023 1024 static void 1025 run_preinit(struct interface *ifp) 1026 { 1027 1028 if (ifp->ctx->options & DHCPCD_TEST) 1029 return; 1030 1031 script_runreason(ifp, "PREINIT"); 1032 if (ifp->wireless && if_is_link_up(ifp)) 1033 dhcpcd_reportssid(ifp); 1034 if (ifp->options->options & DHCPCD_LINK && ifp->carrier != LINK_UNKNOWN) 1035 script_runreason(ifp, 1036 ifp->carrier == LINK_UP ? "CARRIER" : "NOCARRIER"); 1037 } 1038 1039 void 1040 dhcpcd_activateinterface(struct interface *ifp, unsigned long long options) 1041 { 1042 1043 if (ifp->active) 1044 return; 1045 1046 ifp->active = IF_ACTIVE; 1047 dhcpcd_initstate2(ifp, options); 1048 1049 /* It's possible we might not have been able to load 1050 * a config. */ 1051 if (!ifp->active) 1052 return; 1053 1054 configure_interface1(ifp); 1055 run_preinit(ifp); 1056 dhcpcd_prestartinterface(ifp); 1057 } 1058 1059 int 1060 dhcpcd_handleinterface(void *arg, int action, const char *ifname) 1061 { 1062 struct dhcpcd_ctx *ctx = arg; 1063 struct ifaddrs *ifaddrs; 1064 struct if_head *ifs; 1065 struct interface *ifp, *iff; 1066 const char * const argv[] = { ifname }; 1067 int e; 1068 1069 if (action == -1) { 1070 ifp = if_find(ctx->ifaces, ifname); 1071 if (ifp == NULL) { 1072 errno = ESRCH; 1073 return -1; 1074 } 1075 if (ifp->active) { 1076 logdebugx("%s: interface departed", ifp->name); 1077 stop_interface(ifp, "DEPARTED"); 1078 } 1079 TAILQ_REMOVE(ctx->ifaces, ifp, next); 1080 if_free(ifp); 1081 return 0; 1082 } 1083 1084 ifs = if_discover(ctx, &ifaddrs, -1, UNCONST(argv)); 1085 if (ifs == NULL) { 1086 logerr(__func__); 1087 return -1; 1088 } 1089 1090 ifp = if_find(ifs, ifname); 1091 if (ifp == NULL) { 1092 /* This can happen if an interface is quickly added 1093 * and then removed. */ 1094 errno = ENOENT; 1095 e = -1; 1096 goto out; 1097 } 1098 e = 1; 1099 1100 /* Check if we already have the interface */ 1101 iff = if_find(ctx->ifaces, ifp->name); 1102 1103 if (iff != NULL) { 1104 if (iff->active) 1105 logdebugx("%s: interface updated", iff->name); 1106 /* The flags and hwaddr could have changed */ 1107 iff->flags = ifp->flags; 1108 iff->hwlen = ifp->hwlen; 1109 if (ifp->hwlen != 0) 1110 memcpy(iff->hwaddr, ifp->hwaddr, iff->hwlen); 1111 } else { 1112 TAILQ_REMOVE(ifs, ifp, next); 1113 TAILQ_INSERT_TAIL(ctx->ifaces, ifp, next); 1114 if (ifp->active) { 1115 logdebugx("%s: interface added", ifp->name); 1116 dhcpcd_initstate(ifp, 0); 1117 run_preinit(ifp); 1118 } 1119 iff = ifp; 1120 } 1121 1122 if (action > 0) { 1123 if_learnaddrs(ctx, ifs, &ifaddrs); 1124 if (iff->active) 1125 dhcpcd_prestartinterface(iff); 1126 } 1127 1128 out: 1129 /* Free our discovered list */ 1130 while ((ifp = TAILQ_FIRST(ifs))) { 1131 TAILQ_REMOVE(ifs, ifp, next); 1132 if_free(ifp); 1133 } 1134 free(ifs); 1135 if_freeifaddrs(ctx, &ifaddrs); 1136 1137 return e; 1138 } 1139 1140 static void 1141 dhcpcd_handlelink(void *arg, unsigned short events) 1142 { 1143 struct dhcpcd_ctx *ctx = arg; 1144 1145 if (events != ELE_READ) 1146 logerrx("%s: unexpected event 0x%04x", __func__, events); 1147 1148 if (if_handlelink(ctx) == -1) { 1149 if (errno == ENOBUFS || errno == ENOMEM) { 1150 dhcpcd_linkoverflow(ctx); 1151 return; 1152 } 1153 if (errno != ENOTSUP) 1154 logerr(__func__); 1155 } 1156 } 1157 1158 static void 1159 dhcpcd_checkcarrier(void *arg) 1160 { 1161 struct interface *ifp0 = arg, *ifp; 1162 1163 ifp = if_find(ifp0->ctx->ifaces, ifp0->name); 1164 if (ifp == NULL || ifp->carrier == ifp0->carrier) 1165 return; 1166 1167 dhcpcd_handlecarrier(ifp, ifp0->carrier, ifp0->flags); 1168 if_free(ifp0); 1169 } 1170 1171 #ifndef SMALL 1172 static void 1173 dhcpcd_setlinkrcvbuf(struct dhcpcd_ctx *ctx) 1174 { 1175 socklen_t socklen; 1176 1177 if (ctx->link_rcvbuf == 0) 1178 return; 1179 1180 logdebugx("setting route socket receive buffer size to %d bytes", 1181 ctx->link_rcvbuf); 1182 1183 socklen = sizeof(ctx->link_rcvbuf); 1184 if (setsockopt(ctx->link_fd, SOL_SOCKET, 1185 SO_RCVBUF, &ctx->link_rcvbuf, socklen) == -1) 1186 logerr(__func__); 1187 } 1188 #endif 1189 1190 static void 1191 dhcpcd_runprestartinterface(void *arg) 1192 { 1193 struct interface *ifp = arg; 1194 1195 run_preinit(ifp); 1196 dhcpcd_prestartinterface(ifp); 1197 } 1198 1199 void 1200 dhcpcd_linkoverflow(struct dhcpcd_ctx *ctx) 1201 { 1202 socklen_t socklen; 1203 int rcvbuflen; 1204 char buf[2048]; 1205 ssize_t rlen; 1206 size_t rcnt; 1207 struct if_head *ifaces; 1208 struct ifaddrs *ifaddrs; 1209 struct interface *ifp, *ifn, *ifp1; 1210 1211 socklen = sizeof(rcvbuflen); 1212 if (getsockopt(ctx->link_fd, SOL_SOCKET, 1213 SO_RCVBUF, &rcvbuflen, &socklen) == -1) { 1214 logerr("%s: getsockopt", __func__); 1215 rcvbuflen = 0; 1216 } 1217 #ifdef __linux__ 1218 else 1219 rcvbuflen /= 2; 1220 #endif 1221 1222 logerrx("route socket overflowed (rcvbuflen %d)" 1223 " - learning interface state", rcvbuflen); 1224 1225 /* Drain the socket. 1226 * We cannot open a new one due to privsep. */ 1227 rcnt = 0; 1228 do { 1229 rlen = read(ctx->link_fd, buf, sizeof(buf)); 1230 if (++rcnt % 1000 == 0) 1231 logwarnx("drained %zu messages", rcnt); 1232 } while (rlen != -1 || errno == ENOBUFS || errno == ENOMEM); 1233 if (rcnt % 1000 != 0) 1234 logwarnx("drained %zu messages", rcnt); 1235 1236 /* Work out the current interfaces. */ 1237 ifaces = if_discover(ctx, &ifaddrs, ctx->ifc, ctx->ifv); 1238 if (ifaces == NULL) { 1239 logerr(__func__); 1240 return; 1241 } 1242 1243 /* Punt departed interfaces */ 1244 TAILQ_FOREACH_SAFE(ifp, ctx->ifaces, next, ifn) { 1245 if (if_find(ifaces, ifp->name) != NULL) 1246 continue; 1247 dhcpcd_handleinterface(ctx, -1, ifp->name); 1248 } 1249 1250 /* Add new interfaces */ 1251 while ((ifp = TAILQ_FIRST(ifaces)) != NULL ) { 1252 TAILQ_REMOVE(ifaces, ifp, next); 1253 ifp1 = if_find(ctx->ifaces, ifp->name); 1254 if (ifp1 != NULL) { 1255 /* If the interface already exists, 1256 * check carrier state. 1257 * dhcpcd_checkcarrier will free ifp. */ 1258 eloop_timeout_add_sec(ctx->eloop, 0, 1259 dhcpcd_checkcarrier, ifp); 1260 continue; 1261 } 1262 TAILQ_INSERT_TAIL(ctx->ifaces, ifp, next); 1263 if (ifp->active) { 1264 dhcpcd_initstate(ifp, 0); 1265 eloop_timeout_add_sec(ctx->eloop, 0, 1266 dhcpcd_runprestartinterface, ifp); 1267 } 1268 } 1269 free(ifaces); 1270 1271 /* Update address state. */ 1272 if_markaddrsstale(ctx->ifaces); 1273 if_learnaddrs(ctx, ctx->ifaces, &ifaddrs); 1274 if_deletestaleaddrs(ctx->ifaces); 1275 if_freeifaddrs(ctx, &ifaddrs); 1276 } 1277 1278 void 1279 dhcpcd_handlehwaddr(struct interface *ifp, 1280 uint16_t hwtype, const void *hwaddr, uint8_t hwlen) 1281 { 1282 char buf[sizeof(ifp->hwaddr) * 3]; 1283 1284 if (hwaddr == NULL || !if_valid_hwaddr(hwaddr, hwlen)) 1285 hwlen = 0; 1286 1287 if (hwlen > sizeof(ifp->hwaddr)) { 1288 errno = ENOBUFS; 1289 logerr("%s: %s", __func__, ifp->name); 1290 return; 1291 } 1292 1293 if (ifp->hwtype != hwtype) { 1294 if (ifp->active) 1295 loginfox("%s: hardware address type changed" 1296 " from %d to %d", ifp->name, ifp->hwtype, hwtype); 1297 ifp->hwtype = hwtype; 1298 } 1299 1300 if (ifp->hwlen == hwlen && 1301 (hwlen == 0 || memcmp(ifp->hwaddr, hwaddr, hwlen) == 0)) 1302 return; 1303 1304 if (ifp->active) { 1305 loginfox("%s: old hardware address: %s", ifp->name, 1306 hwaddr_ntoa(ifp->hwaddr, ifp->hwlen, buf, sizeof(buf))); 1307 loginfox("%s: new hardware address: %s", ifp->name, 1308 hwaddr_ntoa(hwaddr, hwlen, buf, sizeof(buf))); 1309 } 1310 ifp->hwlen = hwlen; 1311 if (hwaddr != NULL) 1312 memcpy(ifp->hwaddr, hwaddr, hwlen); 1313 } 1314 1315 static void 1316 if_reboot(struct interface *ifp, int argc, char **argv) 1317 { 1318 #ifdef INET 1319 unsigned long long oldopts; 1320 1321 oldopts = ifp->options->options; 1322 #endif 1323 script_runreason(ifp, "RECONFIGURE"); 1324 dhcpcd_initstate1(ifp, argc, argv, 0); 1325 #ifdef INET 1326 dhcp_reboot_newopts(ifp, oldopts); 1327 #endif 1328 #ifdef DHCP6 1329 dhcp6_reboot(ifp); 1330 #endif 1331 dhcpcd_prestartinterface(ifp); 1332 } 1333 1334 static void 1335 reload_config(struct dhcpcd_ctx *ctx) 1336 { 1337 struct if_options *ifo; 1338 1339 free_globals(ctx); 1340 if ((ifo = read_config(ctx, NULL, NULL, NULL)) == NULL) 1341 return; 1342 add_options(ctx, NULL, ifo, ctx->argc, ctx->argv); 1343 /* We need to preserve these options. */ 1344 if (ctx->options & DHCPCD_STARTED) 1345 ifo->options |= DHCPCD_STARTED; 1346 if (ctx->options & DHCPCD_MANAGER) 1347 ifo->options |= DHCPCD_MANAGER; 1348 if (ctx->options & DHCPCD_DAEMONISED) 1349 ifo->options |= DHCPCD_DAEMONISED; 1350 if (ctx->options & DHCPCD_PRIVSEP) 1351 ifo->options |= DHCPCD_PRIVSEP; 1352 ctx->options = ifo->options; 1353 free_options(ctx, ifo); 1354 } 1355 1356 static void 1357 reconf_reboot(struct dhcpcd_ctx *ctx, int action, int argc, char **argv, int oi) 1358 { 1359 int i; 1360 struct interface *ifp; 1361 1362 TAILQ_FOREACH(ifp, ctx->ifaces, next) { 1363 for (i = oi; i < argc; i++) { 1364 if (strcmp(ifp->name, argv[i]) == 0) 1365 break; 1366 } 1367 if (oi != argc && i == argc) 1368 continue; 1369 if (ifp->active == IF_ACTIVE_USER) { 1370 if (action) 1371 if_reboot(ifp, argc, argv); 1372 #ifdef INET 1373 else 1374 ipv4_applyaddr(ifp); 1375 #endif 1376 } else if (i != argc) { 1377 ifp->active = IF_ACTIVE_USER; 1378 dhcpcd_initstate1(ifp, argc, argv, 0); 1379 run_preinit(ifp); 1380 dhcpcd_prestartinterface(ifp); 1381 } 1382 } 1383 } 1384 1385 static void 1386 stop_all_interfaces(struct dhcpcd_ctx *ctx, unsigned long long opts) 1387 { 1388 struct interface *ifp; 1389 1390 ctx->options |= DHCPCD_EXITING; 1391 if (ctx->ifaces == NULL) 1392 return; 1393 1394 /* Drop the last interface first */ 1395 TAILQ_FOREACH_REVERSE(ifp, ctx->ifaces, if_head, next) { 1396 if (!ifp->active) 1397 continue; 1398 ifp->options->options |= opts; 1399 if (ifp->options->options & DHCPCD_RELEASE) 1400 ifp->options->options &= ~DHCPCD_PERSISTENT; 1401 ifp->options->options |= DHCPCD_EXITING; 1402 stop_interface(ifp, NULL); 1403 } 1404 } 1405 1406 static void 1407 dhcpcd_ifrenew(struct interface *ifp) 1408 { 1409 1410 if (!ifp->active) 1411 return; 1412 1413 if (ifp->options->options & DHCPCD_LINK && !if_is_link_up(ifp)) 1414 return; 1415 1416 #ifdef INET 1417 dhcp_renew(ifp); 1418 #endif 1419 #ifdef INET6 1420 #define DHCPCD_RARENEW (DHCPCD_IPV6 | DHCPCD_IPV6RS) 1421 if ((ifp->options->options & DHCPCD_RARENEW) == DHCPCD_RARENEW) 1422 ipv6nd_startrs(ifp); 1423 #endif 1424 #ifdef DHCP6 1425 dhcp6_renew(ifp); 1426 #endif 1427 } 1428 1429 static void 1430 dhcpcd_renew(struct dhcpcd_ctx *ctx) 1431 { 1432 struct interface *ifp; 1433 1434 TAILQ_FOREACH(ifp, ctx->ifaces, next) { 1435 dhcpcd_ifrenew(ifp); 1436 } 1437 } 1438 1439 #ifdef USE_SIGNALS 1440 #define sigmsg "received %s, %s" 1441 static volatile bool dhcpcd_exiting = false; 1442 void 1443 dhcpcd_signal_cb(int sig, void *arg) 1444 { 1445 struct dhcpcd_ctx *ctx = arg; 1446 unsigned long long opts; 1447 int exit_code; 1448 1449 if (ctx->options & DHCPCD_DUMPLEASE) { 1450 eloop_exit(ctx->eloop, EXIT_FAILURE); 1451 return; 1452 } 1453 1454 if (sig != SIGCHLD && ctx->options & DHCPCD_FORKED) { 1455 if (sig != SIGHUP && 1456 write(ctx->fork_fd, &sig, sizeof(sig)) == -1) 1457 logerr("%s: write", __func__); 1458 return; 1459 } 1460 1461 opts = 0; 1462 exit_code = EXIT_FAILURE; 1463 switch (sig) { 1464 case SIGINT: 1465 loginfox(sigmsg, "SIGINT", "stopping"); 1466 break; 1467 case SIGTERM: 1468 loginfox(sigmsg, "SIGTERM", "stopping"); 1469 exit_code = EXIT_SUCCESS; 1470 break; 1471 case SIGALRM: 1472 loginfox(sigmsg, "SIGALRM", "releasing"); 1473 opts |= DHCPCD_RELEASE; 1474 exit_code = EXIT_SUCCESS; 1475 break; 1476 case SIGHUP: 1477 loginfox(sigmsg, "SIGHUP", "rebinding"); 1478 reload_config(ctx); 1479 /* Preserve any options passed on the commandline 1480 * when we were started. */ 1481 reconf_reboot(ctx, 1, ctx->argc, ctx->argv, 1482 ctx->argc - ctx->ifc); 1483 return; 1484 case SIGUSR1: 1485 loginfox(sigmsg, "SIGUSR1", "renewing"); 1486 dhcpcd_renew(ctx); 1487 return; 1488 case SIGUSR2: 1489 loginfox(sigmsg, "SIGUSR2", "reopening log"); 1490 #ifdef PRIVSEP 1491 if (IN_PRIVSEP(ctx)) { 1492 if (ps_root_logreopen(ctx) == -1) 1493 logerr("ps_root_logreopen"); 1494 return; 1495 } 1496 #endif 1497 if (logopen(ctx->logfile) == -1) 1498 logerr("logopen"); 1499 return; 1500 case SIGCHLD: 1501 #ifdef PRIVSEP 1502 ps_root_signalcb(sig, ctx); 1503 #else 1504 while (waitpid(-1, NULL, WNOHANG) > 0) 1505 ; 1506 #endif 1507 return; 1508 default: 1509 logerrx("received signal %d but don't know what to do with it", 1510 sig); 1511 return; 1512 } 1513 1514 /* 1515 * Privsep has a mini-eloop for reading data from other processes. 1516 * This mini-eloop processes signals as well so we can reap children. 1517 * During teardown we don't want to process SIGTERM or SIGINT again, 1518 * as that could trigger memory issues. 1519 */ 1520 if (dhcpcd_exiting) 1521 return; 1522 1523 dhcpcd_exiting = true; 1524 if (!(ctx->options & DHCPCD_TEST)) 1525 stop_all_interfaces(ctx, opts); 1526 eloop_exit(ctx->eloop, exit_code); 1527 dhcpcd_exiting = false; 1528 } 1529 #endif 1530 1531 int 1532 dhcpcd_handleargs(struct dhcpcd_ctx *ctx, struct fd_list *fd, 1533 int argc, char **argv) 1534 { 1535 struct interface *ifp; 1536 unsigned long long opts; 1537 int opt, oi, oifind, do_reboot, do_renew, af = AF_UNSPEC; 1538 size_t len, l, nifaces; 1539 char *tmp, *p; 1540 1541 /* Special commands for our control socket 1542 * as the other end should be blocking until it gets the 1543 * expected reply we should be safely able just to change the 1544 * write callback on the fd */ 1545 /* Make any change here in privsep-control.c as well. */ 1546 if (strcmp(*argv, "--version") == 0) { 1547 return control_queue(fd, UNCONST(VERSION), 1548 strlen(VERSION) + 1); 1549 } else if (strcmp(*argv, "--getconfigfile") == 0) { 1550 return control_queue(fd, UNCONST(fd->ctx->cffile), 1551 strlen(fd->ctx->cffile) + 1); 1552 } else if (strcmp(*argv, "--getinterfaces") == 0) { 1553 oifind = argc = 0; 1554 goto dumplease; 1555 } else if (strcmp(*argv, "--listen") == 0) { 1556 fd->flags |= FD_LISTEN; 1557 return 0; 1558 } 1559 1560 /* Log the command */ 1561 len = 1; 1562 for (opt = 0; opt < argc; opt++) 1563 len += strlen(argv[opt]) + 1; 1564 tmp = malloc(len); 1565 if (tmp == NULL) 1566 return -1; 1567 p = tmp; 1568 for (opt = 0; opt < argc; opt++) { 1569 l = strlen(argv[opt]); 1570 strlcpy(p, argv[opt], len); 1571 len -= l + 1; 1572 p += l; 1573 *p++ = ' '; 1574 } 1575 *--p = '\0'; 1576 loginfox("control command: %s", tmp); 1577 free(tmp); 1578 1579 optind = 0; 1580 oi = 0; 1581 opts = 0; 1582 do_reboot = do_renew = 0; 1583 while ((opt = getopt_long(argc, argv, IF_OPTS, cf_options, &oi)) != -1) 1584 { 1585 switch (opt) { 1586 case 'g': 1587 /* Assumed if below not set */ 1588 break; 1589 case 'k': 1590 opts |= DHCPCD_RELEASE; 1591 break; 1592 case 'n': 1593 do_reboot = 1; 1594 break; 1595 case 'p': 1596 opts |= DHCPCD_PERSISTENT; 1597 break; 1598 case 'x': 1599 opts |= DHCPCD_EXITING; 1600 break; 1601 case 'N': 1602 do_renew = 1; 1603 break; 1604 case 'U': 1605 opts |= DHCPCD_DUMPLEASE; 1606 break; 1607 case '4': 1608 af = AF_INET; 1609 break; 1610 case '6': 1611 af = AF_INET6; 1612 break; 1613 } 1614 } 1615 1616 /* store the index; the optind will change when a getopt get called */ 1617 oifind = optind; 1618 1619 if (opts & DHCPCD_DUMPLEASE) { 1620 ctx->options |= DHCPCD_DUMPLEASE; 1621 dumplease: 1622 nifaces = 0; 1623 TAILQ_FOREACH(ifp, ctx->ifaces, next) { 1624 if (!ifp->active) 1625 continue; 1626 for (oi = oifind; oi < argc; oi++) { 1627 if (strcmp(ifp->name, argv[oi]) == 0) 1628 break; 1629 } 1630 if (oifind == argc || oi < argc) { 1631 opt = send_interface(NULL, ifp, af); 1632 if (opt == -1) 1633 goto dumperr; 1634 nifaces += (size_t)opt; 1635 } 1636 } 1637 if (write(fd->fd, &nifaces, sizeof(nifaces)) != sizeof(nifaces)) 1638 goto dumperr; 1639 TAILQ_FOREACH(ifp, ctx->ifaces, next) { 1640 if (!ifp->active) 1641 continue; 1642 for (oi = oifind; oi < argc; oi++) { 1643 if (strcmp(ifp->name, argv[oi]) == 0) 1644 break; 1645 } 1646 if (oifind == argc || oi < argc) { 1647 if (send_interface(fd, ifp, af) == -1) 1648 goto dumperr; 1649 } 1650 } 1651 ctx->options &= ~DHCPCD_DUMPLEASE; 1652 return 0; 1653 dumperr: 1654 ctx->options &= ~DHCPCD_DUMPLEASE; 1655 return -1; 1656 } 1657 1658 /* Only privileged users can control dhcpcd via the socket. */ 1659 if (fd->flags & FD_UNPRIV) { 1660 errno = EPERM; 1661 return -1; 1662 } 1663 1664 if (opts & (DHCPCD_EXITING | DHCPCD_RELEASE)) { 1665 if (oifind == argc) { 1666 stop_all_interfaces(ctx, opts); 1667 eloop_exit(ctx->eloop, EXIT_SUCCESS); 1668 return 0; 1669 } 1670 for (oi = oifind; oi < argc; oi++) { 1671 if ((ifp = if_find(ctx->ifaces, argv[oi])) == NULL) 1672 continue; 1673 if (!ifp->active) 1674 continue; 1675 ifp->options->options |= opts; 1676 if (opts & DHCPCD_RELEASE) 1677 ifp->options->options &= ~DHCPCD_PERSISTENT; 1678 stop_interface(ifp, NULL); 1679 } 1680 return 0; 1681 } 1682 1683 if (do_renew) { 1684 if (oifind == argc) { 1685 dhcpcd_renew(ctx); 1686 return 0; 1687 } 1688 for (oi = oifind; oi < argc; oi++) { 1689 if ((ifp = if_find(ctx->ifaces, argv[oi])) == NULL) 1690 continue; 1691 dhcpcd_ifrenew(ifp); 1692 } 1693 return 0; 1694 } 1695 1696 reload_config(ctx); 1697 /* XXX: Respect initial commandline options? */ 1698 reconf_reboot(ctx, do_reboot, argc, argv, oifind); 1699 return 0; 1700 } 1701 1702 static void dhcpcd_readdump1(void *, unsigned short); 1703 1704 static void 1705 dhcpcd_readdump2(void *arg, unsigned short events) 1706 { 1707 struct dhcpcd_ctx *ctx = arg; 1708 ssize_t len; 1709 int exit_code = EXIT_FAILURE; 1710 1711 if (events != ELE_READ) 1712 logerrx("%s: unexpected event 0x%04x", __func__, events); 1713 1714 len = read(ctx->control_fd, ctx->ctl_buf + ctx->ctl_bufpos, 1715 ctx->ctl_buflen - ctx->ctl_bufpos); 1716 if (len == -1) { 1717 logerr(__func__); 1718 goto finished; 1719 } else if (len == 0) 1720 goto finished; 1721 if ((size_t)len + ctx->ctl_bufpos != ctx->ctl_buflen) { 1722 ctx->ctl_bufpos += (size_t)len; 1723 return; 1724 } 1725 1726 if (ctx->ctl_buf[ctx->ctl_buflen - 1] != '\0') /* unlikely */ 1727 ctx->ctl_buf[ctx->ctl_buflen - 1] = '\0'; 1728 script_dump(ctx->ctl_buf, ctx->ctl_buflen); 1729 fflush(stdout); 1730 if (--ctx->ctl_extra != 0) { 1731 putchar('\n'); 1732 if (eloop_event_add(ctx->eloop, ctx->control_fd, ELE_READ, 1733 dhcpcd_readdump1, ctx) == -1) 1734 logerr("%s: eloop_event_add", __func__); 1735 return; 1736 } 1737 exit_code = EXIT_SUCCESS; 1738 1739 finished: 1740 shutdown(ctx->control_fd, SHUT_RDWR); 1741 eloop_exit(ctx->eloop, exit_code); 1742 } 1743 1744 static void 1745 dhcpcd_readdump1(void *arg, unsigned short events) 1746 { 1747 struct dhcpcd_ctx *ctx = arg; 1748 ssize_t len; 1749 1750 if (events != ELE_READ) 1751 logerrx("%s: unexpected event 0x%04x", __func__, events); 1752 1753 len = read(ctx->control_fd, &ctx->ctl_buflen, sizeof(ctx->ctl_buflen)); 1754 if (len != sizeof(ctx->ctl_buflen)) { 1755 if (len != -1) 1756 errno = EINVAL; 1757 goto err; 1758 } 1759 if (ctx->ctl_buflen > SSIZE_MAX) { 1760 errno = ENOBUFS; 1761 goto err; 1762 } 1763 1764 free(ctx->ctl_buf); 1765 ctx->ctl_buf = malloc(ctx->ctl_buflen); 1766 if (ctx->ctl_buf == NULL) 1767 goto err; 1768 1769 ctx->ctl_bufpos = 0; 1770 if (eloop_event_add(ctx->eloop, ctx->control_fd, ELE_READ, 1771 dhcpcd_readdump2, ctx) == -1) 1772 logerr("%s: eloop_event_add", __func__); 1773 return; 1774 1775 err: 1776 logerr(__func__); 1777 eloop_exit(ctx->eloop, EXIT_FAILURE); 1778 } 1779 1780 static void 1781 dhcpcd_readdump0(void *arg, unsigned short events) 1782 { 1783 struct dhcpcd_ctx *ctx = arg; 1784 ssize_t len; 1785 1786 if (events != ELE_READ) 1787 logerrx("%s: unexpected event 0x%04x", __func__, events); 1788 1789 len = read(ctx->control_fd, &ctx->ctl_extra, sizeof(ctx->ctl_extra)); 1790 if (len != sizeof(ctx->ctl_extra)) { 1791 if (len != -1) 1792 errno = EINVAL; 1793 logerr(__func__); 1794 eloop_exit(ctx->eloop, EXIT_FAILURE); 1795 return; 1796 } 1797 1798 if (ctx->ctl_extra == 0) { 1799 eloop_exit(ctx->eloop, EXIT_SUCCESS); 1800 return; 1801 } 1802 1803 if (eloop_event_add(ctx->eloop, ctx->control_fd, ELE_READ, 1804 dhcpcd_readdump1, ctx) == -1) 1805 logerr("%s: eloop_event_add", __func__); 1806 } 1807 1808 static void 1809 dhcpcd_readdumptimeout(void *arg) 1810 { 1811 struct dhcpcd_ctx *ctx = arg; 1812 1813 logerrx(__func__); 1814 eloop_exit(ctx->eloop, EXIT_FAILURE); 1815 } 1816 1817 static int 1818 dhcpcd_readdump(struct dhcpcd_ctx *ctx) 1819 { 1820 1821 ctx->options |= DHCPCD_FORKED; 1822 if (eloop_timeout_add_sec(ctx->eloop, 5, 1823 dhcpcd_readdumptimeout, ctx) == -1) 1824 return -1; 1825 return eloop_event_add(ctx->eloop, ctx->control_fd, ELE_READ, 1826 dhcpcd_readdump0, ctx); 1827 } 1828 1829 static void 1830 dhcpcd_fork_cb(void *arg, unsigned short events) 1831 { 1832 struct dhcpcd_ctx *ctx = arg; 1833 int exit_code; 1834 ssize_t len; 1835 1836 if (!(events & ELE_READ)) 1837 logerrx("%s: unexpected event 0x%04x", __func__, events); 1838 1839 len = read(ctx->fork_fd, &exit_code, sizeof(exit_code)); 1840 if (len == -1) { 1841 logerr(__func__); 1842 exit_code = EXIT_FAILURE; 1843 } else if ((size_t)len < sizeof(exit_code)) { 1844 logerrx("%s: truncated read %zd (expected %zu)", 1845 __func__, len, sizeof(exit_code)); 1846 exit_code = EXIT_FAILURE; 1847 } 1848 if (ctx->options & DHCPCD_FORKED) 1849 eloop_exit(ctx->eloop, exit_code); 1850 else 1851 dhcpcd_signal_cb(exit_code, ctx); 1852 } 1853 1854 static void 1855 dhcpcd_stderr_cb(void *arg, unsigned short events) 1856 { 1857 struct dhcpcd_ctx *ctx = arg; 1858 char log[BUFSIZ]; 1859 ssize_t len; 1860 1861 if (events & ELE_HANGUP) 1862 eloop_exit(ctx->eloop, EXIT_SUCCESS); 1863 1864 if (!(events & ELE_READ)) 1865 return; 1866 1867 len = read(ctx->stderr_fd, log, sizeof(log) - 1); 1868 if (len == -1) { 1869 if (errno != ECONNRESET) 1870 logerr(__func__); 1871 return; 1872 } 1873 1874 log[len] = '\0'; 1875 fprintf(stderr, "%s", log); 1876 } 1877 1878 static void 1879 dhcpcd_pidfile_timeout(void *arg) 1880 { 1881 struct dhcpcd_ctx *ctx = arg; 1882 pid_t pid; 1883 1884 pid = pidfile_read(ctx->pidfile); 1885 1886 if(pid == -1) 1887 eloop_exit(ctx->eloop, EXIT_SUCCESS); 1888 else if (++ctx->duid_len >= 100) { /* overload duid_len */ 1889 logerrx("pid %d failed to exit", pid); 1890 eloop_exit(ctx->eloop, EXIT_FAILURE); 1891 } else 1892 eloop_timeout_add_msec(ctx->eloop, 100, 1893 dhcpcd_pidfile_timeout, ctx); 1894 } 1895 1896 static int dup_null(int fd) 1897 { 1898 int fd_null = open(_PATH_DEVNULL, O_WRONLY); 1899 int err; 1900 1901 if (fd_null == -1) { 1902 logwarn("open %s", _PATH_DEVNULL); 1903 return -1; 1904 } 1905 1906 if ((err = dup2(fd_null, fd)) == -1) 1907 logwarn("dup2 %d", fd); 1908 close(fd_null); 1909 return err; 1910 } 1911 1912 int 1913 main(int argc, char **argv, char **envp) 1914 { 1915 struct dhcpcd_ctx ctx; 1916 struct ifaddrs *ifaddrs = NULL; 1917 struct if_options *ifo; 1918 struct interface *ifp; 1919 sa_family_t family = AF_UNSPEC; 1920 int opt, oi = 0, i; 1921 unsigned int logopts, t; 1922 ssize_t len; 1923 #if defined(USE_SIGNALS) || !defined(THERE_IS_NO_FORK) 1924 pid_t pid; 1925 int fork_fd[2], stderr_fd[2]; 1926 #endif 1927 #ifdef USE_SIGNALS 1928 int sig = 0; 1929 const char *siga = NULL; 1930 size_t si; 1931 #endif 1932 1933 #ifdef SETPROCTITLE_H 1934 setproctitle_init(argc, argv, envp); 1935 #else 1936 UNUSED(envp); 1937 #endif 1938 1939 /* Test for --help and --version */ 1940 if (argc > 1) { 1941 if (strcmp(argv[1], "--help") == 0) { 1942 usage(); 1943 return EXIT_SUCCESS; 1944 } else if (strcmp(argv[1], "--version") == 0) { 1945 printf(""PACKAGE" "VERSION"\n%s\n", dhcpcd_copyright); 1946 printf("Compiled in features:" 1947 #ifdef INET 1948 " INET" 1949 #endif 1950 #ifdef ARP 1951 " ARP" 1952 #endif 1953 #ifdef ARPING 1954 " ARPing" 1955 #endif 1956 #ifdef IPV4LL 1957 " IPv4LL" 1958 #endif 1959 #ifdef INET6 1960 " INET6" 1961 #endif 1962 #ifdef DHCP6 1963 " DHCPv6" 1964 #endif 1965 #ifdef AUTH 1966 " AUTH" 1967 #endif 1968 #ifdef PRIVSEP 1969 " PRIVSEP" 1970 #endif 1971 "\n"); 1972 return EXIT_SUCCESS; 1973 } 1974 } 1975 1976 memset(&ctx, 0, sizeof(ctx)); 1977 1978 ifo = NULL; 1979 ctx.cffile = CONFIG; 1980 ctx.script = UNCONST(dhcpcd_default_script); 1981 ctx.control_fd = ctx.control_unpriv_fd = ctx.link_fd = -1; 1982 ctx.pf_inet_fd = -1; 1983 #ifdef PF_LINK 1984 ctx.pf_link_fd = -1; 1985 #endif 1986 1987 TAILQ_INIT(&ctx.control_fds); 1988 #ifdef USE_SIGNALS 1989 ctx.fork_fd = -1; 1990 #endif 1991 #ifdef PLUGIN_DEV 1992 ctx.dev_fd = -1; 1993 #endif 1994 #ifdef INET 1995 ctx.udp_rfd = -1; 1996 ctx.udp_wfd = -1; 1997 #endif 1998 #if defined(INET6) && !defined(__sun) 1999 ctx.nd_fd = -1; 2000 #endif 2001 #ifdef DHCP6 2002 ctx.dhcp6_rfd = -1; 2003 ctx.dhcp6_wfd = -1; 2004 #endif 2005 #ifdef PRIVSEP 2006 ctx.ps_log_fd = -1; 2007 TAILQ_INIT(&ctx.ps_processes); 2008 #endif 2009 2010 /* Check our streams for validity */ 2011 ctx.stdin_valid = fcntl(STDIN_FILENO, F_GETFD) != -1; 2012 ctx.stdout_valid = fcntl(STDOUT_FILENO, F_GETFD) != -1; 2013 ctx.stderr_valid = fcntl(STDERR_FILENO, F_GETFD) != -1; 2014 2015 /* Even we if we don't have input/outputs, we need to 2016 * ensure they are setup for shells. */ 2017 if (!ctx.stdin_valid) 2018 dup_null(STDIN_FILENO); 2019 if (!ctx.stdout_valid) 2020 dup_null(STDOUT_FILENO); 2021 if (!ctx.stderr_valid) 2022 dup_null(STDERR_FILENO); 2023 2024 logopts = LOGERR_LOG | LOGERR_LOG_DATE | LOGERR_LOG_PID; 2025 if (ctx.stderr_valid) 2026 logopts |= LOGERR_ERR; 2027 2028 i = 0; 2029 2030 while ((opt = getopt_long(argc, argv, 2031 ctx.options & DHCPCD_PRINT_PIDFILE ? NOERR_IF_OPTS : IF_OPTS, 2032 cf_options, &oi)) != -1) 2033 { 2034 switch (opt) { 2035 case '4': 2036 family = AF_INET; 2037 break; 2038 case '6': 2039 family = AF_INET6; 2040 break; 2041 case 'f': 2042 ctx.cffile = optarg; 2043 break; 2044 case 'j': 2045 free(ctx.logfile); 2046 ctx.logfile = strdup(optarg); 2047 break; 2048 #ifdef USE_SIGNALS 2049 case 'k': 2050 sig = SIGALRM; 2051 siga = "ALRM"; 2052 break; 2053 case 'n': 2054 sig = SIGHUP; 2055 siga = "HUP"; 2056 break; 2057 case 'q': 2058 /* -qq disables console output entirely. 2059 * This is important for systemd because it logs 2060 * both console AND syslog to the same log 2061 * resulting in untold confusion. */ 2062 if (logopts & LOGERR_QUIET) 2063 logopts &= ~LOGERR_ERR; 2064 else 2065 logopts |= LOGERR_QUIET; 2066 break; 2067 case 'x': 2068 sig = SIGTERM; 2069 siga = "TERM"; 2070 break; 2071 case 'N': 2072 sig = SIGUSR1; 2073 siga = "USR1"; 2074 break; 2075 #endif 2076 case 'P': 2077 ctx.options |= DHCPCD_PRINT_PIDFILE; 2078 logopts &= ~(LOGERR_LOG | LOGERR_ERR); 2079 break; 2080 case 'T': 2081 i = 1; 2082 logopts &= ~LOGERR_LOG; 2083 break; 2084 case 'U': 2085 i = 3; 2086 break; 2087 case 'V': 2088 i = 2; 2089 break; 2090 case '?': 2091 if (ctx.options & DHCPCD_PRINT_PIDFILE) 2092 continue; 2093 usage(); 2094 goto exit_failure; 2095 } 2096 } 2097 2098 if (optind != argc - 1) 2099 ctx.options |= DHCPCD_MANAGER; 2100 2101 logsetopts(logopts); 2102 logopen(ctx.logfile); 2103 2104 ctx.argv = argv; 2105 ctx.argc = argc; 2106 ctx.ifc = argc - optind; 2107 ctx.ifv = argv + optind; 2108 2109 rt_init(&ctx); 2110 2111 ifo = read_config(&ctx, NULL, NULL, NULL); 2112 if (ifo == NULL) { 2113 if (ctx.options & DHCPCD_PRINT_PIDFILE) 2114 goto printpidfile; 2115 goto exit_failure; 2116 } 2117 2118 opt = add_options(&ctx, NULL, ifo, argc, argv); 2119 if (opt != 1) { 2120 if (ctx.options & DHCPCD_PRINT_PIDFILE) 2121 goto printpidfile; 2122 if (opt == 0) 2123 usage(); 2124 goto exit_failure; 2125 } 2126 if (i == 2) { 2127 printf("Interface options:\n"); 2128 if (optind == argc - 1) { 2129 free_options(&ctx, ifo); 2130 ifo = read_config(&ctx, argv[optind], NULL, NULL); 2131 if (ifo == NULL) 2132 goto exit_failure; 2133 add_options(&ctx, NULL, ifo, argc, argv); 2134 } 2135 if_printoptions(); 2136 #ifdef INET 2137 if (family == 0 || family == AF_INET) { 2138 printf("\nDHCPv4 options:\n"); 2139 dhcp_printoptions(&ctx, 2140 ifo->dhcp_override, ifo->dhcp_override_len); 2141 } 2142 #endif 2143 #ifdef INET6 2144 if (family == 0 || family == AF_INET6) { 2145 printf("\nND options:\n"); 2146 ipv6nd_printoptions(&ctx, 2147 ifo->nd_override, ifo->nd_override_len); 2148 #ifdef DHCP6 2149 printf("\nDHCPv6 options:\n"); 2150 dhcp6_printoptions(&ctx, 2151 ifo->dhcp6_override, ifo->dhcp6_override_len); 2152 #endif 2153 } 2154 #endif 2155 goto exit_success; 2156 } 2157 ctx.options |= ifo->options; 2158 2159 if (i == 1 || i == 3) { 2160 if (i == 1) 2161 ctx.options |= DHCPCD_TEST; 2162 else 2163 ctx.options |= DHCPCD_DUMPLEASE; 2164 ctx.options |= DHCPCD_PERSISTENT; 2165 ctx.options &= ~DHCPCD_DAEMONISE; 2166 } 2167 2168 #ifdef THERE_IS_NO_FORK 2169 ctx.options &= ~DHCPCD_DAEMONISE; 2170 #endif 2171 2172 if (ctx.options & DHCPCD_DEBUG) 2173 logsetopts(logopts | LOGERR_DEBUG); 2174 2175 if (!(ctx.options & (DHCPCD_TEST | DHCPCD_DUMPLEASE))) { 2176 printpidfile: 2177 /* If we have any other args, we should run as a single dhcpcd 2178 * instance for that interface. */ 2179 if (optind == argc - 1 && !(ctx.options & DHCPCD_MANAGER)) { 2180 const char *per; 2181 const char *ifname; 2182 2183 ifname = *ctx.ifv; 2184 if (ifname == NULL || strlen(ifname) > IF_NAMESIZE) { 2185 errno = ifname == NULL ? EINVAL : E2BIG; 2186 logerr("%s: ", ifname); 2187 goto exit_failure; 2188 } 2189 /* Allow a dhcpcd interface per address family */ 2190 switch(family) { 2191 case AF_INET: 2192 per = "-4"; 2193 break; 2194 case AF_INET6: 2195 per = "-6"; 2196 break; 2197 default: 2198 per = ""; 2199 } 2200 snprintf(ctx.pidfile, sizeof(ctx.pidfile), 2201 PIDFILE, ifname, per, "."); 2202 } else { 2203 snprintf(ctx.pidfile, sizeof(ctx.pidfile), 2204 PIDFILE, "", "", ""); 2205 ctx.options |= DHCPCD_MANAGER; 2206 2207 /* 2208 * If we are given any interfaces, we 2209 * cannot send a signal as that would impact 2210 * other interfaces. 2211 */ 2212 if (optind != argc) 2213 sig = 0; 2214 } 2215 if (ctx.options & DHCPCD_PRINT_PIDFILE) { 2216 printf("%s\n", ctx.pidfile); 2217 goto exit_success; 2218 } 2219 } 2220 2221 if (chdir("/") == -1) 2222 logerr("%s: chdir: /", __func__); 2223 2224 /* Freeing allocated addresses from dumping leases can trigger 2225 * eloop removals as well, so init here. */ 2226 if ((ctx.eloop = eloop_new()) == NULL) { 2227 logerr("%s: eloop_init", __func__); 2228 goto exit_failure; 2229 } 2230 2231 #ifdef USE_SIGNALS 2232 for (si = 0; si < dhcpcd_signals_ignore_len; si++) 2233 signal(dhcpcd_signals_ignore[si], SIG_IGN); 2234 2235 /* Save signal mask, block and redirect signals to our handler */ 2236 eloop_signal_set_cb(ctx.eloop, 2237 dhcpcd_signals, dhcpcd_signals_len, 2238 dhcpcd_signal_cb, &ctx); 2239 if (eloop_signal_mask(ctx.eloop, &ctx.sigset) == -1) { 2240 logerr("%s: eloop_signal_mask", __func__); 2241 goto exit_failure; 2242 } 2243 2244 if (sig != 0) { 2245 pid = pidfile_read(ctx.pidfile); 2246 if (pid != 0 && pid != -1) 2247 loginfox("sending signal %s to pid %d", siga, pid); 2248 if (pid == 0 || pid == -1 || kill(pid, sig) != 0) { 2249 if (pid != 0 && pid != -1 && errno != ESRCH) { 2250 logerr("kill"); 2251 goto exit_failure; 2252 } 2253 unlink(ctx.pidfile); 2254 /* We can still continue and send the command 2255 * via the control socket. */ 2256 } else { 2257 if (sig == SIGHUP || sig == SIGUSR1) 2258 goto exit_success; 2259 /* Spin until it exits */ 2260 loginfox("waiting for pid %d to exit", pid); 2261 dhcpcd_pidfile_timeout(&ctx); 2262 goto run_loop; 2263 } 2264 } 2265 #endif 2266 2267 #ifdef HAVE_OPENSSL 2268 OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS | 2269 OPENSSL_INIT_ADD_ALL_DIGESTS | OPENSSL_INIT_LOAD_CONFIG, NULL); 2270 #endif 2271 2272 #ifdef PRIVSEP 2273 ps_init(&ctx); 2274 #endif 2275 2276 #ifndef SMALL 2277 if (ctx.options & DHCPCD_DUMPLEASE && 2278 ioctl(fileno(stdin), FIONREAD, &i, sizeof(i)) == 0 && 2279 i > 0) 2280 { 2281 ctx.options |= DHCPCD_FORKED; /* pretend child process */ 2282 #ifdef PRIVSEP 2283 if (IN_PRIVSEP(&ctx) && ps_managersandbox(&ctx, NULL) == -1) 2284 goto exit_failure; 2285 #endif 2286 ifp = calloc(1, sizeof(*ifp)); 2287 if (ifp == NULL) { 2288 logerr(__func__); 2289 goto exit_failure; 2290 } 2291 ifp->ctx = &ctx; 2292 ifp->options = ifo; 2293 switch (family) { 2294 case AF_INET: 2295 #ifdef INET 2296 if (dhcp_dump(ifp) == -1) 2297 goto exit_failure; 2298 break; 2299 #else 2300 logerrx("No DHCP support"); 2301 goto exit_failure; 2302 #endif 2303 case AF_INET6: 2304 #ifdef DHCP6 2305 if (dhcp6_dump(ifp) == -1) 2306 goto exit_failure; 2307 break; 2308 #else 2309 logerrx("No DHCP6 support"); 2310 goto exit_failure; 2311 #endif 2312 default: 2313 logerrx("Family not specified. Please use -4 or -6."); 2314 goto exit_failure; 2315 } 2316 goto exit_success; 2317 } 2318 #endif 2319 2320 /* Try and contact the manager process to send the instruction. */ 2321 if (!(ctx.options & DHCPCD_TEST)) { 2322 ctx.options |= DHCPCD_FORKED; /* avoid socket unlink */ 2323 if (!(ctx.options & DHCPCD_MANAGER)) 2324 ctx.control_fd = control_open(argv[optind], family, 2325 ctx.options & DHCPCD_DUMPLEASE); 2326 if (!(ctx.options & DHCPCD_MANAGER) && ctx.control_fd == -1) 2327 ctx.control_fd = control_open(argv[optind], AF_UNSPEC, 2328 ctx.options & DHCPCD_DUMPLEASE); 2329 if (ctx.control_fd == -1) 2330 ctx.control_fd = control_open(NULL, AF_UNSPEC, 2331 ctx.options & DHCPCD_DUMPLEASE); 2332 if (ctx.control_fd != -1) { 2333 #ifdef PRIVSEP 2334 if (IN_PRIVSEP(&ctx) && 2335 ps_managersandbox(&ctx, NULL) == -1) 2336 goto exit_failure; 2337 #endif 2338 if (!(ctx.options & DHCPCD_DUMPLEASE)) 2339 loginfox("sending commands to dhcpcd process"); 2340 len = control_send(&ctx, argc, argv); 2341 if (len > 0) 2342 logdebugx("send OK"); 2343 else { 2344 logerr("%s: control_send", __func__); 2345 goto exit_failure; 2346 } 2347 if (ctx.options & DHCPCD_DUMPLEASE) { 2348 if (dhcpcd_readdump(&ctx) == -1) { 2349 logerr("%s: dhcpcd_readdump", __func__); 2350 goto exit_failure; 2351 } 2352 goto run_loop; 2353 } 2354 goto exit_success; 2355 } else { 2356 if (errno != ENOENT) 2357 logerr("%s: control_open", __func__); 2358 /* If asking dhcpcd to exit and we failed to 2359 * send a signal or a message then we 2360 * don't proceed past here. */ 2361 if (ctx.options & DHCPCD_DUMPLEASE || 2362 sig == SIGTERM || sig == SIGALRM) 2363 { 2364 if (errno == ENOENT) 2365 logerrx(PACKAGE" is not running"); 2366 goto exit_failure; 2367 } 2368 if (errno == EPERM || errno == EACCES) 2369 goto exit_failure; 2370 } 2371 ctx.options &= ~DHCPCD_FORKED; 2372 } 2373 2374 if (!(ctx.options & DHCPCD_TEST)) { 2375 /* Ensure we have the needed directories */ 2376 if (mkdir(DBDIR, 0750) == -1 && errno != EEXIST) 2377 logerr("%s: mkdir: %s", __func__, DBDIR); 2378 if (mkdir(RUNDIR, 0755) == -1 && errno != EEXIST) 2379 logerr("%s: mkdir: %s", __func__, RUNDIR); 2380 if ((pid = pidfile_lock(ctx.pidfile)) != 0) { 2381 if (pid == -1) 2382 logerr("%s: pidfile_lock: %s", 2383 __func__, ctx.pidfile); 2384 else 2385 logerrx(PACKAGE 2386 " already running on pid %d (%s)", 2387 pid, ctx.pidfile); 2388 goto exit_failure; 2389 } 2390 } 2391 2392 loginfox(PACKAGE "-" VERSION " starting"); 2393 2394 // We don't need stdin past this point 2395 if (ctx.stdin_valid) 2396 dup_null(STDIN_FILENO); 2397 2398 #if defined(USE_SIGNALS) && !defined(THERE_IS_NO_FORK) 2399 if (!(ctx.options & DHCPCD_DAEMONISE)) 2400 goto start_manager; 2401 2402 if (xsocketpair(AF_UNIX, SOCK_SEQPACKET|SOCK_CXNB, 0, fork_fd) == -1 || 2403 (ctx.stderr_valid && 2404 xsocketpair(AF_UNIX, SOCK_SEQPACKET|SOCK_CXNB, 0, stderr_fd) == -1)) 2405 { 2406 logerr("socketpair"); 2407 goto exit_failure; 2408 } 2409 switch (pid = fork()) { 2410 case -1: 2411 logerr("fork"); 2412 goto exit_failure; 2413 case 0: 2414 ctx.fork_fd = fork_fd[1]; 2415 close(fork_fd[0]); 2416 #ifdef PRIVSEP_RIGHTS 2417 if (ps_rights_limit_fd(ctx.fork_fd) == -1) { 2418 logerr("ps_rights_limit_fdpair"); 2419 goto exit_failure; 2420 } 2421 #endif 2422 if (eloop_event_add(ctx.eloop, ctx.fork_fd, ELE_READ, 2423 dhcpcd_fork_cb, &ctx) == -1) 2424 logerr("%s: eloop_event_add", __func__); 2425 2426 /* 2427 * Redirect stderr to the stderr socketpair. 2428 * Redirect stdout as well. 2429 * dhcpcd doesn't output via stdout, but something in 2430 * a called script might. 2431 */ 2432 if (ctx.stderr_valid) { 2433 if (dup2(stderr_fd[1], STDERR_FILENO) == -1 || 2434 (ctx.stdout_valid && 2435 dup2(stderr_fd[1], STDOUT_FILENO) == -1)) 2436 logerr("dup2"); 2437 close(stderr_fd[0]); 2438 close(stderr_fd[1]); 2439 } else if (ctx.stdout_valid) 2440 dup_null(STDOUT_FILENO); 2441 2442 if (setsid() == -1) { 2443 logerr("%s: setsid", __func__); 2444 goto exit_failure; 2445 } 2446 /* Ensure we can never get a controlling terminal */ 2447 switch (pid = fork()) { 2448 case -1: 2449 logerr("fork"); 2450 goto exit_failure; 2451 case 0: 2452 eloop_forked(ctx.eloop); 2453 break; 2454 default: 2455 ctx.options |= DHCPCD_FORKED; /* A lie */ 2456 i = EXIT_SUCCESS; 2457 goto exit1; 2458 } 2459 break; 2460 default: 2461 setproctitle("[launcher]"); 2462 ctx.options |= DHCPCD_FORKED | DHCPCD_LAUNCHER; 2463 ctx.fork_fd = fork_fd[0]; 2464 close(fork_fd[1]); 2465 #ifdef PRIVSEP_RIGHTS 2466 if (ps_rights_limit_fd(ctx.fork_fd) == -1) { 2467 logerr("ps_rights_limit_fd"); 2468 goto exit_failure; 2469 } 2470 #endif 2471 if (eloop_event_add(ctx.eloop, ctx.fork_fd, ELE_READ, 2472 dhcpcd_fork_cb, &ctx) == -1) 2473 logerr("%s: eloop_event_add", __func__); 2474 2475 if (ctx.stderr_valid) { 2476 ctx.stderr_fd = stderr_fd[0]; 2477 close(stderr_fd[1]); 2478 #ifdef PRIVSEP_RIGHTS 2479 if (ps_rights_limit_fd(ctx.stderr_fd) == 1) { 2480 logerr("ps_rights_limit_fd"); 2481 goto exit_failure; 2482 } 2483 #endif 2484 if (eloop_event_add(ctx.eloop, ctx.stderr_fd, ELE_READ, 2485 dhcpcd_stderr_cb, &ctx) == -1) 2486 logerr("%s: eloop_event_add", __func__); 2487 } 2488 #ifdef PRIVSEP 2489 if (IN_PRIVSEP(&ctx) && ps_managersandbox(&ctx, NULL) == -1) 2490 goto exit_failure; 2491 #endif 2492 goto run_loop; 2493 } 2494 2495 /* We have now forked, setsid, forked once more. 2496 * From this point on, we are the controlling daemon. */ 2497 logdebugx("spawned manager process on PID %d", getpid()); 2498 start_manager: 2499 ctx.options |= DHCPCD_STARTED; 2500 if ((pid = pidfile_lock(ctx.pidfile)) != 0) { 2501 logerr("%s: pidfile_lock %d", __func__, pid); 2502 #ifdef PRIVSEP 2503 /* privsep has not started ... */ 2504 ctx.options &= ~DHCPCD_PRIVSEP; 2505 #endif 2506 goto exit_failure; 2507 } 2508 #endif 2509 2510 os_init(); 2511 2512 #if defined(BSD) && defined(INET6) 2513 /* Disable the kernel RTADV sysctl as early as possible. */ 2514 if (ctx.options & DHCPCD_IPV6 && ctx.options & DHCPCD_IPV6RS) 2515 if_disable_rtadv(); 2516 #endif 2517 2518 #ifdef PRIVSEP 2519 if (IN_PRIVSEP(&ctx) && ps_start(&ctx) == -1) { 2520 logerr("ps_start"); 2521 goto exit_failure; 2522 } 2523 if (ctx.options & DHCPCD_FORKED) 2524 goto run_loop; 2525 #endif 2526 2527 if (!(ctx.options & DHCPCD_TEST)) { 2528 if (control_start(&ctx, 2529 ctx.options & DHCPCD_MANAGER ? 2530 NULL : argv[optind], family) == -1) 2531 { 2532 logerr("%s: control_start", __func__); 2533 goto exit_failure; 2534 } 2535 } 2536 2537 #ifdef PLUGIN_DEV 2538 /* Start any dev listening plugin which may want to 2539 * change the interface name provided by the kernel */ 2540 if (!IN_PRIVSEP(&ctx) && 2541 (ctx.options & (DHCPCD_MANAGER | DHCPCD_DEV)) == 2542 (DHCPCD_MANAGER | DHCPCD_DEV)) 2543 dev_start(&ctx, dhcpcd_handleinterface); 2544 #endif 2545 2546 setproctitle("%s%s%s", 2547 ctx.options & DHCPCD_MANAGER ? "[manager]" : argv[optind], 2548 ctx.options & DHCPCD_IPV4 ? " [ip4]" : "", 2549 ctx.options & DHCPCD_IPV6 ? " [ip6]" : ""); 2550 2551 if (if_opensockets(&ctx) == -1) { 2552 logerr("%s: if_opensockets", __func__); 2553 goto exit_failure; 2554 } 2555 #ifndef SMALL 2556 dhcpcd_setlinkrcvbuf(&ctx); 2557 #endif 2558 2559 /* Try and create DUID from the machine UUID. */ 2560 dhcpcd_initduid(&ctx, NULL); 2561 2562 /* Cache the default vendor option. */ 2563 if (dhcp_vendor(ctx.vendor, sizeof(ctx.vendor)) == -1) 2564 logerr("dhcp_vendor"); 2565 2566 /* Start handling kernel messages for interfaces, addresses and 2567 * routes. */ 2568 if (eloop_event_add(ctx.eloop, ctx.link_fd, ELE_READ, 2569 dhcpcd_handlelink, &ctx) == -1) 2570 logerr("%s: eloop_event_add", __func__); 2571 2572 #ifdef PRIVSEP 2573 if (IN_PRIVSEP(&ctx) && ps_managersandbox(&ctx, "stdio route") == -1) 2574 goto exit_failure; 2575 #endif 2576 2577 /* When running dhcpcd against a single interface, we need to retain 2578 * the old behaviour of waiting for an IP address */ 2579 if (ctx.ifc == 1 && !(ctx.options & DHCPCD_BACKGROUND)) 2580 ctx.options |= DHCPCD_WAITIP; 2581 2582 ctx.ifaces = if_discover(&ctx, &ifaddrs, ctx.ifc, ctx.ifv); 2583 if (ctx.ifaces == NULL) { 2584 logerr("%s: if_discover", __func__); 2585 goto exit_failure; 2586 } 2587 for (i = 0; i < ctx.ifc; i++) { 2588 if ((ifp = if_find(ctx.ifaces, ctx.ifv[i])) == NULL) 2589 logerrx("%s: interface not found", 2590 ctx.ifv[i]); 2591 else if (!ifp->active) 2592 logerrx("%s: interface has an invalid configuration", 2593 ctx.ifv[i]); 2594 } 2595 TAILQ_FOREACH(ifp, ctx.ifaces, next) { 2596 if (ifp->active == IF_ACTIVE_USER) 2597 break; 2598 } 2599 if (ifp == NULL) { 2600 if (ctx.ifc == 0) { 2601 int loglevel; 2602 2603 loglevel = ctx.options & DHCPCD_INACTIVE ? 2604 LOG_DEBUG : LOG_ERR; 2605 logmessage(loglevel, "no valid interfaces found"); 2606 dhcpcd_daemonise(&ctx); 2607 } else 2608 goto exit_failure; 2609 if (!(ctx.options & DHCPCD_LINK)) { 2610 logerrx("aborting as link detection is disabled"); 2611 goto exit_failure; 2612 } 2613 } 2614 2615 TAILQ_FOREACH(ifp, ctx.ifaces, next) { 2616 if (ifp->active) 2617 dhcpcd_initstate1(ifp, argc, argv, 0); 2618 } 2619 if_learnaddrs(&ctx, ctx.ifaces, &ifaddrs); 2620 if_freeifaddrs(&ctx, &ifaddrs); 2621 ifaddrs = NULL; 2622 2623 if (ctx.options & DHCPCD_BACKGROUND) 2624 dhcpcd_daemonise(&ctx); 2625 2626 opt = 0; 2627 TAILQ_FOREACH(ifp, ctx.ifaces, next) { 2628 if (ifp->active) { 2629 run_preinit(ifp); 2630 if (if_is_link_up(ifp)) 2631 opt = 1; 2632 } 2633 } 2634 2635 if (!(ctx.options & DHCPCD_BACKGROUND)) { 2636 if (ctx.options & DHCPCD_MANAGER) 2637 t = ifo->timeout; 2638 else { 2639 t = 0; 2640 TAILQ_FOREACH(ifp, ctx.ifaces, next) { 2641 if (ifp->active) { 2642 t = ifp->options->timeout; 2643 break; 2644 } 2645 } 2646 } 2647 if (opt == 0 && 2648 ctx.options & DHCPCD_LINK && 2649 !(ctx.options & DHCPCD_WAITIP)) 2650 { 2651 int loglevel; 2652 2653 loglevel = ctx.options & DHCPCD_INACTIVE ? 2654 LOG_DEBUG : LOG_WARNING; 2655 logmessage(loglevel, "no interfaces have a carrier"); 2656 dhcpcd_daemonise(&ctx); 2657 } else if (t > 0 && 2658 /* Test mode removes the daemonise bit, so check for both */ 2659 ctx.options & (DHCPCD_DAEMONISE | DHCPCD_TEST)) 2660 { 2661 eloop_timeout_add_sec(ctx.eloop, t, 2662 handle_exit_timeout, &ctx); 2663 } 2664 } 2665 free_options(&ctx, ifo); 2666 ifo = NULL; 2667 2668 TAILQ_FOREACH(ifp, ctx.ifaces, next) { 2669 if (ifp->active) 2670 eloop_timeout_add_sec(ctx.eloop, 0, 2671 dhcpcd_prestartinterface, ifp); 2672 } 2673 2674 run_loop: 2675 i = eloop_start(ctx.eloop, &ctx.sigset); 2676 if (i < 0) { 2677 logerr("%s: eloop_start", __func__); 2678 goto exit_failure; 2679 } 2680 goto exit1; 2681 2682 exit_success: 2683 i = EXIT_SUCCESS; 2684 goto exit1; 2685 2686 exit_failure: 2687 i = EXIT_FAILURE; 2688 2689 exit1: 2690 if (!(ctx.options & DHCPCD_TEST) && control_stop(&ctx) == -1) 2691 logerr("%s: control_stop", __func__); 2692 if_freeifaddrs(&ctx, &ifaddrs); 2693 #ifdef PRIVSEP 2694 ps_stop(&ctx); 2695 #endif 2696 /* Free memory and close fd's */ 2697 if (ctx.ifaces) { 2698 while ((ifp = TAILQ_FIRST(ctx.ifaces))) { 2699 TAILQ_REMOVE(ctx.ifaces, ifp, next); 2700 if_free(ifp); 2701 } 2702 free(ctx.ifaces); 2703 ctx.ifaces = NULL; 2704 } 2705 free_options(&ctx, ifo); 2706 #ifdef HAVE_OPEN_MEMSTREAM 2707 if (ctx.script_fp) 2708 fclose(ctx.script_fp); 2709 #endif 2710 free(ctx.script_buf); 2711 free(ctx.script_env); 2712 rt_dispose(&ctx); 2713 free(ctx.duid); 2714 if (ctx.link_fd != -1) { 2715 eloop_event_delete(ctx.eloop, ctx.link_fd); 2716 close(ctx.link_fd); 2717 } 2718 if_closesockets(&ctx); 2719 free_globals(&ctx); 2720 #ifdef INET6 2721 ipv6_ctxfree(&ctx); 2722 #endif 2723 #ifdef PLUGIN_DEV 2724 dev_stop(&ctx); 2725 #endif 2726 if (ctx.script != dhcpcd_default_script) 2727 free(ctx.script); 2728 #ifdef PRIVSEP 2729 if (ps_stopwait(&ctx) != EXIT_SUCCESS) 2730 i = EXIT_FAILURE; 2731 #endif 2732 if (ctx.options & DHCPCD_STARTED && !(ctx.options & DHCPCD_FORKED)) 2733 loginfox(PACKAGE " exited"); 2734 #ifdef PRIVSEP 2735 if (ps_root_stop(&ctx) == -1) 2736 i = EXIT_FAILURE; 2737 eloop_free(ctx.ps_eloop); 2738 #endif 2739 eloop_free(ctx.eloop); 2740 logclose(); 2741 free(ctx.logfile); 2742 free(ctx.ctl_buf); 2743 #ifdef SETPROCTITLE_H 2744 setproctitle_fini(); 2745 #endif 2746 #ifdef USE_SIGNALS 2747 if (ctx.options & DHCPCD_STARTED) { 2748 /* Try to detach from the launch process. */ 2749 if (ctx.fork_fd != -1 && 2750 write(ctx.fork_fd, &i, sizeof(i)) == -1) 2751 logerr("%s: write", __func__); 2752 } 2753 if (ctx.options & (DHCPCD_FORKED | DHCPCD_PRIVSEP)) 2754 _exit(i); /* so atexit won't remove our pidfile */ 2755 #endif 2756 return i; 2757 } 2758