• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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