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::make_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(
76 address_map.insert(std::make_pair(ipv6_local_address, msg)).second);
77 EXPECT_TRUE(internal::GetNetworkListImpl(
78 &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, online_links,
79 address_map, GetInterfaceName));
80 EXPECT_EQ(results.size(), 0ul);
81
82 // vmware address should return by default.
83 address_map.clear();
84 ASSERT_TRUE(address_map.insert(std::make_pair(ipv6_address, msg)).second);
85 EXPECT_TRUE(internal::GetNetworkListImpl(
86 &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, online_links,
87 address_map, GetInterfaceNameVM));
88 EXPECT_EQ(results.size(), 1ul);
89 EXPECT_EQ(results[0].name, kIfnameVmnet);
90 EXPECT_EQ(results[0].prefix_length, 1ul);
91 EXPECT_EQ(results[0].address, ipv6_address);
92 results.clear();
93
94 // vmware address should be trimmed out if policy specified so.
95 address_map.clear();
96 ASSERT_TRUE(address_map.insert(std::make_pair(ipv6_address, msg)).second);
97 EXPECT_TRUE(internal::GetNetworkListImpl(
98 &results, EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, online_links,
99 address_map, GetInterfaceNameVM));
100 EXPECT_EQ(results.size(), 0ul);
101 results.clear();
102
103 // Addresses with banned attributes should be ignored.
104 address_map.clear();
105 msg.ifa_flags = IFA_F_TENTATIVE;
106 ASSERT_TRUE(address_map.insert(std::make_pair(ipv6_address, msg)).second);
107 EXPECT_TRUE(internal::GetNetworkListImpl(
108 &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, online_links,
109 address_map, GetInterfaceName));
110 EXPECT_EQ(results.size(), 0ul);
111 results.clear();
112
113 // Addresses with allowed attribute IFA_F_TEMPORARY should be returned and
114 // attributes should be translated correctly.
115 address_map.clear();
116 msg.ifa_flags = IFA_F_TEMPORARY;
117 ASSERT_TRUE(address_map.insert(std::make_pair(ipv6_address, msg)).second);
118 EXPECT_TRUE(internal::GetNetworkListImpl(
119 &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, online_links,
120 address_map, GetInterfaceName));
121 EXPECT_EQ(results.size(), 1ul);
122 EXPECT_EQ(results[0].name, kIfnameEm1);
123 EXPECT_EQ(results[0].prefix_length, 1ul);
124 EXPECT_EQ(results[0].address, ipv6_address);
125 EXPECT_EQ(results[0].ip_address_attributes, IP_ADDRESS_ATTRIBUTE_TEMPORARY);
126 results.clear();
127
128 // Addresses with allowed attribute IFA_F_DEPRECATED should be returned and
129 // attributes should be translated correctly.
130 address_map.clear();
131 msg.ifa_flags = IFA_F_DEPRECATED;
132 ASSERT_TRUE(address_map.insert(std::make_pair(ipv6_address, msg)).second);
133 EXPECT_TRUE(internal::GetNetworkListImpl(
134 &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, online_links,
135 address_map, GetInterfaceName));
136 EXPECT_EQ(results.size(), 1ul);
137 EXPECT_EQ(results[0].name, kIfnameEm1);
138 EXPECT_EQ(results[0].prefix_length, 1ul);
139 EXPECT_EQ(results[0].address, ipv6_address);
140 EXPECT_EQ(results[0].ip_address_attributes, IP_ADDRESS_ATTRIBUTE_DEPRECATED);
141 results.clear();
142 }
143
144 const char kWiFiSSID[] = "TestWiFi";
145 const char kInterfaceWithDifferentSSID[] = "wlan999";
146
TestGetInterfaceSSID(const std::string & ifname)147 std::string TestGetInterfaceSSID(const std::string& ifname) {
148 return (ifname == kInterfaceWithDifferentSSID) ? "AnotherSSID" : kWiFiSSID;
149 }
150
TEST(NetworkInterfacesTest,GetWifiSSIDFromInterfaceList)151 TEST(NetworkInterfacesTest, GetWifiSSIDFromInterfaceList) {
152 NetworkInterfaceList list;
153 EXPECT_EQ(std::string(), internal::GetWifiSSIDFromInterfaceListInternal(
154 list, TestGetInterfaceSSID));
155
156 NetworkInterface interface1;
157 interface1.name = "wlan0";
158 interface1.type = NetworkChangeNotifier::CONNECTION_WIFI;
159 list.push_back(interface1);
160 ASSERT_EQ(1u, list.size());
161 EXPECT_EQ(std::string(kWiFiSSID),
162 internal::GetWifiSSIDFromInterfaceListInternal(
163 list, TestGetInterfaceSSID));
164
165 NetworkInterface interface2;
166 interface2.name = "wlan1";
167 interface2.type = NetworkChangeNotifier::CONNECTION_WIFI;
168 list.push_back(interface2);
169 ASSERT_EQ(2u, list.size());
170 EXPECT_EQ(std::string(kWiFiSSID),
171 internal::GetWifiSSIDFromInterfaceListInternal(
172 list, TestGetInterfaceSSID));
173
174 NetworkInterface interface3;
175 interface3.name = kInterfaceWithDifferentSSID;
176 interface3.type = NetworkChangeNotifier::CONNECTION_WIFI;
177 list.push_back(interface3);
178 ASSERT_EQ(3u, list.size());
179 EXPECT_EQ(std::string(), internal::GetWifiSSIDFromInterfaceListInternal(
180 list, TestGetInterfaceSSID));
181
182 list.pop_back();
183 NetworkInterface interface4;
184 interface4.name = "eth0";
185 interface4.type = NetworkChangeNotifier::CONNECTION_ETHERNET;
186 list.push_back(interface4);
187 ASSERT_EQ(3u, list.size());
188 EXPECT_EQ(std::string(), internal::GetWifiSSIDFromInterfaceListInternal(
189 list, TestGetInterfaceSSID));
190 }
191
192 } // namespace
193
194 } // namespace net
195