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