OLD | NEW |
---|---|
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #if !defined(DART_IO_DISABLED) | 5 #if !defined(DART_IO_DISABLED) |
6 | 6 |
7 #include "platform/globals.h" | 7 #include "platform/globals.h" |
8 #if defined(HOST_OS_FUCHSIA) | 8 #if defined(HOST_OS_FUCHSIA) |
9 | 9 |
10 #include "bin/socket_base.h" | 10 #include "bin/socket_base.h" |
11 | 11 |
12 // TODO(MG-766): If/when Fuchsia adds getifaddrs(), use that instead of the | |
13 // ioctl in netconfig.h. | |
14 #include <apps/netstack/apps/include/netconfig.h> | |
12 #include <errno.h> // NOLINT | 15 #include <errno.h> // NOLINT |
13 #include <fcntl.h> // NOLINT | 16 #include <fcntl.h> // NOLINT |
14 #include <ifaddrs.h> // NOLINT | 17 #include <ifaddrs.h> // NOLINT |
15 #include <net/if.h> // NOLINT | 18 #include <net/if.h> // NOLINT |
16 #include <netinet/tcp.h> // NOLINT | 19 #include <netinet/tcp.h> // NOLINT |
17 #include <stdio.h> // NOLINT | 20 #include <stdio.h> // NOLINT |
18 #include <stdlib.h> // NOLINT | 21 #include <stdlib.h> // NOLINT |
19 #include <string.h> // NOLINT | 22 #include <string.h> // NOLINT |
20 #include <sys/ioctl.h> // NOLINT | 23 #include <sys/ioctl.h> // NOLINT |
21 #include <sys/stat.h> // NOLINT | 24 #include <sys/stat.h> // NOLINT |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
275 result = NO_RETRY_EXPECTED(inet_pton(AF_INET, address, &addr->in.sin_addr)); | 278 result = NO_RETRY_EXPECTED(inet_pton(AF_INET, address, &addr->in.sin_addr)); |
276 } else { | 279 } else { |
277 ASSERT(type == SocketAddress::TYPE_IPV6); | 280 ASSERT(type == SocketAddress::TYPE_IPV6); |
278 result = | 281 result = |
279 NO_RETRY_EXPECTED(inet_pton(AF_INET6, address, &addr->in6.sin6_addr)); | 282 NO_RETRY_EXPECTED(inet_pton(AF_INET6, address, &addr->in6.sin6_addr)); |
280 } | 283 } |
281 return (result == 1); | 284 return (result == 1); |
282 } | 285 } |
283 | 286 |
284 | 287 |
288 static bool ShouldIncludeIfaAddrs(netc_if_info_t* if_info, int lookup_family) { | |
289 const int family = if_info->addr.ss_family; | |
290 return ((lookup_family == family) || | |
291 (((lookup_family == AF_UNSPEC) && | |
292 ((family == AF_INET) || (family == AF_INET6))))); | |
293 } | |
294 | |
295 | |
285 bool SocketBase::ListInterfacesSupported() { | 296 bool SocketBase::ListInterfacesSupported() { |
286 return false; | 297 return true; |
287 } | 298 } |
288 | 299 |
289 | 300 |
290 AddressList<InterfaceSocketAddress>* SocketBase::ListInterfaces( | 301 AddressList<InterfaceSocketAddress>* SocketBase::ListInterfaces( |
291 int type, | 302 int type, |
292 OSError** os_error) { | 303 OSError** os_error) { |
293 UNIMPLEMENTED(); | 304 // We need a dummy socket. |
294 return NULL; | 305 const int fd = socket(AF_INET6, SOCK_STREAM, 0); |
306 if (fd < 0) { | |
307 LOG_ERR("ListInterfaces: socket(AF_INET, SOCK_DGRAM, 0) failed\n"); | |
308 return NULL; | |
309 } | |
310 | |
311 // Call the ioctl. | |
312 netc_get_if_info_t get_if_info; | |
313 const ssize_t size = ioctl_netc_get_if_info(fd, &get_if_info); | |
314 if (size < 0) { | |
315 LOG_ERR("ListInterfaces: ioctl_netc_get_if_info() failed"); | |
316 return NULL; | |
317 } | |
318 if (get_if_info.n_info == 0) { | |
tkilbourn
2017/06/30 17:38:47
this seems like a valid return value; should this
zra
2017/06/30 17:42:42
Done.
| |
319 LOG_ERR("ListInterfaces: ioctl_netc_get_if_info() returned no interfaces"); | |
320 return NULL; | |
321 } | |
322 | |
323 // Process the results. | |
324 const int lookup_family = SocketAddress::FromType(type); | |
325 intptr_t count = 0; | |
326 for (intptr_t i = 0; i < get_if_info.n_info; i++) { | |
327 if (ShouldIncludeIfaAddrs(&get_if_info.info[i], lookup_family)) { | |
328 count++; | |
329 } | |
330 } | |
331 | |
332 AddressList<InterfaceSocketAddress>* addresses = | |
333 new AddressList<InterfaceSocketAddress>(count); | |
334 int addresses_idx = 0; | |
335 for (intptr_t i = 0; i < get_if_info.n_info; i++) { | |
336 if (ShouldIncludeIfaAddrs(&get_if_info.info[i], lookup_family)) { | |
337 char* ifa_name = DartUtils::ScopedCopyCString(get_if_info.info[i].name); | |
338 InterfaceSocketAddress* isa = new InterfaceSocketAddress( | |
339 reinterpret_cast<struct sockaddr*>(&get_if_info.info[i].addr), | |
340 ifa_name, | |
341 if_nametoindex(get_if_info.info[i].name)); | |
342 addresses->SetAt(addresses_idx, isa); | |
343 addresses_idx++; | |
344 } | |
345 } | |
346 return addresses; | |
295 } | 347 } |
296 | 348 |
297 | 349 |
298 void SocketBase::Close(intptr_t fd) { | 350 void SocketBase::Close(intptr_t fd) { |
299 IOHandle* handle = reinterpret_cast<IOHandle*>(fd); | 351 IOHandle* handle = reinterpret_cast<IOHandle*>(fd); |
300 ASSERT(handle->fd() >= 0); | 352 ASSERT(handle->fd() >= 0); |
301 NO_RETRY_EXPECTED(close(handle->fd())); | 353 NO_RETRY_EXPECTED(close(handle->fd())); |
302 } | 354 } |
303 | 355 |
304 | 356 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
382 UNIMPLEMENTED(); | 434 UNIMPLEMENTED(); |
383 return false; | 435 return false; |
384 } | 436 } |
385 | 437 |
386 } // namespace bin | 438 } // namespace bin |
387 } // namespace dart | 439 } // namespace dart |
388 | 440 |
389 #endif // defined(HOST_OS_FUCHSIA) | 441 #endif // defined(HOST_OS_FUCHSIA) |
390 | 442 |
391 #endif // !defined(DART_IO_DISABLED) | 443 #endif // !defined(DART_IO_DISABLED) |
OLD | NEW |