Change the display string for HDMI audio type.
[chromium-blink-merge.git] / net / base / net_util_linux.cc
blobe4e0f7f3277e9110cb944ea0714ea9136f36ea18
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"
7 #include <net/if.h>
8 #include <netinet/in.h>
9 #include <set>
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"
24 #include "url/gurl.h"
26 namespace net {
28 namespace {
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
33 // application layer.
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
40 // is completed.
41 if (native_attributes & (
42 #if !defined(OS_ANDROID)
43 IFA_F_OPTIMISTIC | IFA_F_DADFAILED |
44 #endif // !OS_ANDROID
45 IFA_F_TENTATIVE)) {
46 return false;
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;
57 return true;
60 } // namespace
62 namespace internal {
64 inline const unsigned char* GetIPAddressData(const IPAddressNumber& ip) {
65 #if defined(OS_ANDROID)
66 return ip.begin();
67 #else
68 return ip.data();
69 #endif
72 bool GetNetworkListImpl(
73 NetworkInterfaceList* networks,
74 int policy,
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 =
81 address_map.begin();
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())
85 continue;
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)) {
93 continue;
96 // Skip unspecified addresses (i.e. made of zeroes) and loopback addresses
97 if (IsLoopbackOrUnspecifiedAddress(reinterpret_cast<sockaddr*>(&sock_addr)))
98 continue;
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,
106 &ip_attributes))
107 continue;
110 // Find the name of this link.
111 std::map<int, std::string>::const_iterator itname =
112 ifnames.find(it->second.ifa_index);
113 std::string ifname;
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;
118 } else {
119 // Ignore addresses whose interface name can't be retrieved.
120 continue;
122 } else {
123 ifname = itname->second;
126 // Based on the interface name and policy, determine whether we
127 // should ignore it.
128 if (ShouldIgnoreInterface(ifname, policy))
129 continue;
131 networks->push_back(
132 NetworkInterface(ifname, ifname, it->second.ifa_index,
133 NetworkChangeNotifier::CONNECTION_UNKNOWN, it->first,
134 it->second.ifa_prefixlen, ip_attributes));
137 return true;
140 } // namespace internal
142 bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
143 if (networks == NULL)
144 return false;
146 internal::AddressTrackerLinux tracker;
147 tracker.Init();
149 return internal::GetNetworkListImpl(networks, policy,
150 tracker.GetOnlineLinks(),
151 tracker.GetAddressMap(), &if_indextoname);
154 } // namespace net