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