1 // Copyright 2017 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/base/network_interfaces_linux.h"
6
7 #include <net/if.h>
8 #include <netinet/in.h>
9
10 #include <ostream>
11 #include <string>
12 #include <unordered_set>
13
14 #include "base/strings/utf_string_conversions.h"
15 #include "build/build_config.h"
16 #include "net/base/address_tracker_linux.h"
17 #include "net/base/ip_endpoint.h"
18 #include "net/base/network_interfaces_posix.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 namespace net {
22
23 namespace {
24
25 static const char kIfnameEm1[] = "em1";
26 static const char kIfnameVmnet[] = "vmnet";
27 static const unsigned char kIPv6LocalAddr[] = {0, 0, 0, 0, 0, 0, 0, 0,
28 0, 0, 0, 0, 0, 0, 0, 1};
29 static const unsigned char kIPv6Addr[] = {0x24, 0x01, 0xfa, 0x00, 0x00, 0x04,
30 0x10, 0x00, 0xbe, 0x30, 0x5b, 0xff,
31 0xfe, 0xe5, 0x00, 0xc3};
32
GetInterfaceName(int interface_index,char * ifname)33 char* GetInterfaceName(int interface_index, char* ifname) {
34 static_assert(std::size(kIfnameEm1) < IF_NAMESIZE, "Invalid interface name");
35 memcpy(ifname, kIfnameEm1, std::size(kIfnameEm1));
36 return ifname;
37 }
38
GetInterfaceNameVM(int interface_index,char * ifname)39 char* GetInterfaceNameVM(int interface_index, char* ifname) {
40 static_assert(std::size(kIfnameVmnet) < IF_NAMESIZE,
41 "Invalid interface name");
42 memcpy(ifname, kIfnameVmnet, std::size(kIfnameVmnet));
43 return ifname;
44 }
45
TEST(NetworkInterfacesTest,NetworkListTrimmingLinux)46 TEST(NetworkInterfacesTest, NetworkListTrimmingLinux) {
47 IPAddress ipv6_local_address(kIPv6LocalAddr);
48 IPAddress ipv6_address(kIPv6Addr);
49
50 NetworkInterfaceList results;
51 std::unordered_set<int> online_links;
52 internal::AddressTrackerLinux::AddressMap address_map;
53
54 // Interface 1 is offline.
55 struct ifaddrmsg msg = {
56 AF_INET6, // Address type
57 1, // Prefix length
58 IFA_F_TEMPORARY, // Address flags
59 0, // Link scope
60 1 // Link index
61 };
62
63 // Address of offline links should be ignored.
64 ASSERT_TRUE(address_map.insert(std::pair(ipv6_address, msg)).second);
65 EXPECT_TRUE(internal::GetNetworkListImpl(
66 &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, online_links,
67 address_map, GetInterfaceName));
68 EXPECT_EQ(results.size(), 0ul);
69
70 // Mark interface 1 online.
71 online_links.insert(1);
72
73 // Local address should be trimmed out.
74 address_map.clear();
75 ASSERT_TRUE(address_map.insert(std::pair(ipv6_local_address, msg)).second);
76 EXPECT_TRUE(internal::GetNetworkListImpl(
77 &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, online_links,
78 address_map, GetInterfaceName));
79 EXPECT_EQ(results.size(), 0ul);
80
81 // vmware address should return by default.
82 address_map.clear();
83 ASSERT_TRUE(address_map.insert(std::pair(ipv6_address, msg)).second);
84 EXPECT_TRUE(internal::GetNetworkListImpl(
85 &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, online_links,
86 address_map, GetInterfaceNameVM));
87 EXPECT_EQ(results.size(), 1ul);
88 EXPECT_EQ(results[0].name, kIfnameVmnet);
89 EXPECT_EQ(results[0].prefix_length, 1ul);
90 EXPECT_EQ(results[0].address, ipv6_address);
91 results.clear();
92
93 // vmware address should be trimmed out if policy specified so.
94 address_map.clear();
95 ASSERT_TRUE(address_map.insert(std::pair(ipv6_address, msg)).second);
96 EXPECT_TRUE(internal::GetNetworkListImpl(
97 &results, EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, online_links,
98 address_map, GetInterfaceNameVM));
99 EXPECT_EQ(results.size(), 0ul);
100 results.clear();
101
102 // Addresses with banned attributes should be ignored.
103 address_map.clear();
104 msg.ifa_flags = IFA_F_TENTATIVE;
105 ASSERT_TRUE(address_map.insert(std::pair(ipv6_address, msg)).second);
106 EXPECT_TRUE(internal::GetNetworkListImpl(
107 &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, online_links,
108 address_map, GetInterfaceName));
109 EXPECT_EQ(results.size(), 0ul);
110 results.clear();
111
112 // Addresses with allowed attribute IFA_F_TEMPORARY should be returned and
113 // attributes should be translated correctly.
114 address_map.clear();
115 msg.ifa_flags = IFA_F_TEMPORARY;
116 ASSERT_TRUE(address_map.insert(std::pair(ipv6_address, msg)).second);
117 EXPECT_TRUE(internal::GetNetworkListImpl(
118 &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, online_links,
119 address_map, GetInterfaceName));
120 EXPECT_EQ(results.size(), 1ul);
121 EXPECT_EQ(results[0].name, kIfnameEm1);
122 EXPECT_EQ(results[0].prefix_length, 1ul);
123 EXPECT_EQ(results[0].address, ipv6_address);
124 EXPECT_EQ(results[0].ip_address_attributes, IP_ADDRESS_ATTRIBUTE_TEMPORARY);
125 results.clear();
126
127 // Addresses with allowed attribute IFA_F_DEPRECATED should be returned and
128 // attributes should be translated correctly.
129 address_map.clear();
130 msg.ifa_flags = IFA_F_DEPRECATED;
131 ASSERT_TRUE(address_map.insert(std::pair(ipv6_address, msg)).second);
132 EXPECT_TRUE(internal::GetNetworkListImpl(
133 &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, online_links,
134 address_map, GetInterfaceName));
135 EXPECT_EQ(results.size(), 1ul);
136 EXPECT_EQ(results[0].name, kIfnameEm1);
137 EXPECT_EQ(results[0].prefix_length, 1ul);
138 EXPECT_EQ(results[0].address, ipv6_address);
139 EXPECT_EQ(results[0].ip_address_attributes, IP_ADDRESS_ATTRIBUTE_DEPRECATED);
140 results.clear();
141 }
142
143 const char kWiFiSSID[] = "TestWiFi";
144 const char kInterfaceWithDifferentSSID[] = "wlan999";
145
TestGetInterfaceSSID(const std::string & ifname)146 std::string TestGetInterfaceSSID(const std::string& ifname) {
147 return (ifname == kInterfaceWithDifferentSSID) ? "AnotherSSID" : kWiFiSSID;
148 }
149
TEST(NetworkInterfacesTest,GetWifiSSIDFromInterfaceList)150 TEST(NetworkInterfacesTest, GetWifiSSIDFromInterfaceList) {
151 NetworkInterfaceList list;
152 EXPECT_EQ(std::string(), internal::GetWifiSSIDFromInterfaceListInternal(
153 list, TestGetInterfaceSSID));
154
155 NetworkInterface interface1;
156 interface1.name = "wlan0";
157 interface1.type = NetworkChangeNotifier::CONNECTION_WIFI;
158 list.push_back(interface1);
159 ASSERT_EQ(1u, list.size());
160 EXPECT_EQ(std::string(kWiFiSSID),
161 internal::GetWifiSSIDFromInterfaceListInternal(
162 list, TestGetInterfaceSSID));
163
164 NetworkInterface interface2;
165 interface2.name = "wlan1";
166 interface2.type = NetworkChangeNotifier::CONNECTION_WIFI;
167 list.push_back(interface2);
168 ASSERT_EQ(2u, list.size());
169 EXPECT_EQ(std::string(kWiFiSSID),
170 internal::GetWifiSSIDFromInterfaceListInternal(
171 list, TestGetInterfaceSSID));
172
173 NetworkInterface interface3;
174 interface3.name = kInterfaceWithDifferentSSID;
175 interface3.type = NetworkChangeNotifier::CONNECTION_WIFI;
176 list.push_back(interface3);
177 ASSERT_EQ(3u, list.size());
178 EXPECT_EQ(std::string(), internal::GetWifiSSIDFromInterfaceListInternal(
179 list, TestGetInterfaceSSID));
180
181 list.pop_back();
182 NetworkInterface interface4;
183 interface4.name = "eth0";
184 interface4.type = NetworkChangeNotifier::CONNECTION_ETHERNET;
185 list.push_back(interface4);
186 ASSERT_EQ(3u, list.size());
187 EXPECT_EQ(std::string(), internal::GetWifiSSIDFromInterfaceListInternal(
188 list, TestGetInterfaceSSID));
189 }
190
191 } // namespace
192
193 } // namespace net
194