Roll src/third_party/WebKit b4168eb:6c137a7 (svn 202006:202008)
[chromium-blink-merge.git] / net / base / network_interfaces_unittest.cc
blob06ffb07ee41f72f916c010626a67f6ffb619a0d4
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
3 // found in the LICENSE file.
5 #include "net/base/network_interfaces.h"
7 #include <string>
9 #include <ostream>
11 // TODO(eroman): Remove unneeeded headers.
12 #include "base/files/file_path.h"
13 #include "base/format_macros.h"
14 #include "base/scoped_native_library.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/string_util.h"
17 #include "base/strings/stringprintf.h"
18 #include "base/strings/utf_string_conversions.h"
19 #include "base/sys_byteorder.h"
20 #include "base/time/time.h"
21 #include "net/base/ip_endpoint.h"
22 #include "net/base/net_util.h"
24 #if !defined(OS_NACL) && !defined(OS_WIN)
25 #include <net/if.h>
26 #include <netinet/in.h>
27 #if defined(OS_MACOSX)
28 #include <ifaddrs.h>
29 #if !defined(OS_IOS)
30 #include <netinet/in_var.h>
31 #endif // !OS_IOS
32 #endif // OS_MACOSX
33 #endif // !OS_NACL && !OS_WIN
34 #include "testing/gtest/include/gtest/gtest.h"
35 #include "url/gurl.h"
37 #if defined(OS_WIN)
38 #include <iphlpapi.h>
39 #include <objbase.h>
40 #include "base/win/windows_version.h"
41 #endif // OS_WIN
43 #if !defined(OS_MACOSX) && !defined(OS_NACL) && !defined(OS_WIN)
44 #include "net/base/address_tracker_linux.h"
45 #endif // !OS_MACOSX && !OS_NACL && !OS_WIN
47 #if defined(OS_WIN)
48 #include "net/base/network_interfaces_win.h"
49 #else // OS_WIN
50 #include "net/base/network_interfaces_posix.h"
51 #if defined(OS_MACOSX)
52 #include "net/base/network_interfaces_mac.h"
53 #else // OS_MACOSX
54 #include "net/base/network_interfaces_linux.h"
55 #endif // OS_MACOSX
56 #endif // OS_WIN
58 namespace net {
60 namespace {
62 #if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_CHROMEOS)
63 const char kWiFiSSID[] = "TestWiFi";
64 const char kInterfaceWithDifferentSSID[] = "wlan999";
66 std::string TestGetInterfaceSSID(const std::string& ifname) {
67 return (ifname == kInterfaceWithDifferentSSID) ? "AnotherSSID" : kWiFiSSID;
69 #endif
71 #if defined(OS_MACOSX)
72 class IPAttributesGetterTest : public internal::IPAttributesGetterMac {
73 public:
74 IPAttributesGetterTest() : native_attributes_(0) {}
75 bool IsInitialized() const override { return true; }
76 bool GetIPAttributes(const char* ifname,
77 const sockaddr* sock_addr,
78 int* native_attributes) override {
79 *native_attributes = native_attributes_;
80 return true;
82 void set_native_attributes(int native_attributes) {
83 native_attributes_ = native_attributes;
86 private:
87 int native_attributes_;
90 // Helper function to create a single valid ifaddrs
91 bool FillIfaddrs(ifaddrs* interfaces,
92 const char* ifname,
93 uint flags,
94 const IPAddressNumber& ip_address,
95 const IPAddressNumber& ip_netmask,
96 sockaddr_storage sock_addrs[2]) {
97 interfaces->ifa_next = NULL;
98 interfaces->ifa_name = const_cast<char*>(ifname);
99 interfaces->ifa_flags = flags;
101 socklen_t sock_len = sizeof(sockaddr_storage);
103 // Convert to sockaddr for next check.
104 if (!IPEndPoint(ip_address, 0)
105 .ToSockAddr(reinterpret_cast<sockaddr*>(&sock_addrs[0]),
106 &sock_len)) {
107 return false;
109 interfaces->ifa_addr = reinterpret_cast<sockaddr*>(&sock_addrs[0]);
111 sock_len = sizeof(sockaddr_storage);
112 if (!IPEndPoint(ip_netmask, 0)
113 .ToSockAddr(reinterpret_cast<sockaddr*>(&sock_addrs[1]),
114 &sock_len)) {
115 return false;
117 interfaces->ifa_netmask = reinterpret_cast<sockaddr*>(&sock_addrs[1]);
119 return true;
121 #endif // OS_MACOSX
122 // Verify GetNetworkList().
123 TEST(NetUtilTest, GetNetworkList) {
124 NetworkInterfaceList list;
125 ASSERT_TRUE(GetNetworkList(&list, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES));
126 for (NetworkInterfaceList::iterator it = list.begin();
127 it != list.end(); ++it) {
128 // Verify that the names are not empty.
129 EXPECT_FALSE(it->name.empty());
130 EXPECT_FALSE(it->friendly_name.empty());
132 // Verify that the address is correct.
133 EXPECT_TRUE(it->address.size() == kIPv4AddressSize ||
134 it->address.size() == kIPv6AddressSize)
135 << "Invalid address of size " << it->address.size();
136 bool all_zeroes = true;
137 for (size_t i = 0; i < it->address.size(); ++i) {
138 if (it->address[i] != 0) {
139 all_zeroes = false;
140 break;
143 EXPECT_FALSE(all_zeroes);
144 EXPECT_GT(it->prefix_length, 1u);
145 EXPECT_LE(it->prefix_length, it->address.size() * 8);
147 #if defined(OS_WIN)
148 // On Windows |name| is NET_LUID.
149 base::ScopedNativeLibrary phlpapi_lib(
150 base::FilePath(FILE_PATH_LITERAL("iphlpapi.dll")));
151 ASSERT_TRUE(phlpapi_lib.is_valid());
152 typedef NETIO_STATUS (WINAPI* ConvertInterfaceIndexToLuid)(NET_IFINDEX,
153 PNET_LUID);
154 ConvertInterfaceIndexToLuid interface_to_luid =
155 reinterpret_cast<ConvertInterfaceIndexToLuid>(
156 phlpapi_lib.GetFunctionPointer("ConvertInterfaceIndexToLuid"));
158 typedef NETIO_STATUS (WINAPI* ConvertInterfaceLuidToGuid)(NET_LUID*,
159 GUID*);
160 ConvertInterfaceLuidToGuid luid_to_guid =
161 reinterpret_cast<ConvertInterfaceLuidToGuid>(
162 phlpapi_lib.GetFunctionPointer("ConvertInterfaceLuidToGuid"));
164 if (interface_to_luid && luid_to_guid) {
165 NET_LUID luid;
166 EXPECT_EQ(interface_to_luid(it->interface_index, &luid), NO_ERROR);
167 GUID guid;
168 EXPECT_EQ(luid_to_guid(&luid, &guid), NO_ERROR);
169 LPOLESTR name;
170 StringFromCLSID(guid, &name);
171 EXPECT_STREQ(base::UTF8ToWide(it->name).c_str(), name);
172 CoTaskMemFree(name);
173 continue;
174 } else {
175 EXPECT_LT(base::win::GetVersion(), base::win::VERSION_VISTA);
176 EXPECT_LT(it->interface_index, 1u << 24u); // Must fit 0.x.x.x.
177 EXPECT_NE(it->interface_index, 0u); // 0 means to use default.
179 if (it->type == NetworkChangeNotifier::CONNECTION_WIFI) {
180 EXPECT_NE(WIFI_PHY_LAYER_PROTOCOL_NONE, GetWifiPHYLayerProtocol());
182 #elif !defined(OS_ANDROID)
183 char name[IF_NAMESIZE];
184 EXPECT_TRUE(if_indextoname(it->interface_index, name));
185 EXPECT_STREQ(it->name.c_str(), name);
186 #endif
190 static const char ifname_em1[] = "em1";
191 #if defined(OS_WIN)
192 static const char ifname_vm[] = "VMnet";
193 #else
194 static const char ifname_vm[] = "vmnet";
195 #endif // OS_WIN
197 static const unsigned char kIPv6LocalAddr[] = {
198 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
200 // The following 3 addresses need to be changed together. IPv6Addr is the IPv6
201 // address. IPv6Netmask is the mask address with as many leading bits set to 1
202 // as the prefix length. IPv6AddrPrefix needs to match IPv6Addr with the same
203 // number of bits as the prefix length.
204 static const unsigned char kIPv6Addr[] =
205 {0x24, 0x01, 0xfa, 0x00, 0x00, 0x04, 0x10, 0x00, 0xbe, 0x30, 0x5b, 0xff,
206 0xfe, 0xe5, 0x00, 0xc3};
207 #if defined(OS_WIN)
208 static const unsigned char kIPv6AddrPrefix[] =
209 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
210 0x00, 0x00, 0x00, 0x00};
211 #endif // OS_WIN
212 #if defined(OS_MACOSX)
213 static const unsigned char kIPv6Netmask[] =
214 {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
215 0x00, 0x00, 0x00, 0x00};
216 #endif // OS_MACOSX
218 #if !defined(OS_MACOSX) && !defined(OS_WIN) && !defined(OS_NACL)
220 char* CopyInterfaceName(const char* ifname, int ifname_size, char* output) {
221 EXPECT_LT(ifname_size, IF_NAMESIZE);
222 memcpy(output, ifname, ifname_size);
223 return output;
226 char* GetInterfaceName(int interface_index, char* ifname) {
227 return CopyInterfaceName(ifname_em1, arraysize(ifname_em1), ifname);
230 char* GetInterfaceNameVM(int interface_index, char* ifname) {
231 return CopyInterfaceName(ifname_vm, arraysize(ifname_vm), ifname);
234 TEST(NetUtilTest, GetNetworkListTrimming) {
235 IPAddressNumber ipv6_local_address(
236 kIPv6LocalAddr, kIPv6LocalAddr + arraysize(kIPv6LocalAddr));
237 IPAddressNumber ipv6_address(kIPv6Addr, kIPv6Addr + arraysize(kIPv6Addr));
239 NetworkInterfaceList results;
240 ::base::hash_set<int> online_links;
241 internal::AddressTrackerLinux::AddressMap address_map;
243 // Interface 1 is offline.
244 struct ifaddrmsg msg = {
245 AF_INET6,
246 1, /* prefix length */
247 IFA_F_TEMPORARY, /* address flags */
248 0, /* link scope */
249 1 /* link index */
252 // Address of offline links should be ignored.
253 ASSERT_TRUE(address_map.insert(std::make_pair(ipv6_address, msg)).second);
254 EXPECT_TRUE(internal::GetNetworkListImpl(
255 &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, online_links,
256 address_map, GetInterfaceName));
257 EXPECT_EQ(results.size(), 0ul);
259 // Mark interface 1 online.
260 online_links.insert(1);
262 // Local address should be trimmed out.
263 address_map.clear();
264 ASSERT_TRUE(
265 address_map.insert(std::make_pair(ipv6_local_address, msg)).second);
266 EXPECT_TRUE(internal::GetNetworkListImpl(
267 &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, online_links,
268 address_map, GetInterfaceName));
269 EXPECT_EQ(results.size(), 0ul);
271 // vmware address should return by default.
272 address_map.clear();
273 ASSERT_TRUE(address_map.insert(std::make_pair(ipv6_address, msg)).second);
274 EXPECT_TRUE(internal::GetNetworkListImpl(
275 &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, online_links,
276 address_map, GetInterfaceNameVM));
277 EXPECT_EQ(results.size(), 1ul);
278 EXPECT_EQ(results[0].name, ifname_vm);
279 EXPECT_EQ(results[0].prefix_length, 1ul);
280 EXPECT_EQ(results[0].address, ipv6_address);
281 results.clear();
283 // vmware address should be trimmed out if policy specified so.
284 address_map.clear();
285 ASSERT_TRUE(address_map.insert(std::make_pair(ipv6_address, msg)).second);
286 EXPECT_TRUE(internal::GetNetworkListImpl(
287 &results, EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, online_links,
288 address_map, GetInterfaceNameVM));
289 EXPECT_EQ(results.size(), 0ul);
290 results.clear();
292 // Addresses with banned attributes should be ignored.
293 address_map.clear();
294 msg.ifa_flags = IFA_F_TENTATIVE;
295 ASSERT_TRUE(address_map.insert(std::make_pair(ipv6_address, msg)).second);
296 EXPECT_TRUE(internal::GetNetworkListImpl(
297 &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, online_links,
298 address_map, GetInterfaceName));
299 EXPECT_EQ(results.size(), 0ul);
300 results.clear();
302 // Addresses with allowed attribute IFA_F_TEMPORARY should be returned and
303 // attributes should be translated correctly.
304 address_map.clear();
305 msg.ifa_flags = IFA_F_TEMPORARY;
306 ASSERT_TRUE(address_map.insert(std::make_pair(ipv6_address, msg)).second);
307 EXPECT_TRUE(internal::GetNetworkListImpl(
308 &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, online_links,
309 address_map, GetInterfaceName));
310 EXPECT_EQ(results.size(), 1ul);
311 EXPECT_EQ(results[0].name, ifname_em1);
312 EXPECT_EQ(results[0].prefix_length, 1ul);
313 EXPECT_EQ(results[0].address, ipv6_address);
314 EXPECT_EQ(results[0].ip_address_attributes, IP_ADDRESS_ATTRIBUTE_TEMPORARY);
315 results.clear();
317 // Addresses with allowed attribute IFA_F_DEPRECATED should be returned and
318 // attributes should be translated correctly.
319 address_map.clear();
320 msg.ifa_flags = IFA_F_DEPRECATED;
321 ASSERT_TRUE(address_map.insert(std::make_pair(ipv6_address, msg)).second);
322 EXPECT_TRUE(internal::GetNetworkListImpl(
323 &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, online_links,
324 address_map, GetInterfaceName));
325 EXPECT_EQ(results.size(), 1ul);
326 EXPECT_EQ(results[0].name, ifname_em1);
327 EXPECT_EQ(results[0].prefix_length, 1ul);
328 EXPECT_EQ(results[0].address, ipv6_address);
329 EXPECT_EQ(results[0].ip_address_attributes, IP_ADDRESS_ATTRIBUTE_DEPRECATED);
330 results.clear();
333 #elif defined(OS_MACOSX)
335 TEST(NetUtilTest, GetNetworkListTrimming) {
336 IPAddressNumber ipv6_local_address(
337 kIPv6LocalAddr, kIPv6LocalAddr + arraysize(kIPv6LocalAddr));
338 IPAddressNumber ipv6_address(kIPv6Addr, kIPv6Addr + arraysize(kIPv6Addr));
339 IPAddressNumber ipv6_netmask(kIPv6Netmask,
340 kIPv6Netmask + arraysize(kIPv6Netmask));
342 NetworkInterfaceList results;
343 IPAttributesGetterTest ip_attributes_getter;
344 sockaddr_storage addresses[2];
345 ifaddrs interface;
347 // Address of offline links should be ignored.
348 ASSERT_TRUE(FillIfaddrs(&interface, ifname_em1, IFF_UP, ipv6_address,
349 ipv6_netmask, addresses));
350 EXPECT_TRUE(internal::GetNetworkListImpl(
351 &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, &interface,
352 &ip_attributes_getter));
353 EXPECT_EQ(results.size(), 0ul);
355 // Local address should be trimmed out.
356 ASSERT_TRUE(FillIfaddrs(&interface, ifname_em1, IFF_RUNNING,
357 ipv6_local_address, ipv6_netmask, addresses));
358 EXPECT_TRUE(internal::GetNetworkListImpl(
359 &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, &interface,
360 &ip_attributes_getter));
361 EXPECT_EQ(results.size(), 0ul);
363 // vmware address should return by default.
364 ASSERT_TRUE(FillIfaddrs(&interface, ifname_vm, IFF_RUNNING, ipv6_address,
365 ipv6_netmask, addresses));
366 EXPECT_TRUE(internal::GetNetworkListImpl(
367 &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, &interface,
368 &ip_attributes_getter));
369 EXPECT_EQ(results.size(), 1ul);
370 EXPECT_EQ(results[0].name, ifname_vm);
371 EXPECT_EQ(results[0].prefix_length, 1ul);
372 EXPECT_EQ(results[0].address, ipv6_address);
373 results.clear();
375 // vmware address should be trimmed out if policy specified so.
376 ASSERT_TRUE(FillIfaddrs(&interface, ifname_vm, IFF_RUNNING, ipv6_address,
377 ipv6_netmask, addresses));
378 EXPECT_TRUE(internal::GetNetworkListImpl(
379 &results, EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, &interface,
380 &ip_attributes_getter));
381 EXPECT_EQ(results.size(), 0ul);
382 results.clear();
384 #if !defined(OS_IOS)
385 // Addresses with banned attributes should be ignored.
386 ip_attributes_getter.set_native_attributes(IN6_IFF_ANYCAST);
387 ASSERT_TRUE(FillIfaddrs(&interface, ifname_em1, IFF_RUNNING, ipv6_address,
388 ipv6_netmask, addresses));
389 EXPECT_TRUE(internal::GetNetworkListImpl(
390 &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, &interface,
391 &ip_attributes_getter));
392 EXPECT_EQ(results.size(), 0ul);
393 results.clear();
395 // Addresses with allowed attribute IFA_F_TEMPORARY should be returned and
396 // attributes should be translated correctly.
397 ip_attributes_getter.set_native_attributes(IN6_IFF_TEMPORARY);
398 ASSERT_TRUE(FillIfaddrs(&interface, ifname_em1, IFF_RUNNING, ipv6_address,
399 ipv6_netmask, addresses));
400 EXPECT_TRUE(internal::GetNetworkListImpl(
401 &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, &interface,
402 &ip_attributes_getter));
403 EXPECT_EQ(results.size(), 1ul);
404 EXPECT_EQ(results[0].name, ifname_em1);
405 EXPECT_EQ(results[0].prefix_length, 1ul);
406 EXPECT_EQ(results[0].address, ipv6_address);
407 EXPECT_EQ(results[0].ip_address_attributes, IP_ADDRESS_ATTRIBUTE_TEMPORARY);
408 results.clear();
410 // Addresses with allowed attribute IFA_F_DEPRECATED should be returned and
411 // attributes should be translated correctly.
412 ip_attributes_getter.set_native_attributes(IN6_IFF_DEPRECATED);
413 ASSERT_TRUE(FillIfaddrs(&interface, ifname_em1, IFF_RUNNING, ipv6_address,
414 ipv6_netmask, addresses));
415 EXPECT_TRUE(internal::GetNetworkListImpl(
416 &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, &interface,
417 &ip_attributes_getter));
418 EXPECT_EQ(results.size(), 1ul);
419 EXPECT_EQ(results[0].name, ifname_em1);
420 EXPECT_EQ(results[0].prefix_length, 1ul);
421 EXPECT_EQ(results[0].address, ipv6_address);
422 EXPECT_EQ(results[0].ip_address_attributes, IP_ADDRESS_ATTRIBUTE_DEPRECATED);
423 results.clear();
424 #endif // !OS_IOS
426 #elif defined(OS_WIN) // !OS_MACOSX && !OS_WIN && !OS_NACL
428 // Helper function to create a valid IP_ADAPTER_ADDRESSES with reasonable
429 // default value. The output is the |adapter_address|. All the rests are input
430 // to fill the |adapter_address|. |sock_addrs| are temporary storage used by
431 // |adapter_address| once the function is returned.
432 bool FillAdapterAddress(IP_ADAPTER_ADDRESSES* adapter_address,
433 const char* ifname,
434 const IPAddressNumber& ip_address,
435 const IPAddressNumber& ip_netmask,
436 sockaddr_storage sock_addrs[2]) {
437 adapter_address->AdapterName = const_cast<char*>(ifname);
438 adapter_address->FriendlyName = const_cast<PWCHAR>(L"interface");
439 adapter_address->IfType = IF_TYPE_ETHERNET_CSMACD;
440 adapter_address->OperStatus = IfOperStatusUp;
441 adapter_address->FirstUnicastAddress->DadState = IpDadStatePreferred;
442 adapter_address->FirstUnicastAddress->PrefixOrigin = IpPrefixOriginOther;
443 adapter_address->FirstUnicastAddress->SuffixOrigin = IpSuffixOriginOther;
444 adapter_address->FirstUnicastAddress->PreferredLifetime = 100;
445 adapter_address->FirstUnicastAddress->ValidLifetime = 1000;
447 socklen_t sock_len = sizeof(sockaddr_storage);
449 // Convert to sockaddr for next check.
450 if (!IPEndPoint(ip_address, 0)
451 .ToSockAddr(reinterpret_cast<sockaddr*>(&sock_addrs[0]),
452 &sock_len)) {
453 return false;
455 adapter_address->FirstUnicastAddress->Address.lpSockaddr =
456 reinterpret_cast<sockaddr*>(&sock_addrs[0]);
457 adapter_address->FirstUnicastAddress->Address.iSockaddrLength = sock_len;
458 adapter_address->FirstUnicastAddress->OnLinkPrefixLength = 1;
460 sock_len = sizeof(sockaddr_storage);
461 if (!IPEndPoint(ip_netmask, 0)
462 .ToSockAddr(reinterpret_cast<sockaddr*>(&sock_addrs[1]),
463 &sock_len)) {
464 return false;
466 adapter_address->FirstPrefix->Address.lpSockaddr =
467 reinterpret_cast<sockaddr*>(&sock_addrs[1]);
468 adapter_address->FirstPrefix->Address.iSockaddrLength = sock_len;
469 adapter_address->FirstPrefix->PrefixLength = 1;
471 DCHECK_EQ(sock_addrs[0].ss_family, sock_addrs[1].ss_family);
472 if (sock_addrs[0].ss_family == AF_INET6) {
473 adapter_address->Ipv6IfIndex = 0;
474 } else {
475 DCHECK_EQ(sock_addrs[0].ss_family, AF_INET);
476 adapter_address->IfIndex = 0;
479 return true;
482 TEST(NetUtilTest, GetNetworkListTrimming) {
483 IPAddressNumber ipv6_local_address(
484 kIPv6LocalAddr, kIPv6LocalAddr + arraysize(kIPv6LocalAddr));
485 IPAddressNumber ipv6_address(kIPv6Addr, kIPv6Addr + arraysize(kIPv6Addr));
486 IPAddressNumber ipv6_prefix(kIPv6AddrPrefix,
487 kIPv6AddrPrefix + arraysize(kIPv6AddrPrefix));
489 NetworkInterfaceList results;
490 sockaddr_storage addresses[2];
491 IP_ADAPTER_ADDRESSES adapter_address = {};
492 IP_ADAPTER_UNICAST_ADDRESS address = {};
493 IP_ADAPTER_PREFIX adapter_prefix = {};
494 adapter_address.FirstUnicastAddress = &address;
495 adapter_address.FirstPrefix = &adapter_prefix;
497 // Address of offline links should be ignored.
498 ASSERT_TRUE(FillAdapterAddress(
499 &adapter_address /* adapter_address */, ifname_em1 /* ifname */,
500 ipv6_address /* ip_address */, ipv6_prefix /* ip_netmask */,
501 addresses /* sock_addrs */));
502 adapter_address.OperStatus = IfOperStatusDown;
504 EXPECT_TRUE(internal::GetNetworkListImpl(
505 &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, true, &adapter_address));
507 EXPECT_EQ(results.size(), 0ul);
509 // Address on loopback interface should be trimmed out.
510 ASSERT_TRUE(FillAdapterAddress(
511 &adapter_address /* adapter_address */, ifname_em1 /* ifname */,
512 ipv6_local_address /* ip_address */, ipv6_prefix /* ip_netmask */,
513 addresses /* sock_addrs */));
514 adapter_address.IfType = IF_TYPE_SOFTWARE_LOOPBACK;
516 EXPECT_TRUE(internal::GetNetworkListImpl(
517 &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, true, &adapter_address));
518 EXPECT_EQ(results.size(), 0ul);
520 // vmware address should return by default.
521 ASSERT_TRUE(FillAdapterAddress(
522 &adapter_address /* adapter_address */, ifname_vm /* ifname */,
523 ipv6_address /* ip_address */, ipv6_prefix /* ip_netmask */,
524 addresses /* sock_addrs */));
525 EXPECT_TRUE(internal::GetNetworkListImpl(
526 &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, true, &adapter_address));
527 EXPECT_EQ(results.size(), 1ul);
528 EXPECT_EQ(results[0].name, ifname_vm);
529 EXPECT_EQ(results[0].prefix_length, 1ul);
530 EXPECT_EQ(results[0].address, ipv6_address);
531 EXPECT_EQ(results[0].ip_address_attributes, IP_ADDRESS_ATTRIBUTE_NONE);
532 results.clear();
534 // vmware address should be trimmed out if policy specified so.
535 ASSERT_TRUE(FillAdapterAddress(
536 &adapter_address /* adapter_address */, ifname_vm /* ifname */,
537 ipv6_address /* ip_address */, ipv6_prefix /* ip_netmask */,
538 addresses /* sock_addrs */));
539 EXPECT_TRUE(internal::GetNetworkListImpl(
540 &results, EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, true, &adapter_address));
541 EXPECT_EQ(results.size(), 0ul);
542 results.clear();
544 // Addresses with incompleted DAD should be ignored.
545 ASSERT_TRUE(FillAdapterAddress(
546 &adapter_address /* adapter_address */, ifname_em1 /* ifname */,
547 ipv6_address /* ip_address */, ipv6_prefix /* ip_netmask */,
548 addresses /* sock_addrs */));
549 adapter_address.FirstUnicastAddress->DadState = IpDadStateTentative;
551 EXPECT_TRUE(internal::GetNetworkListImpl(
552 &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, true, &adapter_address));
553 EXPECT_EQ(results.size(), 0ul);
554 results.clear();
556 // Addresses with allowed attribute IpSuffixOriginRandom should be returned
557 // and attributes should be translated correctly to
558 // IP_ADDRESS_ATTRIBUTE_TEMPORARY.
559 ASSERT_TRUE(FillAdapterAddress(
560 &adapter_address /* adapter_address */, ifname_em1 /* ifname */,
561 ipv6_address /* ip_address */, ipv6_prefix /* ip_netmask */,
562 addresses /* sock_addrs */));
563 adapter_address.FirstUnicastAddress->PrefixOrigin =
564 IpPrefixOriginRouterAdvertisement;
565 adapter_address.FirstUnicastAddress->SuffixOrigin = IpSuffixOriginRandom;
567 EXPECT_TRUE(internal::GetNetworkListImpl(
568 &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, true, &adapter_address));
569 EXPECT_EQ(results.size(), 1ul);
570 EXPECT_EQ(results[0].name, ifname_em1);
571 EXPECT_EQ(results[0].prefix_length, 1ul);
572 EXPECT_EQ(results[0].address, ipv6_address);
573 EXPECT_EQ(results[0].ip_address_attributes, IP_ADDRESS_ATTRIBUTE_TEMPORARY);
574 results.clear();
576 // Addresses with preferred lifetime 0 should be returned and
577 // attributes should be translated correctly to
578 // IP_ADDRESS_ATTRIBUTE_DEPRECATED.
579 ASSERT_TRUE(FillAdapterAddress(
580 &adapter_address /* adapter_address */, ifname_em1 /* ifname */,
581 ipv6_address /* ip_address */, ipv6_prefix /* ip_netmask */,
582 addresses /* sock_addrs */));
583 adapter_address.FirstUnicastAddress->PreferredLifetime = 0;
584 adapter_address.FriendlyName = const_cast<PWCHAR>(L"FriendlyInterfaceName");
585 EXPECT_TRUE(internal::GetNetworkListImpl(
586 &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, true, &adapter_address));
587 EXPECT_EQ(results.size(), 1ul);
588 EXPECT_EQ(results[0].friendly_name, "FriendlyInterfaceName");
589 EXPECT_EQ(results[0].name, ifname_em1);
590 EXPECT_EQ(results[0].prefix_length, 1ul);
591 EXPECT_EQ(results[0].address, ipv6_address);
592 EXPECT_EQ(results[0].ip_address_attributes, IP_ADDRESS_ATTRIBUTE_DEPRECATED);
593 results.clear();
596 #endif // !OS_MACOSX && !OS_WIN && !OS_NACL
598 TEST(NetUtilTest, GetWifiSSID) {
599 // We can't check the result of GetWifiSSID() directly, since the result
600 // will differ across machines. Simply exercise the code path and hope that it
601 // doesn't crash.
602 EXPECT_NE((const char*)NULL, GetWifiSSID().c_str());
605 #if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_CHROMEOS)
606 TEST(NetUtilTest, GetWifiSSIDFromInterfaceList) {
607 NetworkInterfaceList list;
608 EXPECT_EQ(std::string(), internal::GetWifiSSIDFromInterfaceListInternal(
609 list, TestGetInterfaceSSID));
611 NetworkInterface interface1;
612 interface1.name = "wlan0";
613 interface1.type = NetworkChangeNotifier::CONNECTION_WIFI;
614 list.push_back(interface1);
615 ASSERT_EQ(1u, list.size());
616 EXPECT_EQ(std::string(kWiFiSSID),
617 internal::GetWifiSSIDFromInterfaceListInternal(
618 list, TestGetInterfaceSSID));
620 NetworkInterface interface2;
621 interface2.name = "wlan1";
622 interface2.type = NetworkChangeNotifier::CONNECTION_WIFI;
623 list.push_back(interface2);
624 ASSERT_EQ(2u, list.size());
625 EXPECT_EQ(std::string(kWiFiSSID),
626 internal::GetWifiSSIDFromInterfaceListInternal(
627 list, TestGetInterfaceSSID));
629 NetworkInterface interface3;
630 interface3.name = kInterfaceWithDifferentSSID;
631 interface3.type = NetworkChangeNotifier::CONNECTION_WIFI;
632 list.push_back(interface3);
633 ASSERT_EQ(3u, list.size());
634 EXPECT_EQ(std::string(), internal::GetWifiSSIDFromInterfaceListInternal(
635 list, TestGetInterfaceSSID));
637 list.pop_back();
638 NetworkInterface interface4;
639 interface4.name = "eth0";
640 interface4.type = NetworkChangeNotifier::CONNECTION_ETHERNET;
641 list.push_back(interface4);
642 ASSERT_EQ(3u, list.size());
643 EXPECT_EQ(std::string(), internal::GetWifiSSIDFromInterfaceListInternal(
644 list, TestGetInterfaceSSID));
646 #endif // OS_LINUX
648 #if defined(OS_WIN)
649 bool read_int_or_bool(DWORD data_size,
650 PVOID data) {
651 switch (data_size) {
652 case 1:
653 return !!*reinterpret_cast<uint8_t*>(data);
654 case 4:
655 return !!*reinterpret_cast<uint32_t*>(data);
656 default:
657 LOG(FATAL) << "That is not a type I know!";
658 return false;
662 int GetWifiOptions() {
663 const internal::WlanApi& wlanapi = internal::WlanApi::GetInstance();
664 if (!wlanapi.initialized)
665 return -1;
667 internal::WlanHandle client;
668 DWORD cur_version = 0;
669 const DWORD kMaxClientVersion = 2;
670 DWORD result = wlanapi.OpenHandle(
671 kMaxClientVersion, &cur_version, &client);
672 if (result != ERROR_SUCCESS)
673 return -1;
675 WLAN_INTERFACE_INFO_LIST* interface_list_ptr = NULL;
676 result = wlanapi.enum_interfaces_func(client.Get(), NULL,
677 &interface_list_ptr);
678 if (result != ERROR_SUCCESS)
679 return -1;
680 scoped_ptr<WLAN_INTERFACE_INFO_LIST, internal::WlanApiDeleter> interface_list(
681 interface_list_ptr);
683 for (unsigned i = 0; i < interface_list->dwNumberOfItems; ++i) {
684 WLAN_INTERFACE_INFO* info = &interface_list->InterfaceInfo[i];
685 DWORD data_size;
686 PVOID data;
687 int options = 0;
688 result = wlanapi.query_interface_func(
689 client.Get(),
690 &info->InterfaceGuid,
691 wlan_intf_opcode_background_scan_enabled,
692 NULL,
693 &data_size,
694 &data,
695 NULL);
696 if (result != ERROR_SUCCESS)
697 continue;
698 if (!read_int_or_bool(data_size, data)) {
699 options |= WIFI_OPTIONS_DISABLE_SCAN;
701 internal::WlanApi::GetInstance().free_memory_func(data);
703 result = wlanapi.query_interface_func(
704 client.Get(),
705 &info->InterfaceGuid,
706 wlan_intf_opcode_media_streaming_mode,
707 NULL,
708 &data_size,
709 &data,
710 NULL);
711 if (result != ERROR_SUCCESS)
712 continue;
713 if (read_int_or_bool(data_size, data)) {
714 options |= WIFI_OPTIONS_MEDIA_STREAMING_MODE;
716 internal::WlanApi::GetInstance().free_memory_func(data);
718 // Just the the options from the first succesful
719 // interface.
720 return options;
723 // No wifi interface found.
724 return -1;
727 #else // OS_WIN
729 int GetWifiOptions() {
730 // Not supported.
731 return -1;
734 #endif // OS_WIN
736 void TryChangeWifiOptions(int options) {
737 int previous_options = GetWifiOptions();
738 scoped_ptr<ScopedWifiOptions> scoped_options = SetWifiOptions(options);
739 EXPECT_EQ(previous_options | options, GetWifiOptions());
740 scoped_options.reset();
741 EXPECT_EQ(previous_options, GetWifiOptions());
744 // Test SetWifiOptions().
745 TEST(NetUtilTest, SetWifiOptionsTest) {
746 TryChangeWifiOptions(0);
747 TryChangeWifiOptions(WIFI_OPTIONS_DISABLE_SCAN);
748 TryChangeWifiOptions(WIFI_OPTIONS_MEDIA_STREAMING_MODE);
749 TryChangeWifiOptions(WIFI_OPTIONS_DISABLE_SCAN |
750 WIFI_OPTIONS_MEDIA_STREAMING_MODE);
753 } // namespace
755 } // namespace net