1/* 2 * Copyright (c) 2022-2024 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 "iptables_wrapper.h" 17 18#include <unistd.h> 19 20#include "datetime_ex.h" 21#include "net_manager_constants.h" 22#include "netmanager_base_common_utils.h" 23#include "netnative_log_wrapper.h" 24 25namespace OHOS { 26namespace nmd { 27using namespace NetManagerStandard; 28namespace { 29constexpr const char *IPATBLES_CMD_PATH = "/system/bin/iptables"; 30constexpr const char *IP6TABLES_CMD_PATH = "/system/bin/ip6tables"; 31} // namespace 32 33IptablesWrapper::IptablesWrapper() 34{ 35 isRunningFlag_ = true; 36 isIptablesSystemAccess_ = access(IPATBLES_CMD_PATH, F_OK) == 0; 37 isIp6tablesSystemAccess_ = access(IP6TABLES_CMD_PATH, F_OK) == 0; 38 39 iptablesWrapperFfrtQueue_ = std::make_shared<ffrt::queue>("IptablesWrapper"); 40} 41 42IptablesWrapper::~IptablesWrapper() 43{ 44 isRunningFlag_ = false; 45 iptablesWrapperFfrtQueue_.reset(); 46} 47 48void IptablesWrapper::ExecuteCommand(const std::string &command) 49{ 50 NETNATIVE_LOGI("ExecuteCommand %{public}s", AnonymizeIptablesCommand(command).c_str()); 51 if (CommonUtils::ForkExec(command) == NETMANAGER_ERROR) { 52 NETNATIVE_LOGE("run exec faild"); 53 } 54} 55 56void IptablesWrapper::ExecuteCommandForRes(const std::string &command) 57{ 58 NETNATIVE_LOGI("ExecuteCommandForRes %{public}s", AnonymizeIptablesCommand(command).c_str()); 59 if (CommonUtils::ForkExec(command, &result_) == NETMANAGER_ERROR) { 60 NETNATIVE_LOGE("run exec faild"); 61 } 62} 63 64int32_t IptablesWrapper::RunCommand(const IpType &ipType, const std::string &command) 65{ 66 NETNATIVE_LOGI("IptablesWrapper::RunCommand, ipType:%{public}d", ipType); 67 if (!iptablesWrapperFfrtQueue_) { 68 NETNATIVE_LOGE("FFRT Init Fail"); 69 return NETMANAGER_ERROR; 70 } 71 72 if (isIptablesSystemAccess_ && (ipType == IPTYPE_IPV4 || ipType == IPTYPE_IPV4V6)) { 73 std::string cmd = std::string(IPATBLES_CMD_PATH) + " " + command; 74#if UNITTEST_FORBID_FFRT // Forbid FFRT for unittest, which will cause crash in destructor process 75 ExecuteCommand(cmd); 76#else 77 std::function<void()> executeCommand = std::bind(&IptablesWrapper::ExecuteCommand, shared_from_this(), cmd); 78 iptablesWrapperFfrtQueue_->submit(executeCommand); 79#endif // UNITTEST_FORBID_FFRT 80 } 81 82 if (isIp6tablesSystemAccess_ && (ipType == IPTYPE_IPV6 || ipType == IPTYPE_IPV4V6)) { 83 std::string cmd = std::string(IP6TABLES_CMD_PATH) + " " + command; 84#if UNITTEST_FORBID_FFRT // Forbid FFRT for unittest, which will cause crash in destructor process 85 ExecuteCommand(cmd); 86#else 87 std::function<void()> executeCommand = std::bind(&IptablesWrapper::ExecuteCommand, shared_from_this(), cmd); 88 iptablesWrapperFfrtQueue_->submit(executeCommand); 89#endif // UNITTEST_FORBID_FFRT 90 } 91 92 return NetManagerStandard::NETMANAGER_SUCCESS; 93} 94 95std::string IptablesWrapper::RunCommandForRes(const IpType &ipType, const std::string &command) 96{ 97 NETNATIVE_LOGI("IptablesWrapper::RunCommandForRes, ipType:%{public}d", ipType); 98 if (!iptablesWrapperFfrtQueue_) { 99 NETNATIVE_LOGE("FFRT Init Fail"); 100 return result_; 101 } 102 103 if (ipType == IPTYPE_IPV4 || ipType == IPTYPE_IPV4V6) { 104 std::string cmd = std::string(IPATBLES_CMD_PATH) + " " + command; 105 std::function<void()> executeCommandForRes = 106 std::bind(&IptablesWrapper::ExecuteCommandForRes, shared_from_this(), cmd); 107 108 int64_t start = GetTickCount(); 109 ffrt::task_handle RunCommandForResTaskIpv4 = iptablesWrapperFfrtQueue_->submit_h(executeCommandForRes); 110 iptablesWrapperFfrtQueue_->wait(RunCommandForResTaskIpv4); 111 NETNATIVE_LOGI("FFRT cost:%{public}lld ms", static_cast<long long>(GetTickCount() - start)); 112 } 113 114 if (ipType == IPTYPE_IPV6 || ipType == IPTYPE_IPV4V6) { 115 std::string cmd = std::string(IP6TABLES_CMD_PATH) + " " + command; 116 std::function<void()> executeCommandForRes = 117 std::bind(&IptablesWrapper::ExecuteCommandForRes, shared_from_this(), cmd); 118 119 int64_t start = GetTickCount(); 120 ffrt::task_handle RunCommandForResTaskIpv6 = iptablesWrapperFfrtQueue_->submit_h(executeCommandForRes); 121 iptablesWrapperFfrtQueue_->wait(RunCommandForResTaskIpv6); 122 NETNATIVE_LOGI("FFRT cost:%{public}lld ms", static_cast<long long>(GetTickCount() - start)); 123 } 124 125 return result_; 126} 127 128int32_t IptablesWrapper::RunMutipleCommands(const IpType &ipType, const std::vector<std::string> &commands) 129{ 130 NETNATIVE_LOG_D("IptablesWrapper::RunMutipleCommands, ipType:%{public}d", ipType); 131 if (!iptablesWrapperFfrtQueue_) { 132 NETNATIVE_LOGE("FFRT Init Fail"); 133 return NETMANAGER_ERROR; 134 } 135 136 for (const std::string& command : commands) { 137 if (isIptablesSystemAccess_ && (ipType == IPTYPE_IPV4 || ipType == IPTYPE_IPV4V6)) { 138 std::string cmd = std::string(IPATBLES_CMD_PATH) + " " + command; 139 std::function<void()> executeCommand = std::bind(&IptablesWrapper::ExecuteCommand, shared_from_this(), cmd); 140 iptablesWrapperFfrtQueue_->submit(executeCommand); 141 } 142 143 if (isIp6tablesSystemAccess_ && (ipType == IPTYPE_IPV6 || ipType == IPTYPE_IPV4V6)) { 144 std::string cmd = std::string(IP6TABLES_CMD_PATH) + " " + command; 145 std::function<void()> executeCommand = std::bind(&IptablesWrapper::ExecuteCommand, shared_from_this(), cmd); 146 iptablesWrapperFfrtQueue_->submit(executeCommand); 147 } 148 } 149 150 return NetManagerStandard::NETMANAGER_SUCCESS; 151} 152} // namespace nmd 153} // namespace OHOS 154