diff options
author | Ben Noordhuis <info@bnoordhuis.nl> | 2013-07-30 23:32:53 +0200 |
---|---|---|
committer | Ben Noordhuis <info@bnoordhuis.nl> | 2013-07-30 23:33:45 +0200 |
commit | 3ff2cbc892ce2d6aa01a986963f8437b8070b085 (patch) | |
tree | 84efdd2a7462daad3d2ea79bbeea647ad4f67ce9 /deps/uv/src/unix/freebsd.c | |
parent | 4cc57b4aca65ea86f4e42ddaeadfa796db239719 (diff) | |
download | android-node-v8-3ff2cbc892ce2d6aa01a986963f8437b8070b085.tar.gz android-node-v8-3ff2cbc892ce2d6aa01a986963f8437b8070b085.tar.bz2 android-node-v8-3ff2cbc892ce2d6aa01a986963f8437b8070b085.zip |
deps: upgrade libuv to joyent/libuv@4bdb7d8
Non-release upgrade so pending patches can land.
Diffstat (limited to 'deps/uv/src/unix/freebsd.c')
-rw-r--r-- | deps/uv/src/unix/freebsd.c | 95 |
1 files changed, 92 insertions, 3 deletions
diff --git a/deps/uv/src/unix/freebsd.c b/deps/uv/src/unix/freebsd.c index afdc4095e1..b1e8eb7d06 100644 --- a/deps/uv/src/unix/freebsd.c +++ b/deps/uv/src/unix/freebsd.c @@ -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); } |