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