• 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 #ifdef UNSAFE_BUFFERS_BUILD
6 // TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
7 #pragma allow_unsafe_buffers
8 #endif
9 
10 #include "net/base/network_interfaces_getifaddrs.h"
11 
12 #include <string>
13 
14 #include "build/build_config.h"
15 #include "net/base/ip_endpoint.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 
18 #include <ifaddrs.h>
19 #include <net/if.h>
20 #include <netinet/in.h>
21 
22 namespace net {
23 namespace {
24 
25 class IPAttributesGetterTest : public internal::IPAttributesGetter {
26  public:
27   IPAttributesGetterTest() = default;
28 
29   // internal::IPAttributesGetter interface.
IsInitialized() const30   bool IsInitialized() const override { return true; }
GetAddressAttributes(const ifaddrs * if_addr,int * attributes)31   bool GetAddressAttributes(const ifaddrs* if_addr, int* attributes) override {
32     *attributes = attributes_;
33     return true;
34   }
GetNetworkInterfaceType(const ifaddrs * if_addr)35   NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType(
36       const ifaddrs* if_addr) override {
37     return NetworkChangeNotifier::CONNECTION_UNKNOWN;
38   }
39 
set_attributes(int attributes)40   void set_attributes(int attributes) { attributes_ = attributes; }
41 
42  private:
43   int attributes_ = 0;
44 };
45 
46 // Helper function to create a single valid ifaddrs
FillIfaddrs(ifaddrs * interfaces,const char * ifname,uint flags,const IPAddress & ip_address,const IPAddress & ip_netmask,sockaddr_storage sock_addrs[2])47 bool FillIfaddrs(ifaddrs* interfaces,
48                  const char* ifname,
49                  uint flags,
50                  const IPAddress& ip_address,
51                  const IPAddress& ip_netmask,
52                  sockaddr_storage sock_addrs[2]) {
53   interfaces->ifa_next = nullptr;
54   interfaces->ifa_name = const_cast<char*>(ifname);
55   interfaces->ifa_flags = flags;
56 
57   socklen_t sock_len = sizeof(sockaddr_storage);
58 
59   // Convert to sockaddr for next check.
60   if (!IPEndPoint(ip_address, 0)
61            .ToSockAddr(reinterpret_cast<sockaddr*>(&sock_addrs[0]),
62                        &sock_len)) {
63     return false;
64   }
65   interfaces->ifa_addr = reinterpret_cast<sockaddr*>(&sock_addrs[0]);
66 
67   sock_len = sizeof(sockaddr_storage);
68   if (!IPEndPoint(ip_netmask, 0)
69            .ToSockAddr(reinterpret_cast<sockaddr*>(&sock_addrs[1]),
70                        &sock_len)) {
71     return false;
72   }
73   interfaces->ifa_netmask = reinterpret_cast<sockaddr*>(&sock_addrs[1]);
74 
75   return true;
76 }
77 
78 static const char kIfnameEm1[] = "em1";
79 static const char kIfnameVmnet[] = "vmnet";
80 
81 static const unsigned char kIPv6LocalAddr[] = {0, 0, 0, 0, 0, 0, 0, 0,
82                                                0, 0, 0, 0, 0, 0, 0, 1};
83 
84 // The following 3 addresses need to be changed together. IPv6Addr is the IPv6
85 // address. IPv6Netmask is the mask address with as many leading bits set to 1
86 // as the prefix length. IPv6AddrPrefix needs to match IPv6Addr with the same
87 // number of bits as the prefix length.
88 static const unsigned char kIPv6Addr[] = {0x24, 0x01, 0xfa, 0x00, 0x00, 0x04,
89                                           0x10, 0x00, 0xbe, 0x30, 0x5b, 0xff,
90                                           0xfe, 0xe5, 0x00, 0xc3};
91 
92 static const unsigned char kIPv6Netmask[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
93                                              0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94                                              0x00, 0x00, 0x00, 0x00};
95 
TEST(NetworkInterfacesTest,IfaddrsToNetworkInterfaceList)96 TEST(NetworkInterfacesTest, IfaddrsToNetworkInterfaceList) {
97   IPAddress ipv6_local_address(kIPv6LocalAddr);
98   IPAddress ipv6_address(kIPv6Addr);
99   IPAddress ipv6_netmask(kIPv6Netmask);
100 
101   NetworkInterfaceList results;
102   IPAttributesGetterTest ip_attributes_getter;
103   sockaddr_storage addresses[2];
104   ifaddrs interface;
105 
106   // Address of offline (not running) links should be ignored.
107   ASSERT_TRUE(FillIfaddrs(&interface, kIfnameEm1, IFF_UP, ipv6_address,
108                           ipv6_netmask, addresses));
109   EXPECT_TRUE(internal::IfaddrsToNetworkInterfaceList(
110       INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, &interface, &ip_attributes_getter,
111       &results));
112   EXPECT_EQ(results.size(), 0ul);
113 
114   // Address of offline (not up) links should be ignored.
115   ASSERT_TRUE(FillIfaddrs(&interface, kIfnameEm1, IFF_RUNNING, ipv6_address,
116                           ipv6_netmask, addresses));
117   EXPECT_TRUE(internal::IfaddrsToNetworkInterfaceList(
118       INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, &interface, &ip_attributes_getter,
119       &results));
120   EXPECT_EQ(results.size(), 0ul);
121 
122   // Local address should be trimmed out.
123   ASSERT_TRUE(FillIfaddrs(&interface, kIfnameEm1, IFF_UP | IFF_RUNNING,
124                           ipv6_local_address, ipv6_netmask, addresses));
125   EXPECT_TRUE(internal::IfaddrsToNetworkInterfaceList(
126       INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, &interface, &ip_attributes_getter,
127       &results));
128   EXPECT_EQ(results.size(), 0ul);
129 
130   // vmware address should return by default.
131   ASSERT_TRUE(FillIfaddrs(&interface, kIfnameVmnet, IFF_UP | IFF_RUNNING,
132                           ipv6_address, ipv6_netmask, addresses));
133   EXPECT_TRUE(internal::IfaddrsToNetworkInterfaceList(
134       INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, &interface, &ip_attributes_getter,
135       &results));
136   EXPECT_EQ(results.size(), 1ul);
137   EXPECT_EQ(results[0].name, kIfnameVmnet);
138   EXPECT_EQ(results[0].prefix_length, 1ul);
139   EXPECT_EQ(results[0].address, ipv6_address);
140   results.clear();
141 
142   // vmware address should be trimmed out if policy specified so.
143   ASSERT_TRUE(FillIfaddrs(&interface, kIfnameVmnet, IFF_UP | IFF_RUNNING,
144                           ipv6_address, ipv6_netmask, addresses));
145   EXPECT_TRUE(internal::IfaddrsToNetworkInterfaceList(
146       EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, &interface, &ip_attributes_getter,
147       &results));
148   EXPECT_EQ(results.size(), 0ul);
149   results.clear();
150 
151   // Addresses with banned attributes should be ignored.
152   ip_attributes_getter.set_attributes(IP_ADDRESS_ATTRIBUTE_ANYCAST);
153   ASSERT_TRUE(FillIfaddrs(&interface, kIfnameEm1, IFF_UP | IFF_RUNNING,
154                           ipv6_address, ipv6_netmask, addresses));
155   EXPECT_TRUE(internal::IfaddrsToNetworkInterfaceList(
156       INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, &interface, &ip_attributes_getter,
157       &results));
158   EXPECT_EQ(results.size(), 0ul);
159   results.clear();
160 
161   // Addresses with allowed attribute IFA_F_TEMPORARY should be returned and
162   // attributes should be translated correctly.
163   ip_attributes_getter.set_attributes(IP_ADDRESS_ATTRIBUTE_TEMPORARY);
164   ASSERT_TRUE(FillIfaddrs(&interface, kIfnameEm1, IFF_UP | IFF_RUNNING,
165                           ipv6_address, ipv6_netmask, addresses));
166   EXPECT_TRUE(internal::IfaddrsToNetworkInterfaceList(
167       INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, &interface, &ip_attributes_getter,
168       &results));
169   EXPECT_EQ(results.size(), 1ul);
170   EXPECT_EQ(results[0].name, kIfnameEm1);
171   EXPECT_EQ(results[0].prefix_length, 1ul);
172   EXPECT_EQ(results[0].address, ipv6_address);
173   EXPECT_EQ(results[0].ip_address_attributes, IP_ADDRESS_ATTRIBUTE_TEMPORARY);
174   results.clear();
175 
176   // Addresses with allowed attribute IFA_F_DEPRECATED should be returned and
177   // attributes should be translated correctly.
178   ip_attributes_getter.set_attributes(IP_ADDRESS_ATTRIBUTE_DEPRECATED);
179   ASSERT_TRUE(FillIfaddrs(&interface, kIfnameEm1, IFF_UP | IFF_RUNNING,
180                           ipv6_address, ipv6_netmask, addresses));
181   EXPECT_TRUE(internal::IfaddrsToNetworkInterfaceList(
182       INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, &interface, &ip_attributes_getter,
183       &results));
184   EXPECT_EQ(results.size(), 1ul);
185   EXPECT_EQ(results[0].name, kIfnameEm1);
186   EXPECT_EQ(results[0].prefix_length, 1ul);
187   EXPECT_EQ(results[0].address, ipv6_address);
188   EXPECT_EQ(results[0].ip_address_attributes, IP_ADDRESS_ATTRIBUTE_DEPRECATED);
189   results.clear();
190 }
191 
192 }  // namespace
193 }  // namespace net
194