unix: factor out reusable BSD ifaddrs impl
Create a dedicated source file to share among platforms on which we find ifaddrs using the BSD getifaddrs API. De-duplicate our existing copies of this implementation on such platforms. PR-URL: https://github.com/libuv/libuv/pull/1240 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com> Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
This commit is contained in:
parent
0f84c305e0
commit
f277cb6f92
15
Makefile.am
15
Makefile.am
@ -339,7 +339,8 @@ include_HEADERS += include/uv-darwin.h \
|
|||||||
include/pthread-barrier.h
|
include/pthread-barrier.h
|
||||||
libuv_la_CFLAGS += -D_DARWIN_USE_64_BIT_INODE=1
|
libuv_la_CFLAGS += -D_DARWIN_USE_64_BIT_INODE=1
|
||||||
libuv_la_CFLAGS += -D_DARWIN_UNLIMITED_SELECT=1
|
libuv_la_CFLAGS += -D_DARWIN_UNLIMITED_SELECT=1
|
||||||
libuv_la_SOURCES += src/unix/darwin.c \
|
libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
|
||||||
|
src/unix/darwin.c \
|
||||||
src/unix/darwin-proctitle.c \
|
src/unix/darwin-proctitle.c \
|
||||||
src/unix/fsevents.c \
|
src/unix/fsevents.c \
|
||||||
src/unix/kqueue.c \
|
src/unix/kqueue.c \
|
||||||
@ -350,7 +351,8 @@ endif
|
|||||||
|
|
||||||
if DRAGONFLY
|
if DRAGONFLY
|
||||||
include_HEADERS += include/uv-bsd.h
|
include_HEADERS += include/uv-bsd.h
|
||||||
libuv_la_SOURCES += src/unix/freebsd.c \
|
libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
|
||||||
|
src/unix/freebsd.c \
|
||||||
src/unix/kqueue.c \
|
src/unix/kqueue.c \
|
||||||
src/unix/posix-hrtime.c
|
src/unix/posix-hrtime.c
|
||||||
test_run_tests_LDFLAGS += -lutil
|
test_run_tests_LDFLAGS += -lutil
|
||||||
@ -358,7 +360,8 @@ endif
|
|||||||
|
|
||||||
if FREEBSD
|
if FREEBSD
|
||||||
include_HEADERS += include/uv-bsd.h
|
include_HEADERS += include/uv-bsd.h
|
||||||
libuv_la_SOURCES += src/unix/freebsd.c \
|
libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
|
||||||
|
src/unix/freebsd.c \
|
||||||
src/unix/kqueue.c \
|
src/unix/kqueue.c \
|
||||||
src/unix/posix-hrtime.c
|
src/unix/posix-hrtime.c
|
||||||
test_run_tests_LDFLAGS += -lutil
|
test_run_tests_LDFLAGS += -lutil
|
||||||
@ -377,7 +380,8 @@ endif
|
|||||||
|
|
||||||
if NETBSD
|
if NETBSD
|
||||||
include_HEADERS += include/uv-bsd.h
|
include_HEADERS += include/uv-bsd.h
|
||||||
libuv_la_SOURCES += src/unix/kqueue.c \
|
libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
|
||||||
|
src/unix/kqueue.c \
|
||||||
src/unix/netbsd.c \
|
src/unix/netbsd.c \
|
||||||
src/unix/posix-hrtime.c
|
src/unix/posix-hrtime.c
|
||||||
test_run_tests_LDFLAGS += -lutil
|
test_run_tests_LDFLAGS += -lutil
|
||||||
@ -385,7 +389,8 @@ endif
|
|||||||
|
|
||||||
if OPENBSD
|
if OPENBSD
|
||||||
include_HEADERS += include/uv-bsd.h
|
include_HEADERS += include/uv-bsd.h
|
||||||
libuv_la_SOURCES += src/unix/kqueue.c \
|
libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
|
||||||
|
src/unix/kqueue.c \
|
||||||
src/unix/openbsd.c \
|
src/unix/openbsd.c \
|
||||||
src/unix/posix-hrtime.c
|
src/unix/posix-hrtime.c
|
||||||
test_run_tests_LDFLAGS += -lutil
|
test_run_tests_LDFLAGS += -lutil
|
||||||
|
|||||||
133
src/unix/bsd-ifaddrs.c
Normal file
133
src/unix/bsd-ifaddrs.c
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
/* Copyright libuv project contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
* deal in the Software without restriction, including without limitation the
|
||||||
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
* sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
* IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uv.h"
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include <ifaddrs.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <net/if_dl.h>
|
||||||
|
|
||||||
|
static int uv__ifaddr_exclude(struct ifaddrs *ent) {
|
||||||
|
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
|
||||||
|
return 1;
|
||||||
|
if (ent->ifa_addr == NULL)
|
||||||
|
return 1;
|
||||||
|
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__)
|
||||||
|
/*
|
||||||
|
* On BSD getifaddrs returns information related to the raw underlying
|
||||||
|
* devices. We're not interested in this information.
|
||||||
|
*/
|
||||||
|
if (ent->ifa_addr->sa_family == AF_LINK)
|
||||||
|
return 1;
|
||||||
|
#elif defined(__NetBSD__) || defined(__OpenBSD__)
|
||||||
|
if (ent->ifa_addr->sa_family != PF_INET)
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
||||||
|
struct ifaddrs* addrs;
|
||||||
|
struct ifaddrs* ent;
|
||||||
|
uv_interface_address_t* address;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (getifaddrs(&addrs) != 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
*count = 0;
|
||||||
|
|
||||||
|
/* Count the number of interfaces */
|
||||||
|
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
||||||
|
if (uv__ifaddr_exclude(ent))
|
||||||
|
continue;
|
||||||
|
(*count)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*addresses = uv__malloc(*count * sizeof(**addresses));
|
||||||
|
|
||||||
|
if (*addresses == NULL) {
|
||||||
|
freeifaddrs(addrs);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
address = *addresses;
|
||||||
|
|
||||||
|
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
||||||
|
if (uv__ifaddr_exclude(ent))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
address->name = uv__strdup(ent->ifa_name);
|
||||||
|
|
||||||
|
if (ent->ifa_addr->sa_family == AF_INET6) {
|
||||||
|
address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
|
||||||
|
} else {
|
||||||
|
address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ent->ifa_netmask->sa_family == AF_INET6) {
|
||||||
|
address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask);
|
||||||
|
} else {
|
||||||
|
address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
|
||||||
|
}
|
||||||
|
|
||||||
|
address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK);
|
||||||
|
|
||||||
|
address++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill in physical addresses for each interface */
|
||||||
|
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
||||||
|
if (uv__ifaddr_exclude(ent))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
address = *addresses;
|
||||||
|
|
||||||
|
for (i = 0; i < *count; i++) {
|
||||||
|
if (strcmp(address->name, ent->ifa_name) == 0) {
|
||||||
|
struct sockaddr_dl* sa_addr;
|
||||||
|
sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
|
||||||
|
memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
|
||||||
|
}
|
||||||
|
address++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
freeifaddrs(addrs);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void uv_free_interface_addresses(uv_interface_address_t* addresses,
|
||||||
|
int count) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
uv__free(addresses[i].name);
|
||||||
|
}
|
||||||
|
|
||||||
|
uv__free(addresses);
|
||||||
|
}
|
||||||
@ -25,10 +25,6 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include <ifaddrs.h>
|
|
||||||
#include <net/if.h>
|
|
||||||
#include <net/if_dl.h>
|
|
||||||
|
|
||||||
#include <mach/mach.h>
|
#include <mach/mach.h>
|
||||||
#include <mach/mach_time.h>
|
#include <mach/mach_time.h>
|
||||||
#include <mach-o/dyld.h> /* _NSGetExecutablePath */
|
#include <mach-o/dyld.h> /* _NSGetExecutablePath */
|
||||||
@ -233,100 +229,3 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
|
|||||||
|
|
||||||
uv__free(cpu_infos);
|
uv__free(cpu_infos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int uv__ifaddr_exclude(struct ifaddrs *ent) {
|
|
||||||
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
|
|
||||||
return 1;
|
|
||||||
if (ent->ifa_addr == NULL)
|
|
||||||
return 1;
|
|
||||||
/*
|
|
||||||
* On Mac OS X getifaddrs returns information related to Mac Addresses for
|
|
||||||
* various devices, such as firewire, etc. These are not relevant here.
|
|
||||||
*/
|
|
||||||
if (ent->ifa_addr->sa_family == AF_LINK)
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
|
||||||
struct ifaddrs *addrs, *ent;
|
|
||||||
uv_interface_address_t* address;
|
|
||||||
int i;
|
|
||||||
struct sockaddr_dl *sa_addr;
|
|
||||||
|
|
||||||
if (getifaddrs(&addrs))
|
|
||||||
return -errno;
|
|
||||||
|
|
||||||
*count = 0;
|
|
||||||
|
|
||||||
/* Count the number of interfaces */
|
|
||||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
|
||||||
if (uv__ifaddr_exclude(ent))
|
|
||||||
continue;
|
|
||||||
(*count)++;
|
|
||||||
}
|
|
||||||
|
|
||||||
*addresses = uv__malloc(*count * sizeof(**addresses));
|
|
||||||
if (!(*addresses)) {
|
|
||||||
freeifaddrs(addrs);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
address = *addresses;
|
|
||||||
|
|
||||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
|
||||||
if (uv__ifaddr_exclude(ent))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
address->name = uv__strdup(ent->ifa_name);
|
|
||||||
|
|
||||||
if (ent->ifa_addr->sa_family == AF_INET6) {
|
|
||||||
address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
|
|
||||||
} else {
|
|
||||||
address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ent->ifa_netmask->sa_family == AF_INET6) {
|
|
||||||
address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask);
|
|
||||||
} else {
|
|
||||||
address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
|
|
||||||
}
|
|
||||||
|
|
||||||
address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK);
|
|
||||||
|
|
||||||
address++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fill in physical addresses for each interface */
|
|
||||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
|
||||||
if (uv__ifaddr_exclude(ent))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
address = *addresses;
|
|
||||||
|
|
||||||
for (i = 0; i < (*count); i++) {
|
|
||||||
if (strcmp(address->name, ent->ifa_name) == 0) {
|
|
||||||
sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
|
|
||||||
memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
|
|
||||||
}
|
|
||||||
address++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
freeifaddrs(addrs);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void uv_free_interface_addresses(uv_interface_address_t* addresses,
|
|
||||||
int count) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
uv__free(addresses[i].name);
|
|
||||||
}
|
|
||||||
|
|
||||||
uv__free(addresses);
|
|
||||||
}
|
|
||||||
|
|||||||
@ -25,10 +25,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include <ifaddrs.h>
|
|
||||||
#include <net/if.h>
|
|
||||||
#include <net/if_dl.h>
|
|
||||||
|
|
||||||
#include <kvm.h>
|
#include <kvm.h>
|
||||||
#include <paths.h>
|
#include <paths.h>
|
||||||
#include <sys/user.h>
|
#include <sys/user.h>
|
||||||
@ -348,99 +344,3 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
|
|||||||
|
|
||||||
uv__free(cpu_infos);
|
uv__free(cpu_infos);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int uv__ifaddr_exclude(struct ifaddrs *ent) {
|
|
||||||
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
|
|
||||||
return 1;
|
|
||||||
if (ent->ifa_addr == NULL)
|
|
||||||
return 1;
|
|
||||||
/*
|
|
||||||
* On FreeBSD getifaddrs returns information related to the raw underlying
|
|
||||||
* devices. We're not interested in this information yet.
|
|
||||||
*/
|
|
||||||
if (ent->ifa_addr->sa_family == AF_LINK)
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
|
||||||
struct ifaddrs *addrs, *ent;
|
|
||||||
uv_interface_address_t* address;
|
|
||||||
int i;
|
|
||||||
struct sockaddr_dl *sa_addr;
|
|
||||||
|
|
||||||
if (getifaddrs(&addrs))
|
|
||||||
return -errno;
|
|
||||||
|
|
||||||
*count = 0;
|
|
||||||
|
|
||||||
/* Count the number of interfaces */
|
|
||||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
|
||||||
if (uv__ifaddr_exclude(ent))
|
|
||||||
continue;
|
|
||||||
(*count)++;
|
|
||||||
}
|
|
||||||
|
|
||||||
*addresses = uv__malloc(*count * sizeof(**addresses));
|
|
||||||
if (!(*addresses)) {
|
|
||||||
freeifaddrs(addrs);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
address = *addresses;
|
|
||||||
|
|
||||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
|
||||||
if (uv__ifaddr_exclude(ent))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
address->name = uv__strdup(ent->ifa_name);
|
|
||||||
|
|
||||||
if (ent->ifa_addr->sa_family == AF_INET6) {
|
|
||||||
address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
|
|
||||||
} else {
|
|
||||||
address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ent->ifa_netmask->sa_family == AF_INET6) {
|
|
||||||
address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask);
|
|
||||||
} else {
|
|
||||||
address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
|
|
||||||
}
|
|
||||||
|
|
||||||
address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK);
|
|
||||||
|
|
||||||
address++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fill in physical addresses for each interface */
|
|
||||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
|
||||||
if (uv__ifaddr_exclude(ent))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
address = *addresses;
|
|
||||||
|
|
||||||
for (i = 0; i < (*count); i++) {
|
|
||||||
if (strcmp(address->name, ent->ifa_name) == 0) {
|
|
||||||
sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
|
|
||||||
memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
|
|
||||||
}
|
|
||||||
address++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
freeifaddrs(addrs);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void uv_free_interface_addresses(uv_interface_address_t* addresses,
|
|
||||||
int count) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
uv__free(addresses[i].name);
|
|
||||||
}
|
|
||||||
|
|
||||||
uv__free(addresses);
|
|
||||||
}
|
|
||||||
|
|||||||
@ -27,14 +27,11 @@
|
|||||||
|
|
||||||
#include <kvm.h>
|
#include <kvm.h>
|
||||||
#include <paths.h>
|
#include <paths.h>
|
||||||
#include <ifaddrs.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
#include <net/if.h>
|
|
||||||
#include <net/if_dl.h>
|
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
@ -273,96 +270,3 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
|
|||||||
|
|
||||||
uv__free(cpu_infos);
|
uv__free(cpu_infos);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int uv__ifaddr_exclude(struct ifaddrs *ent) {
|
|
||||||
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
|
|
||||||
return 1;
|
|
||||||
if (ent->ifa_addr == NULL)
|
|
||||||
return 1;
|
|
||||||
if (ent->ifa_addr->sa_family != PF_INET)
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
|
||||||
struct ifaddrs *addrs, *ent;
|
|
||||||
uv_interface_address_t* address;
|
|
||||||
int i;
|
|
||||||
struct sockaddr_dl *sa_addr;
|
|
||||||
|
|
||||||
if (getifaddrs(&addrs))
|
|
||||||
return -errno;
|
|
||||||
|
|
||||||
*count = 0;
|
|
||||||
|
|
||||||
/* Count the number of interfaces */
|
|
||||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
|
||||||
if (uv__ifaddr_exclude(ent))
|
|
||||||
continue;
|
|
||||||
(*count)++;
|
|
||||||
}
|
|
||||||
|
|
||||||
*addresses = uv__malloc(*count * sizeof(**addresses));
|
|
||||||
|
|
||||||
if (!(*addresses)) {
|
|
||||||
freeifaddrs(addrs);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
address = *addresses;
|
|
||||||
|
|
||||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
|
||||||
if (uv__ifaddr_exclude(ent))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
address->name = uv__strdup(ent->ifa_name);
|
|
||||||
|
|
||||||
if (ent->ifa_addr->sa_family == AF_INET6) {
|
|
||||||
address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
|
|
||||||
} else {
|
|
||||||
address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ent->ifa_netmask->sa_family == AF_INET6) {
|
|
||||||
address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask);
|
|
||||||
} else {
|
|
||||||
address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
|
|
||||||
}
|
|
||||||
|
|
||||||
address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK);
|
|
||||||
|
|
||||||
address++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fill in physical addresses for each interface */
|
|
||||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
|
||||||
if (uv__ifaddr_exclude(ent))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
address = *addresses;
|
|
||||||
|
|
||||||
for (i = 0; i < (*count); i++) {
|
|
||||||
if (strcmp(address->name, ent->ifa_name) == 0) {
|
|
||||||
sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
|
|
||||||
memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
|
|
||||||
}
|
|
||||||
address++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
freeifaddrs(addrs);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
uv__free(addresses[i].name);
|
|
||||||
}
|
|
||||||
|
|
||||||
uv__free(addresses);
|
|
||||||
}
|
|
||||||
|
|||||||
@ -28,10 +28,6 @@
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
|
|
||||||
#include <ifaddrs.h>
|
|
||||||
#include <net/if.h>
|
|
||||||
#include <net/if_dl.h>
|
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <kvm.h>
|
#include <kvm.h>
|
||||||
@ -287,97 +283,3 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
|
|||||||
|
|
||||||
uv__free(cpu_infos);
|
uv__free(cpu_infos);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int uv__ifaddr_exclude(struct ifaddrs *ent) {
|
|
||||||
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
|
|
||||||
return 1;
|
|
||||||
if (ent->ifa_addr == NULL)
|
|
||||||
return 1;
|
|
||||||
if (ent->ifa_addr->sa_family != PF_INET)
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int uv_interface_addresses(uv_interface_address_t** addresses,
|
|
||||||
int* count) {
|
|
||||||
struct ifaddrs *addrs, *ent;
|
|
||||||
uv_interface_address_t* address;
|
|
||||||
int i;
|
|
||||||
struct sockaddr_dl *sa_addr;
|
|
||||||
|
|
||||||
if (getifaddrs(&addrs) != 0)
|
|
||||||
return -errno;
|
|
||||||
|
|
||||||
*count = 0;
|
|
||||||
|
|
||||||
/* Count the number of interfaces */
|
|
||||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
|
||||||
if (uv__ifaddr_exclude(ent))
|
|
||||||
continue;
|
|
||||||
(*count)++;
|
|
||||||
}
|
|
||||||
|
|
||||||
*addresses = uv__malloc(*count * sizeof(**addresses));
|
|
||||||
|
|
||||||
if (!(*addresses)) {
|
|
||||||
freeifaddrs(addrs);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
address = *addresses;
|
|
||||||
|
|
||||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
|
||||||
if (uv__ifaddr_exclude(ent))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
address->name = uv__strdup(ent->ifa_name);
|
|
||||||
|
|
||||||
if (ent->ifa_addr->sa_family == AF_INET6) {
|
|
||||||
address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
|
|
||||||
} else {
|
|
||||||
address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ent->ifa_netmask->sa_family == AF_INET6) {
|
|
||||||
address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask);
|
|
||||||
} else {
|
|
||||||
address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
|
|
||||||
}
|
|
||||||
|
|
||||||
address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK);
|
|
||||||
|
|
||||||
address++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fill in physical addresses for each interface */
|
|
||||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
|
||||||
if (uv__ifaddr_exclude(ent))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
address = *addresses;
|
|
||||||
|
|
||||||
for (i = 0; i < (*count); i++) {
|
|
||||||
if (strcmp(address->name, ent->ifa_name) == 0) {
|
|
||||||
sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
|
|
||||||
memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
|
|
||||||
}
|
|
||||||
address++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
freeifaddrs(addrs);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void uv_free_interface_addresses(uv_interface_address_t* addresses,
|
|
||||||
int count) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
uv__free(addresses[i].name);
|
|
||||||
}
|
|
||||||
|
|
||||||
uv__free(addresses);
|
|
||||||
}
|
|
||||||
|
|||||||
5
uv.gyp
5
uv.gyp
@ -301,7 +301,10 @@
|
|||||||
'sources': [ 'src/unix/posix-hrtime.c' ],
|
'sources': [ 'src/unix/posix-hrtime.c' ],
|
||||||
}],
|
}],
|
||||||
[ 'OS in "ios mac freebsd dragonflybsd openbsd netbsd".split()', {
|
[ 'OS in "ios mac freebsd dragonflybsd openbsd netbsd".split()', {
|
||||||
'sources': [ 'src/unix/kqueue.c' ],
|
'sources': [
|
||||||
|
'src/unix/bsd-ifaddrs.c',
|
||||||
|
'src/unix/kqueue.c',
|
||||||
|
],
|
||||||
}],
|
}],
|
||||||
['uv_library=="shared_library"', {
|
['uv_library=="shared_library"', {
|
||||||
'defines': [ 'BUILDING_UV_SHARED=1' ]
|
'defines': [ 'BUILDING_UV_SHARED=1' ]
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user