source: rtems-libbsd/dhcpcd/dhcpcd.c @ f2ed769

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since f2ed769 was f2ed769, checked in by Sebastian Huber <sebastian.huber@…>, on 01/30/14 at 12:29:46

DHCPCD(8): Import

Import DHCPCD(8) from:

http://roy.marples.name/projects/dhcpcd/

The upstream sources can be obtained via:

fossil clone http://roy.marples.name/projects/dhcpcd

The imported version is 2014-01-29 19:46:44 [6b209507bb].

  • Property mode set to 100644
File size: 35.2 KB
Line 
1/*
2 * dhcpcd - DHCP client daemon
3 * Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
4 * All rights reserved
5
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28const char dhcpcd_copyright[] = "Copyright (c) 2006-2014 Roy Marples";
29
30#include <sys/file.h>
31#include <sys/socket.h>
32#include <sys/stat.h>
33#include <sys/time.h>
34#include <sys/types.h>
35#include <sys/uio.h>
36#include <sys/utsname.h>
37
38#include <ctype.h>
39#include <errno.h>
40#include <getopt.h>
41#include <limits.h>
42#include <paths.h>
43#include <signal.h>
44#include <stdio.h>
45#include <stdlib.h>
46#include <string.h>
47#include <syslog.h>
48#include <unistd.h>
49#include <time.h>
50
51#include "config.h"
52#include "arp.h"
53#include "common.h"
54#include "control.h"
55#include "dev.h"
56#include "dhcpcd.h"
57#include "dhcp6.h"
58#include "duid.h"
59#include "eloop.h"
60#include "if-options.h"
61#include "if-pref.h"
62#include "ipv4.h"
63#include "ipv6.h"
64#include "ipv6nd.h"
65#include "net.h"
66#include "platform.h"
67#include "script.h"
68
69struct if_head *ifaces = NULL;
70char vendor[VENDORCLASSID_MAX_LEN];
71int pidfd = -1;
72struct if_options *if_options = NULL;
73int ifac = 0;
74char **ifav = NULL;
75int ifdc = 0;
76char **ifdv = NULL;
77
78sigset_t dhcpcd_sigset;
79const int handle_sigs[] = {
80        SIGALRM,
81        SIGHUP,
82        SIGINT,
83        SIGPIPE,
84        SIGTERM,
85        SIGUSR1,
86        0
87};
88
89static char *cffile;
90static char *pidfile;
91static int linkfd = -1;
92static char **ifv;
93static int ifc;
94static char **margv;
95static int margc;
96
97static pid_t
98read_pid(void)
99{
100        FILE *fp;
101        pid_t pid;
102
103        if ((fp = fopen(pidfile, "r")) == NULL) {
104                errno = ENOENT;
105                return 0;
106        }
107        if (fscanf(fp, "%d", &pid) != 1)
108                pid = 0;
109        fclose(fp);
110        return pid;
111}
112
113static void
114usage(void)
115{
116
117printf("usage: "PACKAGE"\t[-46ABbDdEGgHJKkLnpqTVw]\n"
118        "\t\t[-C, --nohook hook] [-c, --script script]\n"
119        "\t\t[-e, --env value] [-F, --fqdn FQDN] [-f, --config file]\n"
120        "\t\t[-h, --hostname hostname] [-I, --clientid clientid]\n"
121        "\t\t[-i, --vendorclassid vendorclassid] [-l, --leasetime seconds]\n"
122        "\t\t[-m, --metric metric] [-O, --nooption option]\n"
123        "\t\t[-o, --option option] [-Q, --require option]\n"
124        "\t\t[-r, --request address] [-S, --static value]\n"
125        "\t\t[-s, --inform address[/cidr]] [-t, --timeout seconds]\n"
126        "\t\t[-u, --userclass class] [-v, --vendor code, value]\n"
127        "\t\t[-W, --whitelist address[/cidr]] [-y, --reboot seconds]\n"
128        "\t\t[-X, --blacklist address[/cidr]] [-Z, --denyinterfaces pattern]\n"
129        "\t\t[-z, --allowinterfaces pattern] [interface] [...]\n"
130        "       "PACKAGE"\t-k, --release [interface]\n"
131        "       "PACKAGE"\t-U, --dumplease interface\n"
132        "       "PACKAGE"\t--version\n"
133        "       "PACKAGE"\t-x, --exit [interface]\n");
134}
135
136static void
137free_globals(void)
138{
139        int i;
140        size_t n;
141        struct dhcp_opt *opt;
142
143        for (i = 0; i < ifac; i++)
144                free(ifav[i]);
145        free(ifav);
146        for (i = 0; i < ifdc; i++)
147                free(ifdv[i]);
148        free(ifdv);
149
150#ifdef INET
151        for (n = 0, opt = dhcp_opts; n < dhcp_opts_len; n++, opt++)
152                free_dhcp_opt_embenc(opt);
153        free(dhcp_opts);
154#endif
155#ifdef INET6
156        for (n = 0, opt = dhcp6_opts; n < dhcp6_opts_len; n++, opt++)
157                free_dhcp_opt_embenc(opt);
158        free(dhcp6_opts);
159#endif
160        for (n = 0, opt = vivso; n < vivso_len; n++, opt++)
161                free_dhcp_opt_embenc(opt);
162        free(vivso);
163}
164
165static void
166cleanup(void)
167{
168#ifdef DEBUG_MEMORY
169        struct interface *ifp;
170
171        free(duid);
172        free_options(if_options);
173
174        if (ifaces) {
175                while ((ifp = TAILQ_FIRST(ifaces))) {
176                        TAILQ_REMOVE(ifaces, ifp, next);
177                        free_interface(ifp);
178                }
179                free(ifaces);
180        }
181
182        free_globals();
183#endif
184
185        if (!(options & DHCPCD_FORKED))
186                dev_stop();
187        if (linkfd != -1)
188                close(linkfd);
189        if (pidfd > -1) {
190                if (options & DHCPCD_MASTER) {
191                        if (control_stop() == -1)
192                                syslog(LOG_ERR, "control_stop: %m");
193                }
194                close(pidfd);
195                unlink(pidfile);
196        }
197#ifdef DEBUG_MEMORY
198        free(pidfile);
199#endif
200
201        if (options & DHCPCD_STARTED && !(options & DHCPCD_FORKED))
202                syslog(LOG_INFO, "exited");
203}
204
205/* ARGSUSED */
206static void
207handle_exit_timeout(__unused void *arg)
208{
209        int timeout;
210
211        syslog(LOG_ERR, "timed out");
212        if (!(options & DHCPCD_IPV4) || !(options & DHCPCD_TIMEOUT_IPV4LL)) {
213                if (options & DHCPCD_MASTER) {
214                        /* We've timed out, so remove the waitip requirements.
215                         * If the user doesn't like this they can always set
216                         * an infinite timeout. */
217                        options &=
218                            ~(DHCPCD_WAITIP | DHCPCD_WAITIP4 | DHCPCD_WAITIP6);
219                        daemonise();
220                        return;
221                } else
222                        exit(EXIT_FAILURE);
223        }
224        options &= ~DHCPCD_TIMEOUT_IPV4LL;
225        timeout = (PROBE_NUM * PROBE_MAX) + (PROBE_WAIT * 2);
226        syslog(LOG_WARNING, "allowing %d seconds for IPv4LL timeout", timeout);
227        eloop_timeout_add_sec(timeout, handle_exit_timeout, NULL);
228}
229
230pid_t
231daemonise(void)
232{
233#ifdef THERE_IS_NO_FORK
234        return -1;
235#else
236        pid_t pid;
237        char buf = '\0';
238        int sidpipe[2], fd;
239
240        if (options & DHCPCD_DAEMONISE && !(options & DHCPCD_DAEMONISED)) {
241                if (options & DHCPCD_WAITIP4 &&
242                    !ipv4_addrexists(NULL))
243                        return -1;
244                if (options & DHCPCD_WAITIP6 &&
245                    !ipv6nd_addrexists(NULL) &&
246                    !dhcp6_addrexists(NULL))
247                        return -1;
248                if ((options &
249                    (DHCPCD_WAITIP | DHCPCD_WAITIP4 | DHCPCD_WAITIP6)) ==
250                    DHCPCD_WAITIP &&
251                    !ipv4_addrexists(NULL) &&
252                    !ipv6nd_addrexists(NULL) &&
253                    !dhcp6_addrexists(NULL))
254                        return -1;
255        }
256
257        eloop_timeout_delete(handle_exit_timeout, NULL);
258        if (options & DHCPCD_DAEMONISED || !(options & DHCPCD_DAEMONISE))
259                return 0;
260        /* Setup a signal pipe so parent knows when to exit. */
261        if (pipe(sidpipe) == -1) {
262                syslog(LOG_ERR, "pipe: %m");
263                return -1;
264        }
265        syslog(LOG_DEBUG, "forking to background");
266        switch (pid = fork()) {
267        case -1:
268                syslog(LOG_ERR, "fork: %m");
269                exit(EXIT_FAILURE);
270                /* NOTREACHED */
271        case 0:
272                setsid();
273                /* Notify parent it's safe to exit as we've detached. */
274                close(sidpipe[0]);
275                if (write(sidpipe[1], &buf, 1) == -1)
276                        syslog(LOG_ERR, "failed to notify parent: %m");
277                close(sidpipe[1]);
278                if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
279                        dup2(fd, STDIN_FILENO);
280                        dup2(fd, STDOUT_FILENO);
281                        dup2(fd, STDERR_FILENO);
282                        close(fd);
283                }
284                break;
285        default:
286                /* Wait for child to detach */
287                close(sidpipe[1]);
288                if (read(sidpipe[0], &buf, 1) == -1)
289                        syslog(LOG_ERR, "failed to read child: %m");
290                close(sidpipe[0]);
291                break;
292        }
293        /* Done with the fd now */
294        if (pid != 0) {
295                syslog(LOG_INFO, "forked to background, child pid %d",pid);
296                writepid(pidfd, pid);
297                close(pidfd);
298                pidfd = -1;
299                options |= DHCPCD_FORKED;
300                exit(EXIT_SUCCESS);
301        }
302        options |= DHCPCD_DAEMONISED;
303        return pid;
304#endif
305}
306
307struct interface *
308find_interface(const char *ifname)
309{
310        struct interface *ifp;
311
312        TAILQ_FOREACH(ifp, ifaces, next) {
313                if (strcmp(ifp->name, ifname) == 0)
314                        return ifp;
315        }
316        return NULL;
317}
318
319static void
320stop_interface(struct interface *ifp)
321{
322
323        syslog(LOG_INFO, "%s: removing interface", ifp->name);
324        ifp->options->options |= DHCPCD_STOPPING;
325
326        // Remove the interface from our list
327        TAILQ_REMOVE(ifaces, ifp, next);
328        dhcp6_drop(ifp, NULL);
329        ipv6nd_drop(ifp);
330        dhcp_drop(ifp, "STOP");
331        dhcp_close(ifp);
332        eloop_timeout_delete(NULL, ifp);
333        if (ifp->options->options & DHCPCD_DEPARTED)
334                script_runreason(ifp, "DEPARTED");
335        free_interface(ifp);
336        if (!(options & (DHCPCD_MASTER | DHCPCD_TEST)))
337                exit(EXIT_FAILURE);
338}
339
340static void
341configure_interface1(struct interface *ifp)
342{
343        struct if_options *ifo = ifp->options;
344        int ra_global, ra_iface;
345
346        /* Do any platform specific configuration */
347        if_conf(ifp);
348
349        /* If we want to release a lease, we can't really persist the
350         * address either. */
351        if (ifo->options & DHCPCD_RELEASE)
352                ifo->options &= ~DHCPCD_PERSISTENT;
353
354        if (ifp->flags & IFF_POINTOPOINT && !(ifo->options & DHCPCD_INFORM))
355                ifo->options |= DHCPCD_STATIC;
356        if (ifp->flags & IFF_NOARP ||
357            ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC))
358                ifo->options &= ~(DHCPCD_ARP | DHCPCD_IPV4LL);
359        if (!(ifp->flags & (IFF_POINTOPOINT | IFF_LOOPBACK | IFF_MULTICAST)))
360                ifo->options &= ~DHCPCD_IPV6RS;
361        if (ifo->options & DHCPCD_LINK && carrier_status(ifp) == LINK_UNKNOWN)
362                ifo->options &= ~DHCPCD_LINK;
363
364        if (ifo->metric != -1)
365                ifp->metric = ifo->metric;
366
367        if (!(ifo->options & DHCPCD_IPV6))
368                ifo->options &= ~DHCPCD_IPV6RS;
369
370        /* We want to disable kernel interface RA as early as possible. */
371        if (ifo->options & DHCPCD_IPV6RS) {
372                ra_global = check_ipv6(NULL, options & DHCPCD_IPV6RA_OWN ? 1:0);
373                ra_iface = check_ipv6(ifp->name,
374                    ifp->options->options & DHCPCD_IPV6RA_OWN ? 1 : 0);
375                if (ra_global == -1 || ra_iface == -1)
376                        ifo->options &= ~DHCPCD_IPV6RS;
377                else if (ra_iface == 0)
378                        ifo->options |= DHCPCD_IPV6RA_OWN;
379        }
380
381        /* If we haven't specified a ClientID and our hardware address
382         * length is greater than DHCP_CHADDR_LEN then we enforce a ClientID
383         * of the hardware address family and the hardware address. */
384        if (ifp->hwlen > DHCP_CHADDR_LEN)
385                ifo->options |= DHCPCD_CLIENTID;
386
387        /* Firewire and InfiniBand interfaces require ClientID and
388         * the broadcast option being set. */
389        switch (ifp->family) {
390        case ARPHRD_IEEE1394:   /* FALLTHROUGH */
391        case ARPHRD_INFINIBAND:
392                ifo->options |= DHCPCD_CLIENTID | DHCPCD_BROADCAST;
393                break;
394        }
395
396        if (!(ifo->options & DHCPCD_IAID)) {
397                /*
398                 * An IAID is for identifying a unqiue interface within
399                 * the client. It is 4 bytes long. Working out a default
400                 * value is problematic.
401                 *
402                 * Interface name and number are not stable
403                 * between different OS's. Some OS's also cannot make
404                 * up their mind what the interface should be called
405                 * (yes, udev, I'm looking at you).
406                 * Also, the name could be longer than 4 bytes.
407                 * Also, with pluggable interfaces the name and index
408                 * could easily get swapped per actual interface.
409                 *
410                 * The MAC address is 6 bytes long, the final 3
411                 * being unique to the manufacturer and the initial 3
412                 * being unique to the organisation which makes it.
413                 * We could use the last 4 bytes of the MAC address
414                 * as the IAID as it's the most stable part given the
415                 * above, but equally it's not guaranteed to be
416                 * unique.
417                 *
418                 * Given the above, and our need to reliably work
419                 * between reboots without persitent storage,
420                 * generating the IAID from the MAC address is the only
421                 * logical default.
422                 *
423                 * dhclient uses the last 4 bytes of the MAC address.
424                 * dibbler uses an increamenting counter.
425                 * wide-dhcpv6 uses 0 or a configured value.
426                 * odhcp6c uses 1.
427                 * Windows 7 uses the first 3 bytes of the MAC address
428                 * and an unknown byte.
429                 * dhcpcd-6.1.0 and earlier used the interface name,
430                 * falling back to interface index if name > 4.
431                 */
432                memcpy(ifo->iaid, ifp->hwaddr + ifp->hwlen - sizeof(ifo->iaid),
433                    sizeof(ifo->iaid));
434#if 0
435                len = strlen(ifp->name);
436                if (len <= sizeof(ifo->iaid)) {
437                        memcpy(ifo->iaid, ifp->name, len);
438                        memset(ifo->iaid + len, 0, sizeof(ifo->iaid) - len);
439                } else {
440                        /* IAID is the same size as a uint32_t */
441                        len = htonl(ifp->index);
442                        memcpy(ifo->iaid, &len, sizeof(len));
443                }
444#endif
445                ifo->options |= DHCPCD_IAID;
446        }
447
448#ifdef INET6
449        if (ifo->ia == NULL && ifo->options & DHCPCD_IPV6) {
450                ifo->ia = malloc(sizeof(*ifo->ia));
451                if (ifo->ia == NULL)
452                        syslog(LOG_ERR, "%s: %m", __func__);
453                else {
454                        if (ifo->ia_type == 0)
455                                ifo->ia_type = D6_OPTION_IA_NA;
456                        memcpy(ifo->ia->iaid, ifo->iaid, sizeof(ifo->iaid));
457                        ifo->ia_len = 1;
458                        ifo->ia->sla = NULL;
459                        ifo->ia->sla_len = 0;
460                }
461        }
462#endif
463
464        /* If we are not sending an authentication option, don't require it */
465        if (!(ifo->auth.options & DHCPCD_AUTH_SEND))
466                ifo->auth.options &= ~DHCPCD_AUTH_REQUIRE;
467
468}
469
470int
471select_profile(struct interface *ifp, const char *profile)
472{
473        struct if_options *ifo;
474        int ret;
475
476        ret = 0;
477        ifo = read_config(cffile, ifp->name, ifp->ssid, profile);
478        if (ifo == NULL) {
479                syslog(LOG_DEBUG, "%s: no profile %s", ifp->name, profile);
480                ret = -1;
481                goto exit;
482        }
483        if (profile != NULL) {
484                strlcpy(ifp->profile, profile, sizeof(ifp->profile));
485                syslog(LOG_INFO, "%s: selected profile %s",
486                    ifp->name, profile);
487        } else
488                *ifp->profile = '\0';
489        free_options(ifp->options);
490        ifp->options = ifo;
491
492exit:
493        if (profile)
494                configure_interface1(ifp);
495        return ret;
496}
497
498static void
499configure_interface(struct interface *ifp, int argc, char **argv)
500{
501
502        select_profile(ifp, NULL);
503        add_options(ifp->name, ifp->options, argc, argv);
504        configure_interface1(ifp);
505}
506
507void
508handle_carrier(int carrier, int flags, const char *ifname)
509{
510        struct interface *ifp;
511
512        ifp = find_interface(ifname);
513        if (ifp == NULL || !(ifp->options->options & DHCPCD_LINK))
514                return;
515
516        if (carrier == LINK_UNKNOWN)
517                carrier = carrier_status(ifp); /* will set ifp->flags */
518        else
519                ifp->flags = flags;
520
521        if (carrier == LINK_UNKNOWN)
522                syslog(LOG_ERR, "%s: carrier_status: %m", ifname);
523        /* IFF_RUNNING is checked, if needed, earlier and is OS dependant */
524        else if (carrier == LINK_DOWN || (ifp->flags & IFF_UP) == 0) {
525                if (ifp->carrier != LINK_DOWN) {
526                        if (ifp->carrier == LINK_UP)
527                                syslog(LOG_INFO, "%s: carrier lost", ifp->name);
528                        ifp->carrier = LINK_DOWN;
529                        dhcp_close(ifp);
530                        dhcp6_drop(ifp, "EXPIRE6");
531                        ipv6nd_drop(ifp);
532                        /* Don't blindly delete our knowledge of LL addresses.
533                         * We need to listen to what the kernel does with
534                         * them as some OS's will remove, mark tentative or
535                         * do nothing. */
536                        ipv6_free_ll_callbacks(ifp);
537                        dhcp_drop(ifp, "NOCARRIER");
538                }
539        } else if (carrier == LINK_UP && ifp->flags & IFF_UP) {
540                if (ifp->carrier != LINK_UP) {
541                        syslog(LOG_INFO, "%s: carrier acquired", ifp->name);
542                        ifp->carrier = LINK_UP;
543#if !defined(__linux__) && !defined(__NetBSD__)
544                        /* BSD does not emit RTM_NEWADDR or RTM_CHGADDR when the
545                         * hardware address changes so we have to go
546                         * through the disovery process to work it out. */
547                        handle_interface(0, ifp->name);
548#endif
549                        if (ifp->wireless)
550                                getifssid(ifp->name, ifp->ssid);
551                        configure_interface(ifp, margc, margv);
552                        script_runreason(ifp, "CARRIER");
553                        start_interface(ifp);
554                }
555        }
556}
557
558static void
559warn_iaid_conflict(struct interface *ifp, uint8_t *iaid)
560{
561        struct interface *ifn;
562        size_t i;
563
564        TAILQ_FOREACH(ifn, ifaces, next) {
565                if (ifn == ifp)
566                        continue;
567                if (memcmp(ifn->options->iaid, iaid,
568                    sizeof(ifn->options->iaid)) == 0)
569                        break;
570                for (i = 0; i < ifn->options->ia_len; i++) {
571                        if (memcmp(&ifn->options->ia[i].iaid, iaid,
572                            sizeof(ifn->options->ia[i].iaid)) == 0)
573                                break;
574                }
575        }
576
577        /* This is only a problem if the interfaces are on the same network. */
578        if (ifn)
579                syslog(LOG_ERR,
580                    "%s: IAID conflicts with one assigned to %s",
581                    ifp->name, ifn->name);
582}
583
584void
585start_interface(void *arg)
586{
587        struct interface *ifp = arg;
588        struct if_options *ifo = ifp->options;
589        int nolease;
590        size_t i;
591
592        handle_carrier(LINK_UNKNOWN, 0, ifp->name);
593        if (ifp->carrier == LINK_DOWN) {
594                syslog(LOG_INFO, "%s: waiting for carrier", ifp->name);
595                return;
596        }
597
598        if (ifo->options & (DHCPCD_DUID | DHCPCD_IPV6)) {
599                /* Report client DUID */
600                if (duid == NULL) {
601                        if (duid_init(ifp) == 0)
602                                return;
603                        syslog(LOG_INFO, "DUID %s",
604                            hwaddr_ntoa(duid, duid_len));
605                }
606
607                /* Report IAIDs */
608                syslog(LOG_INFO, "%s: IAID %s", ifp->name,
609                    hwaddr_ntoa(ifo->iaid, sizeof(ifo->iaid)));
610                warn_iaid_conflict(ifp, ifo->iaid);
611                for (i = 0; i < ifo->ia_len; i++) {
612                        if (memcmp(ifo->iaid, ifo->ia[i].iaid,
613                            sizeof(ifo->iaid)))
614                        {
615                                syslog(LOG_INFO, "%s: IAID %s", ifp->name,
616                                    hwaddr_ntoa(ifo->ia[i].iaid,
617                                    sizeof(ifo->ia[i].iaid)));
618                                warn_iaid_conflict(ifp, ifo->ia[i].iaid);
619                        }
620                }
621        }
622
623        if (ifo->options & DHCPCD_IPV6) {
624                if (ifo->options & DHCPCD_IPV6RS &&
625                    !(ifo->options & DHCPCD_INFORM))
626                        ipv6nd_startrs(ifp);
627
628                if (!(ifo->options & DHCPCD_IPV6RS)) {
629                        if (ifo->options & DHCPCD_IA_FORCED)
630                                nolease = dhcp6_start(ifp, DH6S_INIT);
631                        else {
632                                nolease = dhcp6_find_delegates(ifp);
633                                /* Enabling the below doesn't really make
634                                 * sense as there is currently no standard
635                                 * to push routes via DHCPv6.
636                                 * (There is an expired working draft,
637                                 * maybe abandoned?)
638                                 * You can also get it to work by forcing
639                                 * an IA as shown above. */
640#if 0
641                                /* With no RS or delegates we might
642                                 * as well try and solicit a DHCPv6 address */
643                                if (nolease == 0)
644                                        nolease = dhcp6_start(ifp, DH6S_INIT);
645#endif
646                        }
647                        if (nolease == -1)
648                                syslog(LOG_ERR,
649                                    "%s: dhcp6_start: %m", ifp->name);
650                }
651        }
652
653        if (ifo->options & DHCPCD_IPV4)
654                dhcp_start(ifp);
655}
656
657/* ARGSUSED */
658static void
659handle_link(__unused void *arg)
660{
661
662        if (manage_link(linkfd) == -1 && errno != ENXIO && errno != ENODEV)
663                syslog(LOG_ERR, "manage_link: %m");
664}
665
666static void
667init_state(struct interface *ifp, int argc, char **argv)
668{
669        struct if_options *ifo;
670        const char *reason = NULL;
671
672        configure_interface(ifp, argc, argv);
673        ifo = ifp->options;
674
675        if (ifo->options & DHCPCD_IPV4 && ipv4_init() == -1) {
676                syslog(LOG_ERR, "ipv4_init: %m");
677                ifo->options &= ~DHCPCD_IPV4;
678        }
679        if (ifo->options & DHCPCD_IPV6 && ipv6_init() == -1) {
680                syslog(LOG_ERR, "ipv6_init: %m");
681                ifo->options &= ~DHCPCD_IPV6RS;
682        }
683
684        if (!(options & DHCPCD_TEST))
685                script_runreason(ifp, "PREINIT");
686
687        if (ifo->options & DHCPCD_LINK) {
688                switch (carrier_status(ifp)) {
689                case LINK_DOWN:
690                        ifp->carrier = LINK_DOWN;
691                        reason = "NOCARRIER";
692                        break;
693                case LINK_UP:
694                        ifp->carrier = LINK_UP;
695                        reason = "CARRIER";
696                        break;
697                default:
698                        ifp->carrier = LINK_UNKNOWN;
699                        return;
700                }
701                if (reason && !(options & DHCPCD_TEST))
702                        script_runreason(ifp, reason);
703        } else
704                ifp->carrier = LINK_UNKNOWN;
705}
706
707void
708handle_interface(int action, const char *ifname)
709{
710        struct if_head *ifs;
711        struct interface *ifp, *ifn, *ifl = NULL;
712        const char * const argv[] = { ifname };
713        int i;
714
715        if (action == -1) {
716                ifp = find_interface(ifname);
717                if (ifp != NULL) {
718                        ifp->options->options |= DHCPCD_DEPARTED;
719                        stop_interface(ifp);
720                }
721                return;
722        }
723
724        /* If running off an interface list, check it's in it. */
725        if (ifc) {
726                for (i = 0; i < ifc; i++)
727                        if (strcmp(ifv[i], ifname) == 0)
728                                break;
729                if (i >= ifc)
730                        return;
731        }
732
733        ifs = discover_interfaces(-1, UNCONST(argv));
734        TAILQ_FOREACH_SAFE(ifp, ifs, next, ifn) {
735                if (strcmp(ifp->name, ifname) != 0)
736                        continue;
737                /* Check if we already have the interface */
738                ifl = find_interface(ifp->name);
739                if (ifl) {
740                        /* The flags and hwaddr could have changed */
741                        ifl->flags = ifp->flags;
742                        ifl->hwlen = ifp->hwlen;
743                        if (ifp->hwlen != 0)
744                                memcpy(ifl->hwaddr, ifp->hwaddr, ifl->hwlen);
745                } else {
746                        TAILQ_REMOVE(ifs, ifp, next);
747                        TAILQ_INSERT_TAIL(ifaces, ifp, next);
748                }
749                if (action == 1) {
750                        init_state(ifp, margc, margv);
751                        start_interface(ifp);
752                }
753        }
754
755        /* Free our discovered list */
756        while ((ifp = TAILQ_FIRST(ifs))) {
757                TAILQ_REMOVE(ifs, ifp, next);
758                free_interface(ifp);
759        }
760        free(ifs);
761}
762
763void
764handle_hwaddr(const char *ifname, const uint8_t *hwaddr, size_t hwlen)
765{
766        struct interface *ifp;
767
768        ifp = find_interface(ifname);
769        if (ifp == NULL)
770                return;
771
772        if (hwlen > sizeof(ifp->hwaddr)) {
773                errno = ENOBUFS;
774                syslog(LOG_ERR, "%s: %s: %m", ifp->name, __func__);
775                return;
776        }
777
778        if (ifp->hwlen == hwlen && memcmp(ifp->hwaddr, hwaddr, hwlen) == 0)
779                return;
780
781        syslog(LOG_INFO, "%s: new hardware address: %s", ifp->name,
782            hwaddr_ntoa(hwaddr, hwlen));
783        ifp->hwlen = hwlen;
784        memcpy(ifp->hwaddr, hwaddr, hwlen);
785}
786
787static void
788if_reboot(struct interface *ifp, int argc, char **argv)
789{
790        int oldopts;
791
792        oldopts = ifp->options->options;
793        script_runreason(ifp, "RECONFIGURE");
794        configure_interface(ifp, argc, argv);
795        dhcp_reboot_newopts(ifp, oldopts);
796        dhcp6_reboot(ifp);
797        start_interface(ifp);
798}
799
800static void
801reconf_reboot(int action, int argc, char **argv, int oi)
802{
803        struct if_head *ifs;
804        struct interface *ifn, *ifp;
805
806        ifs = discover_interfaces(argc - oi, argv + oi);
807        if (ifs == NULL)
808                return;
809
810        while ((ifp = TAILQ_FIRST(ifs))) {
811                TAILQ_REMOVE(ifs, ifp, next);
812                ifn = find_interface(ifp->name);
813                if (ifn) {
814                        if (action)
815                                if_reboot(ifn, argc, argv);
816                        else
817                                ipv4_applyaddr(ifn);
818                        free_interface(ifp);
819                } else {
820                        init_state(ifp, argc, argv);
821                        TAILQ_INSERT_TAIL(ifaces, ifp, next);
822                        start_interface(ifp);
823                }
824        }
825        free(ifs);
826
827        sort_interfaces();
828}
829
830/* ARGSUSED */
831static void
832sig_reboot(void *arg)
833{
834        siginfo_t *siginfo = arg;
835        struct if_options *ifo;
836
837        syslog(LOG_INFO, "received SIGALRM from PID %d, rebinding",
838            (int)siginfo->si_pid);
839
840        free_globals();
841        ifav = NULL;
842        ifac = 0;
843        ifdc = 0;
844        ifdv = NULL;
845
846        ifo = read_config(cffile, NULL, NULL, NULL);
847        add_options(NULL, ifo, margc, margv);
848        /* We need to preserve these two options. */
849        if (options & DHCPCD_MASTER)
850                ifo->options |= DHCPCD_MASTER;
851        if (options & DHCPCD_DAEMONISED)
852                ifo->options |= DHCPCD_DAEMONISED;
853        options = ifo->options;
854        free_options(ifo);
855        reconf_reboot(1, ifc, ifv, 0);
856}
857
858static void
859sig_reconf(void *arg)
860{
861        siginfo_t *siginfo = arg;
862        struct interface *ifp;
863
864        syslog(LOG_INFO, "received SIGUSR from PID %d, reconfiguring",
865            (int)siginfo->si_pid);
866        TAILQ_FOREACH(ifp, ifaces, next) {
867                ipv4_applyaddr(ifp);
868        }
869}
870
871static void
872handle_signal(int sig, siginfo_t *siginfo, __unused void *context)
873{
874        struct interface *ifp;
875        int do_release;
876
877        do_release = 0;
878        switch (sig) {
879        case SIGINT:
880                syslog(LOG_INFO, "received SIGINT from PID %d, stopping",
881                    (int)siginfo->si_pid);
882                break;
883        case SIGTERM:
884                syslog(LOG_INFO, "received SIGTERM from PID %d, stopping",
885                    (int)siginfo->si_pid);
886                break;
887        case SIGALRM:
888                eloop_timeout_add_now(sig_reboot, siginfo);
889                return;
890        case SIGHUP:
891                syslog(LOG_INFO, "received SIGHUP from PID %d, releasing",
892                    (int)siginfo->si_pid);
893                do_release = 1;
894                break;
895        case SIGUSR1:
896                eloop_timeout_add_now(sig_reconf, siginfo);
897                return;
898        case SIGPIPE:
899                syslog(LOG_WARNING, "received SIGPIPE");
900                return;
901        default:
902                syslog(LOG_ERR,
903                    "received signal %d from PID %d, "
904                    "but don't know what to do with it",
905                    sig, (int)siginfo->si_pid);
906                return;
907        }
908
909        if (options & DHCPCD_TEST)
910                exit(EXIT_FAILURE);
911
912        /* As drop_dhcp could re-arrange the order, we do it like this. */
913        for (;;) {
914                /* Be sane and drop the last config first */
915                ifp = TAILQ_LAST(ifaces, if_head);
916                if (ifp == NULL)
917                        break;
918                if (do_release) {
919                        ifp->options->options |= DHCPCD_RELEASE;
920                        ifp->options->options &= ~DHCPCD_PERSISTENT;
921                }
922                ifp->options->options |= DHCPCD_EXITING;
923                stop_interface(ifp);
924        }
925        exit(EXIT_FAILURE);
926}
927
928int
929handle_args(struct fd_list *fd, int argc, char **argv)
930{
931        struct interface *ifp;
932        int do_exit = 0, do_release = 0, do_reboot = 0;
933        int opt, oi = 0;
934        ssize_t len;
935        size_t l;
936        struct iovec iov[2];
937        char *tmp, *p;
938
939        if (fd != NULL) {
940                /* Special commands for our control socket */
941                if (strcmp(*argv, "--version") == 0) {
942                        len = strlen(VERSION) + 1;
943                        iov[0].iov_base = &len;
944                        iov[0].iov_len = sizeof(ssize_t);
945                        iov[1].iov_base = UNCONST(VERSION);
946                        iov[1].iov_len = len;
947                        if (writev(fd->fd, iov, 2) == -1) {
948                                syslog(LOG_ERR, "writev: %m");
949                                return -1;
950                        }
951                        return 0;
952                } else if (strcmp(*argv, "--getconfigfile") == 0) {
953                        len = strlen(cffile ? cffile : CONFIG) + 1;
954                        iov[0].iov_base = &len;
955                        iov[0].iov_len = sizeof(ssize_t);
956                        iov[1].iov_base = cffile ? cffile : UNCONST(CONFIG);
957                        iov[1].iov_len = len;
958                        if (writev(fd->fd, iov, 2) == -1) {
959                                syslog(LOG_ERR, "writev: %m");
960                                return -1;
961                        }
962                        return 0;
963                } else if (strcmp(*argv, "--getinterfaces") == 0) {
964                        len = 0;
965                        if (argc == 1) {
966                                TAILQ_FOREACH(ifp, ifaces, next) {
967                                        len++;
968                                        if (D6_STATE_RUNNING(ifp))
969                                                len++;
970                                        if (ipv6nd_has_ra(ifp))
971                                                len++;
972                                }
973                                len = write(fd->fd, &len, sizeof(len));
974                                if (len != sizeof(len))
975                                        return -1;
976                                TAILQ_FOREACH(ifp, ifaces, next) {
977                                        send_interface(fd->fd, ifp);
978                                }
979                                return 0;
980                        }
981                        opt = 0;
982                        while (argv[++opt] != NULL) {
983                                TAILQ_FOREACH(ifp, ifaces, next) {
984                                        if (strcmp(argv[opt], ifp->name) == 0) {
985                                                len++;
986                                                if (D6_STATE_RUNNING(ifp))
987                                                        len++;
988                                                if (ipv6nd_has_ra(ifp))
989                                                        len++;
990                                        }
991                                }
992                        }
993                        len = write(fd->fd, &len, sizeof(len));
994                        if (len != sizeof(len))
995                                return -1;
996                        opt = 0;
997                        while (argv[++opt] != NULL) {
998                                TAILQ_FOREACH(ifp, ifaces, next) {
999                                        if (strcmp(argv[opt], ifp->name) == 0)
1000                                                send_interface(fd->fd, ifp);
1001                                }
1002                        }
1003                        return 0;
1004                } else if (strcmp(*argv, "--listen") == 0) {
1005                        fd->listener = 1;
1006                        return 0;
1007                }
1008        }
1009
1010        /* Log the command */
1011        len = 0;
1012        for (opt = 0; opt < argc; opt++)
1013                len += strlen(argv[opt]) + 1;
1014        tmp = p = malloc(len + 1);
1015        if (tmp == NULL) {
1016                syslog(LOG_ERR, "%s: %m", __func__);
1017                return -1;
1018        }
1019        for (opt = 0; opt < argc; opt++) {
1020                l = strlen(argv[opt]);
1021                strlcpy(p, argv[opt], l + 1);
1022                p += l;
1023                *p++ = ' ';
1024        }
1025        *--p = '\0';
1026        syslog(LOG_INFO, "control command: %s", tmp);
1027        free(tmp);
1028
1029        optind = 0;
1030        while ((opt = getopt_long(argc, argv, IF_OPTS, cf_options, &oi)) != -1)
1031        {
1032                switch (opt) {
1033                case 'g':
1034                        /* Assumed if below not set */
1035                        break;
1036                case 'k':
1037                        do_release = 1;
1038                        break;
1039                case 'n':
1040                        do_reboot = 1;
1041                        break;
1042                case 'x':
1043                        do_exit = 1;
1044                        break;
1045                }
1046        }
1047
1048        /* We need at least one interface */
1049        if (optind == argc) {
1050                syslog(LOG_ERR, "%s: no interface", __func__);
1051                return -1;
1052        }
1053
1054        if (do_release || do_exit) {
1055                for (oi = optind; oi < argc; oi++) {
1056                        if ((ifp = find_interface(argv[oi])) == NULL)
1057                                continue;
1058                        if (do_release) {
1059                                ifp->options->options |= DHCPCD_RELEASE;
1060                                ifp->options->options &= ~DHCPCD_PERSISTENT;
1061                        }
1062                        ifp->options->options |= DHCPCD_EXITING;
1063                        stop_interface(ifp);
1064                }
1065                return 0;
1066        }
1067
1068        reconf_reboot(do_reboot, argc, argv, optind);
1069        return 0;
1070}
1071
1072static int
1073signal_init(void (*func)(int, siginfo_t *, void *), sigset_t *oldset)
1074{
1075        unsigned int i;
1076        struct sigaction sa;
1077        sigset_t newset;
1078
1079        sigfillset(&newset);
1080        if (sigprocmask(SIG_SETMASK, &newset, oldset) == -1)
1081                return -1;
1082
1083        memset(&sa, 0, sizeof(sa));
1084        sa.sa_sigaction = func;
1085        sa.sa_flags = SA_SIGINFO;
1086        sigemptyset(&sa.sa_mask);
1087
1088        for (i = 0; handle_sigs[i]; i++) {
1089                if (sigaction(handle_sigs[i], &sa, NULL) == -1)
1090                        return -1;
1091        }
1092        return 0;
1093}
1094
1095int
1096main(int argc, char **argv)
1097{
1098        struct interface *ifp;
1099        uint16_t family = 0;
1100        int opt, oi = 0, sig = 0, i, control_fd;
1101        size_t len;
1102        pid_t pid;
1103        struct timespec ts;
1104        struct utsname utn;
1105        const char *platform;
1106
1107        closefrom(3);
1108        openlog(PACKAGE, LOG_PERROR | LOG_PID, LOG_DAEMON);
1109        setlogmask(LOG_UPTO(LOG_INFO));
1110
1111        /* Test for --help and --version */
1112        if (argc > 1) {
1113                if (strcmp(argv[1], "--help") == 0) {
1114                        usage();
1115                        exit(EXIT_SUCCESS);
1116                } else if (strcmp(argv[1], "--version") == 0) {
1117                        printf(""PACKAGE" "VERSION"\n%s\n", dhcpcd_copyright);
1118                        exit(EXIT_SUCCESS);
1119                }
1120        }
1121
1122        platform = hardware_platform();
1123        if (uname(&utn) == 0)
1124                snprintf(vendor, VENDORCLASSID_MAX_LEN,
1125                    "%s-%s:%s-%s:%s%s%s", PACKAGE, VERSION,
1126                    utn.sysname, utn.release, utn.machine,
1127                    platform ? ":" : "", platform ? platform : "");
1128        else
1129                snprintf(vendor, VENDORCLASSID_MAX_LEN,
1130                    "%s-%s", PACKAGE, VERSION);
1131
1132        i = 0;
1133        while ((opt = getopt_long(argc, argv, IF_OPTS, cf_options, &oi)) != -1)
1134        {
1135                switch (opt) {
1136                case '4':
1137                        family = AF_INET;
1138                        break;
1139                case '6':
1140                        family = AF_INET6;
1141                        break;
1142                case 'f':
1143                        cffile = optarg;
1144                        break;
1145                case 'g':
1146                        sig = SIGUSR1;
1147                        break;
1148                case 'k':
1149                        sig = SIGHUP;
1150                        break;
1151                case 'n':
1152                        sig = SIGALRM;
1153                        break;
1154                case 'x':
1155                        sig = SIGTERM;
1156                        break;
1157                case 'T':
1158                        i = 1;
1159                        break;
1160                case 'U':
1161                        i = 2;
1162                        break;
1163                case 'V':
1164                        i = 3;
1165                        break;
1166                case '?':
1167                        usage();
1168                        exit(EXIT_FAILURE);
1169                }
1170        }
1171
1172        margv = argv;
1173        margc = argc;
1174        if_options = read_config(cffile, NULL, NULL, NULL);
1175        opt = add_options(NULL, if_options, argc, argv);
1176        if (opt != 1) {
1177                if (opt == 0)
1178                        usage();
1179                exit(EXIT_FAILURE);
1180        }
1181        if (i == 3) {
1182                printf("Interface options:\n");
1183                if_printoptions();
1184#ifdef INET
1185                if (family == 0 || family == AF_INET) {
1186                        printf("\nDHCPv4 options:\n");
1187                        dhcp_printoptions();
1188                }
1189#endif
1190#ifdef INET6
1191                if (family == 0 || family == AF_INET6) {
1192                        printf("\nDHCPv6 options:\n");
1193                        dhcp6_printoptions();
1194                }
1195#endif
1196#ifdef DEBUG_MEMORY
1197                cleanup();
1198#endif
1199                exit(EXIT_SUCCESS);
1200        }
1201        options = if_options->options;
1202        if (i != 0) {
1203                if (i == 1)
1204                        options |= DHCPCD_TEST;
1205                else
1206                        options |= DHCPCD_DUMPLEASE;
1207                options |= DHCPCD_PERSISTENT;
1208                options &= ~DHCPCD_DAEMONISE;
1209        }
1210
1211#ifdef THERE_IS_NO_FORK
1212        options &= ~DHCPCD_DAEMONISE;
1213#endif
1214
1215        if (options & DHCPCD_DEBUG)
1216                setlogmask(LOG_UPTO(LOG_DEBUG));
1217        if (options & DHCPCD_QUIET) {
1218                i = open(_PATH_DEVNULL, O_RDWR);
1219                if (i == -1)
1220                        syslog(LOG_ERR, "%s: open: %m", __func__);
1221                else {
1222                        dup2(i, STDERR_FILENO);
1223                        close(i);
1224                }
1225        }
1226
1227        if (!(options & (DHCPCD_TEST | DHCPCD_DUMPLEASE))) {
1228                /* If we have any other args, we should run as a single dhcpcd
1229                 *  instance for that interface. */
1230                len = strlen(PIDFILE) + IF_NAMESIZE + 2;
1231                pidfile = malloc(len);
1232                if (pidfile == NULL) {
1233                        syslog(LOG_ERR, "%s: %m", __func__);
1234                        exit(EXIT_FAILURE);
1235                }
1236                if (optind == argc - 1)
1237                        snprintf(pidfile, len, PIDFILE, "-", argv[optind]);
1238                else {
1239                        snprintf(pidfile, len, PIDFILE, "", "");
1240                        options |= DHCPCD_MASTER;
1241                }
1242        }
1243
1244        if (chdir("/") == -1)
1245                syslog(LOG_ERR, "chdir `/': %m");
1246        atexit(cleanup);
1247
1248        if (options & DHCPCD_DUMPLEASE) {
1249                if (optind != argc - 1) {
1250                        syslog(LOG_ERR, "dumplease requires an interface");
1251                        exit(EXIT_FAILURE);
1252                }
1253                if (dhcp_dump(argv[optind]) == -1)
1254                        exit(EXIT_FAILURE);
1255                exit(EXIT_SUCCESS);
1256        }
1257
1258        if (!(options & (DHCPCD_MASTER | DHCPCD_TEST))) {
1259                control_fd = control_open();
1260                if (control_fd != -1) {
1261                        syslog(LOG_INFO,
1262                            "sending commands to master dhcpcd process");
1263                        i = control_send(argc, argv);
1264                        if (i > 0) {
1265                                syslog(LOG_DEBUG, "send OK");
1266                                exit(EXIT_SUCCESS);
1267                        } else {
1268                                syslog(LOG_ERR, "failed to send commands");
1269                                exit(EXIT_FAILURE);
1270                        }
1271                } else {
1272                        if (errno != ENOENT)
1273                                syslog(LOG_ERR, "control_open: %m");
1274                }
1275        }
1276
1277        if (geteuid())
1278                syslog(LOG_WARNING,
1279                    PACKAGE " will not work correctly unless run as root");
1280
1281        if (sig != 0) {
1282                pid = read_pid();
1283                if (pid != 0)
1284                        syslog(LOG_INFO, "sending signal %d to pid %d",
1285                            sig, pid);
1286                if (pid == 0 || kill(pid, sig) != 0) {
1287                        if (sig != SIGALRM && errno != EPERM)
1288                                syslog(LOG_ERR, ""PACKAGE" not running");
1289                        if (pid != 0 && errno != ESRCH) {
1290                                syslog(LOG_ERR, "kill: %m");
1291                                exit(EXIT_FAILURE);
1292                        }
1293                        unlink(pidfile);
1294                        if (sig != SIGALRM)
1295                                exit(EXIT_FAILURE);
1296                } else {
1297                        if (sig == SIGALRM || sig == SIGUSR1)
1298                                exit(EXIT_SUCCESS);
1299                        /* Spin until it exits */
1300                        syslog(LOG_INFO, "waiting for pid %d to exit", pid);
1301                        ts.tv_sec = 0;
1302                        ts.tv_nsec = 100000000; /* 10th of a second */
1303                        for(i = 0; i < 100; i++) {
1304                                nanosleep(&ts, NULL);
1305                                if (read_pid() == 0)
1306                                        exit(EXIT_SUCCESS);
1307                        }
1308                        syslog(LOG_ERR, "pid %d failed to exit", pid);
1309                        exit(EXIT_FAILURE);
1310                }
1311        }
1312
1313        if (!(options & DHCPCD_TEST)) {
1314                if ((pid = read_pid()) > 0 &&
1315                    kill(pid, 0) == 0)
1316                {
1317                        syslog(LOG_ERR, ""PACKAGE
1318                            " already running on pid %d (%s)",
1319                            pid, pidfile);
1320                        exit(EXIT_FAILURE);
1321                }
1322
1323                /* Ensure we have the needed directories */
1324                if (mkdir(RUNDIR, 0755) == -1 && errno != EEXIST)
1325                        syslog(LOG_ERR, "mkdir `%s': %m", RUNDIR);
1326                if (mkdir(DBDIR, 0755) == -1 && errno != EEXIST)
1327                        syslog(LOG_ERR, "mkdir `%s': %m", DBDIR);
1328
1329                pidfd = open(pidfile, O_WRONLY | O_CREAT | O_NONBLOCK, 0664);
1330                if (pidfd == -1)
1331                        syslog(LOG_ERR, "open `%s': %m", pidfile);
1332                else {
1333                        /* Lock the file so that only one instance of dhcpcd
1334                         * runs on an interface */
1335                        if (flock(pidfd, LOCK_EX | LOCK_NB) == -1) {
1336                                syslog(LOG_ERR, "flock `%s': %m", pidfile);
1337                                exit(EXIT_FAILURE);
1338                        }
1339                        if (set_cloexec(pidfd) == -1)
1340                                exit(EXIT_FAILURE);
1341                        writepid(pidfd, getpid());
1342                }
1343        }
1344
1345        syslog(LOG_INFO, "version " VERSION " starting");
1346        options |= DHCPCD_STARTED;
1347
1348#ifdef DEBUG_MEMORY
1349        eloop_init();
1350#endif
1351
1352        /* Save signal mask, block and redirect signals to our handler */
1353        if (signal_init(handle_signal, &dhcpcd_sigset) == -1) {
1354                syslog(LOG_ERR, "signal_setup: %m");
1355                exit(EXIT_FAILURE);
1356        }
1357
1358        if (options & DHCPCD_MASTER) {
1359                if (control_start() == -1)
1360                        syslog(LOG_ERR, "control_start: %m");
1361        }
1362
1363        if (open_sockets() == -1) {
1364                syslog(LOG_ERR, "open_sockets: %m");
1365                exit(EXIT_FAILURE);
1366        }
1367
1368#if 0
1369        if (options & DHCPCD_IPV6RS && disable_rtadv() == -1) {
1370                syslog(LOG_ERR, "disable_rtadvd: %m");
1371                options &= ~DHCPCD_IPV6RS;
1372        }
1373#endif
1374
1375        ifc = argc - optind;
1376        ifv = argv + optind;
1377
1378        /* When running dhcpcd against a single interface, we need to retain
1379         * the old behaviour of waiting for an IP address */
1380        if (ifc == 1 && !(options & DHCPCD_BACKGROUND))
1381                options |= DHCPCD_WAITIP;
1382
1383        /* RTM_NEWADDR goes through the link socket as well which we
1384         * need for IPv6 DAD, so we check for DHCPCD_LINK in handle_carrier
1385         * instead.
1386         * We also need to open this before checking for interfaces below
1387         * so that we pickup any new addresses during the discover phase. */
1388        if (linkfd == -1) {
1389                linkfd = open_link_socket();
1390                if (linkfd == -1)
1391                        syslog(LOG_ERR, "open_link_socket: %m");
1392                else
1393                        eloop_event_add(linkfd, handle_link, NULL);
1394        }
1395
1396        /* Start any dev listening plugin which may want to
1397         * change the interface name provided by the kernel */
1398        if ((options & (DHCPCD_MASTER | DHCPCD_DEV)) ==
1399            (DHCPCD_MASTER | DHCPCD_DEV))
1400                dev_start(dev_load);
1401
1402        ifaces = discover_interfaces(ifc, ifv);
1403        for (i = 0; i < ifc; i++) {
1404                if (find_interface(ifv[i]) == NULL)
1405                        syslog(LOG_ERR, "%s: interface not found or invalid",
1406                            ifv[i]);
1407        }
1408        if (ifaces == NULL || TAILQ_FIRST(ifaces) == NULL) {
1409                if (ifc == 0)
1410                        syslog(LOG_ERR, "no valid interfaces found");
1411                else
1412                        exit(EXIT_FAILURE);
1413                if (!(options & DHCPCD_LINK)) {
1414                        syslog(LOG_ERR,
1415                            "aborting as link detection is disabled");
1416                        exit(EXIT_FAILURE);
1417                }
1418        }
1419
1420        if (options & DHCPCD_BACKGROUND)
1421                daemonise();
1422
1423        opt = 0;
1424        TAILQ_FOREACH(ifp, ifaces, next) {
1425                init_state(ifp, argc, argv);
1426                if (ifp->carrier != LINK_DOWN)
1427                        opt = 1;
1428        }
1429
1430        if (!(options & DHCPCD_BACKGROUND)) {
1431                /* If we don't have a carrier, we may have to wait for a second
1432                 * before one becomes available if we brought an interface up */
1433                if (opt == 0 &&
1434                    options & DHCPCD_LINK &&
1435                    options & DHCPCD_WAITUP &&
1436                    !(options & DHCPCD_WAITIP))
1437                {
1438                        ts.tv_sec = 1;
1439                        ts.tv_nsec = 0;
1440                        nanosleep(&ts, NULL);
1441                        TAILQ_FOREACH(ifp, ifaces, next) {
1442                                handle_carrier(LINK_UNKNOWN, 0, ifp->name);
1443                                if (ifp->carrier != LINK_DOWN) {
1444                                        opt = 1;
1445                                        break;
1446                                }
1447                        }
1448                }
1449                if (options & DHCPCD_MASTER)
1450                        i = if_options->timeout;
1451                else if ((ifp = TAILQ_FIRST(ifaces)))
1452                        i = ifp->options->timeout;
1453                else
1454                        i = 0;
1455                if (opt == 0 &&
1456                    options & DHCPCD_LINK &&
1457                    !(options & DHCPCD_WAITIP))
1458                {
1459                        syslog(LOG_WARNING, "no interfaces have a carrier");
1460                        daemonise();
1461                } else if (i > 0) {
1462                        if (options & DHCPCD_IPV4LL)
1463                                options |= DHCPCD_TIMEOUT_IPV4LL;
1464                        eloop_timeout_add_sec(i, handle_exit_timeout, NULL);
1465                }
1466        }
1467        free_options(if_options);
1468        if_options = NULL;
1469
1470        sort_interfaces();
1471        TAILQ_FOREACH(ifp, ifaces, next) {
1472                eloop_timeout_add_sec(0, start_interface, ifp);
1473        }
1474
1475        eloop_start(&dhcpcd_sigset);
1476        exit(EXIT_SUCCESS);
1477}
Note: See TracBrowser for help on using the repository browser.