xref: /aosp_15_r20/external/cronet/net/base/network_interfaces_linux_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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