| Index: net/base/net_util_win.cc
|
| diff --git a/net/base/net_util_win.cc b/net/base/net_util_win.cc
|
| index 7d146b91e511f2f3ba1c8f213ea90eb2652b3e4b..ec4023384c4c48699195cd51b3be7ed0506995e4 100644
|
| --- a/net/base/net_util_win.cc
|
| +++ b/net/base/net_util_win.cc
|
| @@ -85,35 +85,11 @@ WlanApi::WlanApi() : initialized(false) {
|
| free_memory_func && close_handle_func;
|
| }
|
|
|
| -} // namespace internal
|
| -
|
| -bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
|
| - // GetAdaptersAddresses() may require IO operations.
|
| - base::ThreadRestrictions::AssertIOAllowed();
|
| - bool is_xp = base::win::GetVersion() < base::win::VERSION_VISTA;
|
| - ULONG len = 0;
|
| - ULONG flags = is_xp ? GAA_FLAG_INCLUDE_PREFIX : 0;
|
| - // First get number of networks.
|
| - ULONG result = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, NULL, &len);
|
| - if (result != ERROR_BUFFER_OVERFLOW) {
|
| - // There are 0 networks.
|
| - return true;
|
| - }
|
| - scoped_ptr<char[]> buf(new char[len]);
|
| - IP_ADAPTER_ADDRESSES *adapters =
|
| - reinterpret_cast<IP_ADAPTER_ADDRESSES *>(buf.get());
|
| - result = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapters, &len);
|
| - if (result != NO_ERROR) {
|
| - LOG(ERROR) << "GetAdaptersAddresses failed: " << result;
|
| - return false;
|
| - }
|
| -
|
| - // These two variables are used below when this method is asked to pick a
|
| - // IPv6 address which has the shortest lifetime.
|
| - ULONG ipv6_valid_lifetime = 0;
|
| - scoped_ptr<NetworkInterface> ipv6_address;
|
| -
|
| - for (IP_ADAPTER_ADDRESSES *adapter = adapters; adapter != NULL;
|
| +bool GetNetworkListImpl(NetworkInterfaceList* networks,
|
| + int policy,
|
| + bool is_xp,
|
| + const IP_ADAPTER_ADDRESSES* adapters) {
|
| + for (const IP_ADAPTER_ADDRESSES* adapter = adapters; adapter != NULL;
|
| adapter = adapter->Next) {
|
| // Ignore the loopback device.
|
| if (adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK) {
|
| @@ -128,7 +104,7 @@ bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
|
| // VMware Virtual Ethernet Adapter for VMnet1
|
| // but don't ignore any GUEST side adapters with a description like:
|
| // VMware Accelerated AMD PCNet Adapter #2
|
| - if (policy == EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES &&
|
| + if ((policy & EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES) &&
|
| strstr(adapter->AdapterName, "VMnet") != NULL) {
|
| continue;
|
| }
|
| @@ -141,7 +117,7 @@ bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
|
| if (endpoint.FromSockAddr(address->Address.lpSockaddr,
|
| address->Address.iSockaddrLength)) {
|
| // XP has no OnLinkPrefixLength field.
|
| - size_t net_prefix = is_xp ? 0 : address->OnLinkPrefixLength;
|
| + size_t prefix_length = is_xp ? 0 : address->OnLinkPrefixLength;
|
| if (is_xp) {
|
| // Prior to Windows Vista the FirstPrefix pointed to the list with
|
| // single prefix for each IP address assigned to the adapter.
|
| @@ -157,50 +133,70 @@ bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
|
| IPNumberMatchesPrefix(endpoint.address(),
|
| network_endpoint.address(),
|
| prefix->PrefixLength)) {
|
| - net_prefix = std::max<size_t>(net_prefix, prefix->PrefixLength);
|
| + prefix_length =
|
| + std::max<size_t>(prefix_length, prefix->PrefixLength);
|
| }
|
| }
|
| }
|
| +
|
| + // If the duplicate address detection (DAD) state is not changed to
|
| + // Preferred, skip this address.
|
| + if (address->DadState != IpDadStatePreferred) {
|
| + continue;
|
| + }
|
| +
|
| uint32 index =
|
| (family == AF_INET) ? adapter->IfIndex : adapter->Ipv6IfIndex;
|
| - // Pick one IPv6 address with least valid lifetime.
|
| - // The reason we are checking |ValidLifeftime| as there is no other
|
| - // way identifying the interface type. Usually (and most likely) temp
|
| - // IPv6 will have a shorter ValidLifetime value then the permanent
|
| - // interface.
|
| - if (family == AF_INET6 &&
|
| - (policy & INCLUDE_ONLY_TEMP_IPV6_ADDRESS_IF_POSSIBLE)) {
|
| - if (ipv6_valid_lifetime == 0 ||
|
| - ipv6_valid_lifetime > address->ValidLifetime) {
|
| - ipv6_valid_lifetime = address->ValidLifetime;
|
| - ipv6_address.reset(new NetworkInterface(
|
| - adapter->AdapterName,
|
| - base::SysWideToNativeMB(adapter->FriendlyName),
|
| - index,
|
| - GetNetworkInterfaceType(adapter->IfType),
|
| - endpoint.address(),
|
| - net_prefix,
|
| - IP_ADDRESS_ATTRIBUTE_NONE));
|
| - continue;
|
| +
|
| + // From http://technet.microsoft.com/en-us/ff568768(v=vs.60).aspx, the
|
| + // way to identify a temporary IPv6 Address is to check if
|
| + // PrefixOrigin is equal to IpPrefixOriginRouterAdvertisement and
|
| + // SuffixOrigin equal to IpSuffixOriginRandom.
|
| + int ip_address_attributes = IP_ADDRESS_ATTRIBUTE_NONE;
|
| + if (family == AF_INET6) {
|
| + if (address->PrefixOrigin == IpPrefixOriginRouterAdvertisement &&
|
| + address->SuffixOrigin == IpSuffixOriginRandom) {
|
| + ip_address_attributes |= IP_ADDRESS_ATTRIBUTE_TEMPORARY;
|
| + }
|
| + if (address->PreferredLifetime == 0) {
|
| + ip_address_attributes |= IP_ADDRESS_ATTRIBUTE_DEPRECATED;
|
| }
|
| }
|
| - networks->push_back(
|
| - NetworkInterface(adapter->AdapterName,
|
| - base::SysWideToNativeMB(adapter->FriendlyName),
|
| - index,
|
| - GetNetworkInterfaceType(adapter->IfType),
|
| - endpoint.address(),
|
| - net_prefix,
|
| - IP_ADDRESS_ATTRIBUTE_NONE));
|
| + networks->push_back(NetworkInterface(
|
| + adapter->AdapterName,
|
| + base::SysWideToNativeMB(adapter->FriendlyName), index,
|
| + GetNetworkInterfaceType(adapter->IfType), endpoint.address(),
|
| + prefix_length, ip_address_attributes));
|
| }
|
| }
|
| }
|
| }
|
| + return true;
|
| +}
|
| +
|
| +} // namespace internal
|
|
|
| - if (ipv6_address.get()) {
|
| - networks->push_back(*(ipv6_address.get()));
|
| +bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
|
| + bool is_xp = base::win::GetVersion() < base::win::VERSION_VISTA;
|
| + ULONG len = 0;
|
| + ULONG flags = is_xp ? GAA_FLAG_INCLUDE_PREFIX : 0;
|
| + // GetAdaptersAddresses() may require IO operations.
|
| + base::ThreadRestrictions::AssertIOAllowed();
|
| + ULONG result = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, NULL, &len);
|
| + if (result != ERROR_BUFFER_OVERFLOW) {
|
| + // There are 0 networks.
|
| + return true;
|
| }
|
| - return true;
|
| + scoped_ptr<char[]> buf(new char[len]);
|
| + IP_ADAPTER_ADDRESSES* adapters =
|
| + reinterpret_cast<IP_ADAPTER_ADDRESSES*>(buf.get());
|
| + result = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapters, &len);
|
| + if (result != NO_ERROR) {
|
| + LOG(ERROR) << "GetAdaptersAddresses failed: " << result;
|
| + return false;
|
| + }
|
| +
|
| + return internal::GetNetworkListImpl(networks, policy, is_xp, adapters);
|
| }
|
|
|
| WifiPHYLayerProtocol GetWifiPHYLayerProtocol() {
|
|
|