source: rtems-libbsd/dhcpcd/dhcpcd.c @ 7758fcc

4.115-freebsd-12freebsd-9.3
Last change on this file since 7758fcc was 7758fcc, checked in by Sebastian Huber <sebastian.huber@…>, on Dec 17, 2013 at 1:04:28 PM

DHCPCD(8): Add MASTER_ONLY option

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