2 __RCSID("$NetBSD: if.c,v 1.16 2015/09/04 12:25:01 roy Exp $");
5 * dhcpcd - DHCP client daemon
6 * Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 #include <sys/param.h>
32 #include <sys/types.h>
33 #include <sys/ioctl.h>
34 #include <sys/socket.h>
37 #include <net/if_arp.h>
38 #include <netinet/in.h>
39 #ifdef __FreeBSD__ /* Needed so that including netinet6/in6_var.h works */
40 # include <net/if_var.h>
43 # include <net/if_dl.h>
44 # include <net/if_types.h>
45 # include <netinet/in_var.h>
48 # include <netpacket/packet.h>
51 # include <net/if_media.h>
53 #include <net/route.h>
72 #include "if-options.h"
78 if_free(struct interface
*ifp
)
89 free_options(ifp
->options
);
94 if_opensockets(struct dhcpcd_ctx
*ctx
)
97 if ((ctx
->link_fd
= if_openlinksocket()) == -1)
100 ctx
->pf_inet_fd
= xsocket(PF_INET
, SOCK_DGRAM
, 0, O_CLOEXEC
);
101 if (ctx
->pf_inet_fd
== -1)
104 #if defined(INET6) && defined(BSD)
105 ctx
->pf_inet6_fd
= xsocket(PF_INET6
, SOCK_DGRAM
, 0, O_CLOEXEC
);
106 if (ctx
->pf_inet6_fd
== -1)
111 ctx
->pf_link_fd
= xsocket(PF_LINK
, SOCK_DGRAM
, 0, O_CLOEXEC
);
112 if (ctx
->pf_link_fd
== -1)
120 if_carrier(struct interface
*ifp
)
125 struct ifmediareq ifmr
;
128 memset(&ifr
, 0, sizeof(ifr
));
129 strlcpy(ifr
.ifr_name
, ifp
->name
, sizeof(ifr
.ifr_name
));
130 if (ioctl(ifp
->ctx
->pf_inet_fd
, SIOCGIFFLAGS
, &ifr
) == -1)
132 ifp
->flags
= (unsigned int)ifr
.ifr_flags
;
135 memset(&ifmr
, 0, sizeof(ifmr
));
136 strlcpy(ifmr
.ifm_name
, ifp
->name
, sizeof(ifmr
.ifm_name
));
137 if (ioctl(ifp
->ctx
->pf_inet_fd
, SIOCGIFMEDIA
, &ifmr
) != -1 &&
138 ifmr
.ifm_status
& IFM_AVALID
)
139 r
= (ifmr
.ifm_status
& IFM_ACTIVE
) ? LINK_UP
: LINK_DOWN
;
141 r
= ifr
.ifr_flags
& IFF_RUNNING
? LINK_UP
: LINK_UNKNOWN
;
143 r
= ifr
.ifr_flags
& IFF_RUNNING
? LINK_UP
: LINK_DOWN
;
149 if_setflag(struct interface
*ifp
, short flag
)
154 memset(&ifr
, 0, sizeof(ifr
));
155 strlcpy(ifr
.ifr_name
, ifp
->name
, sizeof(ifr
.ifr_name
));
157 if (ioctl(ifp
->ctx
->pf_inet_fd
, SIOCGIFFLAGS
, &ifr
) == 0) {
158 if (flag
== 0 || (ifr
.ifr_flags
& flag
) == flag
)
161 ifr
.ifr_flags
|= flag
;
162 if (ioctl(ifp
->ctx
->pf_inet_fd
, SIOCSIFFLAGS
, &ifr
) ==0)
165 ifp
->flags
= (unsigned int)ifr
.ifr_flags
;
171 if_hasconf(struct dhcpcd_ctx
*ctx
, const char *ifname
)
175 for (i
= 0; i
< ctx
->ifcc
; i
++) {
176 if (strcmp(ctx
->ifcv
[i
], ifname
) == 0)
182 static void if_learnaddrs1(struct dhcpcd_ctx
*ctx
, struct if_head
*ifs
,
183 struct ifaddrs
*ifaddrs
)
186 struct interface
*ifp
;
188 const struct sockaddr_in
*addr
, *net
, *dst
;
191 struct sockaddr_in6
*sin6
, *net6
;
196 for (ifa
= ifaddrs
; ifa
; ifa
= ifa
->ifa_next
) {
197 if (ifa
->ifa_addr
== NULL
)
199 if ((ifp
= if_find(ifs
, ifa
->ifa_name
)) == NULL
)
201 switch(ifa
->ifa_addr
->sa_family
) {
204 addr
= (const struct sockaddr_in
*)
205 (void *)ifa
->ifa_addr
;
206 net
= (const struct sockaddr_in
*)
207 (void *)ifa
->ifa_netmask
;
208 if (ifa
->ifa_flags
& IFF_POINTOPOINT
)
209 dst
= (const struct sockaddr_in
*)
210 (void *)ifa
->ifa_dstaddr
;
213 ifa_flags
= if_addrflags(&addr
->sin_addr
, ifp
);
214 ipv4_handleifa(ctx
, RTM_NEWADDR
, ifs
, ifa
->ifa_name
,
217 dst
? &dst
->sin_addr
: NULL
, ifa_flags
);
222 sin6
= (struct sockaddr_in6
*)(void *)ifa
->ifa_addr
;
223 net6
= (struct sockaddr_in6
*)(void *)ifa
->ifa_netmask
;
225 if (IN6_IS_ADDR_LINKLOCAL(&sin6
->sin6_addr
))
226 /* Remove the scope from the address */
227 sin6
->sin6_addr
.s6_addr
[2] =
228 sin6
->sin6_addr
.s6_addr
[3] = '\0';
230 ifa_flags
= if_addrflags6(&sin6
->sin6_addr
, ifp
);
232 ipv6_handleifa(ctx
, RTM_NEWADDR
, ifs
,
235 ipv6_prefixlen(&net6
->sin6_addr
),
244 if_discover(struct dhcpcd_ctx
*ctx
, int argc
, char * const *argv
)
246 struct ifaddrs
*ifaddrs
, *ifa
;
250 struct interface
*ifp
;
252 char ifn
[IF_NAMESIZE
];
255 const struct sockaddr_dl
*sdl
;
256 #ifdef SIOCGIFPRIORITY
260 struct if_laddrreq iflr
;
264 memset(&iflr
, 0, sizeof(iflr
));
267 const struct sockaddr_ll
*sll
;
270 if (getifaddrs(&ifaddrs
) == -1)
272 ifs
= malloc(sizeof(*ifs
));
277 for (ifa
= ifaddrs
; ifa
; ifa
= ifa
->ifa_next
) {
278 if (ifa
->ifa_addr
!= NULL
) {
280 if (ifa
->ifa_addr
->sa_family
!= AF_LINK
)
283 if (ifa
->ifa_addr
->sa_family
!= AF_PACKET
)
288 /* It's possible for an interface to have >1 AF_LINK.
289 * For our purposes, we use the first one. */
290 TAILQ_FOREACH(ifp
, ifs
, next
) {
291 if (strcmp(ifp
->name
, ifa
->ifa_name
) == 0)
298 for (i
= 0; i
< argc
; i
++) {
300 /* Check the real interface name */
301 strlcpy(ifn
, argv
[i
], sizeof(ifn
));
302 p
= strchr(ifn
, ':');
305 if (strcmp(ifn
, ifa
->ifa_name
) == 0)
308 if (strcmp(argv
[i
], ifa
->ifa_name
) == 0)
318 strlcpy(ifn
, ifa
->ifa_name
, sizeof(ifn
));
320 /* -1 means we're discovering against a specific
321 * interface, but we still need the below rules
323 if (argc
== -1 && strcmp(argv
[0], ifa
->ifa_name
) != 0)
326 for (i
= 0; i
< ctx
->ifdc
; i
++)
327 if (!fnmatch(ctx
->ifdv
[i
], p
, 0))
331 for (i
= 0; i
< ctx
->ifac
; i
++)
332 if (!fnmatch(ctx
->ifav
[i
], p
, 0))
334 if (ctx
->ifac
&& i
== ctx
->ifac
)
337 /* Ensure that the interface name has settled */
338 if (!dev_initialized(ctx
, p
))
341 /* Don't allow loopback or pointopoint unless explicit */
342 if (ifa
->ifa_flags
& (IFF_LOOPBACK
| IFF_POINTOPOINT
)) {
343 if ((argc
== 0 || argc
== -1) &&
344 ctx
->ifac
== 0 && !if_hasconf(ctx
, p
))
348 if (if_vimaster(ctx
, p
) == 1) {
349 logger(ctx
, argc
? LOG_ERR
: LOG_DEBUG
,
350 "%s: is a Virtual Interface Master, skipping", p
);
354 ifp
= calloc(1, sizeof(*ifp
));
356 logger(ctx
, LOG_ERR
, "%s: %m", __func__
);
361 strlcpy(ifp
->name
, ifn
, sizeof(ifp
->name
));
362 strlcpy(ifp
->alias
, p
, sizeof(ifp
->alias
));
364 strlcpy(ifp
->name
, p
, sizeof(ifp
->name
));
366 ifp
->flags
= ifa
->ifa_flags
;
367 ifp
->carrier
= if_carrier(ifp
);
369 if (ifa
->ifa_addr
!= NULL
) {
371 sdl
= (const struct sockaddr_dl
*)(void *)ifa
->ifa_addr
;
374 /* We need to check for active address */
375 strlcpy(iflr
.iflr_name
, ifp
->name
,
376 sizeof(iflr
.iflr_name
));
377 memcpy(&iflr
.addr
, ifa
->ifa_addr
,
378 MIN(ifa
->ifa_addr
->sa_len
, sizeof(iflr
.addr
)));
379 iflr
.flags
= IFLR_PREFIX
;
380 iflr
.prefixlen
= (unsigned int)sdl
->sdl_alen
* NBBY
;
381 if (ioctl(ctx
->pf_link_fd
, SIOCGLIFADDR
, &iflr
) == -1 ||
382 !(iflr
.flags
& IFLR_ACTIVE
))
389 ifp
->index
= sdl
->sdl_index
;
390 switch(sdl
->sdl_type
) {
392 case IFT_BRIDGE
: /* FALLTHROUGH */
395 case IFT_PPP
: /* FALLTHROUGH */
397 #ifdef IFT_PROPVIRTUAL
398 case IFT_PROPVIRTUAL
: /* FALLTHROUGH */
400 #if defined(IFT_BRIDGE) || defined(IFT_PPP) || defined(IFT_PROPVIRTUAL)
401 /* Don't allow unless explicit */
402 if ((argc
== 0 || argc
== -1) &&
404 !if_hasconf(ctx
, ifp
->name
))
406 logger(ifp
->ctx
, LOG_DEBUG
,
407 "%s: ignoring due to"
408 " interface type and"
417 case IFT_L2VLAN
: /* FALLTHROUGH */
420 case IFT_L3IPVLAN
: /* FALLTHROUGH */
423 ifp
->family
= ARPHRD_ETHER
;
427 ifp
->family
= ARPHRD_IEEE1394
;
430 #ifdef IFT_INFINIBAND
432 ifp
->family
= ARPHRD_INFINIBAND
;
436 /* Don't allow unless explicit */
437 if ((argc
== 0 || argc
== -1) &&
439 !if_hasconf(ctx
, ifp
->name
))
444 logger(ifp
->ctx
, LOG_WARNING
,
445 "%s: unsupported interface type %.2x",
446 ifp
->name
, sdl
->sdl_type
);
447 /* Pretend it's ethernet */
448 ifp
->family
= ARPHRD_ETHER
;
451 ifp
->hwlen
= sdl
->sdl_alen
;
453 # define CLLADDR(s) ((const char *)((s)->sdl_data + (s)->sdl_nlen))
455 memcpy(ifp
->hwaddr
, CLLADDR(sdl
), ifp
->hwlen
);
457 sll
= (const struct sockaddr_ll
*)(void *)ifa
->ifa_addr
;
458 ifp
->index
= (unsigned int)sll
->sll_ifindex
;
459 ifp
->family
= sll
->sll_hatype
;
460 ifp
->hwlen
= sll
->sll_halen
;
462 memcpy(ifp
->hwaddr
, sll
->sll_addr
, ifp
->hwlen
);
466 /* PPP addresses on Linux don't have hardware addresses */
468 ifp
->index
= if_nametoindex(ifp
->name
);
471 /* We only work on ethernet by default */
472 if (ifp
->family
!= ARPHRD_ETHER
) {
473 if ((argc
== 0 || argc
== -1) &&
474 ctx
->ifac
== 0 && !if_hasconf(ctx
, ifp
->name
))
479 switch (ifp
->family
) {
480 case ARPHRD_IEEE1394
:
481 case ARPHRD_INFINIBAND
:
482 #ifdef ARPHRD_LOOPBACK
483 case ARPHRD_LOOPBACK
:
488 /* We don't warn for supported families */
491 /* IFT already checked */
494 logger(ifp
->ctx
, LOG_WARNING
,
495 "%s: unsupported interface family %.2x",
496 ifp
->name
, ifp
->family
);
502 if (!(ctx
->options
& (DHCPCD_DUMPLEASE
| DHCPCD_TEST
))) {
503 /* Handle any platform init for the interface */
504 if (if_init(ifp
) == -1) {
505 logger(ifp
->ctx
, LOG_ERR
, "%s: if_init: %m", p
);
510 /* Ensure that the MTU is big enough for DHCP */
511 if (if_getmtu(ifp
) < MTU_MIN
&&
512 if_setmtu(ifp
, MTU_MIN
) == -1)
514 logger(ifp
->ctx
, LOG_ERR
,
515 "%s: if_setmtu: %m", p
);
521 #ifdef SIOCGIFPRIORITY
522 /* Respect the interface priority */
523 memset(&ifr
, 0, sizeof(ifr
));
524 strlcpy(ifr
.ifr_name
, ifp
->name
, sizeof(ifr
.ifr_name
));
525 if (ioctl(ctx
->pf_inet_fd
, SIOCGIFPRIORITY
, &ifr
) == 0)
526 ifp
->metric
= ifr
.ifr_metric
;
528 /* We reserve the 100 range for virtual interfaces, if and when
529 * we can work them out. */
530 ifp
->metric
= 200 + ifp
->index
;
531 if (if_getssid(ifp
) != -1) {
537 TAILQ_INSERT_TAIL(ifs
, ifp
, next
);
540 if_learnaddrs1(ctx
, ifs
, ifaddrs
);
541 freeifaddrs(ifaddrs
);
546 static struct interface
*
547 if_findindexname(struct if_head
*ifaces
, unsigned int idx
, const char *name
)
550 if (ifaces
!= NULL
) {
551 struct interface
*ifp
;
553 TAILQ_FOREACH(ifp
, ifaces
, next
) {
554 if ((name
&& strcmp(ifp
->name
, name
) == 0) ||
556 (name
&& strcmp(ifp
->alias
, name
) == 0) ||
558 (!name
&& ifp
->index
== idx
))
568 if_find(struct if_head
*ifaces
, const char *name
)
571 return if_findindexname(ifaces
, 0, name
);
575 if_findindex(struct if_head
*ifaces
, unsigned int idx
)
578 return if_findindexname(ifaces
, idx
, NULL
);
582 if_domtu(const struct interface
*ifp
, short int mtu
)
587 memset(&ifr
, 0, sizeof(ifr
));
588 strlcpy(ifr
.ifr_name
, ifp
->name
, sizeof(ifr
.ifr_name
));
590 r
= ioctl(ifp
->ctx
->pf_inet_fd
, mtu
? SIOCSIFMTU
: SIOCGIFMTU
, &ifr
);
596 /* Interface comparer for working out ordering. */
598 if_cmp(const struct interface
*si
, const struct interface
*ti
)
604 /* Check carrier status first */
605 if (si
->carrier
> ti
->carrier
)
607 if (si
->carrier
< ti
->carrier
)
610 if (D_STATE_RUNNING(si
) && !D_STATE_RUNNING(ti
))
612 if (!D_STATE_RUNNING(si
) && D_STATE_RUNNING(ti
))
614 if (RS_STATE_RUNNING(si
) && !RS_STATE_RUNNING(ti
))
616 if (!RS_STATE_RUNNING(si
) && RS_STATE_RUNNING(ti
))
618 if (D6_STATE_RUNNING(si
) && !D6_STATE_RUNNING(ti
))
620 if (!D6_STATE_RUNNING(si
) && D6_STATE_RUNNING(ti
))
624 /* Special attention needed here due to states and IPv4LL. */
625 if ((r
= ipv4_ifcmp(si
, ti
)) != 0)
629 /* Finally, metric */
630 if (si
->metric
< ti
->metric
)
632 if (si
->metric
> ti
->metric
)
637 /* Sort the interfaces into a preferred order - best first, worst last. */
639 if_sortinterfaces(struct dhcpcd_ctx
*ctx
)
641 struct if_head sorted
;
642 struct interface
*ifp
, *ift
;
644 if (ctx
->ifaces
== NULL
||
645 (ifp
= TAILQ_FIRST(ctx
->ifaces
)) == NULL
||
646 TAILQ_NEXT(ifp
, next
) == NULL
)
650 TAILQ_REMOVE(ctx
->ifaces
, ifp
, next
);
651 TAILQ_INSERT_HEAD(&sorted
, ifp
, next
);
652 while ((ifp
= TAILQ_FIRST(ctx
->ifaces
))) {
653 TAILQ_REMOVE(ctx
->ifaces
, ifp
, next
);
654 TAILQ_FOREACH(ift
, &sorted
, next
) {
655 if (if_cmp(ifp
, ift
) == -1) {
656 TAILQ_INSERT_BEFORE(ift
, ifp
, next
);
661 TAILQ_INSERT_TAIL(&sorted
, ifp
, next
);
663 TAILQ_CONCAT(ctx
->ifaces
, &sorted
, next
);
667 xsocket(int domain
, int type
, int protocol
, int flags
)
670 if (flags
& O_CLOEXEC
)
671 type
|= SOCK_CLOEXEC
;
672 if (flags
& O_NONBLOCK
)
673 type
|= SOCK_NONBLOCK
;
675 return socket(domain
, type
, protocol
);
679 if ((s
= socket(domain
, type
, protocol
)) == -1)
681 if ((flags
& O_CLOEXEC
) && (xflags
= fcntl(s
, F_GETFD
, 0)) == -1 ||
682 fcntl(s
, F_SETFD
, xflags
| FD_CLOEXEC
) == -1)
684 if ((flags
& O_NONBLOCK
) && (xflags
= fcntl(s
, F_GETFL
, 0)) == -1 ||
685 fcntl(s
, F_SETFL
, xflags
| O_NONBLOCK
) == -1)