blob: facc96bfa2fa79f7e77e5dcc3915ad8ef482f5c7 [file] [log] [blame]
Avi Drissman64595482022-09-14 20:52:291// Copyright 2017 The Chromium Authors
Sergey Ulanov2beef3d2017-10-19 21:53:532// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Kevin Marshall3e89fd72018-06-05 21:29:105#include "net/base/network_interfaces_fuchsia.h"
Sergey Ulanov2beef3d2017-10-19 21:53:536
David Songae64e8f4d2023-01-17 21:33:177#include <fuchsia/net/interfaces/cpp/fidl.h>
8#include <zircon/types.h>
Sergey Ulanov2beef3d2017-10-19 21:53:539
Kevin Marshall3e89fd72018-06-05 21:29:1010#include <string>
11#include <utility>
12
David Songae64e8f4d2023-01-17 21:33:1713#include "base/logging.h"
14#include "net/base/fuchsia/network_interface_cache.h"
15#include "net/base/network_change_notifier.h"
16#include "net/base/network_change_notifier_fuchsia.h"
Kevin Marshall3e89fd72018-06-05 21:29:1017#include "net/base/network_interfaces.h"
David Songae64e8f4d2023-01-17 21:33:1718#include "third_party/abseil-cpp/absl/types/optional.h"
Sergey Ulanov2beef3d2017-10-19 21:53:5319
20namespace net {
Kevin Marshall3e89fd72018-06-05 21:29:1021namespace internal {
22namespace {
23
Marina Cioceac05c3e32020-12-03 19:36:5824IPAddress FuchsiaIpAddressToIPAddress(const fuchsia::net::IpAddress& address) {
25 switch (address.Which()) {
26 case fuchsia::net::IpAddress::kIpv4:
27 return IPAddress(address.ipv4().addr.data(), address.ipv4().addr.size());
28 case fuchsia::net::IpAddress::kIpv6:
29 return IPAddress(address.ipv6().addr.data(), address.ipv6().addr.size());
30 default:
31 return IPAddress();
Kevin Marshall3e89fd72018-06-05 21:29:1032 }
Kevin Marshall3e89fd72018-06-05 21:29:1033}
34
35} // namespace
Sergey Ulanov2beef3d2017-10-19 21:53:5336
Marina Cioceac05c3e32020-12-03 19:36:5837// static
Anton Bikineev068d2912021-05-15 20:43:5238absl::optional<InterfaceProperties> InterfaceProperties::VerifyAndCreate(
Marina Cioceac05c3e32020-12-03 19:36:5839 fuchsia::net::interfaces::Properties properties) {
40 if (!internal::VerifyCompleteInterfaceProperties(properties))
Anton Bikineev068d2912021-05-15 20:43:5241 return absl::nullopt;
42 return absl::make_optional(InterfaceProperties(std::move(properties)));
Marina Cioceac05c3e32020-12-03 19:36:5843}
44
45InterfaceProperties::InterfaceProperties(
46 fuchsia::net::interfaces::Properties properties)
47 : properties_(std::move(properties)) {}
48
49InterfaceProperties::InterfaceProperties(InterfaceProperties&& interface) =
50 default;
51
52InterfaceProperties& InterfaceProperties::operator=(
53 InterfaceProperties&& interface) = default;
54
55InterfaceProperties::~InterfaceProperties() = default;
56
57bool InterfaceProperties::Update(
58 fuchsia::net::interfaces::Properties properties) {
59 if (!properties.has_id() || properties_.id() != properties.id()) {
David Songae64e8f4d2023-01-17 21:33:1760 LOG(ERROR) << "Update failed: invalid properties.";
Marina Cioceac05c3e32020-12-03 19:36:5861 return false;
62 }
63
64 if (properties.has_addresses()) {
65 for (const auto& fidl_address : properties.addresses()) {
66 if (!fidl_address.has_addr()) {
David Songae64e8f4d2023-01-17 21:33:1767 LOG(ERROR) << "Update failed: invalid properties.";
Marina Cioceac05c3e32020-12-03 19:36:5868 return false;
69 }
70 }
71 properties_.set_addresses(std::move(*properties.mutable_addresses()));
72 }
73
74 if (properties.has_online())
75 properties_.set_online(properties.online());
76 if (properties.has_has_default_ipv4_route())
77 properties_.set_has_default_ipv4_route(properties.has_default_ipv4_route());
78 if (properties.has_has_default_ipv6_route())
79 properties_.set_has_default_ipv6_route(properties.has_default_ipv6_route());
80
81 return true;
82}
83
84void InterfaceProperties::AppendNetworkInterfaces(
85 NetworkInterfaceList* interfaces) const {
Marina Cioceac05c3e32020-12-03 19:36:5886 for (const auto& fidl_address : properties_.addresses()) {
87 IPAddress address = FuchsiaIpAddressToIPAddress(fidl_address.addr().addr);
88 if (address.empty()) {
89 LOG(WARNING) << "Unknown fuchsia.net/IpAddress variant "
90 << fidl_address.addr().addr.Which();
91 continue;
92 }
93
Marina Cioceac05c3e32020-12-03 19:36:5894 const int kAttributes = 0;
Marina Cioceac05c3e32020-12-03 19:36:5895 interfaces->emplace_back(
Peter Johnston501ae4d62020-12-15 17:22:5396 properties_.name(), properties_.name(), properties_.id(),
Marina Cioceac05c3e32020-12-03 19:36:5897 internal::ConvertConnectionType(properties_.device_class()),
98 std::move(address), fidl_address.addr().prefix_len, kAttributes);
99 }
100}
101
102bool InterfaceProperties::IsPubliclyRoutable() const {
103 if (!properties_.online())
104 return false;
105
106 for (const auto& fidl_address : properties_.addresses()) {
107 const IPAddress address =
108 FuchsiaIpAddressToIPAddress(fidl_address.addr().addr);
109 if ((address.IsIPv4() && properties_.has_default_ipv4_route() &&
110 !address.IsLinkLocal()) ||
111 (address.IsIPv6() && properties_.has_default_ipv6_route() &&
112 address.IsPubliclyRoutable())) {
113 return true;
114 }
115 }
116 return false;
117}
118
Aidan Wolterd89b7542019-01-24 11:01:21119NetworkChangeNotifier::ConnectionType ConvertConnectionType(
Marina Cioceac05c3e32020-12-03 19:36:58120 const fuchsia::net::interfaces::DeviceClass& device_class) {
121 switch (device_class.Which()) {
122 case fuchsia::net::interfaces::DeviceClass::kLoopback:
123 return NetworkChangeNotifier::CONNECTION_NONE;
124 case fuchsia::net::interfaces::DeviceClass::kDevice:
125 switch (device_class.device()) {
126 case fuchsia::hardware::network::DeviceClass::WLAN:
127 return NetworkChangeNotifier::CONNECTION_WIFI;
128 case fuchsia::hardware::network::DeviceClass::ETHERNET:
129 return NetworkChangeNotifier::CONNECTION_ETHERNET;
130 default:
131 return NetworkChangeNotifier::CONNECTION_UNKNOWN;
132 }
133 default:
134 LOG(WARNING) << "Received unknown fuchsia.net.interfaces/DeviceClass "
135 << device_class.Which();
136 return NetworkChangeNotifier::CONNECTION_UNKNOWN;
Aidan Wolterd89b7542019-01-24 11:01:21137 }
Aidan Wolterd89b7542019-01-24 11:01:21138}
139
Marina Cioceac05c3e32020-12-03 19:36:58140bool VerifyCompleteInterfaceProperties(
141 const fuchsia::net::interfaces::Properties& properties) {
142 if (!properties.has_id())
143 return false;
144 if (!properties.has_addresses())
145 return false;
146 for (const auto& fidl_address : properties.addresses()) {
147 if (!fidl_address.has_addr())
148 return false;
Kevin Marshall3e89fd72018-06-05 21:29:10149 }
Marina Cioceac05c3e32020-12-03 19:36:58150 if (!properties.has_online())
151 return false;
152 if (!properties.has_device_class())
153 return false;
154 if (!properties.has_has_default_ipv4_route())
155 return false;
156 if (!properties.has_has_default_ipv6_route())
157 return false;
David Songae64e8f4d2023-01-17 21:33:17158 if (!properties.has_name()) {
159 return false;
Stephen Roeb9b97022020-11-20 03:57:23160 }
David Songae64e8f4d2023-01-17 21:33:17161 return true;
Kevin Marshall3e89fd72018-06-05 21:29:10162}
163
164} // namespace internal
165
Sergey Ulanov2beef3d2017-10-19 21:53:53166bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
Kevin Marshall3e89fd72018-06-05 21:29:10167 DCHECK(networks);
Sergey Ulanovf7b22142018-05-01 00:58:32168
David Songae64e8f4d2023-01-17 21:33:17169 const internal::NetworkInterfaceCache* cache_ptr =
170 NetworkChangeNotifier::GetNetworkInterfaceCache();
171 if (cache_ptr) {
172 return cache_ptr->GetOnlineInterfaces(networks);
Stephen Roeb9b97022020-11-20 03:57:23173 }
David Songae64e8f4d2023-01-17 21:33:17174
175 fuchsia::net::interfaces::WatcherHandle watcher_handle =
176 internal::ConnectInterfacesWatcher();
177 std::vector<fuchsia::net::interfaces::Properties> interfaces;
178
179 auto handle_or_status = internal::ReadExistingNetworkInterfacesFromNewWatcher(
180 std::move(watcher_handle), interfaces);
181 if (!handle_or_status.has_value()) {
182 return false;
183 }
184
185 internal::NetworkInterfaceCache temp_cache(/*require_wlan=*/false);
186 auto change_bits = temp_cache.AddInterfaces(std::move(interfaces));
187 if (!change_bits.has_value()) {
188 return false;
189 }
190
191 return temp_cache.GetOnlineInterfaces(networks);
Sergey Ulanov2beef3d2017-10-19 21:53:53192}
193
194std::string GetWifiSSID() {
195 NOTIMPLEMENTED();
196 return std::string();
197}
198
199} // namespace net