1b1b8bc3fSopenharmony_ci/* 2b1b8bc3fSopenharmony_ci * Copyright (c) 2024 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 <arpa/inet.h> 17b1b8bc3fSopenharmony_ci#include <cstdio> 18b1b8bc3fSopenharmony_ci#include <libbpf.h> 19b1b8bc3fSopenharmony_ci#include <linux/bpf.h> 20b1b8bc3fSopenharmony_ci#include <net/if.h> 21b1b8bc3fSopenharmony_ci#include <netinet/in.h> 22b1b8bc3fSopenharmony_ci#include <securec.h> 23b1b8bc3fSopenharmony_ci#include <sys/epoll.h> 24b1b8bc3fSopenharmony_ci#include <sys/socket.h> 25b1b8bc3fSopenharmony_ci#include <vector> 26b1b8bc3fSopenharmony_ci#include <ctime> 27b1b8bc3fSopenharmony_ci 28b1b8bc3fSopenharmony_ci#include "bpf_loader.h" 29b1b8bc3fSopenharmony_ci#include "bpf_netfirewall.h" 30b1b8bc3fSopenharmony_ci#include "netnative_log_wrapper.h" 31b1b8bc3fSopenharmony_ci#include "iservice_registry.h" 32b1b8bc3fSopenharmony_ci#include "bpf_ring_buffer.h" 33b1b8bc3fSopenharmony_ci#include "ffrt_inner.h" 34b1b8bc3fSopenharmony_ci 35b1b8bc3fSopenharmony_ciusing namespace std; 36b1b8bc3fSopenharmony_ciusing namespace OHOS; 37b1b8bc3fSopenharmony_ciusing namespace OHOS::NetsysNative; 38b1b8bc3fSopenharmony_ci 39b1b8bc3fSopenharmony_cinamespace OHOS { 40b1b8bc3fSopenharmony_cinamespace NetManagerStandard { 41b1b8bc3fSopenharmony_cistd::shared_ptr<NetsysBpfNetFirewall> NetsysBpfNetFirewall::instance_ = nullptr; 42b1b8bc3fSopenharmony_cibool NetsysBpfNetFirewall::keepListen_ = false; 43b1b8bc3fSopenharmony_cibool NetsysBpfNetFirewall::keepGc_ = false; 44b1b8bc3fSopenharmony_cibool NetsysBpfNetFirewall::isBpfLoaded_ = false; 45b1b8bc3fSopenharmony_cistd::unique_ptr<BpfMapper<CtKey, CtVaule>> NetsysBpfNetFirewall::ctRdMap_ = nullptr; 46b1b8bc3fSopenharmony_cistd::unique_ptr<BpfMapper<CtKey, CtVaule>> NetsysBpfNetFirewall::ctWrMap_ = nullptr; 47b1b8bc3fSopenharmony_ci 48b1b8bc3fSopenharmony_ciNetsysBpfNetFirewall::NetsysBpfNetFirewall() 49b1b8bc3fSopenharmony_ci{ 50b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("NetsysBpfNetFirewall construct"); 51b1b8bc3fSopenharmony_ci isBpfLoaded_ = false; 52b1b8bc3fSopenharmony_ci} 53b1b8bc3fSopenharmony_ci 54b1b8bc3fSopenharmony_cistd::shared_ptr<NetsysBpfNetFirewall> NetsysBpfNetFirewall::GetInstance() 55b1b8bc3fSopenharmony_ci{ 56b1b8bc3fSopenharmony_ci static std::mutex instanceMutex; 57b1b8bc3fSopenharmony_ci std::lock_guard<std::mutex> guard(instanceMutex); 58b1b8bc3fSopenharmony_ci if (instance_ == nullptr) { 59b1b8bc3fSopenharmony_ci instance_.reset(new NetsysBpfNetFirewall()); 60b1b8bc3fSopenharmony_ci return instance_; 61b1b8bc3fSopenharmony_ci } 62b1b8bc3fSopenharmony_ci return instance_; 63b1b8bc3fSopenharmony_ci} 64b1b8bc3fSopenharmony_ci 65b1b8bc3fSopenharmony_civoid NetsysBpfNetFirewall::ConntrackGcTask() 66b1b8bc3fSopenharmony_ci{ 67b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("ConntrackGcTask: running"); 68b1b8bc3fSopenharmony_ci std::vector<CtKey> keys = ctRdMap_->GetAllKeys(); 69b1b8bc3fSopenharmony_ci if (keys.empty()) { 70b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("GcConntrackCb: key is empty"); 71b1b8bc3fSopenharmony_ci return; 72b1b8bc3fSopenharmony_ci } 73b1b8bc3fSopenharmony_ci 74b1b8bc3fSopenharmony_ci timespec now = { 0 }; 75b1b8bc3fSopenharmony_ci // bpf_ktime_get_ns: CLOCK_MONOTONIC 76b1b8bc3fSopenharmony_ci if (!clock_gettime(CLOCK_MONOTONIC, &now)) { 77b1b8bc3fSopenharmony_ci return; 78b1b8bc3fSopenharmony_ci } 79b1b8bc3fSopenharmony_ci for (const CtKey &k : keys) { 80b1b8bc3fSopenharmony_ci CtVaule v = {}; 81b1b8bc3fSopenharmony_ci if (ctRdMap_->Read(k, v) < 0) { 82b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("GcConntrackCb: read failed"); 83b1b8bc3fSopenharmony_ci continue; 84b1b8bc3fSopenharmony_ci } 85b1b8bc3fSopenharmony_ci 86b1b8bc3fSopenharmony_ci if (v.lifetime < now.tv_sec) { 87b1b8bc3fSopenharmony_ci if (ctWrMap_->Delete(k) != 0) { 88b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("GcConntrackCb: delete failed"); 89b1b8bc3fSopenharmony_ci continue; 90b1b8bc3fSopenharmony_ci } 91b1b8bc3fSopenharmony_ci } 92b1b8bc3fSopenharmony_ci } 93b1b8bc3fSopenharmony_ci} 94b1b8bc3fSopenharmony_ci 95b1b8bc3fSopenharmony_civoid NetsysBpfNetFirewall::RingBufferListenThread(void) 96b1b8bc3fSopenharmony_ci{ 97b1b8bc3fSopenharmony_ci if (keepListen_) { 98b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("under listening"); 99b1b8bc3fSopenharmony_ci return; 100b1b8bc3fSopenharmony_ci } 101b1b8bc3fSopenharmony_ci 102b1b8bc3fSopenharmony_ci int mapFd = NetsysBpfRingBuffer::GetRingbufFd(MAP_PATH(EVENT_MAP), 0); 103b1b8bc3fSopenharmony_ci if (mapFd < 0) { 104b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("failed to get ring buffer fd: errno=%{public}d", errno); 105b1b8bc3fSopenharmony_ci return; 106b1b8bc3fSopenharmony_ci } 107b1b8bc3fSopenharmony_ci ring_buffer *rb = ring_buffer__new(mapFd, NetsysBpfNetFirewall::HandleEvent, NULL, NULL); 108b1b8bc3fSopenharmony_ci if (!rb) { 109b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("failed to create ring buffer: errno=%{public}d", errno); 110b1b8bc3fSopenharmony_ci return; 111b1b8bc3fSopenharmony_ci } 112b1b8bc3fSopenharmony_ci 113b1b8bc3fSopenharmony_ci keepListen_ = true; 114b1b8bc3fSopenharmony_ci while (keepListen_) { 115b1b8bc3fSopenharmony_ci if (ffrt::this_task::get_id() != 0) { 116b1b8bc3fSopenharmony_ci ffrt::sync_io(mapFd); 117b1b8bc3fSopenharmony_ci } 118b1b8bc3fSopenharmony_ci int err = ring_buffer__poll(rb, RING_BUFFER_POLL_TIME_OUT_MS); 119b1b8bc3fSopenharmony_ci if (err < 0) { 120b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("Error polling ring buffer: errno=%{public}d", errno); 121b1b8bc3fSopenharmony_ci keepListen_ = false; 122b1b8bc3fSopenharmony_ci break; 123b1b8bc3fSopenharmony_ci } 124b1b8bc3fSopenharmony_ci } 125b1b8bc3fSopenharmony_ci 126b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("Could not get bpf event ring buffer map"); 127b1b8bc3fSopenharmony_ci ring_buffer__free(rb); 128b1b8bc3fSopenharmony_ci} 129b1b8bc3fSopenharmony_ci 130b1b8bc3fSopenharmony_ciint32_t NetsysBpfNetFirewall::StartListener() 131b1b8bc3fSopenharmony_ci{ 132b1b8bc3fSopenharmony_ci if (!isBpfLoaded_) { 133b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("bfp is not loaded"); 134b1b8bc3fSopenharmony_ci return -1; 135b1b8bc3fSopenharmony_ci } 136b1b8bc3fSopenharmony_ci ctRdMap_ = std::make_unique<BpfMapper<CtKey, CtVaule>>(MAP_PATH(CT_MAP), BPF_F_RDONLY); 137b1b8bc3fSopenharmony_ci ctWrMap_ = std::make_unique<BpfMapper<CtKey, CtVaule>>(MAP_PATH(CT_MAP), BPF_F_WRONLY); 138b1b8bc3fSopenharmony_ci 139b1b8bc3fSopenharmony_ci ffrt::submit(RingBufferListenThread, {}, {}, ffrt::task_attr().name("RingBufferListen")); 140b1b8bc3fSopenharmony_ci ffrt::submit(StartConntrackGcThread, { &ctRdMap_ }, { &ctWrMap_ }); 141b1b8bc3fSopenharmony_ci return 0; 142b1b8bc3fSopenharmony_ci} 143b1b8bc3fSopenharmony_ci 144b1b8bc3fSopenharmony_ciint32_t NetsysBpfNetFirewall::StopListener() 145b1b8bc3fSopenharmony_ci{ 146b1b8bc3fSopenharmony_ci keepListen_ = false; 147b1b8bc3fSopenharmony_ci StopConntrackGc(); 148b1b8bc3fSopenharmony_ci return 0; 149b1b8bc3fSopenharmony_ci} 150b1b8bc3fSopenharmony_ci 151b1b8bc3fSopenharmony_civoid NetsysBpfNetFirewall::StartConntrackGcThread(void) 152b1b8bc3fSopenharmony_ci{ 153b1b8bc3fSopenharmony_ci if (keepGc_) { 154b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("under keepGc"); 155b1b8bc3fSopenharmony_ci return; 156b1b8bc3fSopenharmony_ci } 157b1b8bc3fSopenharmony_ci if (!ctRdMap_->IsValid()) { 158b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("GcConntrackCb: ctRdMap is invalid"); 159b1b8bc3fSopenharmony_ci return; 160b1b8bc3fSopenharmony_ci } 161b1b8bc3fSopenharmony_ci 162b1b8bc3fSopenharmony_ci if (!ctWrMap_->IsValid()) { 163b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("GcConntrackCb: ctWrMap is invalid"); 164b1b8bc3fSopenharmony_ci return; 165b1b8bc3fSopenharmony_ci } 166b1b8bc3fSopenharmony_ci 167b1b8bc3fSopenharmony_ci keepGc_ = true; 168b1b8bc3fSopenharmony_ci 169b1b8bc3fSopenharmony_ci int rdMapFd = NetsysBpfRingBuffer::GetRingbufFd(MAP_PATH(CT_MAP), BPF_F_RDONLY); 170b1b8bc3fSopenharmony_ci int wrMapFd = NetsysBpfRingBuffer::GetRingbufFd(MAP_PATH(CT_MAP), BPF_F_WRONLY); 171b1b8bc3fSopenharmony_ci if (rdMapFd < 0 || wrMapFd < 0) { 172b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("failed to get rdMapFd or wrMapFd: errno=%{public}d", errno); 173b1b8bc3fSopenharmony_ci return; 174b1b8bc3fSopenharmony_ci } 175b1b8bc3fSopenharmony_ci 176b1b8bc3fSopenharmony_ci while (keepGc_) { 177b1b8bc3fSopenharmony_ci ffrt::this_task::sleep_for(std::chrono::milliseconds(CONNTRACK_GC_INTTERVAL_MS)); 178b1b8bc3fSopenharmony_ci if (ffrt::this_task::get_id() != 0) { 179b1b8bc3fSopenharmony_ci ffrt::sync_io(rdMapFd); 180b1b8bc3fSopenharmony_ci ffrt::sync_io(wrMapFd); 181b1b8bc3fSopenharmony_ci } 182b1b8bc3fSopenharmony_ci ConntrackGcTask(); 183b1b8bc3fSopenharmony_ci } 184b1b8bc3fSopenharmony_ci} 185b1b8bc3fSopenharmony_ci 186b1b8bc3fSopenharmony_civoid NetsysBpfNetFirewall::StopConntrackGc() 187b1b8bc3fSopenharmony_ci{ 188b1b8bc3fSopenharmony_ci keepGc_ = false; 189b1b8bc3fSopenharmony_ci} 190b1b8bc3fSopenharmony_ci 191b1b8bc3fSopenharmony_civoid NetsysBpfNetFirewall::SetBpfLoaded(bool load) 192b1b8bc3fSopenharmony_ci{ 193b1b8bc3fSopenharmony_ci isBpfLoaded_ = load; 194b1b8bc3fSopenharmony_ci} 195b1b8bc3fSopenharmony_ci 196b1b8bc3fSopenharmony_civoid NetsysBpfNetFirewall::ClearBpfFirewallRules(NetFirewallRuleDirection direction) 197b1b8bc3fSopenharmony_ci{ 198b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("ClearBpfFirewallRules: direction=%{public}d", direction); 199b1b8bc3fSopenharmony_ci Ipv4LpmKey ip4Key = {}; 200b1b8bc3fSopenharmony_ci Ipv6LpmKey ip6Key = {}; 201b1b8bc3fSopenharmony_ci PortKey portKey = 0; 202b1b8bc3fSopenharmony_ci ProtoKey protoKey = 0; 203b1b8bc3fSopenharmony_ci AppUidKey appIdKey = 0; 204b1b8bc3fSopenharmony_ci UidKey uidKey = 0; 205b1b8bc3fSopenharmony_ci ActionKey actKey = 1; 206b1b8bc3fSopenharmony_ci ActionValue actVal; 207b1b8bc3fSopenharmony_ci RuleCode ruleCode; 208b1b8bc3fSopenharmony_ci CtKey ctKey; 209b1b8bc3fSopenharmony_ci CtVaule ctVal; 210b1b8bc3fSopenharmony_ci 211b1b8bc3fSopenharmony_ci bool ingress = (direction == NetFirewallRuleDirection::RULE_IN); 212b1b8bc3fSopenharmony_ci ClearBpfMap(GET_MAP_PATH(ingress, saddr), ip4Key, ruleCode); 213b1b8bc3fSopenharmony_ci ClearBpfMap(GET_MAP_PATH(ingress, saddr6), ip6Key, ruleCode); 214b1b8bc3fSopenharmony_ci ClearBpfMap(GET_MAP_PATH(ingress, daddr), ip4Key, ruleCode); 215b1b8bc3fSopenharmony_ci ClearBpfMap(GET_MAP_PATH(ingress, daddr6), ip6Key, ruleCode); 216b1b8bc3fSopenharmony_ci ClearBpfMap(GET_MAP_PATH(ingress, sport), portKey, ruleCode); 217b1b8bc3fSopenharmony_ci ClearBpfMap(GET_MAP_PATH(ingress, dport), portKey, ruleCode); 218b1b8bc3fSopenharmony_ci ClearBpfMap(GET_MAP_PATH(ingress, proto), protoKey, ruleCode); 219b1b8bc3fSopenharmony_ci ClearBpfMap(GET_MAP_PATH(ingress, appuid), appIdKey, ruleCode); 220b1b8bc3fSopenharmony_ci ClearBpfMap(GET_MAP_PATH(ingress, uid), uidKey, ruleCode); 221b1b8bc3fSopenharmony_ci ClearBpfMap(GET_MAP_PATH(ingress, action), actKey, actVal); 222b1b8bc3fSopenharmony_ci ClearBpfMap(MAP_PATH(CT_MAP), ctKey, ctVal); 223b1b8bc3fSopenharmony_ci} 224b1b8bc3fSopenharmony_ci 225b1b8bc3fSopenharmony_ciint32_t NetsysBpfNetFirewall::ClearFirewallRules() 226b1b8bc3fSopenharmony_ci{ 227b1b8bc3fSopenharmony_ci firewallIpRules_.clear(); 228b1b8bc3fSopenharmony_ci ClearBpfFirewallRules(NetFirewallRuleDirection::RULE_IN); 229b1b8bc3fSopenharmony_ci ClearBpfFirewallRules(NetFirewallRuleDirection::RULE_OUT); 230b1b8bc3fSopenharmony_ci return NETFIREWALL_SUCCESS; 231b1b8bc3fSopenharmony_ci} 232b1b8bc3fSopenharmony_ci 233b1b8bc3fSopenharmony_ciint32_t NetsysBpfNetFirewall::SetBpfFirewallRules(const std::vector<sptr<NetFirewallIpRule>> &ruleList, 234b1b8bc3fSopenharmony_ci NetFirewallRuleDirection direction) 235b1b8bc3fSopenharmony_ci{ 236b1b8bc3fSopenharmony_ci BitmapManager manager; 237b1b8bc3fSopenharmony_ci int32_t ret = manager.BuildBitmapMap(ruleList); 238b1b8bc3fSopenharmony_ci if (ret) { 239b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("SetBpfFirewallRules: BuildBitmapMap failed: %{public}d", ret); 240b1b8bc3fSopenharmony_ci return ret; 241b1b8bc3fSopenharmony_ci } 242b1b8bc3fSopenharmony_ci 243b1b8bc3fSopenharmony_ci ClearBpfFirewallRules(direction); 244b1b8bc3fSopenharmony_ci WriteSrcIpv4BpfMap(manager, direction); 245b1b8bc3fSopenharmony_ci WriteSrcIpv6BpfMap(manager, direction); 246b1b8bc3fSopenharmony_ci WriteDstIpv4BpfMap(manager, direction); 247b1b8bc3fSopenharmony_ci WriteDstIpv6BpfMap(manager, direction); 248b1b8bc3fSopenharmony_ci WriteSrcPortBpfMap(manager, direction); 249b1b8bc3fSopenharmony_ci WriteDstPortBpfMap(manager, direction); 250b1b8bc3fSopenharmony_ci WriteProtoBpfMap(manager, direction); 251b1b8bc3fSopenharmony_ci WriteAppUidBpfMap(manager, direction); 252b1b8bc3fSopenharmony_ci WriteUidBpfMap(manager, direction); 253b1b8bc3fSopenharmony_ci WriteActionBpfMap(manager, direction); 254b1b8bc3fSopenharmony_ci return NETFIREWALL_SUCCESS; 255b1b8bc3fSopenharmony_ci} 256b1b8bc3fSopenharmony_ci 257b1b8bc3fSopenharmony_ciint32_t NetsysBpfNetFirewall::SetFirewallRules(const std::vector<sptr<NetFirewallBaseRule>> &ruleList, bool isFinish) 258b1b8bc3fSopenharmony_ci{ 259b1b8bc3fSopenharmony_ci NETNATIVE_LOGI("SetFirewallRules: size=%{public}zu isFinish=%{public}" PRId32, ruleList.size(), isFinish); 260b1b8bc3fSopenharmony_ci if (!isBpfLoaded_) { 261b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("SetFirewallRules: bpf not loaded"); 262b1b8bc3fSopenharmony_ci return NETFIREWALL_ERR; 263b1b8bc3fSopenharmony_ci } 264b1b8bc3fSopenharmony_ci if (ruleList.empty()) { 265b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("SetFirewallRules: rules is empty"); 266b1b8bc3fSopenharmony_ci return NETFIREWALL_ERR; 267b1b8bc3fSopenharmony_ci } 268b1b8bc3fSopenharmony_ci for (const auto &rule : ruleList) { 269b1b8bc3fSopenharmony_ci firewallIpRules_.emplace_back(firewall_rule_cast<NetFirewallIpRule>(rule)); 270b1b8bc3fSopenharmony_ci } 271b1b8bc3fSopenharmony_ci int32_t ret = NETFIREWALL_SUCCESS; 272b1b8bc3fSopenharmony_ci if (isFinish) { 273b1b8bc3fSopenharmony_ci ret = SetFirewallIpRules(firewallIpRules_); 274b1b8bc3fSopenharmony_ci firewallIpRules_.clear(); 275b1b8bc3fSopenharmony_ci } 276b1b8bc3fSopenharmony_ci return ret; 277b1b8bc3fSopenharmony_ci} 278b1b8bc3fSopenharmony_ci 279b1b8bc3fSopenharmony_ciint32_t NetsysBpfNetFirewall::SetFirewallIpRules(const std::vector<sptr<NetFirewallIpRule>> &ruleList) 280b1b8bc3fSopenharmony_ci{ 281b1b8bc3fSopenharmony_ci std::vector<sptr<NetFirewallIpRule>> inRules; 282b1b8bc3fSopenharmony_ci std::vector<sptr<NetFirewallIpRule>> outRules; 283b1b8bc3fSopenharmony_ci 284b1b8bc3fSopenharmony_ci for (const auto &rule : ruleList) { 285b1b8bc3fSopenharmony_ci if (rule->ruleDirection == NetFirewallRuleDirection::RULE_IN) { 286b1b8bc3fSopenharmony_ci if (rule->protocol == NetworkProtocol::ICMP || rule->protocol == NetworkProtocol::ICMPV6) { 287b1b8bc3fSopenharmony_ci outRules.emplace_back(rule); 288b1b8bc3fSopenharmony_ci } else { 289b1b8bc3fSopenharmony_ci inRules.emplace_back(rule); 290b1b8bc3fSopenharmony_ci } 291b1b8bc3fSopenharmony_ci } 292b1b8bc3fSopenharmony_ci if (rule->ruleDirection == NetFirewallRuleDirection::RULE_OUT) { 293b1b8bc3fSopenharmony_ci outRules.emplace_back(rule); 294b1b8bc3fSopenharmony_ci } 295b1b8bc3fSopenharmony_ci } 296b1b8bc3fSopenharmony_ci 297b1b8bc3fSopenharmony_ci int32_t ret = NETFIREWALL_SUCCESS; 298b1b8bc3fSopenharmony_ci if (!inRules.empty()) { 299b1b8bc3fSopenharmony_ci ret = SetBpfFirewallRules(inRules, NetFirewallRuleDirection::RULE_IN); 300b1b8bc3fSopenharmony_ci } 301b1b8bc3fSopenharmony_ci if (!outRules.empty()) { 302b1b8bc3fSopenharmony_ci ret += SetBpfFirewallRules(outRules, NetFirewallRuleDirection::RULE_OUT); 303b1b8bc3fSopenharmony_ci } 304b1b8bc3fSopenharmony_ci return ret; 305b1b8bc3fSopenharmony_ci} 306b1b8bc3fSopenharmony_ci 307b1b8bc3fSopenharmony_ciint32_t NetsysBpfNetFirewall::SetFirewallDefaultAction(FirewallRuleAction inDefault, FirewallRuleAction outDefault) 308b1b8bc3fSopenharmony_ci{ 309b1b8bc3fSopenharmony_ci if (!isBpfLoaded_) { 310b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("SetFirewallDefaultAction: bpf not loaded"); 311b1b8bc3fSopenharmony_ci return NETFIREWALL_ERR; 312b1b8bc3fSopenharmony_ci } 313b1b8bc3fSopenharmony_ci DefaultActionKey key = DEFAULT_ACT_IN_KEY; 314b1b8bc3fSopenharmony_ci enum sk_action val = (inDefault == FirewallRuleAction::RULE_ALLOW) ? SK_PASS : SK_DROP; 315b1b8bc3fSopenharmony_ci WriteBpfMap(MAP_PATH(DEFAULT_ACTION_MAP), key, val); 316b1b8bc3fSopenharmony_ci 317b1b8bc3fSopenharmony_ci key = DEFAULT_ACT_OUT_KEY; 318b1b8bc3fSopenharmony_ci val = (outDefault == FirewallRuleAction::RULE_ALLOW) ? SK_PASS : SK_DROP; 319b1b8bc3fSopenharmony_ci WriteBpfMap(MAP_PATH(DEFAULT_ACTION_MAP), key, val); 320b1b8bc3fSopenharmony_ci CtKey ctKey; 321b1b8bc3fSopenharmony_ci CtVaule ctVal; 322b1b8bc3fSopenharmony_ci ClearBpfMap(MAP_PATH(CT_MAP), ctKey, ctVal); 323b1b8bc3fSopenharmony_ci return NETFIREWALL_SUCCESS; 324b1b8bc3fSopenharmony_ci} 325b1b8bc3fSopenharmony_ci 326b1b8bc3fSopenharmony_ciint32_t NetsysBpfNetFirewall::SetFirewallCurrentUserId(int32_t userId) 327b1b8bc3fSopenharmony_ci{ 328b1b8bc3fSopenharmony_ci if (!isBpfLoaded_) { 329b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("SetFirewallCurrentUserId: bpf not loaded"); 330b1b8bc3fSopenharmony_ci return NETFIREWALL_ERR; 331b1b8bc3fSopenharmony_ci } 332b1b8bc3fSopenharmony_ci 333b1b8bc3fSopenharmony_ci CurrentUserIdKey key = CURRENT_USER_ID_KEY; 334b1b8bc3fSopenharmony_ci UidKey val = (UidKey)userId; 335b1b8bc3fSopenharmony_ci WriteBpfMap(MAP_PATH(CURRENT_UID_MAP), key, val); 336b1b8bc3fSopenharmony_ci return NETFIREWALL_SUCCESS; 337b1b8bc3fSopenharmony_ci} 338b1b8bc3fSopenharmony_ci 339b1b8bc3fSopenharmony_civoid NetsysBpfNetFirewall::WriteSrcIpv4BpfMap(BitmapManager &manager, NetFirewallRuleDirection direction) 340b1b8bc3fSopenharmony_ci{ 341b1b8bc3fSopenharmony_ci std::vector<Ip4RuleBitmap> &srcIp4Map = manager.GetSrcIp4Map(); 342b1b8bc3fSopenharmony_ci if (srcIp4Map.empty()) { 343b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("WriteSrcIpv4BpfMap: srcIp4Map is empty"); 344b1b8bc3fSopenharmony_ci return; 345b1b8bc3fSopenharmony_ci } 346b1b8bc3fSopenharmony_ci bool ingress = (direction == NetFirewallRuleDirection::RULE_IN); 347b1b8bc3fSopenharmony_ci for (const auto &node : srcIp4Map) { 348b1b8bc3fSopenharmony_ci Bitmap val = node.bitmap; 349b1b8bc3fSopenharmony_ci RuleCode rule; 350b1b8bc3fSopenharmony_ci memcpy_s(rule.val, sizeof(RuleCode), val.Get(), sizeof(RuleCode)); 351b1b8bc3fSopenharmony_ci 352b1b8bc3fSopenharmony_ci Ipv4LpmKey key = { 0 }; 353b1b8bc3fSopenharmony_ci key.prefixlen = node.mask; 354b1b8bc3fSopenharmony_ci key.data = static_cast<Ip4Key>(node.data); 355b1b8bc3fSopenharmony_ci WriteBpfMap(GET_MAP_PATH(ingress, saddr), key, rule); 356b1b8bc3fSopenharmony_ci } 357b1b8bc3fSopenharmony_ci} 358b1b8bc3fSopenharmony_ci 359b1b8bc3fSopenharmony_civoid NetsysBpfNetFirewall::WriteSrcIpv6BpfMap(BitmapManager &manager, NetFirewallRuleDirection direction) 360b1b8bc3fSopenharmony_ci{ 361b1b8bc3fSopenharmony_ci std::vector<Ip6RuleBitmap> &srcIp6Map = manager.GetSrcIp6Map(); 362b1b8bc3fSopenharmony_ci if (srcIp6Map.empty()) { 363b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("WriteSrcIpv6BpfMap: srcIp6Map is empty"); 364b1b8bc3fSopenharmony_ci return; 365b1b8bc3fSopenharmony_ci } 366b1b8bc3fSopenharmony_ci bool ingress = (direction == NetFirewallRuleDirection::RULE_IN); 367b1b8bc3fSopenharmony_ci for (const auto &node : srcIp6Map) { 368b1b8bc3fSopenharmony_ci Bitmap val = node.bitmap; 369b1b8bc3fSopenharmony_ci RuleCode rule; 370b1b8bc3fSopenharmony_ci memcpy_s(rule.val, sizeof(RuleCode), val.Get(), sizeof(RuleCode)); 371b1b8bc3fSopenharmony_ci 372b1b8bc3fSopenharmony_ci Ipv6LpmKey key = { 0 }; 373b1b8bc3fSopenharmony_ci key.prefixlen = node.prefixlen; 374b1b8bc3fSopenharmony_ci key.data = static_cast<Ip6Key>(node.data); 375b1b8bc3fSopenharmony_ci WriteBpfMap(GET_MAP_PATH(ingress, saddr6), key, rule); 376b1b8bc3fSopenharmony_ci } 377b1b8bc3fSopenharmony_ci} 378b1b8bc3fSopenharmony_ci 379b1b8bc3fSopenharmony_civoid NetsysBpfNetFirewall::WriteDstIpv4BpfMap(BitmapManager &manager, NetFirewallRuleDirection direction) 380b1b8bc3fSopenharmony_ci{ 381b1b8bc3fSopenharmony_ci std::vector<Ip4RuleBitmap> &dstIp4Map = manager.GetDstIp4Map(); 382b1b8bc3fSopenharmony_ci if (dstIp4Map.empty()) { 383b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("WriteDstIp4BpfMap: dstIp4Map is empty"); 384b1b8bc3fSopenharmony_ci } else { 385b1b8bc3fSopenharmony_ci bool ingress = (direction == NetFirewallRuleDirection::RULE_IN); 386b1b8bc3fSopenharmony_ci for (const auto &node : dstIp4Map) { 387b1b8bc3fSopenharmony_ci Bitmap val = node.bitmap; 388b1b8bc3fSopenharmony_ci RuleCode rule; 389b1b8bc3fSopenharmony_ci memcpy_s(rule.val, sizeof(RuleCode), val.Get(), sizeof(RuleCode)); 390b1b8bc3fSopenharmony_ci 391b1b8bc3fSopenharmony_ci Ipv4LpmKey key = { 0 }; 392b1b8bc3fSopenharmony_ci key.prefixlen = node.mask; 393b1b8bc3fSopenharmony_ci key.data = static_cast<Ip4Key>(node.data); 394b1b8bc3fSopenharmony_ci WriteBpfMap(GET_MAP_PATH(ingress, daddr), key, rule); 395b1b8bc3fSopenharmony_ci } 396b1b8bc3fSopenharmony_ci } 397b1b8bc3fSopenharmony_ci} 398b1b8bc3fSopenharmony_ci 399b1b8bc3fSopenharmony_civoid NetsysBpfNetFirewall::WriteDstIpv6BpfMap(BitmapManager &manager, NetFirewallRuleDirection direction) 400b1b8bc3fSopenharmony_ci{ 401b1b8bc3fSopenharmony_ci std::vector<Ip6RuleBitmap> &dstIp6Map = manager.GetDstIp6Map(); 402b1b8bc3fSopenharmony_ci if (dstIp6Map.empty()) { 403b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("WriteDstIp6BpfMap: dstIp6Map is empty"); 404b1b8bc3fSopenharmony_ci } else { 405b1b8bc3fSopenharmony_ci bool ingress = (direction == NetFirewallRuleDirection::RULE_IN); 406b1b8bc3fSopenharmony_ci for (const auto &node : dstIp6Map) { 407b1b8bc3fSopenharmony_ci Bitmap val = node.bitmap; 408b1b8bc3fSopenharmony_ci RuleCode rule; 409b1b8bc3fSopenharmony_ci memcpy_s(rule.val, sizeof(RuleCode), val.Get(), sizeof(RuleCode)); 410b1b8bc3fSopenharmony_ci 411b1b8bc3fSopenharmony_ci Ipv6LpmKey key = { 0 }; 412b1b8bc3fSopenharmony_ci key.prefixlen = node.prefixlen; 413b1b8bc3fSopenharmony_ci key.data = static_cast<Ip6Key>(node.data); 414b1b8bc3fSopenharmony_ci WriteBpfMap(GET_MAP_PATH(ingress, daddr6), key, rule); 415b1b8bc3fSopenharmony_ci } 416b1b8bc3fSopenharmony_ci } 417b1b8bc3fSopenharmony_ci} 418b1b8bc3fSopenharmony_ci 419b1b8bc3fSopenharmony_civoid NetsysBpfNetFirewall::WriteSrcPortBpfMap(BitmapManager &manager, NetFirewallRuleDirection direction) 420b1b8bc3fSopenharmony_ci{ 421b1b8bc3fSopenharmony_ci BpfPortMap &srcPortMap = manager.GetSrcPortMap(); 422b1b8bc3fSopenharmony_ci if (srcPortMap.Empty()) { 423b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("WriteSrcPortBpfMap: srcPortMap is empty"); 424b1b8bc3fSopenharmony_ci } else { 425b1b8bc3fSopenharmony_ci bool ingress = (direction == NetFirewallRuleDirection::RULE_IN); 426b1b8bc3fSopenharmony_ci for (const auto &pair : srcPortMap.Get()) { 427b1b8bc3fSopenharmony_ci PortKey key = pair.first; 428b1b8bc3fSopenharmony_ci Bitmap val = pair.second; 429b1b8bc3fSopenharmony_ci RuleCode rule; 430b1b8bc3fSopenharmony_ci memcpy_s(rule.val, sizeof(RuleCode), val.Get(), sizeof(RuleCode)); 431b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("sport_map=%{public}u", key); 432b1b8bc3fSopenharmony_ci WriteBpfMap(GET_MAP_PATH(ingress, sport), key, rule); 433b1b8bc3fSopenharmony_ci } 434b1b8bc3fSopenharmony_ci } 435b1b8bc3fSopenharmony_ci} 436b1b8bc3fSopenharmony_ci 437b1b8bc3fSopenharmony_civoid NetsysBpfNetFirewall::WriteDstPortBpfMap(BitmapManager &manager, NetFirewallRuleDirection direction) 438b1b8bc3fSopenharmony_ci{ 439b1b8bc3fSopenharmony_ci BpfPortMap &dstPortMap = manager.GetDstPortMap(); 440b1b8bc3fSopenharmony_ci if (dstPortMap.Empty()) { 441b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("WriteDstPortBpfMap: dstPortMap is empty"); 442b1b8bc3fSopenharmony_ci } else { 443b1b8bc3fSopenharmony_ci bool ingress = (direction == NetFirewallRuleDirection::RULE_IN); 444b1b8bc3fSopenharmony_ci for (const auto &pair : dstPortMap.Get()) { 445b1b8bc3fSopenharmony_ci PortKey key = pair.first; 446b1b8bc3fSopenharmony_ci Bitmap val = pair.second; 447b1b8bc3fSopenharmony_ci RuleCode rule; 448b1b8bc3fSopenharmony_ci memcpy_s(rule.val, sizeof(RuleCode), val.Get(), sizeof(RuleCode)); 449b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("dport_map=%{public}u", key); 450b1b8bc3fSopenharmony_ci WriteBpfMap(GET_MAP_PATH(ingress, dport), key, rule); 451b1b8bc3fSopenharmony_ci } 452b1b8bc3fSopenharmony_ci } 453b1b8bc3fSopenharmony_ci} 454b1b8bc3fSopenharmony_ci 455b1b8bc3fSopenharmony_civoid NetsysBpfNetFirewall::WriteProtoBpfMap(BitmapManager &manager, NetFirewallRuleDirection direction) 456b1b8bc3fSopenharmony_ci{ 457b1b8bc3fSopenharmony_ci BpfProtoMap &protoMap = manager.GetProtoMap(); 458b1b8bc3fSopenharmony_ci if (protoMap.Empty()) { 459b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("WriteProtoBpfMap: protoMap is empty"); 460b1b8bc3fSopenharmony_ci } else { 461b1b8bc3fSopenharmony_ci bool ingress = (direction == NetFirewallRuleDirection::RULE_IN); 462b1b8bc3fSopenharmony_ci for (const auto &pair : protoMap.Get()) { 463b1b8bc3fSopenharmony_ci ProtoKey key = pair.first; 464b1b8bc3fSopenharmony_ci Bitmap val = pair.second; 465b1b8bc3fSopenharmony_ci RuleCode rule; 466b1b8bc3fSopenharmony_ci memcpy_s(rule.val, sizeof(RuleCode), val.Get(), sizeof(RuleCode)); 467b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("proto_map=%{public}u", key); 468b1b8bc3fSopenharmony_ci WriteBpfMap(GET_MAP_PATH(ingress, proto), key, rule); 469b1b8bc3fSopenharmony_ci } 470b1b8bc3fSopenharmony_ci } 471b1b8bc3fSopenharmony_ci} 472b1b8bc3fSopenharmony_ci 473b1b8bc3fSopenharmony_civoid NetsysBpfNetFirewall::WriteAppUidBpfMap(BitmapManager &manager, NetFirewallRuleDirection direction) 474b1b8bc3fSopenharmony_ci{ 475b1b8bc3fSopenharmony_ci BpfAppUidMap &appIdMap = manager.GetAppIdMap(); 476b1b8bc3fSopenharmony_ci if (appIdMap.Empty()) { 477b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("WriteAppUidBpfMap: appIdMap is empty"); 478b1b8bc3fSopenharmony_ci } else { 479b1b8bc3fSopenharmony_ci bool ingress = (direction == NetFirewallRuleDirection::RULE_IN); 480b1b8bc3fSopenharmony_ci for (const auto &pair : appIdMap.Get()) { 481b1b8bc3fSopenharmony_ci AppUidKey key = pair.first; 482b1b8bc3fSopenharmony_ci Bitmap val = pair.second; 483b1b8bc3fSopenharmony_ci RuleCode rule; 484b1b8bc3fSopenharmony_ci memcpy_s(rule.val, sizeof(RuleCode), val.Get(), sizeof(RuleCode)); 485b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("appuid_map=%{public}u", key); 486b1b8bc3fSopenharmony_ci WriteBpfMap(GET_MAP_PATH(ingress, appuid), key, rule); 487b1b8bc3fSopenharmony_ci } 488b1b8bc3fSopenharmony_ci } 489b1b8bc3fSopenharmony_ci} 490b1b8bc3fSopenharmony_ci 491b1b8bc3fSopenharmony_civoid NetsysBpfNetFirewall::WriteUidBpfMap(BitmapManager &manager, NetFirewallRuleDirection direction) 492b1b8bc3fSopenharmony_ci{ 493b1b8bc3fSopenharmony_ci BpfUidMap &uidMap = manager.GetUidMap(); 494b1b8bc3fSopenharmony_ci if (uidMap.Empty()) { 495b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("WriteUidBpfMap: uidMap is empty"); 496b1b8bc3fSopenharmony_ci } else { 497b1b8bc3fSopenharmony_ci bool ingress = (direction == NetFirewallRuleDirection::RULE_IN); 498b1b8bc3fSopenharmony_ci for (const auto &pair : uidMap.Get()) { 499b1b8bc3fSopenharmony_ci UidKey key = pair.first; 500b1b8bc3fSopenharmony_ci Bitmap val = pair.second; 501b1b8bc3fSopenharmony_ci RuleCode rule; 502b1b8bc3fSopenharmony_ci memcpy_s(rule.val, sizeof(RuleCode), val.Get(), sizeof(RuleCode)); 503b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("uidMap=%{public}u", key); 504b1b8bc3fSopenharmony_ci WriteBpfMap(GET_MAP_PATH(ingress, uid), key, rule); 505b1b8bc3fSopenharmony_ci } 506b1b8bc3fSopenharmony_ci } 507b1b8bc3fSopenharmony_ci} 508b1b8bc3fSopenharmony_ci 509b1b8bc3fSopenharmony_civoid NetsysBpfNetFirewall::WriteActionBpfMap(BitmapManager &manager, NetFirewallRuleDirection direction) 510b1b8bc3fSopenharmony_ci{ 511b1b8bc3fSopenharmony_ci BpfActionMap &actionMap = manager.GetActionMap(); 512b1b8bc3fSopenharmony_ci if (actionMap.Empty()) { 513b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("WriteActionBpfMap: actionMap is empty"); 514b1b8bc3fSopenharmony_ci } else { 515b1b8bc3fSopenharmony_ci bool ingress = (direction == NetFirewallRuleDirection::RULE_IN); 516b1b8bc3fSopenharmony_ci for (const auto &pair : actionMap.Get()) { 517b1b8bc3fSopenharmony_ci ActionKey key = pair.first; 518b1b8bc3fSopenharmony_ci Bitmap val = pair.second; 519b1b8bc3fSopenharmony_ci RuleCode rule; 520b1b8bc3fSopenharmony_ci memcpy_s(rule.val, sizeof(RuleCode), val.Get(), sizeof(RuleCode)); 521b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("action_map=%{public}u", val.Get()[0]); 522b1b8bc3fSopenharmony_ci WriteBpfMap(GET_MAP_PATH(ingress, action), key, rule); 523b1b8bc3fSopenharmony_ci } 524b1b8bc3fSopenharmony_ci } 525b1b8bc3fSopenharmony_ci} 526b1b8bc3fSopenharmony_ci 527b1b8bc3fSopenharmony_ciint32_t NetsysBpfNetFirewall::RegisterCallback(const sptr<NetsysNative::INetFirewallCallback> &callback) 528b1b8bc3fSopenharmony_ci{ 529b1b8bc3fSopenharmony_ci if (!callback) { 530b1b8bc3fSopenharmony_ci return -1; 531b1b8bc3fSopenharmony_ci } 532b1b8bc3fSopenharmony_ci 533b1b8bc3fSopenharmony_ci callbacks_.emplace_back(callback); 534b1b8bc3fSopenharmony_ci 535b1b8bc3fSopenharmony_ci return 0; 536b1b8bc3fSopenharmony_ci} 537b1b8bc3fSopenharmony_ciint32_t NetsysBpfNetFirewall::UnregisterCallback(const sptr<NetsysNative::INetFirewallCallback> &callback) 538b1b8bc3fSopenharmony_ci{ 539b1b8bc3fSopenharmony_ci if (!callback) { 540b1b8bc3fSopenharmony_ci return -1; 541b1b8bc3fSopenharmony_ci } 542b1b8bc3fSopenharmony_ci 543b1b8bc3fSopenharmony_ci for (auto it = callbacks_.begin(); it != callbacks_.end(); ++it) { 544b1b8bc3fSopenharmony_ci if (*it == callback) { 545b1b8bc3fSopenharmony_ci callbacks_.erase(it); 546b1b8bc3fSopenharmony_ci return 0; 547b1b8bc3fSopenharmony_ci } 548b1b8bc3fSopenharmony_ci } 549b1b8bc3fSopenharmony_ci return -1; 550b1b8bc3fSopenharmony_ci} 551b1b8bc3fSopenharmony_ci 552b1b8bc3fSopenharmony_cibool NetsysBpfNetFirewall::ShouldSkipNotify(sptr<InterceptRecord> record) 553b1b8bc3fSopenharmony_ci{ 554b1b8bc3fSopenharmony_ci if (!record) { 555b1b8bc3fSopenharmony_ci return true; 556b1b8bc3fSopenharmony_ci } 557b1b8bc3fSopenharmony_ci if (oldRecord_ != nullptr && (record->time - oldRecord_->time) < INTERCEPT_BUFF_INTERVAL_SEC) { 558b1b8bc3fSopenharmony_ci if (record->localIp == oldRecord_->localIp && record->remoteIp == oldRecord_->remoteIp && 559b1b8bc3fSopenharmony_ci record->localPort == oldRecord_->localPort && record->remotePort == oldRecord_->remotePort && 560b1b8bc3fSopenharmony_ci record->protocol == oldRecord_->protocol && record->appUid == oldRecord_->appUid) { 561b1b8bc3fSopenharmony_ci return true; 562b1b8bc3fSopenharmony_ci } 563b1b8bc3fSopenharmony_ci } 564b1b8bc3fSopenharmony_ci oldRecord_ = record; 565b1b8bc3fSopenharmony_ci return false; 566b1b8bc3fSopenharmony_ci} 567b1b8bc3fSopenharmony_ci 568b1b8bc3fSopenharmony_civoid NetsysBpfNetFirewall::NotifyInterceptEvent(InterceptEvent *info) 569b1b8bc3fSopenharmony_ci{ 570b1b8bc3fSopenharmony_ci if (!info) { 571b1b8bc3fSopenharmony_ci return; 572b1b8bc3fSopenharmony_ci } 573b1b8bc3fSopenharmony_ci sptr<InterceptRecord> record = new (std::nothrow) InterceptRecord(); 574b1b8bc3fSopenharmony_ci record->time = (int32_t)time(NULL); 575b1b8bc3fSopenharmony_ci record->localPort = BitmapManager::Nstohl(info->sport); 576b1b8bc3fSopenharmony_ci record->remotePort = BitmapManager::Nstohl(info->dport); 577b1b8bc3fSopenharmony_ci record->protocol = static_cast<uint16_t>(info->protocol); 578b1b8bc3fSopenharmony_ci record->appUid = (int32_t)info->appuid; 579b1b8bc3fSopenharmony_ci std::string srcIp; 580b1b8bc3fSopenharmony_ci std::string dstIp; 581b1b8bc3fSopenharmony_ci if (info->family == AF_INET) { 582b1b8bc3fSopenharmony_ci char ip4[INET_ADDRSTRLEN] = {}; 583b1b8bc3fSopenharmony_ci inet_ntop(AF_INET, &(info->ipv4.saddr), ip4, INET_ADDRSTRLEN); 584b1b8bc3fSopenharmony_ci srcIp = ip4; 585b1b8bc3fSopenharmony_ci memset_s(ip4, INET_ADDRSTRLEN, 0, INET_ADDRSTRLEN); 586b1b8bc3fSopenharmony_ci inet_ntop(AF_INET, &(info->ipv4.daddr), ip4, INET_ADDRSTRLEN); 587b1b8bc3fSopenharmony_ci dstIp = ip4; 588b1b8bc3fSopenharmony_ci } else { 589b1b8bc3fSopenharmony_ci char ip6[INET6_ADDRSTRLEN] = {}; 590b1b8bc3fSopenharmony_ci inet_ntop(AF_INET6, &(info->ipv6.saddr), ip6, INET6_ADDRSTRLEN); 591b1b8bc3fSopenharmony_ci srcIp = ip6; 592b1b8bc3fSopenharmony_ci memset_s(ip6, INET6_ADDRSTRLEN, 0, INET6_ADDRSTRLEN); 593b1b8bc3fSopenharmony_ci inet_ntop(AF_INET6, &(info->ipv6.daddr), ip6, INET6_ADDRSTRLEN); 594b1b8bc3fSopenharmony_ci dstIp = ip6; 595b1b8bc3fSopenharmony_ci } 596b1b8bc3fSopenharmony_ci if (info->dir == INGRESS) { 597b1b8bc3fSopenharmony_ci record->localIp = srcIp; 598b1b8bc3fSopenharmony_ci record->remoteIp = dstIp; 599b1b8bc3fSopenharmony_ci } else { 600b1b8bc3fSopenharmony_ci record->localIp = dstIp; 601b1b8bc3fSopenharmony_ci record->remoteIp = srcIp; 602b1b8bc3fSopenharmony_ci } 603b1b8bc3fSopenharmony_ci if (ShouldSkipNotify(record)) { 604b1b8bc3fSopenharmony_ci return; 605b1b8bc3fSopenharmony_ci } 606b1b8bc3fSopenharmony_ci for (auto callback : callbacks_) { 607b1b8bc3fSopenharmony_ci callback->OnIntercept(record); 608b1b8bc3fSopenharmony_ci } 609b1b8bc3fSopenharmony_ci} 610b1b8bc3fSopenharmony_ci 611b1b8bc3fSopenharmony_civoid NetsysBpfNetFirewall::HandleTupleEvent(TupleEvent *ev) 612b1b8bc3fSopenharmony_ci{ 613b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D( 614b1b8bc3fSopenharmony_ci "%{public}s tuple: sport=%{public}u dport=%{public}u protocol=%{public}u appuid=%{public}u uid=%{public}u", 615b1b8bc3fSopenharmony_ci (ev->dir == INGRESS) ? "> ingress" : "< egress", ntohs(ev->sport), ntohs(ev->dport), ev->protocol, ev->appuid, 616b1b8bc3fSopenharmony_ci ev->uid); 617b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("\trstpacket=%{public}u", ev->rst); 618b1b8bc3fSopenharmony_ci} 619b1b8bc3fSopenharmony_ci 620b1b8bc3fSopenharmony_civoid NetsysBpfNetFirewall::HandleInterceptEvent(InterceptEvent *ev) 621b1b8bc3fSopenharmony_ci{ 622b1b8bc3fSopenharmony_ci GetInstance()->NotifyInterceptEvent(ev); 623b1b8bc3fSopenharmony_ci 624b1b8bc3fSopenharmony_ci NETNATIVE_LOGI("%{public}s intercept: sport=%{public}u dport=%{public}u protocol=%{public}u appuid=%{public}u", 625b1b8bc3fSopenharmony_ci (ev->dir == INGRESS) ? "ingress" : "egress", ntohs(ev->sport), ntohs(ev->dport), ev->protocol, ev->appuid); 626b1b8bc3fSopenharmony_ci} 627b1b8bc3fSopenharmony_ci 628b1b8bc3fSopenharmony_civoid NetsysBpfNetFirewall::HandleDebugEvent(DebugEvent *ev) 629b1b8bc3fSopenharmony_ci{ 630b1b8bc3fSopenharmony_ci const char *direction = ev->dir == INGRESS ? ">" : "<"; 631b1b8bc3fSopenharmony_ci switch (ev->type) { 632b1b8bc3fSopenharmony_ci case DBG_MATCH_SPORT: 633b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("%{public}s sport: %{public}u bitmap: %{public}x", direction, ntohs(ev->arg1), ev->arg2); 634b1b8bc3fSopenharmony_ci break; 635b1b8bc3fSopenharmony_ci case DBG_MATCH_DPORT: 636b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("%{public}s dport: %{public}u bitmap: %{public}x", direction, ntohs(ev->arg1), ev->arg2); 637b1b8bc3fSopenharmony_ci break; 638b1b8bc3fSopenharmony_ci case DBG_MATCH_PROTO: 639b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("%{public}s protocol: %{public}u bitmap: %{public}x", direction, ev->arg1, ev->arg2); 640b1b8bc3fSopenharmony_ci break; 641b1b8bc3fSopenharmony_ci case DBG_MATCH_APPUID: 642b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("%{public}s appuid: %{public}u bitmap: %{public}x", direction, ev->arg1, ev->arg2); 643b1b8bc3fSopenharmony_ci break; 644b1b8bc3fSopenharmony_ci case DBG_MATCH_UID: 645b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("%{public}s uid: %{public}u bitmap: %{public}x", direction, ev->arg1, ev->arg2); 646b1b8bc3fSopenharmony_ci break; 647b1b8bc3fSopenharmony_ci case DBG_ACTION_KEY: 648b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("%{public}s actionkey: %{public}x", direction, ev->arg1); 649b1b8bc3fSopenharmony_ci break; 650b1b8bc3fSopenharmony_ci case DBG_MATCH_ACTION: 651b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("%{public}s action: %{public}s", direction, (ev->arg1 == SK_PASS ? "PASS" : "DROP")); 652b1b8bc3fSopenharmony_ci break; 653b1b8bc3fSopenharmony_ci case DBG_CT_LOOKUP: 654b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("%{public}s ct lookup status: %{public}u", direction, ev->arg1); 655b1b8bc3fSopenharmony_ci break; 656b1b8bc3fSopenharmony_ci case DBG_MATCH_DOMAIN: 657b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("egress match domain, action PASS"); 658b1b8bc3fSopenharmony_ci break; 659b1b8bc3fSopenharmony_ci default: 660b1b8bc3fSopenharmony_ci break; 661b1b8bc3fSopenharmony_ci } 662b1b8bc3fSopenharmony_ci} 663b1b8bc3fSopenharmony_ci 664b1b8bc3fSopenharmony_ciint NetsysBpfNetFirewall::HandleEvent(void *ctx, void *data, size_t len) 665b1b8bc3fSopenharmony_ci{ 666b1b8bc3fSopenharmony_ci if (data && len > 0) { 667b1b8bc3fSopenharmony_ci Event *ev = (Event *)data; 668b1b8bc3fSopenharmony_ci 669b1b8bc3fSopenharmony_ci switch (ev->type) { 670b1b8bc3fSopenharmony_ci case EVENT_DEBUG: { 671b1b8bc3fSopenharmony_ci HandleDebugEvent(&(ev->debug)); 672b1b8bc3fSopenharmony_ci break; 673b1b8bc3fSopenharmony_ci } 674b1b8bc3fSopenharmony_ci case EVENT_INTERCEPT: { 675b1b8bc3fSopenharmony_ci HandleInterceptEvent(&(ev->intercept)); 676b1b8bc3fSopenharmony_ci break; 677b1b8bc3fSopenharmony_ci } 678b1b8bc3fSopenharmony_ci case EVENT_TUPLE_DEBUG: { 679b1b8bc3fSopenharmony_ci HandleTupleEvent(&(ev->tuple)); 680b1b8bc3fSopenharmony_ci break; 681b1b8bc3fSopenharmony_ci } 682b1b8bc3fSopenharmony_ci default: 683b1b8bc3fSopenharmony_ci break; 684b1b8bc3fSopenharmony_ci } 685b1b8bc3fSopenharmony_ci } 686b1b8bc3fSopenharmony_ci return 0; 687b1b8bc3fSopenharmony_ci} 688b1b8bc3fSopenharmony_ci 689b1b8bc3fSopenharmony_civoid OnDemandLoadManagerCallback::OnLoadSystemAbilitySuccess(int32_t systemAbilityId, 690b1b8bc3fSopenharmony_ci const sptr<IRemoteObject> &remoteObject) 691b1b8bc3fSopenharmony_ci{ 692b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("OnLoadSystemAbilitySuccess systemAbilityId: [%{public}d]", systemAbilityId); 693b1b8bc3fSopenharmony_ci} 694b1b8bc3fSopenharmony_ci 695b1b8bc3fSopenharmony_civoid OnDemandLoadManagerCallback::OnLoadSystemAbilityFail(int32_t systemAbilityId) 696b1b8bc3fSopenharmony_ci{ 697b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("OnLoadSystemAbilityFail: [%{public}d]", systemAbilityId); 698b1b8bc3fSopenharmony_ci} 699b1b8bc3fSopenharmony_ci 700b1b8bc3fSopenharmony_ciint32_t NetsysBpfNetFirewall::LoadSystemAbility(int32_t systemAbilityId) 701b1b8bc3fSopenharmony_ci{ 702b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("LoadSystemAbility: [%{public}d]", systemAbilityId); 703b1b8bc3fSopenharmony_ci auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 704b1b8bc3fSopenharmony_ci if (saManager == nullptr) { 705b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("GetCmProxy registry is null"); 706b1b8bc3fSopenharmony_ci return -1; 707b1b8bc3fSopenharmony_ci } 708b1b8bc3fSopenharmony_ci 709b1b8bc3fSopenharmony_ci auto object = saManager->CheckSystemAbility(systemAbilityId); 710b1b8bc3fSopenharmony_ci if (object != nullptr) { 711b1b8bc3fSopenharmony_ci return 0; 712b1b8bc3fSopenharmony_ci } 713b1b8bc3fSopenharmony_ci 714b1b8bc3fSopenharmony_ci sptr<OnDemandLoadManagerCallback> loadCallBack = new (std::nothrow) OnDemandLoadManagerCallback(); 715b1b8bc3fSopenharmony_ci if (loadCallBack == nullptr) { 716b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("new OnDemandLoadCertManagerCallback failed"); 717b1b8bc3fSopenharmony_ci return -1; 718b1b8bc3fSopenharmony_ci } 719b1b8bc3fSopenharmony_ci 720b1b8bc3fSopenharmony_ci int32_t ret = saManager->LoadSystemAbility(systemAbilityId, loadCallBack); 721b1b8bc3fSopenharmony_ci if (ret != ERR_OK) { 722b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("systemAbilityId:%d load failed,result code:%d", systemAbilityId, ret); 723b1b8bc3fSopenharmony_ci return -1; 724b1b8bc3fSopenharmony_ci } 725b1b8bc3fSopenharmony_ci return 0; 726b1b8bc3fSopenharmony_ci} 727b1b8bc3fSopenharmony_ci 728b1b8bc3fSopenharmony_civoid NetsysBpfNetFirewall::AddDomainCache(const NetAddrInfo &addrInfo) 729b1b8bc3fSopenharmony_ci{ 730b1b8bc3fSopenharmony_ci NETNATIVE_LOGI("AddDomainCache"); 731b1b8bc3fSopenharmony_ci domain_value value = 1; 732b1b8bc3fSopenharmony_ci if (addrInfo.aiFamily == AF_INET) { 733b1b8bc3fSopenharmony_ci Ipv4LpmKey key = { 0 }; 734b1b8bc3fSopenharmony_ci key.prefixlen = IPV4_MAX_PREFIXLEN; 735b1b8bc3fSopenharmony_ci key.data = addrInfo.aiAddr.sin.s_addr; 736b1b8bc3fSopenharmony_ci WriteBpfMap(MAP_PATH(DOMAIN_IPV4_MAP), key, value); 737b1b8bc3fSopenharmony_ci } else { 738b1b8bc3fSopenharmony_ci Ipv6LpmKey key = { 0 }; 739b1b8bc3fSopenharmony_ci key.prefixlen = IPV6_MAX_PREFIXLEN; 740b1b8bc3fSopenharmony_ci key.data = addrInfo.aiAddr.sin6; 741b1b8bc3fSopenharmony_ci WriteBpfMap(MAP_PATH(DOMAIN_IPV6_MAP), key, value); 742b1b8bc3fSopenharmony_ci } 743b1b8bc3fSopenharmony_ci} 744b1b8bc3fSopenharmony_ci 745b1b8bc3fSopenharmony_civoid NetsysBpfNetFirewall::ClearDomainCache() 746b1b8bc3fSopenharmony_ci{ 747b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("ClearDomainCache"); 748b1b8bc3fSopenharmony_ci Ipv4LpmKey ip4Key = {}; 749b1b8bc3fSopenharmony_ci Ipv6LpmKey ip6Key = {}; 750b1b8bc3fSopenharmony_ci domain_value value; 751b1b8bc3fSopenharmony_ci ClearBpfMap(MAP_PATH(DOMAIN_IPV4_MAP), ip4Key, value); 752b1b8bc3fSopenharmony_ci ClearBpfMap(MAP_PATH(DOMAIN_IPV6_MAP), ip6Key, value); 753b1b8bc3fSopenharmony_ci} 754b1b8bc3fSopenharmony_ci} // namespace NetManagerStandard 755b1b8bc3fSopenharmony_ci} // namespace OHOS