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)
188 ifp
->flags
= (unsigned int)ifr
.ifr_flags
;
193 if_randomisemac(struct interface
*ifp
)
196 size_t hwlen
= ifp
->hwlen
, rlen
= 0;
197 uint8_t buf
[HWADDR_LEN
], *bp
= buf
, *rp
= (uint8_t *)&randnum
;
198 char sbuf
[HWADDR_LEN
* 3];
205 if (hwlen
> sizeof(buf
)) {
210 for (; hwlen
!= 0; hwlen
--) {
212 randnum
= arc4random();
213 rp
= (uint8_t *)&randnum
;
214 rlen
= sizeof(randnum
);
220 /* Unicast address and locally administered. */
224 logdebugx("%s: hardware address randomised to %s",
226 hwaddr_ntoa(buf
, ifp
->hwlen
, sbuf
, sizeof(sbuf
)));
227 retval
= if_setmac(ifp
, buf
, ifp
->hwlen
);
229 memcpy(ifp
->hwaddr
, buf
, ifp
->hwlen
);
234 if_hasconf(struct dhcpcd_ctx
*ctx
, const char *ifname
)
238 for (i
= 0; i
< ctx
->ifcc
; i
++) {
239 if (strcmp(ctx
->ifcv
[i
], ifname
) == 0)
246 if_markaddrsstale(struct if_head
*ifs
)
248 struct interface
*ifp
;
250 TAILQ_FOREACH(ifp
, ifs
, next
) {
252 ipv4_markaddrsstale(ifp
);
255 ipv6_markaddrsstale(ifp
, 0);
261 if_learnaddrs(struct dhcpcd_ctx
*ctx
, struct if_head
*ifs
,
262 struct ifaddrs
**ifaddrs
)
265 struct interface
*ifp
;
267 const struct sockaddr_in
*addr
, *net
, *brd
;
270 struct sockaddr_in6
*sin6
, *net6
;
274 for (ifa
= *ifaddrs
; ifa
; ifa
= ifa
->ifa_next
) {
275 if (ifa
->ifa_addr
== NULL
)
277 if ((ifp
= if_find(ifs
, ifa
->ifa_name
)) == NULL
)
279 #ifdef HAVE_IFADDRS_ADDRFLAGS
280 addrflags
= (int)ifa
->ifa_addrflags
;
282 switch(ifa
->ifa_addr
->sa_family
) {
285 addr
= (void *)ifa
->ifa_addr
;
286 net
= (void *)ifa
->ifa_netmask
;
287 if (ifa
->ifa_flags
& IFF_POINTOPOINT
)
288 brd
= (void *)ifa
->ifa_dstaddr
;
290 brd
= (void *)ifa
->ifa_broadaddr
;
291 #ifndef HAVE_IFADDRS_ADDRFLAGS
292 addrflags
= if_addrflags(ifp
, &addr
->sin_addr
,
294 if (addrflags
== -1) {
295 if (errno
!= EEXIST
&& errno
!= EADDRNOTAVAIL
) {
296 char dbuf
[INET_ADDRSTRLEN
];
299 dbp
= inet_ntop(AF_INET
, &addr
->sin_addr
,
301 logerr("%s: if_addrflags: %s%%%s",
302 __func__
, dbp
, ifp
->name
);
307 ipv4_handleifa(ctx
, RTM_NEWADDR
, ifs
, ifa
->ifa_name
,
308 &addr
->sin_addr
, &net
->sin_addr
,
309 brd
? &brd
->sin_addr
: NULL
, addrflags
, 0);
314 sin6
= (void *)ifa
->ifa_addr
;
315 net6
= (void *)ifa
->ifa_netmask
;
318 if (IN6_IS_ADDR_LINKLOCAL(&sin6
->sin6_addr
))
319 /* Remove the scope from the address */
320 sin6
->sin6_addr
.s6_addr
[2] =
321 sin6
->sin6_addr
.s6_addr
[3] = '\0';
323 #ifndef HAVE_IFADDRS_ADDRFLAGS
324 addrflags
= if_addrflags6(ifp
, &sin6
->sin6_addr
,
326 if (addrflags
== -1) {
327 if (errno
!= EEXIST
&& errno
!= EADDRNOTAVAIL
) {
328 char dbuf
[INET6_ADDRSTRLEN
];
331 dbp
= inet_ntop(AF_INET6
, &sin6
->sin6_addr
,
333 logerr("%s: if_addrflags6: %s%%%s",
334 __func__
, dbp
, ifp
->name
);
339 ipv6_handleifa(ctx
, RTM_NEWADDR
, ifs
,
340 ifa
->ifa_name
, &sin6
->sin6_addr
,
341 ipv6_prefixlen(&net6
->sin6_addr
), addrflags
, 0);
347 #ifdef PRIVSEP_GETIFADDRS
352 freeifaddrs(*ifaddrs
);
357 if_deletestaleaddrs(struct if_head
*ifs
)
359 struct interface
*ifp
;
361 TAILQ_FOREACH(ifp
, ifs
, next
) {
363 ipv4_deletestaleaddrs(ifp
);
366 ipv6_deletestaleaddrs(ifp
);
372 if_valid_hwaddr(const uint8_t *hwaddr
, size_t hwlen
)
375 bool all_zeros
, all_ones
;
377 all_zeros
= all_ones
= true;
378 for (i
= 0; i
< hwlen
; i
++) {
379 if (hwaddr
[i
] != 0x00)
381 if (hwaddr
[i
] != 0xff)
383 if (!all_zeros
&& !all_ones
)
389 #if defined(AF_PACKET) && !defined(AF_LINK)
391 if_check_arphrd(struct interface
*ifp
, unsigned int active
, bool if_noconf
)
394 switch(ifp
->hwtype
) {
395 case ARPHRD_ETHER
: /* FALLTHROUGH */
396 case ARPHRD_IEEE1394
: /* FALLTHROUGH */
397 case ARPHRD_INFINIBAND
: /* FALLTHROUGH */
398 case ARPHRD_NONE
: /* FALLTHROUGH */
400 case ARPHRD_LOOPBACK
:
403 logdebugx("%s: ignoring due to interface type and"
406 active
= IF_INACTIVE
;
411 active
= IF_INACTIVE
;
413 logwarnx("%s: unsupported interface type 0x%.2x",
414 ifp
->name
, ifp
->hwtype
);
423 if_discover(struct dhcpcd_ctx
*ctx
, struct ifaddrs
**ifaddrs
,
424 int argc
, char * const *argv
)
430 struct interface
*ifp
;
434 const struct sockaddr_dl
*sdl
;
436 struct if_laddrreq iflr
= { .flags
= IFLR_PREFIX
};
438 #elif defined(AF_PACKET)
439 const struct sockaddr_ll
*sll
;
441 #if defined(SIOCGIFPRIORITY)
445 if ((ifs
= malloc(sizeof(*ifs
))) == NULL
) {
451 #ifdef PRIVSEP_GETIFADDRS
452 if (ctx
->options
& DHCPCD_PRIVSEP
) {
453 if (ps_root_getifaddrs(ctx
, ifaddrs
) == -1) {
454 logerr("ps_root_getifaddrs");
460 if (getifaddrs(ifaddrs
) == -1) {
461 logerr("getifaddrs");
466 for (ifa
= *ifaddrs
; ifa
; ifa
= ifa
->ifa_next
) {
467 if (ifa
->ifa_addr
!= NULL
) {
469 if (ifa
->ifa_addr
->sa_family
!= AF_LINK
)
471 #elif defined(AF_PACKET)
472 if (ifa
->ifa_addr
->sa_family
!= AF_PACKET
)
476 if (if_nametospec(ifa
->ifa_name
, &spec
) != 0)
479 /* It's possible for an interface to have >1 AF_LINK.
480 * For our purposes, we use the first one. */
481 TAILQ_FOREACH(ifp
, ifs
, next
) {
482 if (strcmp(ifp
->name
, spec
.devname
) == 0)
489 for (i
= 0; i
< argc
; i
++) {
490 if (strcmp(argv
[i
], spec
.devname
) == 0)
493 active
= (i
== argc
) ? IF_INACTIVE
: IF_ACTIVE_USER
;
495 /* -1 means we're discovering against a specific
496 * interface, but we still need the below rules
498 if (argc
== -1 && strcmp(argv
[0], spec
.devname
) != 0)
500 active
= ctx
->options
& DHCPCD_INACTIVE
?
501 IF_INACTIVE
: IF_ACTIVE_USER
;
504 for (i
= 0; i
< ctx
->ifdc
; i
++)
505 if (fnmatch(ctx
->ifdv
[i
], spec
.devname
, 0) == 0)
508 active
= IF_INACTIVE
;
509 for (i
= 0; i
< ctx
->ifc
; i
++)
510 if (fnmatch(ctx
->ifv
[i
], spec
.devname
, 0) == 0)
512 if (ctx
->ifc
&& i
== ctx
->ifc
)
513 active
= IF_INACTIVE
;
514 for (i
= 0; i
< ctx
->ifac
; i
++)
515 if (fnmatch(ctx
->ifav
[i
], spec
.devname
, 0) == 0)
517 if (ctx
->ifac
&& i
== ctx
->ifac
)
518 active
= IF_INACTIVE
;
521 /* Ensure that the interface name has settled */
522 if (!dev_initialized(ctx
, spec
.devname
))
526 if (if_vimaster(ctx
, spec
.devname
) == 1) {
527 int loglevel
= argc
!= 0 ? LOG_ERR
: LOG_DEBUG
;
529 "%s: is a Virtual Interface Master, skipping",
534 if_noconf
= ((argc
== 0 || argc
== -1) && ctx
->ifac
== 0 &&
535 !if_hasconf(ctx
, spec
.devname
));
537 /* Don't allow some reserved interface names unless explicit. */
538 if (if_noconf
&& if_ignore(ctx
, spec
.devname
))
539 active
= IF_INACTIVE
;
541 ifp
= calloc(1, sizeof(*ifp
));
547 strlcpy(ifp
->name
, spec
.devname
, sizeof(ifp
->name
));
548 ifp
->flags
= ifa
->ifa_flags
;
550 if (ifa
->ifa_addr
!= NULL
) {
552 sdl
= (const void *)ifa
->ifa_addr
;
555 /* We need to check for active address */
556 strlcpy(iflr
.iflr_name
, ifp
->name
,
557 sizeof(iflr
.iflr_name
));
558 memcpy(&iflr
.addr
, ifa
->ifa_addr
,
559 MIN(ifa
->ifa_addr
->sa_len
, sizeof(iflr
.addr
)));
560 iflr
.flags
= IFLR_PREFIX
;
561 iflr
.prefixlen
= (unsigned int)sdl
->sdl_alen
* NBBY
;
562 if (ioctl(ctx
->pf_link_fd
, SIOCGLIFADDR
, &iflr
) == -1 ||
563 !(iflr
.flags
& IFLR_ACTIVE
))
570 ifp
->index
= sdl
->sdl_index
;
571 switch(sdl
->sdl_type
) {
573 case IFT_BRIDGE
: /* FALLTHROUGH */
575 #ifdef IFT_PROPVIRTUAL
576 case IFT_PROPVIRTUAL
: /* FALLTHROUGH */
579 case IFT_TUNNEL
: /* FALLTHROUGH */
581 case IFT_LOOP
: /* FALLTHROUGH */
583 /* Don't allow unless explicit */
585 logdebugx("%s: ignoring due to"
586 " interface type and"
589 active
= IF_INACTIVE
;
591 __fallthrough
; /* appease gcc */
594 case IFT_L2VLAN
: /* FALLTHROUGH */
597 case IFT_L3IPVLAN
: /* FALLTHROUGH */
600 ifp
->hwtype
= ARPHRD_ETHER
;
604 ifp
->hwtype
= ARPHRD_IEEE1394
;
607 #ifdef IFT_INFINIBAND
609 ifp
->hwtype
= ARPHRD_INFINIBAND
;
613 /* Don't allow unless explicit */
615 active
= IF_INACTIVE
;
617 logwarnx("%s: unsupported"
618 " interface type 0x%.2x",
619 ifp
->name
, sdl
->sdl_type
);
620 /* Pretend it's ethernet */
621 ifp
->hwtype
= ARPHRD_ETHER
;
624 ifp
->hwlen
= sdl
->sdl_alen
;
625 memcpy(ifp
->hwaddr
, CLLADDR(sdl
), ifp
->hwlen
);
626 #elif defined(AF_PACKET)
627 sll
= (const void *)ifa
->ifa_addr
;
628 ifp
->index
= (unsigned int)sll
->sll_ifindex
;
629 ifp
->hwtype
= sll
->sll_hatype
;
630 ifp
->hwlen
= sll
->sll_halen
;
632 memcpy(ifp
->hwaddr
, sll
->sll_addr
, ifp
->hwlen
);
633 active
= if_check_arphrd(ifp
, active
, if_noconf
);
638 struct ifreq ifr
= { .ifr_flags
= 0 };
640 /* This is a huge bug in getifaddrs(3) as there
641 * is no reason why this can't be returned in
643 strlcpy(ifr
.ifr_name
, ifa
->ifa_name
,
644 sizeof(ifr
.ifr_name
));
645 if (ioctl(ctx
->pf_inet_fd
, SIOCGIFHWADDR
, &ifr
) == -1)
646 logerr("%s: SIOCGIFHWADDR", ifa
->ifa_name
);
647 ifp
->hwtype
= ifr
.ifr_hwaddr
.sa_family
;
648 if (ioctl(ctx
->pf_inet_fd
, SIOCGIFINDEX
, &ifr
) == -1)
649 logerr("%s: SIOCGIFINDEX", ifa
->ifa_name
);
650 ifp
->index
= (unsigned int)ifr
.ifr_ifindex
;
651 if_check_arphrd(ifp
, active
, if_noconf
);
655 if (!(ctx
->options
& (DHCPCD_DUMPLEASE
| DHCPCD_TEST
))) {
656 /* Handle any platform init for the interface */
657 if (active
!= IF_INACTIVE
&& if_init(ifp
) == -1) {
658 logerr("%s: if_init", ifp
->name
);
664 ifp
->vlanid
= if_vlanid(ifp
);
666 #ifdef SIOCGIFPRIORITY
667 /* Respect the interface priority */
668 memset(&ifr
, 0, sizeof(ifr
));
669 strlcpy(ifr
.ifr_name
, ifp
->name
, sizeof(ifr
.ifr_name
));
670 if (pioctl(ctx
, SIOCGIFPRIORITY
, &ifr
, sizeof(ifr
)) == 0)
671 ifp
->metric
= (unsigned int)ifr
.ifr_metric
;
674 /* We reserve the 100 range for virtual interfaces, if and when
675 * we can work them out. */
676 ifp
->metric
= 200 + ifp
->index
;
677 if (if_getssid(ifp
) != -1) {
678 ifp
->wireless
= true;
683 ifp
->active
= active
;
685 ifp
->carrier
= if_carrier(ifp
);
687 ifp
->carrier
= LINK_UNKNOWN
;
688 TAILQ_INSERT_TAIL(ifs
, ifp
, next
);
697 struct interface
*ifp
= arg
;
698 unsigned int flags
= ifp
->flags
;
701 carrier
= if_carrier(ifp
); /* if_carrier will update ifp->flags */
702 if (ifp
->carrier
!= carrier
|| ifp
->flags
!= flags
)
703 dhcpcd_handlecarrier(ifp
->ctx
, carrier
, ifp
->flags
, ifp
->name
);
705 if (ifp
->options
->poll
!= 0 || ifp
->carrier
!= LINK_UP
)
710 if_pollinit(struct interface
*ifp
)
714 msec
= ifp
->options
->poll
!= 0 ? ifp
->options
->poll
: IF_POLL_UP
;
715 return eloop_timeout_add_msec(ifp
->ctx
->eloop
, msec
, if_poll
, ifp
);
719 * eth0.100:2 OR eth0i100:2 (seems to be NetBSD xvif(4) only)
722 * devname == eth0.100 OR eth0i100
727 if_nametospec(const char *ifname
, struct if_spec
*spec
)
732 if (ifname
== NULL
|| *ifname
== '\0' ||
733 strlcpy(spec
->ifname
, ifname
, sizeof(spec
->ifname
)) >=
734 sizeof(spec
->ifname
) ||
735 strlcpy(spec
->drvname
, ifname
, sizeof(spec
->drvname
)) >=
736 sizeof(spec
->drvname
))
743 ep
= strchr(spec
->drvname
, ':');
745 spec
->lun
= (int)strtoi(ep
+ 1, NULL
, 10, 0, INT_MAX
, &e
);
757 ep
= spec
->drvname
+ strlen(spec
->drvname
) - 1;
761 strlcpy(spec
->devname
, spec
->drvname
, sizeof(spec
->devname
));
763 /* Solaris has numbers in the driver name, such as e1000g */
764 while (ep
> spec
->drvname
&& isdigit((int)*ep
))
771 /* BSD and Linux no not have numbers in the driver name */
772 for (ep
= spec
->drvname
; *ep
!= '\0' && !isdigit((int)*ep
); ep
++) {
779 spec
->ppa
= (int)strtoi(ep
, &pp
, 10, 0, INT_MAX
, &e
);
784 * . is used for VLAN style names
785 * i is used on NetBSD for xvif interfaces
787 if (pp
!= NULL
&& (*pp
== '.' || *pp
== 'i')) {
788 spec
->vlid
= (int)strtoi(pp
+ 1, NULL
, 10, 0, INT_MAX
, &e
);
798 static struct interface
*
799 if_findindexname(struct if_head
*ifaces
, unsigned int idx
, const char *name
)
802 if (ifaces
!= NULL
) {
804 struct interface
*ifp
;
806 if (name
&& if_nametospec(name
, &spec
) == -1)
809 TAILQ_FOREACH(ifp
, ifaces
, next
) {
810 if ((name
&& strcmp(ifp
->name
, spec
.devname
) == 0) ||
811 (!name
&& ifp
->index
== idx
))
821 if_find(struct if_head
*ifaces
, const char *name
)
824 return if_findindexname(ifaces
, 0, name
);
828 if_findindex(struct if_head
*ifaces
, unsigned int idx
)
831 return if_findindexname(ifaces
, idx
, NULL
);
835 if_loopback(struct dhcpcd_ctx
*ctx
)
837 struct interface
*ifp
;
839 TAILQ_FOREACH(ifp
, ctx
->ifaces
, next
) {
840 if (ifp
->flags
& IFF_LOOPBACK
)
847 if_domtu(const struct interface
*ifp
, short int mtu
)
854 return if_mtu_os(ifp
);
857 memset(&ifr
, 0, sizeof(ifr
));
858 strlcpy(ifr
.ifr_name
, ifp
->name
, sizeof(ifr
.ifr_name
));
861 r
= if_ioctl(ifp
->ctx
, SIOCSIFMTU
, &ifr
, sizeof(ifr
));
863 r
= pioctl(ifp
->ctx
, SIOCGIFMTU
, &ifr
, sizeof(ifr
));
872 if_makealias(char *alias
, size_t alias_len
, const char *ifname
, int lun
)
876 return strlcpy(alias
, ifname
, alias_len
);
877 return snprintf(alias
, alias_len
, "%s:%u", ifname
, lun
);
882 if_findifpfromcmsg(struct dhcpcd_ctx
*ctx
, struct msghdr
*msg
, int *hoplimit
)
885 unsigned int ifindex
= 0;
886 struct interface
*ifp
;
889 struct sockaddr_dl sdl
;
891 struct in_pktinfo ipi
;
895 struct in6_pktinfo ipi6
;
900 for (cm
= (struct cmsghdr
*)CMSG_FIRSTHDR(msg
);
902 cm
= (struct cmsghdr
*)CMSG_NXTHDR(msg
, cm
))
905 if (cm
->cmsg_level
== IPPROTO_IP
) {
906 switch(cm
->cmsg_type
) {
910 offsetof(struct sockaddr_dl
, sdl_index
) +
911 sizeof(sdl
.sdl_index
))
913 memcpy(&sdl
, CMSG_DATA(cm
),
914 MIN(sizeof(sdl
), cm
->cmsg_len
));
915 ifindex
= sdl
.sdl_index
;
919 if (cm
->cmsg_len
!= CMSG_LEN(sizeof(ipi
)))
921 memcpy(&ipi
, CMSG_DATA(cm
), sizeof(ipi
));
922 ifindex
= (unsigned int)ipi
.ipi_ifindex
;
929 if (cm
->cmsg_level
== IPPROTO_IPV6
) {
930 switch(cm
->cmsg_type
) {
932 if (cm
->cmsg_len
!= CMSG_LEN(sizeof(ipi6
)))
934 memcpy(&ipi6
, CMSG_DATA(cm
), sizeof(ipi6
));
935 ifindex
= (unsigned int)ipi6
.ipi6_ifindex
;
938 if (cm
->cmsg_len
!= CMSG_LEN(sizeof(int)))
940 if (hoplimit
== NULL
)
942 memcpy(hoplimit
, CMSG_DATA(cm
), sizeof(int));
949 /* Find the receiving interface */
950 TAILQ_FOREACH(ifp
, ctx
->ifaces
, next
) {
951 if (ifp
->index
== ifindex
)
960 xsocket(int domain
, int type
, int protocol
)
963 #if !defined(HAVE_SOCK_CLOEXEC) || !defined(HAVE_SOCK_NONBLOCK)
964 int xflags
, xtype
= type
;
967 #ifndef HAVE_SOCK_CLOEXEC
968 if (xtype
& SOCK_CLOEXEC
)
969 type
&= ~SOCK_CLOEXEC
;
971 #ifndef HAVE_SOCK_NONBLOCK
972 if (xtype
& SOCK_NONBLOCK
)
973 type
&= ~SOCK_NONBLOCK
;
976 if ((s
= socket(domain
, type
, protocol
)) == -1)
979 #ifndef HAVE_SOCK_CLOEXEC
980 if ((xtype
& SOCK_CLOEXEC
) && ((xflags
= fcntl(s
, F_GETFD
)) == -1 ||
981 fcntl(s
, F_SETFD
, xflags
| FD_CLOEXEC
) == -1))
984 #ifndef HAVE_SOCK_NONBLOCK
985 if ((xtype
& SOCK_NONBLOCK
) && ((xflags
= fcntl(s
, F_GETFL
)) == -1 ||
986 fcntl(s
, F_SETFL
, xflags
| O_NONBLOCK
) == -1))
992 #if !defined(HAVE_SOCK_CLOEXEC) || !defined(HAVE_SOCK_NONBLOCK)
1000 xsocketpair(int domain
, int type
, int protocol
, int fd
[2])
1003 #if !defined(HAVE_SOCK_CLOEXEC) || !defined(HAVE_SOCK_NONBLOCK)
1004 int xflags
, xtype
= type
;
1007 #ifndef HAVE_SOCK_CLOEXEC
1008 if (xtype
& SOCK_CLOEXEC
)
1009 type
&= ~SOCK_CLOEXEC
;
1011 #ifndef HAVE_SOCK_NONBLOCK
1012 if (xtype
& SOCK_NONBLOCK
)
1013 type
&= ~SOCK_NONBLOCK
;
1016 if ((s
= socketpair(domain
, type
, protocol
, fd
)) == -1)
1019 #ifndef HAVE_SOCK_CLOEXEC
1020 if ((xtype
& SOCK_CLOEXEC
) && ((xflags
= fcntl(fd
[0], F_GETFD
)) == -1 ||
1021 fcntl(fd
[0], F_SETFD
, xflags
| FD_CLOEXEC
) == -1))
1023 if ((xtype
& SOCK_CLOEXEC
) && ((xflags
= fcntl(fd
[1], F_GETFD
)) == -1 ||
1024 fcntl(fd
[1], F_SETFD
, xflags
| FD_CLOEXEC
) == -1))
1027 #ifndef HAVE_SOCK_NONBLOCK
1028 if ((xtype
& SOCK_NONBLOCK
) && ((xflags
= fcntl(fd
[0], F_GETFL
)) == -1 ||
1029 fcntl(fd
[0], F_SETFL
, xflags
| O_NONBLOCK
) == -1))
1031 if ((xtype
& SOCK_NONBLOCK
) && ((xflags
= fcntl(fd
[1], F_GETFL
)) == -1 ||
1032 fcntl(fd
[1], F_SETFL
, xflags
| O_NONBLOCK
) == -1))
1038 #if !defined(HAVE_SOCK_CLOEXEC) || !defined(HAVE_SOCK_NONBLOCK)