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