summaryrefslogtreecommitdiff
path: root/deps/uv/src/unix/freebsd.c
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2013-07-30 23:32:53 +0200
committerBen Noordhuis <info@bnoordhuis.nl>2013-07-30 23:33:45 +0200
commit3ff2cbc892ce2d6aa01a986963f8437b8070b085 (patch)
tree84efdd2a7462daad3d2ea79bbeea647ad4f67ce9 /deps/uv/src/unix/freebsd.c
parent4cc57b4aca65ea86f4e42ddaeadfa796db239719 (diff)
downloadandroid-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.c95
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);
}