Showing with 306 additions and 45 deletions.
  1. +1 −0 include/uv.h
  2. +27 −8 src/unix/darwin.c
  3. +92 −3 src/unix/freebsd.c
  4. +30 −11 src/unix/linux-core.c
  5. +28 −10 src/unix/netbsd.c
  6. +88 −3 src/unix/openbsd.c
  7. +25 −10 src/unix/sunos.c
  8. +7 −0 src/win/util.c
  9. +8 −0 test/test-platform-output.c
@@ -1526,6 +1526,7 @@ struct uv_cpu_info_s {

struct uv_interface_address_s {
char* name;
char phys_addr[6];
int is_internal;
union {
struct sockaddr_in address4;
@@ -27,6 +27,7 @@

#include <ifaddrs.h>
#include <net/if.h>
#include <net/if_dl.h>

#include <CoreFoundation/CFRunLoop.h>

@@ -355,6 +356,8 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
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;
@@ -363,7 +366,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {

/* Count the number of interfaces */
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING) ||
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
(ent->ifa_addr == NULL) ||
(ent->ifa_addr->sa_family == AF_LINK)) {
continue;
@@ -379,21 +382,18 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
address = *addresses;

for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING)) {
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
continue;
}

if (ent->ifa_addr == NULL) {
if (ent->ifa_addr == NULL)
continue;
}

/*
* 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) {
if (ent->ifa_addr->sa_family == AF_LINK)
continue;
}

address->name = strdup(ent->ifa_name);

@@ -409,11 +409,30 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
}

address->is_internal = ent->ifa_flags & IFF_LOOPBACK ? 1 : 0;
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 (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
(ent->ifa_addr == NULL) ||
(ent->ifa_addr->sa_family != AF_LINK)) {
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;
@@ -25,6 +25,10 @@
#include <string.h>
#include <errno.h>

#include <ifaddrs.h>
#include <net/if.h>
#include <net/if_dl.h>

#include <kvm.h>
#include <paths.h>
#include <sys/user.h>
@@ -322,13 +326,98 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {


int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
/* TODO: implement */
*addresses = NULL;
*count = 0;
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 (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
(ent->ifa_addr == NULL) ||
(ent->ifa_addr->sa_family == AF_LINK)) {
continue;
}

(*count)++;
}

*addresses = malloc(*count * sizeof(**addresses));
if (!(*addresses))
return -ENOMEM;

address = *addresses;

for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
continue;

if (ent->ifa_addr == NULL)
continue;

/*
* 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)
continue;

address->name = 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 (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
(ent->ifa_addr == NULL) ||
(ent->ifa_addr->sa_family != AF_LINK)) {
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++) {
free(addresses[i].name);
}

free(addresses);
}
@@ -47,6 +47,9 @@
#endif
#ifdef HAVE_IFADDRS_H
# include <ifaddrs.h>
# include <sys/socket.h>
# include <net/ethernet.h>
# include <linux/if_packet.h>
#endif

#undef NANOSEC
@@ -624,8 +627,9 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
return -ENOSYS;
#else
struct ifaddrs *addrs, *ent;
char ip[INET6_ADDRSTRLEN];
uv_interface_address_t* address;
int i;
struct sockaddr_ll *sll;

if (getifaddrs(&addrs))
return -errno;
@@ -634,7 +638,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses,

/* Count the number of interfaces */
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING) ||
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
(ent->ifa_addr == NULL) ||
(ent->ifa_addr->sa_family == PF_PACKET)) {
continue;
@@ -650,22 +654,18 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
address = *addresses;

for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
bzero(&ip, sizeof (ip));
if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING)) {
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
continue;
}

if (ent->ifa_addr == NULL) {
if (ent->ifa_addr == NULL)
continue;
}

/*
* On Linux getifaddrs returns information related to the raw underlying
* devices. We're not interested in this information.
* devices. We're not interested in this information yet.
*/
if (ent->ifa_addr->sa_family == PF_PACKET) {
if (ent->ifa_addr->sa_family == PF_PACKET)
continue;
}

address->name = strdup(ent->ifa_name);

@@ -681,11 +681,30 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
}

address->is_internal = ent->ifa_flags & IFF_LOOPBACK ? 1 : 0;
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 (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
(ent->ifa_addr == NULL) ||
(ent->ifa_addr->sa_family != PF_PACKET)) {
continue;
}

address = *addresses;

for (i = 0; i < (*count); i++) {
if (strcmp(address->name, ent->ifa_name) == 0) {
sll = (struct sockaddr_ll*)ent->ifa_addr;
memcpy(address->phys_addr, sll->sll_addr, sizeof(address->phys_addr));
}
address++;
}
}

freeifaddrs(addrs);

return 0;
@@ -34,6 +34,7 @@
#include <fcntl.h>

#include <net/if.h>
#include <net/if_dl.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <sys/sysctl.h>
@@ -274,9 +275,10 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {


int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
struct ifaddrs *addrs;
struct ifaddrs *ent;
struct ifaddrs *addrs, *ent;
uv_interface_address_t* address;
int i;
struct sockaddr_dl *sa_addr;

if (getifaddrs(&addrs))
return -errno;
@@ -285,7 +287,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {

/* Count the number of interfaces */
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING) ||
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
(ent->ifa_addr == NULL) ||
(ent->ifa_addr->sa_family != PF_INET)) {
continue;
@@ -301,17 +303,14 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
address = *addresses;

for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING)) {
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
continue;
}

if (ent->ifa_addr == NULL) {
if (ent->ifa_addr == NULL)
continue;
}

if (ent->ifa_addr->sa_family != PF_INET) {
if (ent->ifa_addr->sa_family != PF_INET)
continue;
}

address->name = strdup(ent->ifa_name);

@@ -327,11 +326,30 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
}

address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK) ? 1 : 0;
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 (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
(ent->ifa_addr == NULL) ||
(ent->ifa_addr->sa_family != AF_LINK)) {
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;