1 // Copyright (c) 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/base/net_util_linux.h"
8 #include <netinet/in.h>
10 #include <sys/types.h>
12 #include "base/files/file_path.h"
13 #include "base/logging.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/string_tokenizer.h"
17 #include "base/strings/string_util.h"
18 #include "base/threading/thread_restrictions.h"
19 #include "net/base/address_tracker_linux.h"
20 #include "net/base/escape.h"
21 #include "net/base/ip_endpoint.h"
22 #include "net/base/net_errors.h"
23 #include "net/base/net_util_posix.h"
30 // When returning true, the platform native IPv6 address attributes were
31 // successfully converted to net IP address attributes. Otherwise, returning
32 // false and the caller should drop the IP address which can't be used by the
34 bool TryConvertNativeToNetIPAttributes(int native_attributes
,
35 int* net_attributes
) {
36 // For Linux/ChromeOS/Android, we disallow addresses with attributes
37 // IFA_F_OPTIMISTIC, IFA_F_DADFAILED, and IFA_F_TENTATIVE as these
38 // are still progressing through duplicated address detection (DAD)
39 // and shouldn't be used by the application layer until DAD process
41 if (native_attributes
& (
42 #if !defined(OS_ANDROID)
43 IFA_F_OPTIMISTIC
| IFA_F_DADFAILED
|
49 if (native_attributes
& IFA_F_TEMPORARY
) {
50 *net_attributes
|= IP_ADDRESS_ATTRIBUTE_TEMPORARY
;
53 if (native_attributes
& IFA_F_DEPRECATED
) {
54 *net_attributes
|= IP_ADDRESS_ATTRIBUTE_DEPRECATED
;
64 inline const unsigned char* GetIPAddressData(const IPAddressNumber
& ip
) {
65 #if defined(OS_ANDROID)
72 bool GetNetworkListImpl(
73 NetworkInterfaceList
* networks
,
75 const base::hash_set
<int>& online_links
,
76 const internal::AddressTrackerLinux::AddressMap
& address_map
,
77 GetInterfaceNameFunction get_interface_name
) {
78 std::map
<int, std::string
> ifnames
;
80 for (internal::AddressTrackerLinux::AddressMap::const_iterator it
=
82 it
!= address_map
.end(); ++it
) {
83 // Ignore addresses whose links are not online.
84 if (online_links
.find(it
->second
.ifa_index
) == online_links
.end())
87 sockaddr_storage sock_addr
;
88 socklen_t sock_len
= sizeof(sockaddr_storage
);
90 // Convert to sockaddr for next check.
91 if (!IPEndPoint(it
->first
, 0)
92 .ToSockAddr(reinterpret_cast<sockaddr
*>(&sock_addr
), &sock_len
)) {
96 // Skip unspecified addresses (i.e. made of zeroes) and loopback addresses
97 if (IsLoopbackOrUnspecifiedAddress(reinterpret_cast<sockaddr
*>(&sock_addr
)))
100 int ip_attributes
= IP_ADDRESS_ATTRIBUTE_NONE
;
102 if (it
->second
.ifa_family
== AF_INET6
) {
103 // Ignore addresses whose attributes are not actionable by
104 // the application layer.
105 if (!TryConvertNativeToNetIPAttributes(it
->second
.ifa_flags
,
110 // Find the name of this link.
111 std::map
<int, std::string
>::const_iterator itname
=
112 ifnames
.find(it
->second
.ifa_index
);
114 if (itname
== ifnames
.end()) {
115 char buffer
[IF_NAMESIZE
] = {0};
116 if (get_interface_name(it
->second
.ifa_index
, buffer
)) {
117 ifname
= ifnames
[it
->second
.ifa_index
] = buffer
;
119 // Ignore addresses whose interface name can't be retrieved.
123 ifname
= itname
->second
;
126 // Based on the interface name and policy, determine whether we
128 if (ShouldIgnoreInterface(ifname
, policy
))
132 NetworkInterface(ifname
, ifname
, it
->second
.ifa_index
,
133 NetworkChangeNotifier::CONNECTION_UNKNOWN
, it
->first
,
134 it
->second
.ifa_prefixlen
, ip_attributes
));
140 } // namespace internal
142 bool GetNetworkList(NetworkInterfaceList
* networks
, int policy
) {
143 if (networks
== NULL
)
146 internal::AddressTrackerLinux tracker
;
149 return internal::GetNetworkListImpl(networks
, policy
,
150 tracker
.GetOnlineLinks(),
151 tracker
.GetAddressMap(), &if_indextoname
);