| // Copyright 2017 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "net/base/network_interfaces_linux.h" |
| |
| #include <net/if.h> |
| #include <netinet/in.h> |
| |
| #include <ostream> |
| #include <string> |
| #include <unordered_set> |
| |
| #include "base/stl_util.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "build/build_config.h" |
| #include "net/base/address_tracker_linux.h" |
| #include "net/base/ip_endpoint.h" |
| #include "net/base/network_interfaces_posix.h" |
| #include "starboard/memory.h" |
| #include "starboard/types.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace net { |
| |
| namespace { |
| |
| static const char kIfnameEm1[] = "em1"; |
| static const char kIfnameVmnet[] = "vmnet"; |
| static const unsigned char kIPv6LocalAddr[] = {0, 0, 0, 0, 0, 0, 0, 0, |
| 0, 0, 0, 0, 0, 0, 0, 1}; |
| static const unsigned char kIPv6Addr[] = {0x24, 0x01, 0xfa, 0x00, 0x00, 0x04, |
| 0x10, 0x00, 0xbe, 0x30, 0x5b, 0xff, |
| 0xfe, 0xe5, 0x00, 0xc3}; |
| |
| char* GetInterfaceName(int interface_index, char* ifname) { |
| static_assert(base::size(kIfnameEm1) < IF_NAMESIZE, "Invalid interface name"); |
| memcpy(ifname, kIfnameEm1, base::size(kIfnameEm1)); |
| return ifname; |
| } |
| |
| char* GetInterfaceNameVM(int interface_index, char* ifname) { |
| static_assert(base::size(kIfnameVmnet) < IF_NAMESIZE, |
| "Invalid interface name"); |
| memcpy(ifname, kIfnameVmnet, base::size(kIfnameVmnet)); |
| return ifname; |
| } |
| |
| TEST(NetworkInterfacesTest, NetworkListTrimmingLinux) { |
| IPAddress ipv6_local_address(kIPv6LocalAddr); |
| IPAddress ipv6_address(kIPv6Addr); |
| |
| NetworkInterfaceList results; |
| std::unordered_set<int> online_links; |
| internal::AddressTrackerLinux::AddressMap address_map; |
| |
| // Interface 1 is offline. |
| struct ifaddrmsg msg = { |
| AF_INET6, // Address type |
| 1, // Prefix length |
| IFA_F_TEMPORARY, // Address flags |
| 0, // Link scope |
| 1 // Link index |
| }; |
| |
| // Address of offline links should be ignored. |
| ASSERT_TRUE(address_map.insert(std::make_pair(ipv6_address, msg)).second); |
| EXPECT_TRUE(internal::GetNetworkListImpl( |
| &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, online_links, |
| address_map, GetInterfaceName)); |
| EXPECT_EQ(results.size(), 0ul); |
| |
| // Mark interface 1 online. |
| online_links.insert(1); |
| |
| // Local address should be trimmed out. |
| address_map.clear(); |
| ASSERT_TRUE( |
| address_map.insert(std::make_pair(ipv6_local_address, msg)).second); |
| EXPECT_TRUE(internal::GetNetworkListImpl( |
| &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, online_links, |
| address_map, GetInterfaceName)); |
| EXPECT_EQ(results.size(), 0ul); |
| |
| // vmware address should return by default. |
| address_map.clear(); |
| ASSERT_TRUE(address_map.insert(std::make_pair(ipv6_address, msg)).second); |
| EXPECT_TRUE(internal::GetNetworkListImpl( |
| &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, online_links, |
| address_map, GetInterfaceNameVM)); |
| EXPECT_EQ(results.size(), 1ul); |
| EXPECT_EQ(results[0].name, kIfnameVmnet); |
| EXPECT_EQ(results[0].prefix_length, 1ul); |
| EXPECT_EQ(results[0].address, ipv6_address); |
| results.clear(); |
| |
| // vmware address should be trimmed out if policy specified so. |
| address_map.clear(); |
| ASSERT_TRUE(address_map.insert(std::make_pair(ipv6_address, msg)).second); |
| EXPECT_TRUE(internal::GetNetworkListImpl( |
| &results, EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, online_links, |
| address_map, GetInterfaceNameVM)); |
| EXPECT_EQ(results.size(), 0ul); |
| results.clear(); |
| |
| // Addresses with banned attributes should be ignored. |
| address_map.clear(); |
| msg.ifa_flags = IFA_F_TENTATIVE; |
| ASSERT_TRUE(address_map.insert(std::make_pair(ipv6_address, msg)).second); |
| EXPECT_TRUE(internal::GetNetworkListImpl( |
| &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, online_links, |
| address_map, GetInterfaceName)); |
| EXPECT_EQ(results.size(), 0ul); |
| results.clear(); |
| |
| // Addresses with allowed attribute IFA_F_TEMPORARY should be returned and |
| // attributes should be translated correctly. |
| address_map.clear(); |
| msg.ifa_flags = IFA_F_TEMPORARY; |
| ASSERT_TRUE(address_map.insert(std::make_pair(ipv6_address, msg)).second); |
| EXPECT_TRUE(internal::GetNetworkListImpl( |
| &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, online_links, |
| address_map, GetInterfaceName)); |
| EXPECT_EQ(results.size(), 1ul); |
| EXPECT_EQ(results[0].name, kIfnameEm1); |
| EXPECT_EQ(results[0].prefix_length, 1ul); |
| EXPECT_EQ(results[0].address, ipv6_address); |
| EXPECT_EQ(results[0].ip_address_attributes, IP_ADDRESS_ATTRIBUTE_TEMPORARY); |
| results.clear(); |
| |
| // Addresses with allowed attribute IFA_F_DEPRECATED should be returned and |
| // attributes should be translated correctly. |
| address_map.clear(); |
| msg.ifa_flags = IFA_F_DEPRECATED; |
| ASSERT_TRUE(address_map.insert(std::make_pair(ipv6_address, msg)).second); |
| EXPECT_TRUE(internal::GetNetworkListImpl( |
| &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, online_links, |
| address_map, GetInterfaceName)); |
| EXPECT_EQ(results.size(), 1ul); |
| EXPECT_EQ(results[0].name, kIfnameEm1); |
| EXPECT_EQ(results[0].prefix_length, 1ul); |
| EXPECT_EQ(results[0].address, ipv6_address); |
| EXPECT_EQ(results[0].ip_address_attributes, IP_ADDRESS_ATTRIBUTE_DEPRECATED); |
| results.clear(); |
| } |
| |
| const char kWiFiSSID[] = "TestWiFi"; |
| const char kInterfaceWithDifferentSSID[] = "wlan999"; |
| |
| std::string TestGetInterfaceSSID(const std::string& ifname) { |
| return (ifname == kInterfaceWithDifferentSSID) ? "AnotherSSID" : kWiFiSSID; |
| } |
| |
| TEST(NetworkInterfacesTest, GetWifiSSIDFromInterfaceList) { |
| NetworkInterfaceList list; |
| EXPECT_EQ(std::string(), internal::GetWifiSSIDFromInterfaceListInternal( |
| list, TestGetInterfaceSSID)); |
| |
| NetworkInterface interface1; |
| interface1.name = "wlan0"; |
| interface1.type = NetworkChangeNotifier::CONNECTION_WIFI; |
| list.push_back(interface1); |
| ASSERT_EQ(1u, list.size()); |
| EXPECT_EQ(std::string(kWiFiSSID), |
| internal::GetWifiSSIDFromInterfaceListInternal( |
| list, TestGetInterfaceSSID)); |
| |
| NetworkInterface interface2; |
| interface2.name = "wlan1"; |
| interface2.type = NetworkChangeNotifier::CONNECTION_WIFI; |
| list.push_back(interface2); |
| ASSERT_EQ(2u, list.size()); |
| EXPECT_EQ(std::string(kWiFiSSID), |
| internal::GetWifiSSIDFromInterfaceListInternal( |
| list, TestGetInterfaceSSID)); |
| |
| NetworkInterface interface3; |
| interface3.name = kInterfaceWithDifferentSSID; |
| interface3.type = NetworkChangeNotifier::CONNECTION_WIFI; |
| list.push_back(interface3); |
| ASSERT_EQ(3u, list.size()); |
| EXPECT_EQ(std::string(), internal::GetWifiSSIDFromInterfaceListInternal( |
| list, TestGetInterfaceSSID)); |
| |
| list.pop_back(); |
| NetworkInterface interface4; |
| interface4.name = "eth0"; |
| interface4.type = NetworkChangeNotifier::CONNECTION_ETHERNET; |
| list.push_back(interface4); |
| ASSERT_EQ(3u, list.size()); |
| EXPECT_EQ(std::string(), internal::GetWifiSSIDFromInterfaceListInternal( |
| list, TestGetInterfaceSSID)); |
| } |
| |
| } // namespace |
| |
| } // namespace net |