1 /* SPDX-License-Identifier: BSD-2-Clause */
3 * dhcpcd - DHCP client daemon
4 * Copyright (c) 2006-2020 Roy Marples <roy@marples.name>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/param.h>
30 #include <sys/types.h>
31 #include <sys/ioctl.h>
32 #include <sys/socket.h>
34 #include <fcntl.h> /* Needs to be here for old Linux */
39 #include <net/if_arp.h>
40 #include <netinet/in.h>
42 # include <net/if_dl.h>
43 # include <net/if_types.h>
44 # include <netinet/in_var.h>
45 # undef AF_PACKET /* Newer Illumos defines this */
48 # include <netpacket/packet.h>
51 # include <net/if_media.h>
53 #include <net/route.h>
67 #define ELOOP_QUEUE ELOOP_IF
74 #include "if-options.h"
82 if_free(struct interface
*ifp
)
102 free_options(ifp
->ctx
, ifp
->options
);
107 if_opensockets(struct dhcpcd_ctx
*ctx
)
110 if (if_opensockets_os(ctx
) == -1)
114 ctx
->pf_link_fd
= xsocket(PF_LINK
, SOCK_DGRAM
| SOCK_CLOEXEC
, 0);
115 if (ctx
->pf_link_fd
== -1)
118 if (ps_rights_limit_ioctl(ctx
->pf_link_fd
) == -1)
123 /* We use this socket for some operations without INET. */
124 ctx
->pf_inet_fd
= xsocket(PF_INET
, SOCK_DGRAM
| SOCK_CLOEXEC
, 0);
125 if (ctx
->pf_inet_fd
== -1)
132 if_closesockets(struct dhcpcd_ctx
*ctx
)
135 if (ctx
->pf_inet_fd
!= -1)
136 close(ctx
->pf_inet_fd
);
138 if (ctx
->pf_link_fd
!= -1)
139 close(ctx
->pf_link_fd
);
143 if_closesockets_os(ctx
);
149 if_ioctl(struct dhcpcd_ctx
*ctx
, ioctl_request_t req
, void *data
, size_t len
)
153 if (ctx
->options
& DHCPCD_PRIVSEP
)
154 return (int)ps_root_ioctl(ctx
, req
, data
, len
);
156 return ioctl(ctx
->pf_inet_fd
, req
, data
, len
);
160 if_getflags(struct interface
*ifp
)
162 struct ifreq ifr
= { .ifr_flags
= 0 };
164 strlcpy(ifr
.ifr_name
, ifp
->name
, sizeof(ifr
.ifr_name
));
165 if (ioctl(ifp
->ctx
->pf_inet_fd
, SIOCGIFFLAGS
, &ifr
) == -1)
167 ifp
->flags
= (unsigned int)ifr
.ifr_flags
;
172 if_setflag(struct interface
*ifp
, short setflag
, short unsetflag
)
174 struct ifreq ifr
= { .ifr_flags
= 0 };
177 strlcpy(ifr
.ifr_name
, ifp
->name
, sizeof(ifr
.ifr_name
));
178 if (ioctl(ifp
->ctx
->pf_inet_fd
, SIOCGIFFLAGS
, &ifr
) == -1)
181 oflags
= ifr
.ifr_flags
;
182 ifr
.ifr_flags
|= setflag
;
183 ifr
.ifr_flags
&= (short)~unsetflag
;
184 if (ifr
.ifr_flags
!= oflags
&&
185 if_ioctl(ifp
->ctx
, SIOCSIFFLAGS
, &ifr
, sizeof(ifr
)) == -1)
189 * Do NOT set ifp->flags here.
190 * We need to listen for flag updates from the kernel as they
191 * need to sync with carrier.
197 if_randomisemac(struct interface
*ifp
)
200 size_t hwlen
= ifp
->hwlen
, rlen
= 0;
201 uint8_t buf
[HWADDR_LEN
], *bp
= buf
, *rp
= (uint8_t *)&randnum
;
202 char sbuf
[HWADDR_LEN
* 3];
209 if (hwlen
> sizeof(buf
)) {
214 for (; hwlen
!= 0; hwlen
--) {
216 randnum
= arc4random();
217 rp
= (uint8_t *)&randnum
;
218 rlen
= sizeof(randnum
);
224 /* Unicast address and locally administered. */
228 logdebugx("%s: hardware address randomised to %s",
230 hwaddr_ntoa(buf
, ifp
->hwlen
, sbuf
, sizeof(sbuf
)));
231 retval
= if_setmac(ifp
, buf
, ifp
->hwlen
);
233 memcpy(ifp
->hwaddr
, buf
, ifp
->hwlen
);
238 if_hasconf(struct dhcpcd_ctx
*ctx
, const char *ifname
)
242 for (i
= 0; i
< ctx
->ifcc
; i
++) {
243 if (strcmp(ctx
->ifcv
[i
], ifname
) == 0)
250 if_markaddrsstale(struct if_head
*ifs
)
252 struct interface
*ifp
;
254 TAILQ_FOREACH(ifp
, ifs
, next
) {
256 ipv4_markaddrsstale(ifp
);
259 ipv6_markaddrsstale(ifp
, 0);
265 if_learnaddrs(struct dhcpcd_ctx
*ctx
, struct if_head
*ifs
,
266 struct ifaddrs
**ifaddrs
)
269 struct interface
*ifp
;
271 const struct sockaddr_in
*addr
, *net
, *brd
;
274 struct sockaddr_in6
*sin6
, *net6
;
278 for (ifa
= *ifaddrs
; ifa
; ifa
= ifa
->ifa_next
) {
279 if (ifa
->ifa_addr
== NULL
)
281 if ((ifp
= if_find(ifs
, ifa
->ifa_name
)) == NULL
)
283 #ifdef HAVE_IFADDRS_ADDRFLAGS
284 addrflags
= (int)ifa
->ifa_addrflags
;
286 switch(ifa
->ifa_addr
->sa_family
) {
289 addr
= (void *)ifa
->ifa_addr
;
290 net
= (void *)ifa
->ifa_netmask
;
291 if (ifa
->ifa_flags
& IFF_POINTOPOINT
)
292 brd
= (void *)ifa
->ifa_dstaddr
;
294 brd
= (void *)ifa
->ifa_broadaddr
;
295 #ifndef HAVE_IFADDRS_ADDRFLAGS
296 addrflags
= if_addrflags(ifp
, &addr
->sin_addr
,
298 if (addrflags
== -1) {
299 if (errno
!= EEXIST
&& errno
!= EADDRNOTAVAIL
) {
300 char dbuf
[INET_ADDRSTRLEN
];
303 dbp
= inet_ntop(AF_INET
, &addr
->sin_addr
,
305 logerr("%s: if_addrflags: %s%%%s",
306 __func__
, dbp
, ifp
->name
);
311 ipv4_handleifa(ctx
, RTM_NEWADDR
, ifs
, ifa
->ifa_name
,
312 &addr
->sin_addr
, &net
->sin_addr
,
313 brd
? &brd
->sin_addr
: NULL
, addrflags
, 0);
318 sin6
= (void *)ifa
->ifa_addr
;
319 net6
= (void *)ifa
->ifa_netmask
;
322 if (IN6_IS_ADDR_LINKLOCAL(&sin6
->sin6_addr
))
323 /* Remove the scope from the address */
324 sin6
->sin6_addr
.s6_addr
[2] =
325 sin6
->sin6_addr
.s6_addr
[3] = '\0';
327 #ifndef HAVE_IFADDRS_ADDRFLAGS
328 addrflags
= if_addrflags6(ifp
, &sin6
->sin6_addr
,
330 if (addrflags
== -1) {
331 if (errno
!= EEXIST
&& errno
!= EADDRNOTAVAIL
) {
332 char dbuf
[INET6_ADDRSTRLEN
];
335 dbp
= inet_ntop(AF_INET6
, &sin6
->sin6_addr
,
337 logerr("%s: if_addrflags6: %s%%%s",
338 __func__
, dbp
, ifp
->name
);
343 ipv6_handleifa(ctx
, RTM_NEWADDR
, ifs
,
344 ifa
->ifa_name
, &sin6
->sin6_addr
,
345 ipv6_prefixlen(&net6
->sin6_addr
), addrflags
, 0);
351 #ifdef PRIVSEP_GETIFADDRS
356 freeifaddrs(*ifaddrs
);
361 if_deletestaleaddrs(struct if_head
*ifs
)
363 struct interface
*ifp
;
365 TAILQ_FOREACH(ifp
, ifs
, next
) {
367 ipv4_deletestaleaddrs(ifp
);
370 ipv6_deletestaleaddrs(ifp
);
376 if_valid_hwaddr(const uint8_t *hwaddr
, size_t hwlen
)
379 bool all_zeros
, all_ones
;
381 all_zeros
= all_ones
= true;
382 for (i
= 0; i
< hwlen
; i
++) {
383 if (hwaddr
[i
] != 0x00)
385 if (hwaddr
[i
] != 0xff)
387 if (!all_zeros
&& !all_ones
)
393 #if defined(AF_PACKET) && !defined(AF_LINK)
395 if_check_arphrd(struct interface
*ifp
, unsigned int active
, bool if_noconf
)
398 switch(ifp
->hwtype
) {
399 case ARPHRD_ETHER
: /* FALLTHROUGH */
400 case ARPHRD_IEEE1394
: /* FALLTHROUGH */
401 case ARPHRD_INFINIBAND
: /* FALLTHROUGH */
402 case ARPHRD_NONE
: /* FALLTHROUGH */
404 case ARPHRD_LOOPBACK
:
406 if (if_noconf
&& active
) {
407 logdebugx("%s: ignoring due to interface type and"
410 active
= IF_INACTIVE
;
415 active
= IF_INACTIVE
;
417 logwarnx("%s: unsupported interface type 0x%.2x",
418 ifp
->name
, ifp
->hwtype
);
427 if_discover(struct dhcpcd_ctx
*ctx
, struct ifaddrs
**ifaddrs
,
428 int argc
, char * const *argv
)
434 struct interface
*ifp
;
438 const struct sockaddr_dl
*sdl
;
440 struct if_laddrreq iflr
= { .flags
= IFLR_PREFIX
};
442 #elif defined(AF_PACKET)
443 const struct sockaddr_ll
*sll
;
445 #if defined(SIOCGIFPRIORITY)
449 if ((ifs
= malloc(sizeof(*ifs
))) == NULL
) {
455 #ifdef PRIVSEP_GETIFADDRS
456 if (ctx
->options
& DHCPCD_PRIVSEP
) {
457 if (ps_root_getifaddrs(ctx
, ifaddrs
) == -1) {
458 logerr("ps_root_getifaddrs");
464 if (getifaddrs(ifaddrs
) == -1) {
465 logerr("getifaddrs");
470 for (ifa
= *ifaddrs
; ifa
; ifa
= ifa
->ifa_next
) {
471 if (ifa
->ifa_addr
!= NULL
) {
473 if (ifa
->ifa_addr
->sa_family
!= AF_LINK
)
475 #elif defined(AF_PACKET)
476 if (ifa
->ifa_addr
->sa_family
!= AF_PACKET
)
480 if (if_nametospec(ifa
->ifa_name
, &spec
) != 0)
483 /* It's possible for an interface to have >1 AF_LINK.
484 * For our purposes, we use the first one. */
485 TAILQ_FOREACH(ifp
, ifs
, next
) {
486 if (strcmp(ifp
->name
, spec
.devname
) == 0)
493 for (i
= 0; i
< argc
; i
++) {
494 if (strcmp(argv
[i
], spec
.devname
) == 0)
497 active
= (i
== argc
) ? IF_INACTIVE
: IF_ACTIVE_USER
;
499 /* -1 means we're discovering against a specific
500 * interface, but we still need the below rules
502 if (argc
== -1 && strcmp(argv
[0], spec
.devname
) != 0)
504 active
= ctx
->options
& DHCPCD_INACTIVE
?
505 IF_INACTIVE
: IF_ACTIVE_USER
;
508 for (i
= 0; i
< ctx
->ifdc
; i
++)
509 if (fnmatch(ctx
->ifdv
[i
], spec
.devname
, 0) == 0)
512 active
= IF_INACTIVE
;
513 for (i
= 0; i
< ctx
->ifc
; i
++)
514 if (fnmatch(ctx
->ifv
[i
], spec
.devname
, 0) == 0)
516 if (ctx
->ifc
&& i
== ctx
->ifc
)
517 active
= IF_INACTIVE
;
518 for (i
= 0; i
< ctx
->ifac
; i
++)
519 if (fnmatch(ctx
->ifav
[i
], spec
.devname
, 0) == 0)
521 if (ctx
->ifac
&& i
== ctx
->ifac
)
522 active
= IF_INACTIVE
;
525 /* Ensure that the interface name has settled */
526 if (!dev_initialised(ctx
, spec
.devname
)) {
527 logdebugx("%s: waiting for interface to initialise",
533 if (if_vimaster(ctx
, spec
.devname
) == 1) {
534 int loglevel
= argc
!= 0 ? LOG_ERR
: LOG_DEBUG
;
536 "%s: is a Virtual Interface Master, skipping",
541 if_noconf
= ((argc
== 0 || argc
== -1) && ctx
->ifac
== 0 &&
542 !if_hasconf(ctx
, spec
.devname
));
544 /* Don't allow some reserved interface names unless explicit. */
545 if (if_noconf
&& if_ignore(ctx
, spec
.devname
)) {
546 logdebugx("%s: ignoring due to interface type and"
547 " no config", spec
.devname
);
548 active
= IF_INACTIVE
;
551 ifp
= calloc(1, sizeof(*ifp
));
557 strlcpy(ifp
->name
, spec
.devname
, sizeof(ifp
->name
));
558 ifp
->flags
= ifa
->ifa_flags
;
560 if (ifa
->ifa_addr
!= NULL
) {
562 sdl
= (const void *)ifa
->ifa_addr
;
565 /* We need to check for active address */
566 strlcpy(iflr
.iflr_name
, ifp
->name
,
567 sizeof(iflr
.iflr_name
));
568 memcpy(&iflr
.addr
, ifa
->ifa_addr
,
569 MIN(ifa
->ifa_addr
->sa_len
, sizeof(iflr
.addr
)));
570 iflr
.flags
= IFLR_PREFIX
;
571 iflr
.prefixlen
= (unsigned int)sdl
->sdl_alen
* NBBY
;
572 if (ioctl(ctx
->pf_link_fd
, SIOCGLIFADDR
, &iflr
) == -1 ||
573 !(iflr
.flags
& IFLR_ACTIVE
))
580 ifp
->index
= sdl
->sdl_index
;
581 switch(sdl
->sdl_type
) {
583 case IFT_BRIDGE
: /* FALLTHROUGH */
585 #ifdef IFT_PROPVIRTUAL
586 case IFT_PROPVIRTUAL
: /* FALLTHROUGH */
589 case IFT_TUNNEL
: /* FALLTHROUGH */
591 case IFT_LOOP
: /* FALLTHROUGH */
593 /* Don't allow unless explicit */
594 if (if_noconf
&& active
) {
595 logdebugx("%s: ignoring due to"
596 " interface type and"
599 active
= IF_INACTIVE
;
601 __fallthrough
; /* appease gcc */
604 case IFT_L2VLAN
: /* FALLTHROUGH */
607 case IFT_L3IPVLAN
: /* FALLTHROUGH */
610 ifp
->hwtype
= ARPHRD_ETHER
;
614 ifp
->hwtype
= ARPHRD_IEEE1394
;
617 #ifdef IFT_INFINIBAND
619 ifp
->hwtype
= ARPHRD_INFINIBAND
;
623 /* Don't allow unless explicit */
625 active
= IF_INACTIVE
;
627 logwarnx("%s: unsupported"
628 " interface type 0x%.2x",
629 ifp
->name
, sdl
->sdl_type
);
630 /* Pretend it's ethernet */
631 ifp
->hwtype
= ARPHRD_ETHER
;
634 ifp
->hwlen
= sdl
->sdl_alen
;
635 memcpy(ifp
->hwaddr
, CLLADDR(sdl
), ifp
->hwlen
);
636 #elif defined(AF_PACKET)
637 sll
= (const void *)ifa
->ifa_addr
;
638 ifp
->index
= (unsigned int)sll
->sll_ifindex
;
639 ifp
->hwtype
= sll
->sll_hatype
;
640 ifp
->hwlen
= sll
->sll_halen
;
642 memcpy(ifp
->hwaddr
, sll
->sll_addr
, ifp
->hwlen
);
643 active
= if_check_arphrd(ifp
, active
, if_noconf
);
648 struct ifreq ifr
= { .ifr_flags
= 0 };
650 /* This is a huge bug in getifaddrs(3) as there
651 * is no reason why this can't be returned in
653 strlcpy(ifr
.ifr_name
, ifa
->ifa_name
,
654 sizeof(ifr
.ifr_name
));
655 if (ioctl(ctx
->pf_inet_fd
, SIOCGIFHWADDR
, &ifr
) == -1)
656 logerr("%s: SIOCGIFHWADDR", ifa
->ifa_name
);
657 ifp
->hwtype
= ifr
.ifr_hwaddr
.sa_family
;
658 if (ioctl(ctx
->pf_inet_fd
, SIOCGIFINDEX
, &ifr
) == -1)
659 logerr("%s: SIOCGIFINDEX", ifa
->ifa_name
);
660 ifp
->index
= (unsigned int)ifr
.ifr_ifindex
;
661 if_check_arphrd(ifp
, active
, if_noconf
);
665 if (!(ctx
->options
& (DHCPCD_DUMPLEASE
| DHCPCD_TEST
))) {
666 /* Handle any platform init for the interface */
667 if (active
!= IF_INACTIVE
&& if_init(ifp
) == -1) {
668 logerr("%s: if_init", ifp
->name
);
674 ifp
->vlanid
= if_vlanid(ifp
);
676 #ifdef SIOCGIFPRIORITY
677 /* Respect the interface priority */
678 memset(&ifr
, 0, sizeof(ifr
));
679 strlcpy(ifr
.ifr_name
, ifp
->name
, sizeof(ifr
.ifr_name
));
680 if (pioctl(ctx
, SIOCGIFPRIORITY
, &ifr
, sizeof(ifr
)) == 0)
681 ifp
->metric
= (unsigned int)ifr
.ifr_metric
;
684 /* We reserve the 100 range for virtual interfaces, if and when
685 * we can work them out. */
686 ifp
->metric
= 200 + ifp
->index
;
687 if (if_getssid(ifp
) != -1) {
688 ifp
->wireless
= true;
693 ifp
->active
= active
;
694 ifp
->carrier
= if_carrier(ifp
, ifa
->ifa_data
);
695 TAILQ_INSERT_TAIL(ifs
, ifp
, next
);
702 * eth0.100:2 OR eth0i100:2 (seems to be NetBSD xvif(4) only)
705 * devname == eth0.100 OR eth0i100
710 if_nametospec(const char *ifname
, struct if_spec
*spec
)
715 if (ifname
== NULL
|| *ifname
== '\0' ||
716 strlcpy(spec
->ifname
, ifname
, sizeof(spec
->ifname
)) >=
717 sizeof(spec
->ifname
) ||
718 strlcpy(spec
->drvname
, ifname
, sizeof(spec
->drvname
)) >=
719 sizeof(spec
->drvname
))
726 ep
= strchr(spec
->drvname
, ':');
728 spec
->lun
= (int)strtoi(ep
+ 1, NULL
, 10, 0, INT_MAX
, &e
);
740 ep
= spec
->drvname
+ strlen(spec
->drvname
) - 1;
744 strlcpy(spec
->devname
, spec
->drvname
, sizeof(spec
->devname
));
746 /* Solaris has numbers in the driver name, such as e1000g */
747 while (ep
> spec
->drvname
&& isdigit((int)*ep
))
754 /* BSD and Linux no not have numbers in the driver name */
755 for (ep
= spec
->drvname
; *ep
!= '\0' && !isdigit((int)*ep
); ep
++) {
762 spec
->ppa
= (int)strtoi(ep
, &pp
, 10, 0, INT_MAX
, &e
);
767 * . is used for VLAN style names
768 * i is used on NetBSD for xvif interfaces
770 if (pp
!= NULL
&& (*pp
== '.' || *pp
== 'i')) {
771 spec
->vlid
= (int)strtoi(pp
+ 1, NULL
, 10, 0, INT_MAX
, &e
);
781 static struct interface
*
782 if_findindexname(struct if_head
*ifaces
, unsigned int idx
, const char *name
)
785 if (ifaces
!= NULL
) {
787 struct interface
*ifp
;
789 if (name
&& if_nametospec(name
, &spec
) == -1)
792 TAILQ_FOREACH(ifp
, ifaces
, next
) {
793 if ((name
&& strcmp(ifp
->name
, spec
.devname
) == 0) ||
794 (!name
&& ifp
->index
== idx
))
804 if_find(struct if_head
*ifaces
, const char *name
)
807 return if_findindexname(ifaces
, 0, name
);
811 if_findindex(struct if_head
*ifaces
, unsigned int idx
)
814 return if_findindexname(ifaces
, idx
, NULL
);
818 if_loopback(struct dhcpcd_ctx
*ctx
)
820 struct interface
*ifp
;
822 TAILQ_FOREACH(ifp
, ctx
->ifaces
, next
) {
823 if (ifp
->flags
& IFF_LOOPBACK
)
830 if_domtu(const struct interface
*ifp
, short int mtu
)
837 return if_mtu_os(ifp
);
840 memset(&ifr
, 0, sizeof(ifr
));
841 strlcpy(ifr
.ifr_name
, ifp
->name
, sizeof(ifr
.ifr_name
));
844 r
= if_ioctl(ifp
->ctx
, SIOCSIFMTU
, &ifr
, sizeof(ifr
));
846 r
= pioctl(ifp
->ctx
, SIOCGIFMTU
, &ifr
, sizeof(ifr
));
855 if_makealias(char *alias
, size_t alias_len
, const char *ifname
, int lun
)
859 return strlcpy(alias
, ifname
, alias_len
);
860 return snprintf(alias
, alias_len
, "%s:%u", ifname
, lun
);
865 if_findifpfromcmsg(struct dhcpcd_ctx
*ctx
, struct msghdr
*msg
, int *hoplimit
)
868 unsigned int ifindex
= 0;
869 struct interface
*ifp
;
872 struct sockaddr_dl sdl
;
874 struct in_pktinfo ipi
;
878 struct in6_pktinfo ipi6
;
883 for (cm
= (struct cmsghdr
*)CMSG_FIRSTHDR(msg
);
885 cm
= (struct cmsghdr
*)CMSG_NXTHDR(msg
, cm
))
888 if (cm
->cmsg_level
== IPPROTO_IP
) {
889 switch(cm
->cmsg_type
) {
893 offsetof(struct sockaddr_dl
, sdl_index
) +
894 sizeof(sdl
.sdl_index
))
896 memcpy(&sdl
, CMSG_DATA(cm
),
897 MIN(sizeof(sdl
), cm
->cmsg_len
));
898 ifindex
= sdl
.sdl_index
;
902 if (cm
->cmsg_len
!= CMSG_LEN(sizeof(ipi
)))
904 memcpy(&ipi
, CMSG_DATA(cm
), sizeof(ipi
));
905 ifindex
= (unsigned int)ipi
.ipi_ifindex
;
912 if (cm
->cmsg_level
== IPPROTO_IPV6
) {
913 switch(cm
->cmsg_type
) {
915 if (cm
->cmsg_len
!= CMSG_LEN(sizeof(ipi6
)))
917 memcpy(&ipi6
, CMSG_DATA(cm
), sizeof(ipi6
));
918 ifindex
= (unsigned int)ipi6
.ipi6_ifindex
;
921 if (cm
->cmsg_len
!= CMSG_LEN(sizeof(int)))
923 if (hoplimit
== NULL
)
925 memcpy(hoplimit
, CMSG_DATA(cm
), sizeof(int));
932 /* Find the receiving interface */
933 TAILQ_FOREACH(ifp
, ctx
->ifaces
, next
) {
934 if (ifp
->index
== ifindex
)
943 xsocket(int domain
, int type
, int protocol
)
946 #if !defined(HAVE_SOCK_CLOEXEC) || !defined(HAVE_SOCK_NONBLOCK)
947 int xflags
, xtype
= type
;
950 #ifndef HAVE_SOCK_CLOEXEC
951 if (xtype
& SOCK_CLOEXEC
)
952 type
&= ~SOCK_CLOEXEC
;
954 #ifndef HAVE_SOCK_NONBLOCK
955 if (xtype
& SOCK_NONBLOCK
)
956 type
&= ~SOCK_NONBLOCK
;
959 if ((s
= socket(domain
, type
, protocol
)) == -1)
962 #ifndef HAVE_SOCK_CLOEXEC
963 if ((xtype
& SOCK_CLOEXEC
) && ((xflags
= fcntl(s
, F_GETFD
)) == -1 ||
964 fcntl(s
, F_SETFD
, xflags
| FD_CLOEXEC
) == -1))
967 #ifndef HAVE_SOCK_NONBLOCK
968 if ((xtype
& SOCK_NONBLOCK
) && ((xflags
= fcntl(s
, F_GETFL
)) == -1 ||
969 fcntl(s
, F_SETFL
, xflags
| O_NONBLOCK
) == -1))
975 #if !defined(HAVE_SOCK_CLOEXEC) || !defined(HAVE_SOCK_NONBLOCK)
983 xsocketpair(int domain
, int type
, int protocol
, int fd
[2])
986 #if !defined(HAVE_SOCK_CLOEXEC) || !defined(HAVE_SOCK_NONBLOCK)
987 int xflags
, xtype
= type
;
990 #ifndef HAVE_SOCK_CLOEXEC
991 if (xtype
& SOCK_CLOEXEC
)
992 type
&= ~SOCK_CLOEXEC
;
994 #ifndef HAVE_SOCK_NONBLOCK
995 if (xtype
& SOCK_NONBLOCK
)
996 type
&= ~SOCK_NONBLOCK
;
999 if ((s
= socketpair(domain
, type
, protocol
, fd
)) == -1)
1002 #ifndef HAVE_SOCK_CLOEXEC
1003 if ((xtype
& SOCK_CLOEXEC
) && ((xflags
= fcntl(fd
[0], F_GETFD
)) == -1 ||
1004 fcntl(fd
[0], F_SETFD
, xflags
| FD_CLOEXEC
) == -1))
1006 if ((xtype
& SOCK_CLOEXEC
) && ((xflags
= fcntl(fd
[1], F_GETFD
)) == -1 ||
1007 fcntl(fd
[1], F_SETFD
, xflags
| FD_CLOEXEC
) == -1))
1010 #ifndef HAVE_SOCK_NONBLOCK
1011 if ((xtype
& SOCK_NONBLOCK
) && ((xflags
= fcntl(fd
[0], F_GETFL
)) == -1 ||
1012 fcntl(fd
[0], F_SETFL
, xflags
| O_NONBLOCK
) == -1))
1014 if ((xtype
& SOCK_NONBLOCK
) && ((xflags
= fcntl(fd
[1], F_GETFL
)) == -1 ||
1015 fcntl(fd
[1], F_SETFL
, xflags
| O_NONBLOCK
) == -1))
1021 #if !defined(HAVE_SOCK_CLOEXEC) || !defined(HAVE_SOCK_NONBLOCK)