• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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 "sharing_manager.h"
17 
18 #include <cerrno>
19 #include <fcntl.h>
20 #include <regex>
21 #include <unistd.h>
22 #include <charconv>
23 
24 #include "net_manager_constants.h"
25 #include "netmanager_base_common_utils.h"
26 #include "netnative_log_wrapper.h"
27 #include "route_manager.h"
28 
29 namespace OHOS {
30 namespace nmd {
31 using namespace NetManagerStandard;
32 namespace {
33 constexpr const char *IPV4_FORWARDING_PROC_FILE = "/proc/sys/net/ipv4/ip_forward";
34 constexpr const char *IPV6_FORWARDING_PROC_FILE = "/proc/sys/net/ipv6/conf/all/forwarding";
35 constexpr const char *IPTABLES_TMP_BAK = "/data/service/el1/public/netmanager/ipfwd.bak";
36 constexpr const char *IPV6_PROC_PATH = "/proc/sys/net/ipv6/conf/";
37 constexpr const char *IP6TABLES_TMP_BAK = "/data/service/el1/public/netmanager/ip6fwd.bak";
38 constexpr const int MAX_MATCH_SIZE = 4;
39 constexpr const int TWO_LIST_CORRECT_DATA = 2;
40 constexpr const int NEXT_LIST_CORRECT_DATA = 1;
41 constexpr uint32_t NET_TRAFFIC_RESULT_INDEX_OFFSET = 2;
42 const std::string CELLULAR_IFACE_NAME = "rmnet";
43 const std::string WLAN_IFACE_NAME = "wlan";
44 
45 // commands of create tables
46 constexpr const char *CREATE_TETHERCTRL_NAT_POSTROUTING = "-t nat -N tetherctrl_nat_POSTROUTING";
47 constexpr const char *CREATE_TETHERCTRL_FORWARD = "-t filter -N tetherctrl_FORWARD";
48 constexpr const char *CREATE_TETHERCTRL_COUNTERS = "-t filter -N tetherctrl_counters";
49 constexpr const char *CREATE_TETHERCTRL_MANGLE_FORWARD = "-t mangle -N tetherctrl_mangle_FORWARD";
50 constexpr const char *OPEN_IPV6_PRIVACY_EXTENSIONS = "2";
51 constexpr const char *CLOSE_IPV6_PRIVACY_EXTENSIONS = "0";
52 constexpr const char *ENABLE_IPV6_VALUE = "0";
53 constexpr const char *DISABLE_IPV6_VALUE = "1";
54 
55 // commands of set nat
56 constexpr const char *APPEND_NAT_POSTROUTING = "-t nat -A POSTROUTING -j tetherctrl_nat_POSTROUTING";
57 constexpr const char *APPEND_MANGLE_FORWARD = "-t mangle -A FORWARD -j tetherctrl_mangle_FORWARD";
58 constexpr const char *APPEND_TETHERCTRL_MANGLE_FORWARD =
59     "-t mangle -A tetherctrl_mangle_FORWARD "
60     "-p tcp -m tcp --tcp-flags SYN SYN -j TCPMSS --clamp-mss-to-pmtu";
61 constexpr const char *CLEAR_TETHERCTRL_NAT_POSTROUTING = "-t nat -F tetherctrl_nat_POSTROUTING";
62 constexpr const char *CLEAR_TETHERCTRL_MANGLE_FORWARD = "-t mangle -F tetherctrl_mangle_FORWARD";
63 constexpr const char *DELETE_TETHERCTRL_NAT_POSTROUTING = "-t nat -D POSTROUTING -j tetherctrl_nat_POSTROUTING";
64 constexpr const char *DELETE_TETHERCTRL_MANGLE_FORWARD = "-t mangle -D FORWARD -j tetherctrl_mangle_FORWARD";
65 
66 constexpr const char *IPATBLES_RESTORE_CMD_PATH = "/system/bin/iptables-restore";
67 constexpr const char *IPATBLES_SAVE_CMD_PATH = "/system/bin/iptables-save";
68 
69 constexpr const char *IP6ATBLES_RESTORE_CMD_PATH = "/system/bin/ip6tables-restore";
70 constexpr const char *IP6ATBLES_SAVE_CMD_PATH = "/system/bin/ip6tables-save";
71 
EnableNatCmd(const std::string & down)72 const std::string EnableNatCmd(const std::string &down)
73 {
74     return "-t nat -A tetherctrl_nat_POSTROUTING -o " + down + " -j MASQUERADE";
75 }
76 
77 // commands of set ipfwd, all commands with filter
78 constexpr const char *FORWARD_JUMP_TETHERCTRL_FORWARD = " FORWARD -j tetherctrl_FORWARD";
79 constexpr const char *SET_TETHERCTRL_FORWARD_DROP = " tetherctrl_FORWARD -j DROP";
SetTetherctrlForward1(const std::string & from,const std::string & to)80 const std::string SetTetherctrlForward1(const std::string &from, const std::string &to)
81 {
82     return " tetherctrl_FORWARD -i " + from + " -o " + to +
83            " -m state --state RELATED,ESTABLISHED"
84            " -g tetherctrl_counters";
85 }
86 
SetTetherctrlForward2(const std::string & from,const std::string & to)87 const std::string SetTetherctrlForward2(const std::string &from, const std::string &to)
88 {
89     return " tetherctrl_FORWARD -i " + to + " -o " + from + " -m state --state INVALID -j DROP";
90 }
91 
SetTetherctrlForward3(const std::string & from,const std::string & to)92 const std::string SetTetherctrlForward3(const std::string &from, const std::string &to)
93 {
94     return " tetherctrl_FORWARD -i " + to + " -o " + from + " -g tetherctrl_counters";
95 }
96 
SetTetherctrlCounters1(const std::string & from,const std::string & to)97 const std::string SetTetherctrlCounters1(const std::string &from, const std::string &to)
98 {
99     return " tetherctrl_counters -i " + to + " -o " + from + " -j RETURN";
100 }
101 
SetTetherctrlCounters2(const std::string & from,const std::string & to)102 const std::string SetTetherctrlCounters2(const std::string &from, const std::string &to)
103 {
104     return " tetherctrl_counters -i " + from + " -o " + to + " -j RETURN";
105 }
106 
WriteToFile(const char * fileName,const char * value)107 bool WriteToFile(const char *fileName, const char *value)
108 {
109     if (fileName == nullptr) {
110         return false;
111     }
112     int fd = open(fileName, O_WRONLY | O_CLOEXEC);
113     if (fd < 0) {
114         NETNATIVE_LOGE("failed to open file: %{public}s", strerror(errno));
115         return false;
116     }
117 
118     const ssize_t len = strlen(value);
119     if (write(fd, value, len) != len) {
120         NETNATIVE_LOGE("faield to write %{public}s: %{public}s", value, strerror(errno));
121         close(fd);
122         return false;
123     }
124 
125     close(fd);
126     return true;
127 }
128 
Rollback()129 void Rollback()
130 {
131     NETNATIVE_LOGE("iptables rollback");
132     std::string rollBak = std::string(IPATBLES_RESTORE_CMD_PATH) + " -T filter < ";
133     rollBak.append(IPTABLES_TMP_BAK);
134     CommonUtils::ForkExec(rollBak);
135 
136     rollBak = std::string(IP6ATBLES_RESTORE_CMD_PATH) + " -T filter < ";
137     rollBak.append(IP6TABLES_TMP_BAK);
138     CommonUtils::ForkExec(rollBak);
139 }
140 } // namespace
141 
SharingManager()142 SharingManager::SharingManager()
143 {
144     iptablesWrapper_ = IptablesWrapper::GetInstance();
145 }
146 
InitChildChains()147 void SharingManager::InitChildChains()
148 {
149     iptablesWrapper_->RunCommand(IPTYPE_IPV4V6, CREATE_TETHERCTRL_NAT_POSTROUTING);
150     iptablesWrapper_->RunCommand(IPTYPE_IPV4V6, CREATE_TETHERCTRL_FORWARD);
151     iptablesWrapper_->RunCommand(IPTYPE_IPV4V6, CREATE_TETHERCTRL_COUNTERS);
152     iptablesWrapper_->RunCommand(IPTYPE_IPV4V6, CREATE_TETHERCTRL_MANGLE_FORWARD);
153     inited_ = true;
154 }
155 
IpEnableForwarding(const std::string & requestor)156 int32_t SharingManager::IpEnableForwarding(const std::string &requestor)
157 {
158     NETNATIVE_LOG_D("IpEnableForwarding requestor: %{public}s", requestor.c_str());
159     {
160         std::lock_guard<std::mutex> guard(initedMutex_);
161         forwardingRequests_.insert(requestor);
162     }
163     return SetIpFwdEnable();
164 }
165 
IpDisableForwarding(const std::string & requestor)166 int32_t SharingManager::IpDisableForwarding(const std::string &requestor)
167 {
168     NETNATIVE_LOG_D("IpDisableForwarding requestor: %{public}s", requestor.c_str());
169     {
170         std::lock_guard<std::mutex> guard(initedMutex_);
171         forwardingRequests_.erase(requestor);
172     }
173     return SetIpFwdEnable();
174 }
175 
EnableNat(const std::string & downstreamIface,const std::string & upstreamIface)176 int32_t SharingManager::EnableNat(const std::string &downstreamIface, const std::string &upstreamIface)
177 {
178     DisableNat(downstreamIface, upstreamIface);
179     CheckInited();
180     if (downstreamIface == upstreamIface) {
181         NETNATIVE_LOGE("Duplicate interface specified: %{public}s %{public}s", downstreamIface.c_str(),
182                        upstreamIface.c_str());
183         return -1;
184     }
185     if (!CommonUtils::CheckIfaceName(upstreamIface)) {
186         NETNATIVE_LOGE("iface name valid check fail: %{public}s", upstreamIface.c_str());
187         return -1;
188     }
189     iptablesWrapper_->RunCommand(IPTYPE_IPV4V6, APPEND_NAT_POSTROUTING);
190     iptablesWrapper_->RunCommand(IPTYPE_IPV4V6, APPEND_MANGLE_FORWARD);
191 
192     NETNATIVE_LOGI("EnableNat downstreamIface: %{public}s, upstreamIface: %{public}s", downstreamIface.c_str(),
193                    upstreamIface.c_str());
194 
195     if (iptablesWrapper_->RunCommand(IPTYPE_IPV4V6, EnableNatCmd(upstreamIface)) !=
196         NetManagerStandard::NETMANAGER_SUCCESS) {
197         NETNATIVE_LOGE("IptablesWrapper run command failed");
198         return -1;
199     }
200 
201     if (iptablesWrapper_->RunCommand(IPTYPE_IPV4V6, APPEND_TETHERCTRL_MANGLE_FORWARD) !=
202         NetManagerStandard::NETMANAGER_SUCCESS) {
203         NETNATIVE_LOGE("IptablesWrapper run command failed");
204         return -1;
205     }
206     return 0;
207 }
208 
DisableNat(const std::string & downstreamIface,const std::string & upstreamIface)209 int32_t SharingManager::DisableNat(const std::string &downstreamIface, const std::string &upstreamIface)
210 {
211     CheckInited();
212     if (downstreamIface == upstreamIface) {
213         NETNATIVE_LOGE("Duplicate interface specified: %{public}s %s", downstreamIface.c_str(), upstreamIface.c_str());
214         return -1;
215     }
216     if (!CommonUtils::CheckIfaceName(upstreamIface)) {
217         NETNATIVE_LOGE("iface name valid check fail: %{public}s", upstreamIface.c_str());
218         return -1;
219     }
220 
221     NETNATIVE_LOGI("DisableNat downstreamIface: %{public}s, upstreamIface: %{public}s", downstreamIface.c_str(),
222                    upstreamIface.c_str());
223 
224     if (iptablesWrapper_->RunCommand(IPTYPE_IPV4V6, CLEAR_TETHERCTRL_NAT_POSTROUTING) !=
225         NetManagerStandard::NETMANAGER_SUCCESS) {
226         NETNATIVE_LOGE("IptablesWrapper run command failed");
227         return -1;
228     }
229     if (iptablesWrapper_->RunCommand(IPTYPE_IPV4V6, CLEAR_TETHERCTRL_MANGLE_FORWARD) !=
230         NetManagerStandard::NETMANAGER_SUCCESS) {
231         NETNATIVE_LOGE("IptablesWrapper run command failed");
232         return -1;
233     }
234 
235     iptablesWrapper_->RunCommand(IPTYPE_IPV4V6, DELETE_TETHERCTRL_NAT_POSTROUTING);
236     iptablesWrapper_->RunCommand(IPTYPE_IPV4V6, DELETE_TETHERCTRL_MANGLE_FORWARD);
237     return 0;
238 }
SetIpv6PrivacyExtensions(const std::string & interfaceName,const uint32_t on)239 int32_t SharingManager::SetIpv6PrivacyExtensions(const std::string &interfaceName, const uint32_t on)
240 {
241     std::string option = IPV6_PROC_PATH + interfaceName + "/use_tempaddr";
242     const char *value = on ? OPEN_IPV6_PRIVACY_EXTENSIONS : CLOSE_IPV6_PRIVACY_EXTENSIONS;
243     bool ipv6Success = WriteToFile(option.c_str(), value);
244     return ipv6Success ? 0 : -1;
245 }
246 
SetEnableIpv6(const std::string & interfaceName,const uint32_t on)247 int32_t SharingManager::SetEnableIpv6(const std::string &interfaceName, const uint32_t on)
248 {
249     std::string option = IPV6_PROC_PATH + interfaceName + "/disable_ipv6";
250     const char *value = on ? ENABLE_IPV6_VALUE : DISABLE_IPV6_VALUE;
251     bool ipv6Success = WriteToFile(option.c_str(), value);
252     return ipv6Success ? 0 : -1;
253 }
254 
SetIpFwdEnable()255 int32_t SharingManager::SetIpFwdEnable()
256 {
257     bool disable = forwardingRequests_.empty();
258     const char *value = disable ? "0" : "1";
259     bool ipv4Success = WriteToFile(IPV4_FORWARDING_PROC_FILE, value);
260     bool ipv6Success = WriteToFile(IPV6_FORWARDING_PROC_FILE, value);
261     return (ipv4Success && ipv6Success) ? 0 : -1;
262 }
263 
IpfwdExecSaveBak()264 void SharingManager::IpfwdExecSaveBak()
265 {
266     std::string saveBak = std::string(IPATBLES_SAVE_CMD_PATH) + " -t filter > ";
267     saveBak.append(IPTABLES_TMP_BAK);
268     CommonUtils::ForkExec(saveBak);
269     saveBak = std::string(IP6ATBLES_SAVE_CMD_PATH) + " -t filter > ";
270     saveBak.append(IP6TABLES_TMP_BAK);
271     CommonUtils::ForkExec(saveBak);
272 }
273 
IpfwdAddInterfaceForward(const std::string & fromIface,const std::string & toIface)274 int32_t SharingManager::IpfwdAddInterfaceForward(const std::string &fromIface, const std::string &toIface)
275 {
276     CheckInited();
277     if (fromIface == toIface) {
278         NETNATIVE_LOGE("Duplicate interface specified: %{public}s %{public}s", fromIface.c_str(), toIface.c_str());
279         return -1;
280     }
281     if (!(CommonUtils::CheckIfaceName(fromIface)) || !(CommonUtils::CheckIfaceName(toIface))) {
282         NETNATIVE_LOGE("iface name valid check fail: %{public}s %{public}s", fromIface.c_str(), toIface.c_str());
283         return -1;
284     }
285     NETNATIVE_LOGI("IpfwdAddInterfaceForward fromIface: %{public}s, toIface: %{public}s", fromIface.c_str(),
286                    toIface.c_str());
287     if (interfaceForwards_.empty()) {
288         SetForwardRules(true, FORWARD_JUMP_TETHERCTRL_FORWARD);
289     }
290 
291     IpfwdExecSaveBak();
292     int32_t result = 0;
293 
294     /*
295      * Add a forward rule, when the status of packets is RELATED,
296      * ESTABLISED and from fromIface to toIface, goto tetherctrl_counters
297      */
298     if (SetForwardRules(true, SetTetherctrlForward1(toIface, fromIface))) {
299         return result;
300     }
301 
302     /*
303      * Add a forward rule, when the status is INVALID and from toIface to fromIface, just drop
304      */
305     if (SetForwardRules(true, SetTetherctrlForward2(toIface, fromIface))) {
306         Rollback();
307         return result;
308     }
309 
310     /*
311      * Add a forward rule, from toIface to fromIface, goto tetherctrl_counters
312      */
313     if (SetForwardRules(true, SetTetherctrlForward3(toIface, fromIface))) {
314         Rollback();
315         return result;
316     }
317 
318     SetForwardRules(false, SET_TETHERCTRL_FORWARD_DROP);
319 
320     /*
321      * Add a forward rule, drop others
322      */
323     if (SetForwardRules(true, SET_TETHERCTRL_FORWARD_DROP)) {
324         Rollback();
325         return result;
326     }
327 
328     /*
329      * Add a forward rule, if from toIface to fromIface return chain of father
330      */
331     if (SetForwardRules(true, SetTetherctrlCounters1(fromIface, toIface))) {
332         Rollback();
333         return result;
334     }
335 
336     /*
337      * Add a forward rule, if from fromIface to toIface return chain of father
338      */
339     if (SetForwardRules(true, SetTetherctrlCounters2(fromIface, toIface))) {
340         Rollback();
341         return result;
342     }
343 
344     if (RouteManager::EnableSharing(fromIface, toIface)) {
345         Rollback();
346         return result;
347     }
348     interfaceForwards_.insert(fromIface + toIface);
349     return 0;
350 }
351 
IpfwdRemoveInterfaceForward(const std::string & fromIface,const std::string & toIface)352 int32_t SharingManager::IpfwdRemoveInterfaceForward(const std::string &fromIface, const std::string &toIface)
353 {
354     CheckInited();
355     if (fromIface == toIface) {
356         NETNATIVE_LOGE("Duplicate interface specified: %{public}s %{public}s", fromIface.c_str(), toIface.c_str());
357         return -1;
358     }
359     if (!(CommonUtils::CheckIfaceName(fromIface)) || !(CommonUtils::CheckIfaceName(toIface))) {
360         NETNATIVE_LOGE("iface name valid check fail: %{public}s %{public}s", fromIface.c_str(), toIface.c_str());
361         return -1;
362     }
363     NETNATIVE_LOGI("IpfwdRemoveInterfaceForward fromIface: %{public}s, toIface: %{public}s", fromIface.c_str(),
364                    toIface.c_str());
365 
366     SetForwardRules(false, SetTetherctrlForward1(toIface, fromIface));
367     SetForwardRules(false, SetTetherctrlForward2(toIface, fromIface));
368     SetForwardRules(false, SetTetherctrlForward3(toIface, fromIface));
369     SetForwardRules(false, SET_TETHERCTRL_FORWARD_DROP);
370     SetForwardRules(false, SetTetherctrlCounters1(fromIface, toIface));
371     SetForwardRules(false, SetTetherctrlCounters2(fromIface, toIface));
372 
373     RouteManager::DisableSharing(fromIface, toIface);
374 
375     interfaceForwards_.erase(fromIface + toIface);
376     if (interfaceForwards_.empty()) {
377         SetForwardRules(false, FORWARD_JUMP_TETHERCTRL_FORWARD);
378     }
379 
380     return 0;
381 }
382 
GetNetworkSharingTraffic(const std::string & downIface,const std::string & upIface,NetworkSharingTraffic & traffic)383 int32_t SharingManager::GetNetworkSharingTraffic(const std::string &downIface, const std::string &upIface,
384                                                  NetworkSharingTraffic &traffic)
385 {
386     const std::string cmds = "-t filter -L tetherctrl_counters -nvx";
387     std::string result = iptablesWrapper_->RunCommandForRes(IPTYPE_IPV4V6, cmds);
388     const std::string num = "(\\d+)";
389     const std::string iface = "([^\\s]+)";
390     const std::string dst = "(0.0.0.0/0|::/0)";
391     const std::string counters = "\\s*" + num + "\\s+" + num + " RETURN     all(  --  |      )" + iface + "\\s+" +
392                                  iface + "\\s+" + dst + "\\s+" + dst;
393     static const std::regex IP_RE(counters);
394 
395     bool isFindTx = false;
396     bool isFindRx = false;
397     const std::vector<std::string> lines = CommonUtils::Split(result, "\n");
398     std::size_t size1 = lines.size();
399     for (auto line : lines) {
400         std::smatch matches;
401         std::regex_search(line, matches, IP_RE);
402         if (matches.size() < MAX_MATCH_SIZE) {
403             continue;
404         }
405         for (uint32_t i = 0; i < matches.size() - 1; i++) {
406             std::string tempMatch = matches[i];
407             NETNATIVE_LOG_D("GetNetworkSharingTraffic matche[%{public}s]", tempMatch.c_str());
408             if (matches[i] == downIface && matches[i + NEXT_LIST_CORRECT_DATA] == upIface &&
409                 ((i - TWO_LIST_CORRECT_DATA) >= 0)) {
410                 int64_t send =
411                     static_cast<int64_t>(strtoul(matches[i - TWO_LIST_CORRECT_DATA].str().c_str(), nullptr, 0));
412                 isFindTx = true;
413                 traffic.send = send;
414                 traffic.all += send;
415             } else if (matches[i] == upIface && matches[i + NEXT_LIST_CORRECT_DATA] == downIface &&
416                        ((i - NET_TRAFFIC_RESULT_INDEX_OFFSET) >= 0)) {
417                 int64_t receive =
418                     static_cast<int64_t>(strtoul(matches[i - TWO_LIST_CORRECT_DATA].str().c_str(), nullptr, 0));
419                 isFindRx = true;
420                 traffic.receive = receive;
421                 traffic.all += receive;
422             }
423             if (isFindTx && isFindRx) {
424                 NETNATIVE_LOG_D("GetNetworkSharingTraffic success total");
425                 return NETMANAGER_SUCCESS;
426             }
427         }
428     }
429     NETNATIVE_LOGE("GetNetworkSharingTraffic failed");
430     return NETMANAGER_ERROR;
431 }
432 
GetNetworkCellularSharingTraffic(NetworkSharingTraffic & traffic,std::string & ifaceName)433 int32_t SharingManager::GetNetworkCellularSharingTraffic(NetworkSharingTraffic &traffic, std::string &ifaceName)
434 {
435     const std::string cmds = "-t filter -L tetherctrl_counters -nvx";
436     for (IpType ipType : {IPTYPE_IPV4, IPTYPE_IPV6}) {
437         NetworkSharingTraffic traffic0;
438         std::string ifaceName0 = "";
439         std::string result = iptablesWrapper_->RunCommandForRes(ipType, cmds);
440         int32_t ret = QueryCellularSharingTraffic(traffic0, result, ifaceName0);
441         if (ret != NETMANAGER_SUCCESS) {
442             NETNATIVE_LOGI("ipv4 GetNetworkSharingTraffic failed");
443             return NETMANAGER_ERROR;
444         }
445         traffic.receive += traffic0.receive;
446         traffic.send += traffic0.send;
447         traffic.all += traffic0.all;
448         ifaceName = ifaceName0;
449     }
450     NETNATIVE_LOG_D("GetNetworkCellularSharingTraffic success");
451     return NETMANAGER_SUCCESS;
452 }
453 
QueryCellularSharingTraffic(NetworkSharingTraffic & traffic,const std::string & result,std::string & ifaceName)454 int32_t SharingManager::QueryCellularSharingTraffic(NetworkSharingTraffic &traffic,
455     const std::string &result, std::string &ifaceName)
456 {
457     const std::string num = "(\\d+)";
458     const std::string iface = "([^\\s]+)";
459     const std::string dst = "(0.0.0.0/0|::/0)";
460     const std::string counters = "\\s*" + num + "\\s+" + num + " RETURN     all(  --  |      )" + iface + "\\s+" +
461                                  iface + "\\s+" + dst + "\\s+" + dst;
462     static const std::regex IP_RE(counters);
463 
464     bool isFindTx = false;
465     bool isFindRx = false;
466     const std::vector<std::string> lines = CommonUtils::Split(result, "\n");
467     for (auto line : lines) {
468         std::smatch matches;
469         std::regex_search(line, matches, IP_RE);
470         if (matches.size() < MAX_MATCH_SIZE) {
471             continue;
472         }
473         GetTraffic(matches, ifaceName, traffic, isFindTx, isFindRx);
474         if (isFindTx && isFindRx) {
475             NETNATIVE_LOG_D("GetNetworkSharingTraffic success total");
476             return NETMANAGER_SUCCESS;
477         }
478     }
479     NETNATIVE_LOGI("GetNetworkSharingTraffic failed");
480     return NETMANAGER_ERROR;
481 }
482 
ConvertStrToLong(const std::string & str,int64_t & value)483 static bool ConvertStrToLong(const std::string &str, int64_t &value)
484 {
485     auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), value);
486     return ec == std::errc{} && ptr == str.data() + str.size();
487 }
488 
GetTraffic(std::smatch & matches,std::string & ifaceName,NetworkSharingTraffic & traffic,bool & isFindTx,bool & isFindRx)489 void SharingManager::GetTraffic(std::smatch &matches, std::string &ifaceName, NetworkSharingTraffic &traffic,
490     bool &isFindTx, bool &isFindRx)
491 {
492     for (uint32_t i = 0; i < matches.size() - 1; i++) {
493         std::string matchTemp = matches[i];
494         NETNATIVE_LOG_D("GetNetworkCellularSharingTraffic matche[%{public}s]", matchTemp.c_str());
495         std::string matchNext = matches[i + NEXT_LIST_CORRECT_DATA];
496         if (matchTemp.find(CELLULAR_IFACE_NAME) != std::string::npos
497             && matchNext.find(WLAN_IFACE_NAME) != std::string::npos && ((i - TWO_LIST_CORRECT_DATA) >= 0)) {
498             int64_t send = 0;
499             if (!ConvertStrToLong(matches[i - TWO_LIST_CORRECT_DATA].str(), send)) {
500                 return;
501             }
502             isFindTx = true;
503             traffic.send = send;
504             traffic.all += send;
505             ifaceName = matchTemp;
506         } else if (matchTemp.find(WLAN_IFACE_NAME) != std::string::npos
507             && matchNext.find(CELLULAR_IFACE_NAME) != std::string::npos && ((i - TWO_LIST_CORRECT_DATA) >= 0)) {
508             int64_t receive = 0;
509             if (!ConvertStrToLong(matches[i - TWO_LIST_CORRECT_DATA].str(), receive)) {
510                 return;
511             }
512             isFindRx = true;
513             traffic.receive = receive;
514             traffic.all += receive;
515         } else if (matchTemp.find(WLAN_IFACE_NAME) != std::string::npos
516             && matchNext.find(WLAN_IFACE_NAME) != std::string::npos && ((i - TWO_LIST_CORRECT_DATA) >= 0)
517             && ifaceName == "") {
518             int64_t send = 0;
519             if (!ConvertStrToLong(matches[i - TWO_LIST_CORRECT_DATA].str(), send)) {
520                 return;
521             }
522             isFindTx = true;
523             traffic.send = send;
524             traffic.all += send;
525             ifaceName = matchTemp;
526         } else if (matchTemp.find(WLAN_IFACE_NAME) != std::string::npos
527             && matchNext.find(WLAN_IFACE_NAME) != std::string::npos && ((i - TWO_LIST_CORRECT_DATA) >= 0)
528             && ifaceName.find(WLAN_IFACE_NAME) != std::string::npos) {
529             int64_t receive = 0;
530             if (!ConvertStrToLong(matches[i - TWO_LIST_CORRECT_DATA].str(), receive)) {
531                 return;
532             }
533             isFindRx = true;
534             traffic.receive = receive;
535             traffic.all += receive;
536         }
537     }
538 }
539 
CheckInited()540 void SharingManager::CheckInited()
541 {
542     std::lock_guard<std::mutex> guard(initedMutex_);
543     if (inited_) {
544         return;
545     }
546     InitChildChains();
547 }
548 
SetForwardRules(bool set,const std::string & cmds)549 int32_t SharingManager::SetForwardRules(bool set, const std::string &cmds)
550 {
551     const std::string op = set ? "-A" : "-D";
552 
553     if (iptablesWrapper_->RunCommand(IPTYPE_IPV4V6, "-t filter " + op + cmds) !=
554         NetManagerStandard::NETMANAGER_SUCCESS) {
555         NETNATIVE_LOGE("IptablesWrapper run command failed");
556         return -1;
557     }
558     return 0;
559 }
560 } // namespace nmd
561 } // namespace OHOS
562