1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "network.h"
17 #include "netsys_controller.h"
18 #include "net_mgr_log_wrapper.h"
19 #include "securec.h"
20
21 namespace OHOS {
22 namespace NetManagerStandard {
Network(int32_t netId,uint32_t supplierId,NetDetectionHandler handler)23 Network::Network(int32_t netId, uint32_t supplierId, NetDetectionHandler handler)
24 : netId_(netId), supplierId_(supplierId), netCallback_(handler)
25 {
26 StartDetectionThread();
27 }
28
~Network()29 Network::~Network()
30 {
31 if (!ReleaseBasicNetwork()) {
32 NETMGR_LOG_E("ReleaseBasicNetwork fail.");
33 }
34 if (netMonitor_ != nullptr) {
35 netMonitor_->StopNetMonitorThread();
36 }
37 }
38
GetNetId() const39 int32_t Network::GetNetId() const
40 {
41 return netId_;
42 }
43
operator ==(const Network & network) const44 bool Network::operator == (const Network &network) const
45 {
46 return netId_ == network.netId_;
47 }
48
UpdateBasicNetwork(bool isAvailable_)49 bool Network::UpdateBasicNetwork(bool isAvailable_)
50 {
51 NETMGR_LOG_D("Enter UpdateBasicNetwork");
52 if (isAvailable_) {
53 return CreateBasicNetwork();
54 } else {
55 return ReleaseBasicNetwork();
56 }
57 }
58
CreateBasicNetwork()59 bool Network::CreateBasicNetwork()
60 {
61 NETMGR_LOG_D("Enter CreateBasicNetwork");
62 if (!isPhyNetCreated_) {
63 NETMGR_LOG_D("Create physical network");
64 // Create a physical network
65 NetsysController::GetInstance().NetworkCreatePhysical(netId_, 0);
66 NetsysController::GetInstance().CreateNetworkCache(netId_);
67 isPhyNetCreated_ = true;
68 }
69 return true;
70 }
71
ReleaseBasicNetwork()72 bool Network::ReleaseBasicNetwork()
73 {
74 NETMGR_LOG_D("Enter ReleaseBasicNetwork");
75 if (isPhyNetCreated_) {
76 NETMGR_LOG_D("Destroy physical network");
77 StopNetDetection();
78 for (auto it = netLinkInfo_.netAddrList_.begin(); it != netLinkInfo_.netAddrList_.end(); ++it) {
79 const struct INetAddr &inetAddr = *it;
80 int32_t prefixLen = inetAddr.prefixlen_;
81 if (prefixLen == 0) {
82 prefixLen = Ipv4PrefixLen(inetAddr.netMask_);
83 }
84 NetsysController::GetInstance().InterfaceDelAddress(netLinkInfo_.ifaceName_, inetAddr.address_, prefixLen);
85 }
86 NetsysController::GetInstance().NetworkRemoveInterface(netId_, netLinkInfo_.ifaceName_);
87 NetsysController::GetInstance().NetworkDestroy(netId_);
88 NetsysController::GetInstance().DestroyNetworkCache(netId_);
89 netLinkInfo_.Initialize();
90 isPhyNetCreated_ = false;
91 }
92 return true;
93 }
94
UpdateNetLinkInfo(const NetLinkInfo & netLinkInfo)95 bool Network::UpdateNetLinkInfo(const NetLinkInfo &netLinkInfo)
96 {
97 NETMGR_LOG_D("update net link information process");
98 UpdateInterfaces(netLinkInfo);
99 UpdateIpAddrs(netLinkInfo);
100 UpdateRoutes(netLinkInfo);
101 UpdateDnses(netLinkInfo);
102 UpdateMtu(netLinkInfo);
103 netLinkInfo_ = netLinkInfo;
104 StartNetDetection();
105 return true;
106 }
107
GetNetLinkInfo() const108 NetLinkInfo Network::GetNetLinkInfo() const
109 {
110 return netLinkInfo_;
111 }
112
UpdateInterfaces(const NetLinkInfo & netLinkInfo)113 void Network::UpdateInterfaces(const NetLinkInfo &netLinkInfo)
114 {
115 NETMGR_LOG_D("Network UpdateInterfaces in.");
116 if (netLinkInfo.ifaceName_ == netLinkInfo_.ifaceName_) {
117 NETMGR_LOG_D("Network UpdateInterfaces out. same with before.");
118 return;
119 }
120
121 // Call netsys to add and remove interface
122 if (!netLinkInfo.ifaceName_.empty()) {
123 NetsysController::GetInstance().NetworkAddInterface(netId_, netLinkInfo.ifaceName_);
124 }
125 if (!netLinkInfo_.ifaceName_.empty()) {
126 NetsysController::GetInstance().NetworkRemoveInterface(netId_, netLinkInfo_.ifaceName_);
127 }
128 netLinkInfo_.ifaceName_ = netLinkInfo.ifaceName_;
129 NETMGR_LOG_D("Network UpdateInterfaces out.");
130 }
131
Ipv4PrefixLen(const std::string & ip)132 int32_t Network::Ipv4PrefixLen(const std::string &ip)
133 {
134 constexpr int32_t BIT32 = 32;
135 constexpr int32_t BIT24 = 24;
136 constexpr int32_t BIT16 = 16;
137 constexpr int32_t BIT8 = 8;
138 if (ip.empty()) {
139 return 0;
140 }
141 int32_t ret = 0;
142 uint32_t ipNum = 0;
143 uint8_t c1 = 0;
144 uint8_t c2 = 0;
145 uint8_t c3 = 0;
146 uint8_t c4 = 0;
147 int32_t cnt = 0;
148 ret = sscanf_s(ip.c_str(), "%hhu.%hhu.%hhu.%hhu", &c1, &c2, &c3, &c4);
149 if (ret != sizeof(int32_t)) {
150 return 0;
151 }
152 ipNum = (c1 << static_cast<uint32_t>(BIT24)) | (c2 << static_cast<uint32_t>(BIT16)) |
153 (c3 << static_cast<uint32_t>(BIT8)) | c4;
154 if (ipNum == 0xFFFFFFFF) {
155 return BIT32;
156 }
157 if (ipNum == 0xFFFFFF00) {
158 return BIT24;
159 }
160 if (ipNum == 0xFFFF0000) {
161 return BIT16;
162 }
163 if (ipNum == 0xFF000000) {
164 return BIT8;
165 }
166 for (int32_t i = 0; i < BIT32; i++) {
167 if ((ipNum << i) & 0x80000000) {
168 cnt++;
169 } else {
170 break;
171 }
172 }
173 return cnt;
174 }
175
UpdateIpAddrs(const NetLinkInfo & netLinkInfo)176 void Network::UpdateIpAddrs(const NetLinkInfo &netLinkInfo)
177 {
178 // netLinkInfo_ represents the old, netLinkInfo represents the new
179 // Update: remove old Ips first, then add the new Ips
180 NETMGR_LOG_D("UpdateIpAddrs, old ip addrs: ...");
181 for (auto it = netLinkInfo_.netAddrList_.begin(); it != netLinkInfo_.netAddrList_.end(); ++it) {
182 const struct INetAddr &inetAddr = *it;
183 int32_t prefixLen = inetAddr.prefixlen_;
184 if (prefixLen == 0) {
185 prefixLen = Ipv4PrefixLen(inetAddr.netMask_);
186 }
187 NetsysController::GetInstance().InterfaceDelAddress(netLinkInfo_.ifaceName_, inetAddr.address_, prefixLen);
188 }
189
190 NETMGR_LOG_D("UpdateIpAddrs, new ip addrs: ...");
191 for (auto it = netLinkInfo.netAddrList_.begin(); it != netLinkInfo.netAddrList_.end(); ++it) {
192 const struct INetAddr &inetAddr = *it;
193 int32_t prefixLen = inetAddr.prefixlen_;
194 if (prefixLen == 0) {
195 prefixLen = Ipv4PrefixLen(inetAddr.netMask_);
196 }
197 NetsysController::GetInstance().InterfaceAddAddress(netLinkInfo.ifaceName_, inetAddr.address_, prefixLen);
198 }
199 NETMGR_LOG_D("Network UpdateIpAddrs out.");
200 }
201
UpdateRoutes(const NetLinkInfo & netLinkInfo)202 void Network::UpdateRoutes(const NetLinkInfo &netLinkInfo)
203 {
204 // netLinkInfo_ contains the old routes info, netLinkInfo contains the new routes info
205 // Update: remove old routes first, then add the new routes
206 NETMGR_LOG_D("UpdateRoutes");
207 for (auto it = netLinkInfo_.routeList_.begin(); it != netLinkInfo_.routeList_.end(); ++it) {
208 const struct Route &route = *it;
209 std::string destAddress = route.destination_.address_ + "/" + std::to_string(route.destination_.prefixlen_);
210 NetsysController::GetInstance().NetworkRemoveRoute(netId_, route.iface_, destAddress, route.gateway_.address_);
211 }
212
213 NETMGR_LOG_D("UpdateRoutes");
214 for (auto it = netLinkInfo.routeList_.begin(); it != netLinkInfo.routeList_.end(); ++it) {
215 const struct Route &route = *it;
216 std::string destAddress = route.destination_.address_ + "/" + std::to_string(route.destination_.prefixlen_);
217 NetsysController::GetInstance().NetworkAddRoute(netId_, route.iface_, destAddress, route.gateway_.address_);
218 }
219 NETMGR_LOG_D("Network UpdateRoutes out.");
220 }
221
UpdateDnses(const NetLinkInfo & netLinkInfo)222 void Network::UpdateDnses(const NetLinkInfo &netLinkInfo)
223 {
224 NETMGR_LOG_D("Network UpdateDnses in.");
225 std::vector<std::string> servers;
226 std::vector<std::string> doamains;
227 for (auto it = netLinkInfo.dnsList_.begin(); it != netLinkInfo.dnsList_.end(); ++it) {
228 auto dns = *it;
229 servers.push_back(dns.address_);
230 doamains.push_back(dns.hostName_);
231 }
232 // Call netsys to set dns
233 NetsysController::GetInstance().SetResolverConfig(netId_, 0, 1, servers, doamains);
234 NETMGR_LOG_D("Network UpdateDnses out.");
235 }
236
UpdateMtu(const NetLinkInfo & netLinkInfo)237 void Network::UpdateMtu(const NetLinkInfo &netLinkInfo)
238 {
239 NETMGR_LOG_D("Network UpdateMtu in.");
240 if (netLinkInfo.mtu_ == netLinkInfo_.mtu_) {
241 NETMGR_LOG_D("Network UpdateMtu out. same with before.");
242 return;
243 }
244
245 NetsysController::GetInstance().InterfaceSetMtu(netLinkInfo.ifaceName_, netLinkInfo.mtu_);
246 NETMGR_LOG_D("Network UpdateMtu out.");
247 }
248
RegisterNetDetectionCallback(const sptr<INetDetectionCallback> & callback)249 void Network::RegisterNetDetectionCallback(const sptr<INetDetectionCallback> &callback)
250 {
251 NETMGR_LOG_D("Enter RegisterNetDetectionCallback");
252 if (callback == nullptr) {
253 NETMGR_LOG_E("The parameter callback is null");
254 return;
255 }
256
257 for (auto iter = netDetectionRetCallback_.begin(); iter != netDetectionRetCallback_.end(); ++iter) {
258 if (callback->AsObject().GetRefPtr() == (*iter)->AsObject().GetRefPtr()) {
259 NETMGR_LOG_D("netDetectionRetCallback_ had this callback");
260 return;
261 }
262 }
263
264 netDetectionRetCallback_.emplace_back(callback);
265 }
266
UnRegisterNetDetectionCallback(const sptr<INetDetectionCallback> & callback)267 int32_t Network::UnRegisterNetDetectionCallback(const sptr<INetDetectionCallback> &callback)
268 {
269 NETMGR_LOG_D("Enter UnRegisterNetDetectionCallback");
270 if (callback == nullptr) {
271 NETMGR_LOG_E("The parameter of callback is null");
272 return ERR_SERVICE_NULL_PTR;
273 }
274
275 for (auto iter = netDetectionRetCallback_.begin(); iter != netDetectionRetCallback_.end(); ++iter) {
276 if (callback->AsObject().GetRefPtr() == (*iter)->AsObject().GetRefPtr()) {
277 netDetectionRetCallback_.erase(iter);
278 break;
279 }
280 }
281
282 return ERR_NONE;
283 }
284
StartNetDetection()285 void Network::StartNetDetection()
286 {
287 NETMGR_LOG_D("Enter Network::StartNetDetection");
288 if (netMonitor_ != nullptr) {
289 netMonitor_->SignalNetMonitorThread(netLinkInfo_.ifaceName_);
290 }
291 }
292
StopNetDetection()293 void Network::StopNetDetection()
294 {
295 NETMGR_LOG_D("Enter Network::StopNetDetection");
296 if (netMonitor_ != nullptr) {
297 netMonitor_->StopNetMonitorThread();
298 }
299 }
300
SetExternDetection()301 void Network::SetExternDetection()
302 {
303 isExternDetection_ = true;
304 }
305
StartDetectionThread()306 void Network::StartDetectionThread()
307 {
308 netDetectionState_ = INVALID_DETECTION_STATE;
309 netMonitor_ = std::make_unique<NetMonitor>(
310 std::bind(&Network::HandleNetMonitorResult, this, std::placeholders::_1, std::placeholders::_2));
311 if (netMonitor_ == nullptr) {
312 NETMGR_LOG_E("make_unique NetMonitor failed,netMonitor_ is null!");
313 return;
314 }
315 netMonitor_->InitNetMonitorThread();
316 }
317
GetNetWorkMonitorResult()318 uint64_t Network::GetNetWorkMonitorResult()
319 {
320 return netDetectionState_;
321 }
322
HandleNetMonitorResult(NetDetectionStatus netDetectionState,const std::string & urlRedirect)323 void Network::HandleNetMonitorResult(NetDetectionStatus netDetectionState, const std::string &urlRedirect)
324 {
325 NETMGR_LOG_D("HandleNetMonitorResult, oldState[%{public}d], newState[%{public}d], isExternDetection[%{public}d]",
326 netDetectionState_, netDetectionState, isExternDetection_);
327 bool needReport = false;
328 if (netDetectionState_ != netDetectionState || isExternDetection_) {
329 needReport = true;
330 isExternDetection_ = false;
331 }
332 if (needReport) {
333 NETMGR_LOG_D("need to report net detection result.");
334 NotifyNetDetectionResult(NetDetectionResultConvert(static_cast<int32_t>(netDetectionState)), urlRedirect);
335 if (netCallback_) {
336 netCallback_(supplierId_, netDetectionState == VERIFICATION_STATE);
337 }
338 }
339 netDetectionState_ = netDetectionState;
340 urlRedirect_ = urlRedirect;
341 NETMGR_LOG_D("HandleNetMonitorResult out.");
342 }
343
NotifyNetDetectionResult(NetDetectionResultCode detectionResult,const std::string & urlRedirect)344 void Network::NotifyNetDetectionResult(NetDetectionResultCode detectionResult, const std::string &urlRedirect)
345 {
346 for (auto callback : netDetectionRetCallback_) {
347 NETMGR_LOG_D("start callback!");
348 callback->OnNetDetectionResultChanged(detectionResult, urlRedirect);
349 }
350 }
351
NetDetectionResultConvert(int32_t internalRet)352 NetDetectionResultCode Network::NetDetectionResultConvert(int32_t internalRet)
353 {
354 switch (internalRet) {
355 case static_cast<int32_t>(INVALID_DETECTION_STATE):
356 return NET_DETECTION_FAIL;
357 case static_cast<int32_t>(VERIFICATION_STATE):
358 return NET_DETECTION_SUCCESS;
359 case static_cast<int32_t>(CAPTIVE_PORTAL_STATE):
360 return NET_DETECTION_CAPTIVE_PORTAL;
361 default:
362 break;
363 }
364 return NET_DETECTION_FAIL;
365 }
366
SetDefaultNetWork()367 void Network::SetDefaultNetWork()
368 {
369 NetsysController::GetInstance().SetDefaultNetWork(netId_);
370 }
371
ClearDefaultNetWorkNetId()372 void Network::ClearDefaultNetWorkNetId()
373 {
374 NetsysController::GetInstance().ClearDefaultNetWorkNetId();
375 }
376 } // namespace NetManagerStandard
377 } // namespace OHOS
378