OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/base/net_util.h" | 5 #include "net/base/net_util.h" |
6 | 6 |
7 #include <iphlpapi.h> | 7 #include <iphlpapi.h> |
8 #include <wlanapi.h> | 8 #include <wlanapi.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
11 | 11 |
12 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
13 #include "base/lazy_instance.h" | 13 #include "base/lazy_instance.h" |
14 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.h" |
15 #include "base/strings/string_piece.h" | 15 #include "base/strings/string_piece.h" |
16 #include "base/strings/string_util.h" | 16 #include "base/strings/string_util.h" |
17 #include "base/strings/sys_string_conversions.h" | 17 #include "base/strings/sys_string_conversions.h" |
18 #include "base/strings/utf_string_conversions.h" | 18 #include "base/strings/utf_string_conversions.h" |
19 #include "base/threading/thread_restrictions.h" | 19 #include "base/threading/thread_restrictions.h" |
20 #include "base/win/scoped_handle.h" | 20 #include "base/win/scoped_handle.h" |
| 21 #include "base/win/windows_version.h" |
21 #include "net/base/escape.h" | 22 #include "net/base/escape.h" |
22 #include "net/base/ip_endpoint.h" | 23 #include "net/base/ip_endpoint.h" |
23 #include "net/base/net_errors.h" | 24 #include "net/base/net_errors.h" |
24 #include "url/gurl.h" | 25 #include "url/gurl.h" |
25 | 26 |
26 namespace { | 27 namespace { |
27 | 28 |
28 struct WlanApi { | 29 struct WlanApi { |
29 typedef DWORD (WINAPI *WlanOpenHandleFunc)( | 30 typedef DWORD (WINAPI *WlanOpenHandleFunc)( |
30 DWORD, VOID*, DWORD*, HANDLE*); | 31 DWORD, VOID*, DWORD*, HANDLE*); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 // If so, we converted it to 'Latin-1' and checked if the result was UTF-8. | 123 // If so, we converted it to 'Latin-1' and checked if the result was UTF-8. |
123 // If the check passed, we converted the result to UTF-8. | 124 // If the check passed, we converted the result to UTF-8. |
124 // Otherwise, we treated the result as the native OS encoding. | 125 // Otherwise, we treated the result as the native OS encoding. |
125 // However, that led to http://crbug.com/4619 and http://crbug.com/14153 | 126 // However, that led to http://crbug.com/4619 and http://crbug.com/14153 |
126 return true; | 127 return true; |
127 } | 128 } |
128 | 129 |
129 bool GetNetworkList(NetworkInterfaceList* networks) { | 130 bool GetNetworkList(NetworkInterfaceList* networks) { |
130 // GetAdaptersAddresses() may require IO operations. | 131 // GetAdaptersAddresses() may require IO operations. |
131 base::ThreadRestrictions::AssertIOAllowed(); | 132 base::ThreadRestrictions::AssertIOAllowed(); |
132 | 133 bool is_xp = base::win::GetVersion() < base::win::VERSION_VISTA; |
133 IP_ADAPTER_ADDRESSES info_temp; | |
134 ULONG len = 0; | 134 ULONG len = 0; |
135 | 135 ULONG flags = is_xp ? GAA_FLAG_INCLUDE_PREFIX : 0; |
136 // First get number of networks. | 136 // First get number of networks. |
137 ULONG result = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, &info_temp, &len); | 137 ULONG result = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, NULL, &len); |
138 if (result != ERROR_BUFFER_OVERFLOW) { | 138 if (result != ERROR_BUFFER_OVERFLOW) { |
139 // There are 0 networks. | 139 // There are 0 networks. |
140 return true; | 140 return true; |
141 } | 141 } |
142 | |
143 scoped_ptr<char[]> buf(new char[len]); | 142 scoped_ptr<char[]> buf(new char[len]); |
144 IP_ADAPTER_ADDRESSES *adapters = | 143 IP_ADAPTER_ADDRESSES *adapters = |
145 reinterpret_cast<IP_ADAPTER_ADDRESSES *>(buf.get()); | 144 reinterpret_cast<IP_ADAPTER_ADDRESSES *>(buf.get()); |
146 result = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, adapters, &len); | 145 result = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapters, &len); |
147 if (result != NO_ERROR) { | 146 if (result != NO_ERROR) { |
148 LOG(ERROR) << "GetAdaptersAddresses failed: " << result; | 147 LOG(ERROR) << "GetAdaptersAddresses failed: " << result; |
149 return false; | 148 return false; |
150 } | 149 } |
151 | 150 |
152 for (IP_ADAPTER_ADDRESSES *adapter = adapters; adapter != NULL; | 151 for (IP_ADAPTER_ADDRESSES *adapter = adapters; adapter != NULL; |
153 adapter = adapter->Next) { | 152 adapter = adapter->Next) { |
154 // Ignore the loopback device. | 153 // Ignore the loopback device. |
155 if (adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK) { | 154 if (adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK) { |
156 continue; | 155 continue; |
157 } | 156 } |
158 | 157 |
159 if (adapter->OperStatus != IfOperStatusUp) { | 158 if (adapter->OperStatus != IfOperStatusUp) { |
160 continue; | 159 continue; |
161 } | 160 } |
162 | 161 |
163 IP_ADAPTER_UNICAST_ADDRESS* address; | 162 std::string name = adapter->AdapterName; |
164 for (address = adapter->FirstUnicastAddress; address != NULL; | 163 |
165 address = address->Next) { | 164 for (IP_ADAPTER_UNICAST_ADDRESS* address = adapter->FirstUnicastAddress; |
| 165 address; address = address->Next) { |
166 int family = address->Address.lpSockaddr->sa_family; | 166 int family = address->Address.lpSockaddr->sa_family; |
167 if (family == AF_INET || family == AF_INET6) { | 167 if (family == AF_INET || family == AF_INET6) { |
168 IPEndPoint endpoint; | 168 IPEndPoint endpoint; |
169 if (endpoint.FromSockAddr(address->Address.lpSockaddr, | 169 if (endpoint.FromSockAddr(address->Address.lpSockaddr, |
170 address->Address.iSockaddrLength)) { | 170 address->Address.iSockaddrLength)) { |
171 std::string name = adapter->AdapterName; | 171 // XP has no OnLinkPrefixLength field. |
172 networks->push_back(NetworkInterface(name, endpoint.address(), | 172 size_t net_prefix = is_xp ? 0 : address->OnLinkPrefixLength; |
173 address->OnLinkPrefixLength)); | 173 if (is_xp) { |
| 174 // Prior to Windows Vista the FirstPrefix pointed to the list with |
| 175 // single prefix for each IP address assigned to the adapter. |
| 176 // Order of FirstPrefix does not match order of FirstUnicastAddress, |
| 177 // so we need to find corresponding prefix. |
| 178 for (IP_ADAPTER_PREFIX* prefix = adapter->FirstPrefix; prefix; |
| 179 prefix = prefix->Next) { |
| 180 int prefix_family = prefix->Address.lpSockaddr->sa_family; |
| 181 IPEndPoint network_endpoint; |
| 182 if (prefix_family == family && |
| 183 network_endpoint.FromSockAddr(prefix->Address.lpSockaddr, |
| 184 prefix->Address.iSockaddrLength) && |
| 185 IPNumberMatchesPrefix(endpoint.address(), |
| 186 network_endpoint.address(), |
| 187 prefix->PrefixLength)) { |
| 188 net_prefix = std::max<size_t>(net_prefix, prefix->PrefixLength); |
| 189 } |
| 190 } |
| 191 } |
| 192 networks->push_back( |
| 193 NetworkInterface(adapter->AdapterName, endpoint.address(), |
| 194 net_prefix)); |
174 } | 195 } |
175 } | 196 } |
176 } | 197 } |
177 } | 198 } |
178 | 199 |
179 return true; | 200 return true; |
180 } | 201 } |
181 | 202 |
182 WifiPHYLayerProtocol GetWifiPHYLayerProtocol() { | 203 WifiPHYLayerProtocol GetWifiPHYLayerProtocol() { |
183 static base::LazyInstance<WlanApi>::Leaky lazy_wlanapi = | 204 static base::LazyInstance<WlanApi>::Leaky lazy_wlanapi = |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 case dot11_phy_type_erp: | 286 case dot11_phy_type_erp: |
266 return WIFI_PHY_LAYER_PROTOCOL_G; | 287 return WIFI_PHY_LAYER_PROTOCOL_G; |
267 case dot11_phy_type_ht: | 288 case dot11_phy_type_ht: |
268 return WIFI_PHY_LAYER_PROTOCOL_N; | 289 return WIFI_PHY_LAYER_PROTOCOL_N; |
269 default: | 290 default: |
270 return WIFI_PHY_LAYER_PROTOCOL_UNKNOWN; | 291 return WIFI_PHY_LAYER_PROTOCOL_UNKNOWN; |
271 } | 292 } |
272 } | 293 } |
273 | 294 |
274 } // namespace net | 295 } // namespace net |
OLD | NEW |