Index: runtime/bin/socket_base_fuchsia.cc |
diff --git a/runtime/bin/socket_base_fuchsia.cc b/runtime/bin/socket_base_fuchsia.cc |
index 68e8e472243004a15c8dffa86b984187a29e8d95..7f54b94f138524feb4420c1292b42333a6548dce 100644 |
--- a/runtime/bin/socket_base_fuchsia.cc |
+++ b/runtime/bin/socket_base_fuchsia.cc |
@@ -9,6 +9,9 @@ |
#include "bin/socket_base.h" |
+// TODO(MG-766): If/when Fuchsia adds getifaddrs(), use that instead of the |
+// ioctl in netconfig.h. |
+#include <apps/netstack/apps/include/netconfig.h> |
#include <errno.h> // NOLINT |
#include <fcntl.h> // NOLINT |
#include <ifaddrs.h> // NOLINT |
@@ -282,16 +285,63 @@ bool SocketBase::ParseAddress(int type, const char* address, RawAddr* addr) { |
} |
+static bool ShouldIncludeIfaAddrs(netc_if_info_t* if_info, int lookup_family) { |
+ const int family = if_info->addr.ss_family; |
+ return ((lookup_family == family) || |
+ (((lookup_family == AF_UNSPEC) && |
+ ((family == AF_INET) || (family == AF_INET6))))); |
+} |
+ |
+ |
bool SocketBase::ListInterfacesSupported() { |
- return false; |
+ return true; |
} |
AddressList<InterfaceSocketAddress>* SocketBase::ListInterfaces( |
int type, |
OSError** os_error) { |
- UNIMPLEMENTED(); |
- return NULL; |
+ // We need a dummy socket. |
+ const int fd = socket(AF_INET6, SOCK_STREAM, 0); |
+ if (fd < 0) { |
+ LOG_ERR("ListInterfaces: socket(AF_INET, SOCK_DGRAM, 0) failed\n"); |
+ return NULL; |
+ } |
+ |
+ // Call the ioctl. |
+ netc_get_if_info_t get_if_info; |
+ const ssize_t size = ioctl_netc_get_if_info(fd, &get_if_info); |
+ if (size < 0) { |
+ LOG_ERR("ListInterfaces: ioctl_netc_get_if_info() failed"); |
+ close(fd); |
+ return NULL; |
+ } |
+ |
+ // Process the results. |
+ const int lookup_family = SocketAddress::FromType(type); |
+ intptr_t count = 0; |
+ for (intptr_t i = 0; i < get_if_info.n_info; i++) { |
+ if (ShouldIncludeIfaAddrs(&get_if_info.info[i], lookup_family)) { |
+ count++; |
+ } |
+ } |
+ |
+ AddressList<InterfaceSocketAddress>* addresses = |
+ new AddressList<InterfaceSocketAddress>(count); |
+ int addresses_idx = 0; |
+ for (intptr_t i = 0; i < get_if_info.n_info; i++) { |
+ if (ShouldIncludeIfaAddrs(&get_if_info.info[i], lookup_family)) { |
+ char* ifa_name = DartUtils::ScopedCopyCString(get_if_info.info[i].name); |
+ InterfaceSocketAddress* isa = new InterfaceSocketAddress( |
+ reinterpret_cast<struct sockaddr*>(&get_if_info.info[i].addr), |
+ ifa_name, |
+ if_nametoindex(get_if_info.info[i].name)); |
+ addresses->SetAt(addresses_idx, isa); |
+ addresses_idx++; |
+ } |
+ } |
+ close(fd); |
+ return addresses; |
} |