xref: /dragonfly/contrib/dhcpcd/src/dhcpcd.c (revision 6a6d63c5317abf314a78f8c8300ef73c2bc0c39e)
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_af(struct interface * ifp,int stop,int af)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           }
427 #endif
428 
429 #if !defined(DHCP6) && !defined(DHCP)
430           UNUSED(stop);
431 #endif
432 }
433 
434 static void
dhcpcd_drop(struct interface * ifp,int stop)435 dhcpcd_drop(struct interface *ifp, int stop)
436 {
437 
438           dhcpcd_drop_af(ifp, stop, AF_UNSPEC);
439 }
440 
441 static void
stop_interface(struct interface * ifp,const char * reason)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
configure_interface1(struct interface * ifp)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
dhcpcd_selectprofile(struct interface * ifp,const char * profile)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
configure_interface(struct interface * ifp,int argc,char ** argv,unsigned long long options)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
dhcpcd_initstate1(struct interface * ifp,int argc,char ** argv,unsigned long long options)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
dhcpcd_initstate(struct interface * ifp,unsigned long long options)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
dhcpcd_reportssid(struct interface * ifp)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
dhcpcd_nocarrier_roaming(struct interface * ifp)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
dhcpcd_handlecarrier(struct interface * ifp,int carrier,unsigned int flags)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
warn_iaid_conflict(struct interface * ifp,uint16_t ia_type,uint8_t * iaid)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
dhcpcd_initduid(struct dhcpcd_ctx * ctx,struct interface * ifp)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
dhcpcd_startinterface(void * arg)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
dhcpcd_prestartinterface(void * arg)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
run_preinit(struct interface * ifp)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
dhcpcd_activateinterface(struct interface * ifp,unsigned long long options)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
dhcpcd_handleinterface(void * arg,int action,const char * ifname)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
dhcpcd_handlelink(void * arg,unsigned short events)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
dhcpcd_checkcarrier(void * arg)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
dhcpcd_setlinkrcvbuf(struct dhcpcd_ctx * ctx)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
dhcpcd_runprestartinterface(void * arg)1183 dhcpcd_runprestartinterface(void *arg)
1184 {
1185           struct interface *ifp = arg;
1186 
1187           run_preinit(ifp);
1188           dhcpcd_prestartinterface(ifp);
1189 }
1190 
1191 void
dhcpcd_linkoverflow(struct dhcpcd_ctx * ctx)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
dhcpcd_handlehwaddr(struct interface * ifp,uint16_t hwtype,const void * hwaddr,uint8_t hwlen)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
if_reboot(struct interface * ifp,int argc,char ** argv)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
reload_config(struct dhcpcd_ctx * ctx)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
reconf_reboot(struct dhcpcd_ctx * ctx,int action,int argc,char ** argv,int oi)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
stop_all_interfaces(struct dhcpcd_ctx * ctx,unsigned long long opts)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
dhcpcd_ifrenew(struct interface * ifp)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
dhcpcd_renew(struct dhcpcd_ctx * ctx)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
dhcpcd_signal_cb(int sig,void * arg)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
dhcpcd_handleargs(struct dhcpcd_ctx * ctx,struct fd_list * fd,int argc,char ** argv)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
dhcpcd_readdump2(void * arg,unsigned short events)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
dhcpcd_readdump1(void * arg,unsigned short events)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
dhcpcd_readdump0(void * arg,unsigned short events)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
dhcpcd_readdumptimeout(void * arg)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
dhcpcd_readdump(struct dhcpcd_ctx * ctx)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
dhcpcd_fork_cb(void * arg,unsigned short events)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
dhcpcd_pidfile_timeout(void * arg)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 
dup_null(int fd)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
main(int argc,char ** argv,char ** envp)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