Chromium Code Reviews| Index: runtime/bin/socket_patch.dart |
| diff --git a/runtime/bin/socket_patch.dart b/runtime/bin/socket_patch.dart |
| index d603532e84c93176f182ca76489ac8781fb24877..8ed0aadb2ad00225c3bd956ed95b72891a73ccaa 100644 |
| --- a/runtime/bin/socket_patch.dart |
| +++ b/runtime/bin/socket_patch.dart |
| @@ -42,11 +42,24 @@ patch class InternetAddress { |
| } |
| } |
| +patch class NetworkInterface { |
| + /* patch */ static Future<List<NetworkInterface>> list({ |
| + bool includeLoopback: false, |
| + bool includeLinkLocal: false, |
| + InternetAddressType type: InternetAddressType.ANY}) { |
| + return _NativeSocket.listInterfaces(includeLoopback: includeLoopback, |
| + includeLinkLocal: includeLinkLocal, |
| + type: type); |
| + } |
| +} |
| + |
| class _InternetAddress implements InternetAddress { |
| static const int _ADDRESS_LOOPBACK_IP_V4 = 0; |
| static const int _ADDRESS_LOOPBACK_IP_V6 = 1; |
| static const int _ADDRESS_ANY_IP_V4 = 2; |
| static const int _ADDRESS_ANY_IP_V6 = 3; |
| + static const int _IPV4_ADDR_OFFSET = 4; |
| + static const int _IPV6_ADDR_OFFSET = 8; |
| static _InternetAddress LOOPBACK_IP_V4 = |
| new _InternetAddress.fixed(_ADDRESS_LOOPBACK_IP_V4); |
| @@ -62,6 +75,31 @@ class _InternetAddress implements InternetAddress { |
| final String host; |
| final Uint8List _sockaddr_storage; |
| + bool get isLoopback { |
| + switch (type) { |
| + case InternetAddressType.IP_V4: |
| + return _sockaddr_storage[_IPV4_ADDR_OFFSET] == 127; |
| + |
| + case InternetAddressType.IP_V6: |
| + for (int i = 0; i < 15; i++) { |
|
Søren Gjesse
2013/06/20 14:38:17
15 -> _IPV6_ADDR_LENGTH
Anders Johnsen
2013/06/20 15:00:25
Done.
|
| + if (_sockaddr_storage[_IPV6_ADDR_OFFSET + i] != 0) return false; |
| + } |
| + return _sockaddr_storage[_IPV6_ADDR_OFFSET + 15] == 1; |
|
Søren Gjesse
2013/06/20 14:38:17
Ditto.
Anders Johnsen
2013/06/20 15:00:25
Done.
|
| + } |
| + } |
| + |
| + bool get isLinkLocal { |
| + switch (type) { |
|
Søren Gjesse
2013/06/20 14:38:17
Please add comment here "Checking for 169.256.0.0/
Anders Johnsen
2013/06/20 15:00:25
Done.
|
| + case InternetAddressType.IP_V4: |
| + return _sockaddr_storage[_IPV4_ADDR_OFFSET] == 169 && |
| + _sockaddr_storage[_IPV4_ADDR_OFFSET + 1] == 254; |
| + |
| + case InternetAddressType.IP_V6: |
|
Søren Gjesse
2013/06/20 14:38:17
Ditto.
Anders Johnsen
2013/06/20 15:00:25
Done.
|
| + return _sockaddr_storage[_IPV6_ADDR_OFFSET] == 0xFE && |
| + (_sockaddr_storage[_IPV6_ADDR_OFFSET + 1] & 0xB0) == 0x80; |
| + } |
| + } |
| + |
| _InternetAddress(InternetAddressType this.type, |
| String this.address, |
| String this.host, |
| @@ -95,6 +133,17 @@ class _InternetAddress implements InternetAddress { |
| static Uint8List _fixed(int id) native "InternetAddress_Fixed"; |
| } |
| +class _NetworkInterface implements NetworkInterface{ |
| + final String name; |
| + final List<InternetAddress> addresses; |
| + |
| + _NetworkInterface(String this.name, List<InternetAddress> this.addresses); |
| + |
| + String toString() { |
| + return "NetworkInterface('$name', $addresses)"; |
| + } |
| +} |
| + |
| // The _NativeSocket class encapsulates an OS socket. |
| class _NativeSocket extends NativeFieldWrapperClass1 { |
| @@ -131,6 +180,7 @@ class _NativeSocket extends NativeFieldWrapperClass1 { |
| // Native port messages. |
| static const HOST_NAME_LOOKUP = 0; |
| + static const LIST_INTERFACES = 1; |
| // Socket close state |
| bool isClosed = false; |
| @@ -174,6 +224,37 @@ class _NativeSocket extends NativeFieldWrapperClass1 { |
| }); |
| } |
| + static Future<List<NetworkInterface>> listInterfaces({ |
| + bool includeLoopback: false, |
| + bool includeLinkLocal: false, |
| + InternetAddressType type: InternetAddressType.ANY}) { |
| + ensureSocketService(); |
| + return socketService.call([LIST_INTERFACES, type._value]) |
| + .then((response) { |
| + if (isErrorResponse(response)) { |
| + throw createError(response, "Failed listing interfaces"); |
| + } else { |
| + var list = new List<NetworkInterface>(); |
| + var map = response.skip(1) |
| + .fold(new Map<String, List<InternetAddress>>(), (map, result) { |
| + var type = new InternetAddressType._from(result[0]); |
| + var name = result[3]; |
| + var address = new _InternetAddress( |
| + type, result[1], "", result[2]); |
| + if (!includeLinkLocal && address.isLinkLocal) return map; |
| + if (!includeLoopback && address.isLoopback) return map; |
| + map.putIfAbsent(name, () => new List<InternetAddress>()); |
| + map[name].add(address); |
| + return map; |
| + }) |
| + .forEach((name, addresses) { |
| + list.add(new _NetworkInterface(name, addresses)); |
| + }); |
| + return list; |
| + } |
| + }); |
| + } |
| + |
| static Future<_NativeSocket> connect(host, int port) { |
| return new Future.value(host) |
| .then((host) { |