1b1b8bc3fSopenharmony_ci/*
2b1b8bc3fSopenharmony_ci * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3b1b8bc3fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4b1b8bc3fSopenharmony_ci * you may not use this file except in compliance with the License.
5b1b8bc3fSopenharmony_ci * You may obtain a copy of the License at
6b1b8bc3fSopenharmony_ci *
7b1b8bc3fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8b1b8bc3fSopenharmony_ci *
9b1b8bc3fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10b1b8bc3fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11b1b8bc3fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12b1b8bc3fSopenharmony_ci * See the License for the specific language governing permissions and
13b1b8bc3fSopenharmony_ci * limitations under the License.
14b1b8bc3fSopenharmony_ci */
15b1b8bc3fSopenharmony_ci
16b1b8bc3fSopenharmony_ci#include "sharing_manager.h"
17b1b8bc3fSopenharmony_ci
18b1b8bc3fSopenharmony_ci#include <cerrno>
19b1b8bc3fSopenharmony_ci#include <fcntl.h>
20b1b8bc3fSopenharmony_ci#include <regex>
21b1b8bc3fSopenharmony_ci#include <unistd.h>
22b1b8bc3fSopenharmony_ci
23b1b8bc3fSopenharmony_ci#include "net_manager_constants.h"
24b1b8bc3fSopenharmony_ci#include "netmanager_base_common_utils.h"
25b1b8bc3fSopenharmony_ci#include "netnative_log_wrapper.h"
26b1b8bc3fSopenharmony_ci#include "route_manager.h"
27b1b8bc3fSopenharmony_ci
28b1b8bc3fSopenharmony_cinamespace OHOS {
29b1b8bc3fSopenharmony_cinamespace nmd {
30b1b8bc3fSopenharmony_ciusing namespace NetManagerStandard;
31b1b8bc3fSopenharmony_cinamespace {
32b1b8bc3fSopenharmony_ciconstexpr const char *IPV4_FORWARDING_PROC_FILE = "/proc/sys/net/ipv4/ip_forward";
33b1b8bc3fSopenharmony_ciconstexpr const char *IPV6_FORWARDING_PROC_FILE = "/proc/sys/net/ipv6/conf/all/forwarding";
34b1b8bc3fSopenharmony_ciconstexpr const char *IPTABLES_TMP_BAK = "/data/service/el1/public/netmanager/ipfwd.bak";
35b1b8bc3fSopenharmony_ciconstexpr const char *IPV6_PROC_PATH = "/proc/sys/net/ipv6/conf/";
36b1b8bc3fSopenharmony_ciconstexpr const char *IP6TABLES_TMP_BAK = "/data/service/el1/public/netmanager/ip6fwd.bak";
37b1b8bc3fSopenharmony_ciconstexpr const int MAX_MATCH_SIZE = 4;
38b1b8bc3fSopenharmony_ciconstexpr const int TWO_LIST_CORRECT_DATA = 2;
39b1b8bc3fSopenharmony_ciconstexpr const int NEXT_LIST_CORRECT_DATA = 1;
40b1b8bc3fSopenharmony_ciconstexpr uint32_t NET_TRAFFIC_RESULT_INDEX_OFFSET = 2;
41b1b8bc3fSopenharmony_ci
42b1b8bc3fSopenharmony_ci// commands of create tables
43b1b8bc3fSopenharmony_ciconstexpr const char *CREATE_TETHERCTRL_NAT_POSTROUTING = "-t nat -N tetherctrl_nat_POSTROUTING";
44b1b8bc3fSopenharmony_ciconstexpr const char *CREATE_TETHERCTRL_FORWARD = "-t filter -N tetherctrl_FORWARD";
45b1b8bc3fSopenharmony_ciconstexpr const char *CREATE_TETHERCTRL_COUNTERS = "-t filter -N tetherctrl_counters";
46b1b8bc3fSopenharmony_ciconstexpr const char *CREATE_TETHERCTRL_MANGLE_FORWARD = "-t mangle -N tetherctrl_mangle_FORWARD";
47b1b8bc3fSopenharmony_ciconstexpr const char *OPEN_IPV6_PRIVACY_EXTENSIONS = "2";
48b1b8bc3fSopenharmony_ciconstexpr const char *CLOSE_IPV6_PRIVACY_EXTENSIONS = "0";
49b1b8bc3fSopenharmony_ciconstexpr const char *ENABLE_IPV6_VALUE = "0";
50b1b8bc3fSopenharmony_ciconstexpr const char *DISABLE_IPV6_VALUE = "1";
51b1b8bc3fSopenharmony_ci
52b1b8bc3fSopenharmony_ci// commands of set nat
53b1b8bc3fSopenharmony_ciconstexpr const char *APPEND_NAT_POSTROUTING = "-t nat -A POSTROUTING -j tetherctrl_nat_POSTROUTING";
54b1b8bc3fSopenharmony_ciconstexpr const char *APPEND_MANGLE_FORWARD = "-t mangle -A FORWARD -j tetherctrl_mangle_FORWARD";
55b1b8bc3fSopenharmony_ciconstexpr const char *APPEND_TETHERCTRL_MANGLE_FORWARD =
56b1b8bc3fSopenharmony_ci    "-t mangle -A tetherctrl_mangle_FORWARD "
57b1b8bc3fSopenharmony_ci    "-p tcp -m tcp --tcp-flags SYN SYN -j TCPMSS --clamp-mss-to-pmtu";
58b1b8bc3fSopenharmony_ciconstexpr const char *CLEAR_TETHERCTRL_NAT_POSTROUTING = "-t nat -F tetherctrl_nat_POSTROUTING";
59b1b8bc3fSopenharmony_ciconstexpr const char *CLEAR_TETHERCTRL_MANGLE_FORWARD = "-t mangle -F tetherctrl_mangle_FORWARD";
60b1b8bc3fSopenharmony_ciconstexpr const char *DELETE_TETHERCTRL_NAT_POSTROUTING = "-t nat -D POSTROUTING -j tetherctrl_nat_POSTROUTING";
61b1b8bc3fSopenharmony_ciconstexpr const char *DELETE_TETHERCTRL_MANGLE_FORWARD = "-t mangle -D FORWARD -j tetherctrl_mangle_FORWARD";
62b1b8bc3fSopenharmony_ci
63b1b8bc3fSopenharmony_ciconstexpr const char *IPATBLES_RESTORE_CMD_PATH = "/system/bin/iptables-restore";
64b1b8bc3fSopenharmony_ciconstexpr const char *IPATBLES_SAVE_CMD_PATH = "/system/bin/iptables-save";
65b1b8bc3fSopenharmony_ci
66b1b8bc3fSopenharmony_ciconstexpr const char *IP6ATBLES_RESTORE_CMD_PATH = "/system/bin/ip6tables-restore";
67b1b8bc3fSopenharmony_ciconstexpr const char *IP6ATBLES_SAVE_CMD_PATH = "/system/bin/ip6tables-save";
68b1b8bc3fSopenharmony_ci
69b1b8bc3fSopenharmony_ciconst std::string EnableNatCmd(const std::string &down)
70b1b8bc3fSopenharmony_ci{
71b1b8bc3fSopenharmony_ci    return "-t nat -A tetherctrl_nat_POSTROUTING -o " + down + " -j MASQUERADE";
72b1b8bc3fSopenharmony_ci}
73b1b8bc3fSopenharmony_ci
74b1b8bc3fSopenharmony_ci// commands of set ipfwd, all commands with filter
75b1b8bc3fSopenharmony_ciconstexpr const char *FORWARD_JUMP_TETHERCTRL_FORWARD = " FORWARD -j tetherctrl_FORWARD";
76b1b8bc3fSopenharmony_ciconstexpr const char *SET_TETHERCTRL_FORWARD_DROP = " tetherctrl_FORWARD -j DROP";
77b1b8bc3fSopenharmony_ciconst std::string SetTetherctrlForward1(const std::string &from, const std::string &to)
78b1b8bc3fSopenharmony_ci{
79b1b8bc3fSopenharmony_ci    return " tetherctrl_FORWARD -i " + from + " -o " + to +
80b1b8bc3fSopenharmony_ci           " -m state --state RELATED,ESTABLISHED"
81b1b8bc3fSopenharmony_ci           " -g tetherctrl_counters";
82b1b8bc3fSopenharmony_ci}
83b1b8bc3fSopenharmony_ci
84b1b8bc3fSopenharmony_ciconst std::string SetTetherctrlForward2(const std::string &from, const std::string &to)
85b1b8bc3fSopenharmony_ci{
86b1b8bc3fSopenharmony_ci    return " tetherctrl_FORWARD -i " + to + " -o " + from + " -m state --state INVALID -j DROP";
87b1b8bc3fSopenharmony_ci}
88b1b8bc3fSopenharmony_ci
89b1b8bc3fSopenharmony_ciconst std::string SetTetherctrlForward3(const std::string &from, const std::string &to)
90b1b8bc3fSopenharmony_ci{
91b1b8bc3fSopenharmony_ci    return " tetherctrl_FORWARD -i " + to + " -o " + from + " -g tetherctrl_counters";
92b1b8bc3fSopenharmony_ci}
93b1b8bc3fSopenharmony_ci
94b1b8bc3fSopenharmony_ciconst std::string SetTetherctrlCounters1(const std::string &from, const std::string &to)
95b1b8bc3fSopenharmony_ci{
96b1b8bc3fSopenharmony_ci    return " tetherctrl_counters -i " + to + " -o " + from + " -j RETURN";
97b1b8bc3fSopenharmony_ci}
98b1b8bc3fSopenharmony_ci
99b1b8bc3fSopenharmony_ciconst std::string SetTetherctrlCounters2(const std::string &from, const std::string &to)
100b1b8bc3fSopenharmony_ci{
101b1b8bc3fSopenharmony_ci    return " tetherctrl_counters -i " + from + " -o " + to + " -j RETURN";
102b1b8bc3fSopenharmony_ci}
103b1b8bc3fSopenharmony_ci
104b1b8bc3fSopenharmony_cibool WriteToFile(const char *fileName, const char *value)
105b1b8bc3fSopenharmony_ci{
106b1b8bc3fSopenharmony_ci    if (fileName == nullptr) {
107b1b8bc3fSopenharmony_ci        return false;
108b1b8bc3fSopenharmony_ci    }
109b1b8bc3fSopenharmony_ci    int fd = open(fileName, O_WRONLY | O_CLOEXEC);
110b1b8bc3fSopenharmony_ci    if (fd < 0) {
111b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("failed to open %{private}s: %{public}s", fileName, strerror(errno));
112b1b8bc3fSopenharmony_ci        return false;
113b1b8bc3fSopenharmony_ci    }
114b1b8bc3fSopenharmony_ci
115b1b8bc3fSopenharmony_ci    const ssize_t len = strlen(value);
116b1b8bc3fSopenharmony_ci    if (write(fd, value, len) != len) {
117b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("faield to write %{public}s to %{private}s: %{public}s", value, fileName, strerror(errno));
118b1b8bc3fSopenharmony_ci        close(fd);
119b1b8bc3fSopenharmony_ci        return false;
120b1b8bc3fSopenharmony_ci    }
121b1b8bc3fSopenharmony_ci
122b1b8bc3fSopenharmony_ci    close(fd);
123b1b8bc3fSopenharmony_ci    return true;
124b1b8bc3fSopenharmony_ci}
125b1b8bc3fSopenharmony_ci
126b1b8bc3fSopenharmony_civoid Rollback()
127b1b8bc3fSopenharmony_ci{
128b1b8bc3fSopenharmony_ci    NETNATIVE_LOGE("iptables rollback");
129b1b8bc3fSopenharmony_ci    std::string rollBak = std::string(IPATBLES_RESTORE_CMD_PATH) + " -T filter < ";
130b1b8bc3fSopenharmony_ci    rollBak.append(IPTABLES_TMP_BAK);
131b1b8bc3fSopenharmony_ci    CommonUtils::ForkExec(rollBak);
132b1b8bc3fSopenharmony_ci
133b1b8bc3fSopenharmony_ci    rollBak = std::string(IP6ATBLES_RESTORE_CMD_PATH) + " -T filter < ";
134b1b8bc3fSopenharmony_ci    rollBak.append(IP6TABLES_TMP_BAK);
135b1b8bc3fSopenharmony_ci    CommonUtils::ForkExec(rollBak);
136b1b8bc3fSopenharmony_ci}
137b1b8bc3fSopenharmony_ci} // namespace
138b1b8bc3fSopenharmony_ci
139b1b8bc3fSopenharmony_ciSharingManager::SharingManager()
140b1b8bc3fSopenharmony_ci{
141b1b8bc3fSopenharmony_ci    iptablesWrapper_ = IptablesWrapper::GetInstance();
142b1b8bc3fSopenharmony_ci}
143b1b8bc3fSopenharmony_ci
144b1b8bc3fSopenharmony_civoid SharingManager::InitChildChains()
145b1b8bc3fSopenharmony_ci{
146b1b8bc3fSopenharmony_ci    iptablesWrapper_->RunCommand(IPTYPE_IPV4V6, CREATE_TETHERCTRL_NAT_POSTROUTING);
147b1b8bc3fSopenharmony_ci    iptablesWrapper_->RunCommand(IPTYPE_IPV4V6, CREATE_TETHERCTRL_FORWARD);
148b1b8bc3fSopenharmony_ci    iptablesWrapper_->RunCommand(IPTYPE_IPV4V6, CREATE_TETHERCTRL_COUNTERS);
149b1b8bc3fSopenharmony_ci    iptablesWrapper_->RunCommand(IPTYPE_IPV4V6, CREATE_TETHERCTRL_MANGLE_FORWARD);
150b1b8bc3fSopenharmony_ci    inited_ = true;
151b1b8bc3fSopenharmony_ci}
152b1b8bc3fSopenharmony_ci
153b1b8bc3fSopenharmony_ciint32_t SharingManager::IpEnableForwarding(const std::string &requestor)
154b1b8bc3fSopenharmony_ci{
155b1b8bc3fSopenharmony_ci    NETNATIVE_LOG_D("IpEnableForwarding requestor: %{public}s", requestor.c_str());
156b1b8bc3fSopenharmony_ci    {
157b1b8bc3fSopenharmony_ci        std::lock_guard<std::mutex> guard(initedMutex_);
158b1b8bc3fSopenharmony_ci        forwardingRequests_.insert(requestor);
159b1b8bc3fSopenharmony_ci    }
160b1b8bc3fSopenharmony_ci    return SetIpFwdEnable();
161b1b8bc3fSopenharmony_ci}
162b1b8bc3fSopenharmony_ci
163b1b8bc3fSopenharmony_ciint32_t SharingManager::IpDisableForwarding(const std::string &requestor)
164b1b8bc3fSopenharmony_ci{
165b1b8bc3fSopenharmony_ci    NETNATIVE_LOG_D("IpDisableForwarding requestor: %{public}s", requestor.c_str());
166b1b8bc3fSopenharmony_ci    {
167b1b8bc3fSopenharmony_ci        std::lock_guard<std::mutex> guard(initedMutex_);
168b1b8bc3fSopenharmony_ci        forwardingRequests_.erase(requestor);
169b1b8bc3fSopenharmony_ci    }
170b1b8bc3fSopenharmony_ci    return SetIpFwdEnable();
171b1b8bc3fSopenharmony_ci}
172b1b8bc3fSopenharmony_ci
173b1b8bc3fSopenharmony_ciint32_t SharingManager::EnableNat(const std::string &downstreamIface, const std::string &upstreamIface)
174b1b8bc3fSopenharmony_ci{
175b1b8bc3fSopenharmony_ci    DisableNat(downstreamIface, upstreamIface);
176b1b8bc3fSopenharmony_ci    CheckInited();
177b1b8bc3fSopenharmony_ci    if (downstreamIface == upstreamIface) {
178b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("Duplicate interface specified: %{public}s %{public}s", downstreamIface.c_str(),
179b1b8bc3fSopenharmony_ci                       upstreamIface.c_str());
180b1b8bc3fSopenharmony_ci        return -1;
181b1b8bc3fSopenharmony_ci    }
182b1b8bc3fSopenharmony_ci    if (!CommonUtils::CheckIfaceName(upstreamIface)) {
183b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("iface name valid check fail: %{public}s", upstreamIface.c_str());
184b1b8bc3fSopenharmony_ci        return -1;
185b1b8bc3fSopenharmony_ci    }
186b1b8bc3fSopenharmony_ci    iptablesWrapper_->RunCommand(IPTYPE_IPV4V6, APPEND_NAT_POSTROUTING);
187b1b8bc3fSopenharmony_ci    iptablesWrapper_->RunCommand(IPTYPE_IPV4V6, APPEND_MANGLE_FORWARD);
188b1b8bc3fSopenharmony_ci
189b1b8bc3fSopenharmony_ci    NETNATIVE_LOGI("EnableNat downstreamIface: %{public}s, upstreamIface: %{public}s", downstreamIface.c_str(),
190b1b8bc3fSopenharmony_ci                   upstreamIface.c_str());
191b1b8bc3fSopenharmony_ci
192b1b8bc3fSopenharmony_ci    if (iptablesWrapper_->RunCommand(IPTYPE_IPV4V6, EnableNatCmd(upstreamIface)) !=
193b1b8bc3fSopenharmony_ci        NetManagerStandard::NETMANAGER_SUCCESS) {
194b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("IptablesWrapper run command failed");
195b1b8bc3fSopenharmony_ci        return -1;
196b1b8bc3fSopenharmony_ci    }
197b1b8bc3fSopenharmony_ci
198b1b8bc3fSopenharmony_ci    if (iptablesWrapper_->RunCommand(IPTYPE_IPV4V6, APPEND_TETHERCTRL_MANGLE_FORWARD) !=
199b1b8bc3fSopenharmony_ci        NetManagerStandard::NETMANAGER_SUCCESS) {
200b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("IptablesWrapper run command failed");
201b1b8bc3fSopenharmony_ci        return -1;
202b1b8bc3fSopenharmony_ci    }
203b1b8bc3fSopenharmony_ci    return 0;
204b1b8bc3fSopenharmony_ci}
205b1b8bc3fSopenharmony_ci
206b1b8bc3fSopenharmony_ciint32_t SharingManager::DisableNat(const std::string &downstreamIface, const std::string &upstreamIface)
207b1b8bc3fSopenharmony_ci{
208b1b8bc3fSopenharmony_ci    CheckInited();
209b1b8bc3fSopenharmony_ci    if (downstreamIface == upstreamIface) {
210b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("Duplicate interface specified: %{public}s %s", downstreamIface.c_str(), upstreamIface.c_str());
211b1b8bc3fSopenharmony_ci        return -1;
212b1b8bc3fSopenharmony_ci    }
213b1b8bc3fSopenharmony_ci    if (!CommonUtils::CheckIfaceName(upstreamIface)) {
214b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("iface name valid check fail: %{public}s", upstreamIface.c_str());
215b1b8bc3fSopenharmony_ci        return -1;
216b1b8bc3fSopenharmony_ci    }
217b1b8bc3fSopenharmony_ci
218b1b8bc3fSopenharmony_ci    NETNATIVE_LOGI("DisableNat downstreamIface: %{public}s, upstreamIface: %{public}s", downstreamIface.c_str(),
219b1b8bc3fSopenharmony_ci                   upstreamIface.c_str());
220b1b8bc3fSopenharmony_ci
221b1b8bc3fSopenharmony_ci    if (iptablesWrapper_->RunCommand(IPTYPE_IPV4V6, CLEAR_TETHERCTRL_NAT_POSTROUTING) !=
222b1b8bc3fSopenharmony_ci        NetManagerStandard::NETMANAGER_SUCCESS) {
223b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("IptablesWrapper run command failed");
224b1b8bc3fSopenharmony_ci        return -1;
225b1b8bc3fSopenharmony_ci    }
226b1b8bc3fSopenharmony_ci    if (iptablesWrapper_->RunCommand(IPTYPE_IPV4V6, CLEAR_TETHERCTRL_MANGLE_FORWARD) !=
227b1b8bc3fSopenharmony_ci        NetManagerStandard::NETMANAGER_SUCCESS) {
228b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("IptablesWrapper run command failed");
229b1b8bc3fSopenharmony_ci        return -1;
230b1b8bc3fSopenharmony_ci    }
231b1b8bc3fSopenharmony_ci
232b1b8bc3fSopenharmony_ci    iptablesWrapper_->RunCommand(IPTYPE_IPV4V6, DELETE_TETHERCTRL_NAT_POSTROUTING);
233b1b8bc3fSopenharmony_ci    iptablesWrapper_->RunCommand(IPTYPE_IPV4V6, DELETE_TETHERCTRL_MANGLE_FORWARD);
234b1b8bc3fSopenharmony_ci    return 0;
235b1b8bc3fSopenharmony_ci}
236b1b8bc3fSopenharmony_ciint32_t SharingManager::SetIpv6PrivacyExtensions(const std::string &interfaceName, const uint32_t on)
237b1b8bc3fSopenharmony_ci{
238b1b8bc3fSopenharmony_ci    std::string option = IPV6_PROC_PATH + interfaceName + "/use_tempaddr";
239b1b8bc3fSopenharmony_ci    const char *value = on ? OPEN_IPV6_PRIVACY_EXTENSIONS : CLOSE_IPV6_PRIVACY_EXTENSIONS;
240b1b8bc3fSopenharmony_ci    bool ipv6Success = WriteToFile(option.c_str(), value);
241b1b8bc3fSopenharmony_ci    return ipv6Success ? 0 : -1;
242b1b8bc3fSopenharmony_ci}
243b1b8bc3fSopenharmony_ci
244b1b8bc3fSopenharmony_ciint32_t SharingManager::SetEnableIpv6(const std::string &interfaceName, const uint32_t on)
245b1b8bc3fSopenharmony_ci{
246b1b8bc3fSopenharmony_ci    std::string option = IPV6_PROC_PATH + interfaceName + "/disable_ipv6";
247b1b8bc3fSopenharmony_ci    const char *value = on ? ENABLE_IPV6_VALUE : DISABLE_IPV6_VALUE;
248b1b8bc3fSopenharmony_ci    bool ipv6Success = WriteToFile(option.c_str(), value);
249b1b8bc3fSopenharmony_ci    return ipv6Success ? 0 : -1;
250b1b8bc3fSopenharmony_ci}
251b1b8bc3fSopenharmony_ci
252b1b8bc3fSopenharmony_ciint32_t SharingManager::SetIpFwdEnable()
253b1b8bc3fSopenharmony_ci{
254b1b8bc3fSopenharmony_ci    bool disable = forwardingRequests_.empty();
255b1b8bc3fSopenharmony_ci    const char *value = disable ? "0" : "1";
256b1b8bc3fSopenharmony_ci    bool ipv4Success = WriteToFile(IPV4_FORWARDING_PROC_FILE, value);
257b1b8bc3fSopenharmony_ci    bool ipv6Success = WriteToFile(IPV6_FORWARDING_PROC_FILE, value);
258b1b8bc3fSopenharmony_ci    return (ipv4Success && ipv6Success) ? 0 : -1;
259b1b8bc3fSopenharmony_ci}
260b1b8bc3fSopenharmony_ci
261b1b8bc3fSopenharmony_civoid SharingManager::IpfwdExecSaveBak()
262b1b8bc3fSopenharmony_ci{
263b1b8bc3fSopenharmony_ci    std::string saveBak = std::string(IPATBLES_SAVE_CMD_PATH) + " -t filter > ";
264b1b8bc3fSopenharmony_ci    saveBak.append(IPTABLES_TMP_BAK);
265b1b8bc3fSopenharmony_ci    CommonUtils::ForkExec(saveBak);
266b1b8bc3fSopenharmony_ci    saveBak = std::string(IP6ATBLES_SAVE_CMD_PATH) + " -t filter > ";
267b1b8bc3fSopenharmony_ci    saveBak.append(IP6TABLES_TMP_BAK);
268b1b8bc3fSopenharmony_ci    CommonUtils::ForkExec(saveBak);
269b1b8bc3fSopenharmony_ci}
270b1b8bc3fSopenharmony_ci
271b1b8bc3fSopenharmony_ciint32_t SharingManager::IpfwdAddInterfaceForward(const std::string &fromIface, const std::string &toIface)
272b1b8bc3fSopenharmony_ci{
273b1b8bc3fSopenharmony_ci    CheckInited();
274b1b8bc3fSopenharmony_ci    if (fromIface == toIface) {
275b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("Duplicate interface specified: %{public}s %{public}s", fromIface.c_str(), toIface.c_str());
276b1b8bc3fSopenharmony_ci        return -1;
277b1b8bc3fSopenharmony_ci    }
278b1b8bc3fSopenharmony_ci    if (!(CommonUtils::CheckIfaceName(fromIface)) || !(CommonUtils::CheckIfaceName(toIface))) {
279b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("iface name valid check fail: %{public}s %{public}s", fromIface.c_str(), toIface.c_str());
280b1b8bc3fSopenharmony_ci        return -1;
281b1b8bc3fSopenharmony_ci    }
282b1b8bc3fSopenharmony_ci    NETNATIVE_LOGI("IpfwdAddInterfaceForward fromIface: %{public}s, toIface: %{public}s", fromIface.c_str(),
283b1b8bc3fSopenharmony_ci                   toIface.c_str());
284b1b8bc3fSopenharmony_ci    if (interfaceForwards_.empty()) {
285b1b8bc3fSopenharmony_ci        SetForwardRules(true, FORWARD_JUMP_TETHERCTRL_FORWARD);
286b1b8bc3fSopenharmony_ci    }
287b1b8bc3fSopenharmony_ci
288b1b8bc3fSopenharmony_ci    IpfwdExecSaveBak();
289b1b8bc3fSopenharmony_ci    int32_t result = 0;
290b1b8bc3fSopenharmony_ci
291b1b8bc3fSopenharmony_ci    /*
292b1b8bc3fSopenharmony_ci     * Add a forward rule, when the status of packets is RELATED,
293b1b8bc3fSopenharmony_ci     * ESTABLISED and from fromIface to toIface, goto tetherctrl_counters
294b1b8bc3fSopenharmony_ci     */
295b1b8bc3fSopenharmony_ci    if (SetForwardRules(true, SetTetherctrlForward1(toIface, fromIface))) {
296b1b8bc3fSopenharmony_ci        return result;
297b1b8bc3fSopenharmony_ci    }
298b1b8bc3fSopenharmony_ci
299b1b8bc3fSopenharmony_ci    /*
300b1b8bc3fSopenharmony_ci     * Add a forward rule, when the status is INVALID and from toIface to fromIface, just drop
301b1b8bc3fSopenharmony_ci     */
302b1b8bc3fSopenharmony_ci    if (SetForwardRules(true, SetTetherctrlForward2(toIface, fromIface))) {
303b1b8bc3fSopenharmony_ci        Rollback();
304b1b8bc3fSopenharmony_ci        return result;
305b1b8bc3fSopenharmony_ci    }
306b1b8bc3fSopenharmony_ci
307b1b8bc3fSopenharmony_ci    /*
308b1b8bc3fSopenharmony_ci     * Add a forward rule, from toIface to fromIface, goto tetherctrl_counters
309b1b8bc3fSopenharmony_ci     */
310b1b8bc3fSopenharmony_ci    if (SetForwardRules(true, SetTetherctrlForward3(toIface, fromIface))) {
311b1b8bc3fSopenharmony_ci        Rollback();
312b1b8bc3fSopenharmony_ci        return result;
313b1b8bc3fSopenharmony_ci    }
314b1b8bc3fSopenharmony_ci
315b1b8bc3fSopenharmony_ci    /*
316b1b8bc3fSopenharmony_ci     * Add a forward rule, drop others
317b1b8bc3fSopenharmony_ci     */
318b1b8bc3fSopenharmony_ci    if (SetForwardRules(true, SET_TETHERCTRL_FORWARD_DROP)) {
319b1b8bc3fSopenharmony_ci        Rollback();
320b1b8bc3fSopenharmony_ci        return result;
321b1b8bc3fSopenharmony_ci    }
322b1b8bc3fSopenharmony_ci
323b1b8bc3fSopenharmony_ci    /*
324b1b8bc3fSopenharmony_ci     * Add a forward rule, if from toIface to fromIface return chain of father
325b1b8bc3fSopenharmony_ci     */
326b1b8bc3fSopenharmony_ci    if (SetForwardRules(true, SetTetherctrlCounters1(fromIface, toIface))) {
327b1b8bc3fSopenharmony_ci        Rollback();
328b1b8bc3fSopenharmony_ci        return result;
329b1b8bc3fSopenharmony_ci    }
330b1b8bc3fSopenharmony_ci
331b1b8bc3fSopenharmony_ci    /*
332b1b8bc3fSopenharmony_ci     * Add a forward rule, if from fromIface to toIface return chain of father
333b1b8bc3fSopenharmony_ci     */
334b1b8bc3fSopenharmony_ci    if (SetForwardRules(true, SetTetherctrlCounters2(fromIface, toIface))) {
335b1b8bc3fSopenharmony_ci        Rollback();
336b1b8bc3fSopenharmony_ci        return result;
337b1b8bc3fSopenharmony_ci    }
338b1b8bc3fSopenharmony_ci
339b1b8bc3fSopenharmony_ci    if (RouteManager::EnableSharing(fromIface, toIface)) {
340b1b8bc3fSopenharmony_ci        Rollback();
341b1b8bc3fSopenharmony_ci        return result;
342b1b8bc3fSopenharmony_ci    }
343b1b8bc3fSopenharmony_ci    interfaceForwards_.insert(fromIface + toIface);
344b1b8bc3fSopenharmony_ci    return 0;
345b1b8bc3fSopenharmony_ci}
346b1b8bc3fSopenharmony_ci
347b1b8bc3fSopenharmony_ciint32_t SharingManager::IpfwdRemoveInterfaceForward(const std::string &fromIface, const std::string &toIface)
348b1b8bc3fSopenharmony_ci{
349b1b8bc3fSopenharmony_ci    CheckInited();
350b1b8bc3fSopenharmony_ci    if (fromIface == toIface) {
351b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("Duplicate interface specified: %{public}s %{public}s", fromIface.c_str(), toIface.c_str());
352b1b8bc3fSopenharmony_ci        return -1;
353b1b8bc3fSopenharmony_ci    }
354b1b8bc3fSopenharmony_ci    if (!(CommonUtils::CheckIfaceName(fromIface)) || !(CommonUtils::CheckIfaceName(toIface))) {
355b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("iface name valid check fail: %{public}s %{public}s", fromIface.c_str(), toIface.c_str());
356b1b8bc3fSopenharmony_ci        return -1;
357b1b8bc3fSopenharmony_ci    }
358b1b8bc3fSopenharmony_ci    NETNATIVE_LOGI("IpfwdRemoveInterfaceForward fromIface: %{public}s, toIface: %{public}s", fromIface.c_str(),
359b1b8bc3fSopenharmony_ci                   toIface.c_str());
360b1b8bc3fSopenharmony_ci
361b1b8bc3fSopenharmony_ci    SetForwardRules(false, SetTetherctrlForward1(toIface, fromIface));
362b1b8bc3fSopenharmony_ci    SetForwardRules(false, SetTetherctrlForward2(toIface, fromIface));
363b1b8bc3fSopenharmony_ci    SetForwardRules(false, SetTetherctrlForward3(toIface, fromIface));
364b1b8bc3fSopenharmony_ci    SetForwardRules(false, SET_TETHERCTRL_FORWARD_DROP);
365b1b8bc3fSopenharmony_ci    SetForwardRules(false, SetTetherctrlCounters1(fromIface, toIface));
366b1b8bc3fSopenharmony_ci    SetForwardRules(false, SetTetherctrlCounters2(fromIface, toIface));
367b1b8bc3fSopenharmony_ci
368b1b8bc3fSopenharmony_ci    RouteManager::DisableSharing(fromIface, toIface);
369b1b8bc3fSopenharmony_ci
370b1b8bc3fSopenharmony_ci    interfaceForwards_.erase(fromIface + toIface);
371b1b8bc3fSopenharmony_ci    if (interfaceForwards_.empty()) {
372b1b8bc3fSopenharmony_ci        SetForwardRules(false, FORWARD_JUMP_TETHERCTRL_FORWARD);
373b1b8bc3fSopenharmony_ci    }
374b1b8bc3fSopenharmony_ci
375b1b8bc3fSopenharmony_ci    return 0;
376b1b8bc3fSopenharmony_ci}
377b1b8bc3fSopenharmony_ci
378b1b8bc3fSopenharmony_ciint32_t SharingManager::GetNetworkSharingTraffic(const std::string &downIface, const std::string &upIface,
379b1b8bc3fSopenharmony_ci                                                 NetworkSharingTraffic &traffic)
380b1b8bc3fSopenharmony_ci{
381b1b8bc3fSopenharmony_ci    const std::string cmds = "-t filter -L tetherctrl_counters -nvx";
382b1b8bc3fSopenharmony_ci    std::string result = iptablesWrapper_->RunCommandForRes(IPTYPE_IPV4V6, cmds);
383b1b8bc3fSopenharmony_ci
384b1b8bc3fSopenharmony_ci    const std::string num = "(\\d+)";
385b1b8bc3fSopenharmony_ci    const std::string iface = "([^\\s]+)";
386b1b8bc3fSopenharmony_ci    const std::string dst = "(0.0.0.0/0|::/0)";
387b1b8bc3fSopenharmony_ci    const std::string counters = "\\s*" + num + "\\s+" + num + " RETURN     all(  --  |      )" + iface + "\\s+" +
388b1b8bc3fSopenharmony_ci                                 iface + "\\s+" + dst + "\\s+" + dst;
389b1b8bc3fSopenharmony_ci    static const std::regex IP_RE(counters);
390b1b8bc3fSopenharmony_ci
391b1b8bc3fSopenharmony_ci    bool isFindTx = false;
392b1b8bc3fSopenharmony_ci    bool isFindRx = false;
393b1b8bc3fSopenharmony_ci    const std::vector<std::string> lines = CommonUtils::Split(result, "\n");
394b1b8bc3fSopenharmony_ci    for (auto line : lines) {
395b1b8bc3fSopenharmony_ci        std::smatch matches;
396b1b8bc3fSopenharmony_ci        std::regex_search(line, matches, IP_RE);
397b1b8bc3fSopenharmony_ci        if (matches.size() < MAX_MATCH_SIZE) {
398b1b8bc3fSopenharmony_ci            continue;
399b1b8bc3fSopenharmony_ci        }
400b1b8bc3fSopenharmony_ci        for (uint32_t i = 0; i < matches.size() - 1; i++) {
401b1b8bc3fSopenharmony_ci            std::string tempMatch = matches[i];
402b1b8bc3fSopenharmony_ci            NETNATIVE_LOG_D("GetNetworkSharingTraffic matche[%{public}s]", tempMatch.c_str());
403b1b8bc3fSopenharmony_ci            if (matches[i] == downIface && matches[i + NEXT_LIST_CORRECT_DATA] == upIface &&
404b1b8bc3fSopenharmony_ci                ((i - TWO_LIST_CORRECT_DATA) >= 0)) {
405b1b8bc3fSopenharmony_ci                int64_t send =
406b1b8bc3fSopenharmony_ci                    static_cast<int64_t>(strtoul(matches[i - TWO_LIST_CORRECT_DATA].str().c_str(), nullptr, 0));
407b1b8bc3fSopenharmony_ci                isFindTx = true;
408b1b8bc3fSopenharmony_ci                traffic.send = send;
409b1b8bc3fSopenharmony_ci                traffic.all += send;
410b1b8bc3fSopenharmony_ci            } else if (matches[i] == upIface && matches[i + NEXT_LIST_CORRECT_DATA] == downIface &&
411b1b8bc3fSopenharmony_ci                       ((i - NET_TRAFFIC_RESULT_INDEX_OFFSET) >= 0)) {
412b1b8bc3fSopenharmony_ci                int64_t receive =
413b1b8bc3fSopenharmony_ci                    static_cast<int64_t>(strtoul(matches[i - TWO_LIST_CORRECT_DATA].str().c_str(), nullptr, 0));
414b1b8bc3fSopenharmony_ci                isFindRx = true;
415b1b8bc3fSopenharmony_ci                traffic.receive = receive;
416b1b8bc3fSopenharmony_ci                traffic.all += receive;
417b1b8bc3fSopenharmony_ci            }
418b1b8bc3fSopenharmony_ci            if (isFindTx && isFindRx) {
419b1b8bc3fSopenharmony_ci                NETNATIVE_LOG_D("GetNetworkSharingTraffic success total");
420b1b8bc3fSopenharmony_ci                return NETMANAGER_SUCCESS;
421b1b8bc3fSopenharmony_ci            }
422b1b8bc3fSopenharmony_ci        }
423b1b8bc3fSopenharmony_ci    }
424b1b8bc3fSopenharmony_ci    NETNATIVE_LOGE("GetNetworkSharingTraffic failed");
425b1b8bc3fSopenharmony_ci    return NETMANAGER_ERROR;
426b1b8bc3fSopenharmony_ci}
427b1b8bc3fSopenharmony_ci
428b1b8bc3fSopenharmony_civoid SharingManager::CheckInited()
429b1b8bc3fSopenharmony_ci{
430b1b8bc3fSopenharmony_ci    std::lock_guard<std::mutex> guard(initedMutex_);
431b1b8bc3fSopenharmony_ci    if (inited_) {
432b1b8bc3fSopenharmony_ci        return;
433b1b8bc3fSopenharmony_ci    }
434b1b8bc3fSopenharmony_ci    InitChildChains();
435b1b8bc3fSopenharmony_ci}
436b1b8bc3fSopenharmony_ci
437b1b8bc3fSopenharmony_ciint32_t SharingManager::SetForwardRules(bool set, const std::string &cmds)
438b1b8bc3fSopenharmony_ci{
439b1b8bc3fSopenharmony_ci    const std::string op = set ? "-A" : "-D";
440b1b8bc3fSopenharmony_ci
441b1b8bc3fSopenharmony_ci    if (iptablesWrapper_->RunCommand(IPTYPE_IPV4V6, "-t filter " + op + cmds) !=
442b1b8bc3fSopenharmony_ci        NetManagerStandard::NETMANAGER_SUCCESS) {
443b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("IptablesWrapper run command failed");
444b1b8bc3fSopenharmony_ci        return -1;
445b1b8bc3fSopenharmony_ci    }
446b1b8bc3fSopenharmony_ci    return 0;
447b1b8bc3fSopenharmony_ci}
448b1b8bc3fSopenharmony_ci} // namespace nmd
449b1b8bc3fSopenharmony_ci} // namespace OHOS
450