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 "bitmap_manager.h" 17b1b8bc3fSopenharmony_ci 18b1b8bc3fSopenharmony_ci#include <arpa/inet.h> 19b1b8bc3fSopenharmony_ci#include <cstdio> 20b1b8bc3fSopenharmony_ci#include <netdb.h> 21b1b8bc3fSopenharmony_ci#include <securec.h> 22b1b8bc3fSopenharmony_ci#include <string> 23b1b8bc3fSopenharmony_ci#include <sys/socket.h> 24b1b8bc3fSopenharmony_ci#include <vector> 25b1b8bc3fSopenharmony_ci 26b1b8bc3fSopenharmony_ci#include "netmanager_base_common_utils.h" 27b1b8bc3fSopenharmony_ci#include "netnative_log_wrapper.h" 28b1b8bc3fSopenharmony_ci#include "netsys_net_dns_result_data.h" 29b1b8bc3fSopenharmony_ci 30b1b8bc3fSopenharmony_ciusing namespace OHOS::NetsysNative; 31b1b8bc3fSopenharmony_ci 32b1b8bc3fSopenharmony_cinamespace OHOS { 33b1b8bc3fSopenharmony_cinamespace NetManagerStandard { 34b1b8bc3fSopenharmony_ciconst uint32_t BITMAP_BIT_COUNT = (BITMAP_LEN * sizeof(uint32_t) * BIT_PER_BYTE); 35b1b8bc3fSopenharmony_ci 36b1b8bc3fSopenharmony_ciBitmap::Bitmap() 37b1b8bc3fSopenharmony_ci{ 38b1b8bc3fSopenharmony_ci Clear(); 39b1b8bc3fSopenharmony_ci} 40b1b8bc3fSopenharmony_ci 41b1b8bc3fSopenharmony_ciBitmap::Bitmap(uint32_t n) 42b1b8bc3fSopenharmony_ci{ 43b1b8bc3fSopenharmony_ci Clear(); 44b1b8bc3fSopenharmony_ci Set(n); 45b1b8bc3fSopenharmony_ci} 46b1b8bc3fSopenharmony_ci 47b1b8bc3fSopenharmony_ciBitmap::Bitmap(const Bitmap &other) 48b1b8bc3fSopenharmony_ci{ 49b1b8bc3fSopenharmony_ci memcpy_s(bitmap_, sizeof(bitmap_), other.bitmap_, sizeof(bitmap_)); 50b1b8bc3fSopenharmony_ci} 51b1b8bc3fSopenharmony_ci 52b1b8bc3fSopenharmony_civoid Bitmap::Clear() 53b1b8bc3fSopenharmony_ci{ 54b1b8bc3fSopenharmony_ci memset_s(bitmap_, sizeof(bitmap_), 0, sizeof(bitmap_)); 55b1b8bc3fSopenharmony_ci} 56b1b8bc3fSopenharmony_ci 57b1b8bc3fSopenharmony_ciconst int BIT_OFFSET = 5; // n/32 58b1b8bc3fSopenharmony_ciconst int BIT_REMAINDER = 0x1f; // n%32 59b1b8bc3fSopenharmony_civoid Bitmap::Set(uint32_t n) 60b1b8bc3fSopenharmony_ci{ 61b1b8bc3fSopenharmony_ci if (n < BITMAP_BIT_COUNT) { 62b1b8bc3fSopenharmony_ci int32_t i = n >> BIT_OFFSET; 63b1b8bc3fSopenharmony_ci int32_t j = n & BIT_REMAINDER; 64b1b8bc3fSopenharmony_ci bitmap_[i] |= 1 << j; 65b1b8bc3fSopenharmony_ci } 66b1b8bc3fSopenharmony_ci} 67b1b8bc3fSopenharmony_ci 68b1b8bc3fSopenharmony_ciuint64_t Bitmap::SpecialHash() const 69b1b8bc3fSopenharmony_ci{ 70b1b8bc3fSopenharmony_ci uint64_t h = 0; 71b1b8bc3fSopenharmony_ci for (int32_t i = 0; i < BITMAP_LEN; i++) { 72b1b8bc3fSopenharmony_ci if (bitmap_[i]) { 73b1b8bc3fSopenharmony_ci h = GetHash(bitmap_[i]); 74b1b8bc3fSopenharmony_ci h = h << i; 75b1b8bc3fSopenharmony_ci return h; 76b1b8bc3fSopenharmony_ci } 77b1b8bc3fSopenharmony_ci } 78b1b8bc3fSopenharmony_ci return h; 79b1b8bc3fSopenharmony_ci} 80b1b8bc3fSopenharmony_ci 81b1b8bc3fSopenharmony_civoid Bitmap::And(const Bitmap &other) 82b1b8bc3fSopenharmony_ci{ 83b1b8bc3fSopenharmony_ci for (int32_t i = 0; i < BITMAP_LEN; i++) { 84b1b8bc3fSopenharmony_ci bitmap_[i] &= other.bitmap_[i]; 85b1b8bc3fSopenharmony_ci } 86b1b8bc3fSopenharmony_ci} 87b1b8bc3fSopenharmony_ci 88b1b8bc3fSopenharmony_civoid Bitmap::Or(const Bitmap &other) 89b1b8bc3fSopenharmony_ci{ 90b1b8bc3fSopenharmony_ci for (int32_t i = 0; i < BITMAP_LEN; i++) { 91b1b8bc3fSopenharmony_ci bitmap_[i] |= other.bitmap_[i]; 92b1b8bc3fSopenharmony_ci } 93b1b8bc3fSopenharmony_ci} 94b1b8bc3fSopenharmony_ci 95b1b8bc3fSopenharmony_cibool Bitmap::operator == (const Bitmap &other) const 96b1b8bc3fSopenharmony_ci{ 97b1b8bc3fSopenharmony_ci return (memcmp(bitmap_, other.bitmap_, sizeof(bitmap_)) == 0); 98b1b8bc3fSopenharmony_ci} 99b1b8bc3fSopenharmony_ci 100b1b8bc3fSopenharmony_ciBitmap &Bitmap::operator = (const Bitmap &other) 101b1b8bc3fSopenharmony_ci{ 102b1b8bc3fSopenharmony_ci memcpy_s(bitmap_, sizeof(bitmap_), other.bitmap_, sizeof(bitmap_)); 103b1b8bc3fSopenharmony_ci return *this; 104b1b8bc3fSopenharmony_ci} 105b1b8bc3fSopenharmony_ci 106b1b8bc3fSopenharmony_ci// Thomas Wang's 32 bit Mix Function 107b1b8bc3fSopenharmony_ciuint32_t Bitmap::GetHash(uint32_t key) const 108b1b8bc3fSopenharmony_ci{ 109b1b8bc3fSopenharmony_ci const int THOMAS_INDEX_0 = 15; 110b1b8bc3fSopenharmony_ci const int THOMAS_INDEX_1 = 10; 111b1b8bc3fSopenharmony_ci const int THOMAS_INDEX_2 = 3; 112b1b8bc3fSopenharmony_ci const int THOMAS_INDEX_3 = 6; 113b1b8bc3fSopenharmony_ci const int THOMAS_INDEX_4 = 11; 114b1b8bc3fSopenharmony_ci const int THOMAS_INDEX_5 = 16; 115b1b8bc3fSopenharmony_ci key += ~(key << THOMAS_INDEX_0); 116b1b8bc3fSopenharmony_ci key ^= (key >> THOMAS_INDEX_1); 117b1b8bc3fSopenharmony_ci key += (key << THOMAS_INDEX_2); 118b1b8bc3fSopenharmony_ci key ^= (key >> THOMAS_INDEX_3); 119b1b8bc3fSopenharmony_ci key += ~(key << THOMAS_INDEX_4); 120b1b8bc3fSopenharmony_ci key ^= (key >> THOMAS_INDEX_5); 121b1b8bc3fSopenharmony_ci return key; 122b1b8bc3fSopenharmony_ci} 123b1b8bc3fSopenharmony_ci 124b1b8bc3fSopenharmony_ciuint32_t *Bitmap::Get() 125b1b8bc3fSopenharmony_ci{ 126b1b8bc3fSopenharmony_ci return bitmap_; 127b1b8bc3fSopenharmony_ci} 128b1b8bc3fSopenharmony_ci 129b1b8bc3fSopenharmony_ciuint16_t BitmapManager::Hltons(uint32_t n) 130b1b8bc3fSopenharmony_ci{ 131b1b8bc3fSopenharmony_ci return htons((uint16_t)(n & 0x0000ffff)); 132b1b8bc3fSopenharmony_ci} 133b1b8bc3fSopenharmony_ci 134b1b8bc3fSopenharmony_ciuint16_t BitmapManager::Nstohl(uint16_t n) 135b1b8bc3fSopenharmony_ci{ 136b1b8bc3fSopenharmony_ci uint16_t m = 0; 137b1b8bc3fSopenharmony_ci return m | ntohs(n); 138b1b8bc3fSopenharmony_ci} 139b1b8bc3fSopenharmony_ci 140b1b8bc3fSopenharmony_ciint32_t BitmapManager::BuildBitmapMap(const std::vector<sptr<NetFirewallIpRule>> &ruleList) 141b1b8bc3fSopenharmony_ci{ 142b1b8bc3fSopenharmony_ci Clear(); 143b1b8bc3fSopenharmony_ci int32_t ret = BuildMarkBitmap(ruleList); 144b1b8bc3fSopenharmony_ci if (ret != NETFIREWALL_SUCCESS) { 145b1b8bc3fSopenharmony_ci return ret; 146b1b8bc3fSopenharmony_ci } 147b1b8bc3fSopenharmony_ci 148b1b8bc3fSopenharmony_ci Bitmap bitmap; 149b1b8bc3fSopenharmony_ci srcIp4Map_.OrInsert(OTHER_IP4_KEY, IPV4_MAX_PREFIXLEN, bitmap); 150b1b8bc3fSopenharmony_ci dstIp4Map_.OrInsert(OTHER_IP4_KEY, IPV4_MAX_PREFIXLEN, bitmap); 151b1b8bc3fSopenharmony_ci in6_addr otherIp6Key; 152b1b8bc3fSopenharmony_ci memset_s(&otherIp6Key, sizeof(in6_addr), 0xff, sizeof(in6_addr)); 153b1b8bc3fSopenharmony_ci srcIp6Map_.OrInsert(otherIp6Key, IPV6_MAX_PREFIXLEN, bitmap); 154b1b8bc3fSopenharmony_ci dstIp6Map_.OrInsert(otherIp6Key, IPV6_MAX_PREFIXLEN, bitmap); 155b1b8bc3fSopenharmony_ci srcPortMap_.OrInsert(OTHER_PORT_KEY, Bitmap()); 156b1b8bc3fSopenharmony_ci dstPortMap_.OrInsert(OTHER_PORT_KEY, Bitmap()); 157b1b8bc3fSopenharmony_ci protoMap_.OrInsert(OTHER_PROTO_KEY, Bitmap()); 158b1b8bc3fSopenharmony_ci appUidMap_.OrInsert(OTHER_APPUID_KEY, Bitmap()); 159b1b8bc3fSopenharmony_ci uidMap_.OrInsert(OTHER_UID_KEY, Bitmap()); 160b1b8bc3fSopenharmony_ci action_key Key = 1; 161b1b8bc3fSopenharmony_ci actionMap_.OrInsert(Key, Bitmap()); 162b1b8bc3fSopenharmony_ci 163b1b8bc3fSopenharmony_ci BuildNoMarkBitmap(ruleList); 164b1b8bc3fSopenharmony_ci return NETFIREWALL_SUCCESS; 165b1b8bc3fSopenharmony_ci} 166b1b8bc3fSopenharmony_ci 167b1b8bc3fSopenharmony_civoid BitmapManager::Clear() 168b1b8bc3fSopenharmony_ci{ 169b1b8bc3fSopenharmony_ci srcIp4Map_.Clear(); 170b1b8bc3fSopenharmony_ci srcIp6Map_.Clear(); 171b1b8bc3fSopenharmony_ci dstIp4Map_.Clear(); 172b1b8bc3fSopenharmony_ci dstIp6Map_.Clear(); 173b1b8bc3fSopenharmony_ci srcPortMap_.Clear(); 174b1b8bc3fSopenharmony_ci dstPortMap_.Clear(); 175b1b8bc3fSopenharmony_ci protoMap_.Clear(); 176b1b8bc3fSopenharmony_ci appUidMap_.Clear(); 177b1b8bc3fSopenharmony_ci uidMap_.Clear(); 178b1b8bc3fSopenharmony_ci actionMap_.Clear(); 179b1b8bc3fSopenharmony_ci} 180b1b8bc3fSopenharmony_ci 181b1b8bc3fSopenharmony_ciint32_t BitmapManager::InsertIp4SegBitmap(const NetFirewallIpParam &item, Bitmap &bitmap, Ip4RuleMap *ip4Map) 182b1b8bc3fSopenharmony_ci{ 183b1b8bc3fSopenharmony_ci if (ip4Map == nullptr) { 184b1b8bc3fSopenharmony_ci return NETFIREWALL_ERR; 185b1b8bc3fSopenharmony_ci } 186b1b8bc3fSopenharmony_ci if (item.type == SINGLE_IP) { 187b1b8bc3fSopenharmony_ci uint32_t ipInt = item.ipv4.startIp.s_addr; 188b1b8bc3fSopenharmony_ci ip4Map->OrInsert(ipInt, static_cast<uint32_t>(item.mask), bitmap); 189b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("InsertIpBitmap ipp[%{public}u] ipn[%{public}s] mask[%{public}u]", ipInt, 190b1b8bc3fSopenharmony_ci item.GetStartIp().c_str(), item.mask); 191b1b8bc3fSopenharmony_ci } else if (item.type == MULTIPLE_IP) { 192b1b8bc3fSopenharmony_ci std::vector<Ip4Data> ips; 193b1b8bc3fSopenharmony_ci int32_t ret = IpParamParser::GetIp4AndMask(item.ipv4.startIp, item.ipv4.endIp, ips); 194b1b8bc3fSopenharmony_ci if (ret != NETFIREWALL_SUCCESS) { 195b1b8bc3fSopenharmony_ci return ret; 196b1b8bc3fSopenharmony_ci } 197b1b8bc3fSopenharmony_ci for (auto &ipData : ips) { 198b1b8bc3fSopenharmony_ci ip4Map->OrInsert(htonl(ipData.data), ipData.mask, bitmap); 199b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("InsertIpBitmap ip[%{public}u], mask[%{public}u]", htonl(ipData.data), ipData.mask); 200b1b8bc3fSopenharmony_ci } 201b1b8bc3fSopenharmony_ci } 202b1b8bc3fSopenharmony_ci return NETFIREWALL_SUCCESS; 203b1b8bc3fSopenharmony_ci} 204b1b8bc3fSopenharmony_ci 205b1b8bc3fSopenharmony_ci 206b1b8bc3fSopenharmony_ciint32_t BitmapManager::InsertIp6SegBitmap(const NetFirewallIpParam &item, Bitmap &bitmap, Ip6RuleMap *ip6Map) 207b1b8bc3fSopenharmony_ci{ 208b1b8bc3fSopenharmony_ci if (ip6Map == nullptr) { 209b1b8bc3fSopenharmony_ci return NETFIREWALL_ERR; 210b1b8bc3fSopenharmony_ci } 211b1b8bc3fSopenharmony_ci if (item.type == SINGLE_IP) { 212b1b8bc3fSopenharmony_ci ip6Map->OrInsert(item.ipv6.startIp, static_cast<uint32_t>(item.mask), bitmap); 213b1b8bc3fSopenharmony_ci std::string addrStr = IpParamParser::Addr6ToStr(item.ipv6.startIp); 214b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("InsertIp6SegBitmap ip[%{public}s], mask[%{public}u]", 215b1b8bc3fSopenharmony_ci CommonUtils::ToAnonymousIp(addrStr).c_str(), item.mask); 216b1b8bc3fSopenharmony_ci } else if (item.type == MULTIPLE_IP) { 217b1b8bc3fSopenharmony_ci std::vector<Ip6Data> ips; 218b1b8bc3fSopenharmony_ci int32_t ret = IpParamParser::GetIp6AndMask(item.ipv6.startIp, item.ipv6.endIp, ips); 219b1b8bc3fSopenharmony_ci if (ret != NETFIREWALL_SUCCESS) { 220b1b8bc3fSopenharmony_ci NETNATIVE_LOGW("InsertIp6SegBitmap GetIp6AndMask fail ret=%{public}d", ret); 221b1b8bc3fSopenharmony_ci return ret; 222b1b8bc3fSopenharmony_ci } 223b1b8bc3fSopenharmony_ci for (auto &ipData : ips) { 224b1b8bc3fSopenharmony_ci ip6Map->OrInsert(ipData.data, ipData.prefixlen, bitmap); 225b1b8bc3fSopenharmony_ci } 226b1b8bc3fSopenharmony_ci } 227b1b8bc3fSopenharmony_ci return NETFIREWALL_SUCCESS; 228b1b8bc3fSopenharmony_ci} 229b1b8bc3fSopenharmony_ci 230b1b8bc3fSopenharmony_ciint32_t BitmapManager::InsertIpBitmap(const std::vector<NetFirewallIpParam> &ipInfo, bool isSrc, Bitmap &bitmap) 231b1b8bc3fSopenharmony_ci{ 232b1b8bc3fSopenharmony_ci for (const NetFirewallIpParam &item : ipInfo) { 233b1b8bc3fSopenharmony_ci Ip4RuleMap *ip4Map = nullptr; 234b1b8bc3fSopenharmony_ci Ip6RuleMap *ip6Map = nullptr; 235b1b8bc3fSopenharmony_ci if (isSrc) { 236b1b8bc3fSopenharmony_ci if (item.family == FAMILY_IPV4) { 237b1b8bc3fSopenharmony_ci ip4Map = &srcIp4Map_; 238b1b8bc3fSopenharmony_ci } else if (item.family == FAMILY_IPV6) { 239b1b8bc3fSopenharmony_ci ip6Map = &srcIp6Map_; 240b1b8bc3fSopenharmony_ci } 241b1b8bc3fSopenharmony_ci } else { 242b1b8bc3fSopenharmony_ci if (item.family == FAMILY_IPV4) { 243b1b8bc3fSopenharmony_ci ip4Map = &dstIp4Map_; 244b1b8bc3fSopenharmony_ci } else if (item.family == FAMILY_IPV6) { 245b1b8bc3fSopenharmony_ci ip6Map = &dstIp6Map_; 246b1b8bc3fSopenharmony_ci } 247b1b8bc3fSopenharmony_ci } 248b1b8bc3fSopenharmony_ci 249b1b8bc3fSopenharmony_ci int32_t ret = NETFIREWALL_SUCCESS; 250b1b8bc3fSopenharmony_ci if (item.family == FAMILY_IPV4) { 251b1b8bc3fSopenharmony_ci int32_t ret = InsertIp4SegBitmap(item, bitmap, ip4Map); 252b1b8bc3fSopenharmony_ci if (ret != NETFIREWALL_SUCCESS) { 253b1b8bc3fSopenharmony_ci return ret; 254b1b8bc3fSopenharmony_ci } 255b1b8bc3fSopenharmony_ci } else { 256b1b8bc3fSopenharmony_ci ret = InsertIp6SegBitmap(item, bitmap, ip6Map); 257b1b8bc3fSopenharmony_ci if (ret != NETFIREWALL_SUCCESS) { 258b1b8bc3fSopenharmony_ci return ret; 259b1b8bc3fSopenharmony_ci } 260b1b8bc3fSopenharmony_ci } 261b1b8bc3fSopenharmony_ci } 262b1b8bc3fSopenharmony_ci return NETFIREWALL_SUCCESS; 263b1b8bc3fSopenharmony_ci} 264b1b8bc3fSopenharmony_ci 265b1b8bc3fSopenharmony_civoid BitmapManager::OrInsertPortBitmap(SegmentBitmapMap &portSegMap, BpfUnorderedMap<PortKey> &portMap) 266b1b8bc3fSopenharmony_ci{ 267b1b8bc3fSopenharmony_ci auto &segMap = portSegMap.GetMap(); 268b1b8bc3fSopenharmony_ci for (auto &item : segMap) { 269b1b8bc3fSopenharmony_ci uint32_t start = item.start; 270b1b8bc3fSopenharmony_ci while (start <= item.end) { 271b1b8bc3fSopenharmony_ci if (start == 0) { 272b1b8bc3fSopenharmony_ci continue; 273b1b8bc3fSopenharmony_ci } 274b1b8bc3fSopenharmony_ci PortKey key = (PortKey)Hltons(start); 275b1b8bc3fSopenharmony_ci portMap.OrInsert(key, item.bitmap); 276b1b8bc3fSopenharmony_ci start++; 277b1b8bc3fSopenharmony_ci } 278b1b8bc3fSopenharmony_ci } 279b1b8bc3fSopenharmony_ci} 280b1b8bc3fSopenharmony_ci 281b1b8bc3fSopenharmony_civoid BitmapManager::AddPortBitmap(const std::vector<NetFirewallPortParam> &port, Bitmap &bitmap, 282b1b8bc3fSopenharmony_ci SegmentBitmapMap &portMap) 283b1b8bc3fSopenharmony_ci{ 284b1b8bc3fSopenharmony_ci for (const NetFirewallPortParam &item : port) { 285b1b8bc3fSopenharmony_ci uint16_t startPort = item.startPort; 286b1b8bc3fSopenharmony_ci if (startPort == 0) { 287b1b8bc3fSopenharmony_ci continue; 288b1b8bc3fSopenharmony_ci } 289b1b8bc3fSopenharmony_ci if (item.startPort <= item.endPort) { 290b1b8bc3fSopenharmony_ci portMap.AddMap(item.startPort, item.endPort, bitmap); 291b1b8bc3fSopenharmony_ci } 292b1b8bc3fSopenharmony_ci } 293b1b8bc3fSopenharmony_ci} 294b1b8bc3fSopenharmony_ci 295b1b8bc3fSopenharmony_ciint32_t BitmapManager::BuildMarkBitmap(const std::vector<sptr<NetFirewallIpRule>> &ruleList) 296b1b8bc3fSopenharmony_ci{ 297b1b8bc3fSopenharmony_ci SegmentBitmapMap srcPortMap; 298b1b8bc3fSopenharmony_ci SegmentBitmapMap dstPortMap; 299b1b8bc3fSopenharmony_ci uint32_t index = 0; 300b1b8bc3fSopenharmony_ci int32_t ret; 301b1b8bc3fSopenharmony_ci for (const auto &rule : ruleList) { 302b1b8bc3fSopenharmony_ci Bitmap bitmap(index); 303b1b8bc3fSopenharmony_ci ret = InsertIpBitmap(rule->remoteIps, true, bitmap); 304b1b8bc3fSopenharmony_ci if (ret) { 305b1b8bc3fSopenharmony_ci NETNATIVE_LOGW("BuildMarkBitmap InsertIpBitmap remoteIps fail ret=%{public}d", ret); 306b1b8bc3fSopenharmony_ci return NETFIREWALL_ERR; 307b1b8bc3fSopenharmony_ci } 308b1b8bc3fSopenharmony_ci ret = InsertIpBitmap(rule->localIps, false, bitmap); 309b1b8bc3fSopenharmony_ci if (ret) { 310b1b8bc3fSopenharmony_ci NETNATIVE_LOGW("BuildMarkBitmap InsertIpBitmap localIps fail ret=%{public}d", ret); 311b1b8bc3fSopenharmony_ci return NETFIREWALL_ERR; 312b1b8bc3fSopenharmony_ci } 313b1b8bc3fSopenharmony_ci if (!IsNotNeedPort(rule->protocol)) { 314b1b8bc3fSopenharmony_ci AddPortBitmap(rule->remotePorts, bitmap, srcPortMap); 315b1b8bc3fSopenharmony_ci AddPortBitmap(rule->localPorts, bitmap, dstPortMap); 316b1b8bc3fSopenharmony_ci } 317b1b8bc3fSopenharmony_ci 318b1b8bc3fSopenharmony_ci if (rule->protocol != (NetworkProtocol)0) { 319b1b8bc3fSopenharmony_ci ProtoKey proto = (ProtoKey)rule->protocol; 320b1b8bc3fSopenharmony_ci protoMap_.OrInsert(proto, bitmap); 321b1b8bc3fSopenharmony_ci } 322b1b8bc3fSopenharmony_ci 323b1b8bc3fSopenharmony_ci if (rule->appUid > 0) { 324b1b8bc3fSopenharmony_ci appUidMap_.OrInsert((AppUidKey)rule->appUid, bitmap); 325b1b8bc3fSopenharmony_ci } 326b1b8bc3fSopenharmony_ci 327b1b8bc3fSopenharmony_ci if (rule->userId > 0) { 328b1b8bc3fSopenharmony_ci uidMap_.OrInsert((UidKey)rule->userId, bitmap); 329b1b8bc3fSopenharmony_ci } 330b1b8bc3fSopenharmony_ci 331b1b8bc3fSopenharmony_ci if (rule->ruleAction != FirewallRuleAction::RULE_ALLOW) { 332b1b8bc3fSopenharmony_ci action_key Key = 1; 333b1b8bc3fSopenharmony_ci actionMap_.OrInsert(Key, bitmap); 334b1b8bc3fSopenharmony_ci } 335b1b8bc3fSopenharmony_ci index++; 336b1b8bc3fSopenharmony_ci } 337b1b8bc3fSopenharmony_ci 338b1b8bc3fSopenharmony_ci OrInsertPortBitmap(srcPortMap, srcPortMap_); 339b1b8bc3fSopenharmony_ci OrInsertPortBitmap(dstPortMap, dstPortMap_); 340b1b8bc3fSopenharmony_ci return NETFIREWALL_SUCCESS; 341b1b8bc3fSopenharmony_ci} 342b1b8bc3fSopenharmony_ci 343b1b8bc3fSopenharmony_civoid BitmapManager::BuildNoMarkBitmap(const std::vector<sptr<NetFirewallIpRule>> &ruleList) 344b1b8bc3fSopenharmony_ci{ 345b1b8bc3fSopenharmony_ci uint32_t index = 0; 346b1b8bc3fSopenharmony_ci for (const auto &rule : ruleList) { 347b1b8bc3fSopenharmony_ci Bitmap bitmap(index); 348b1b8bc3fSopenharmony_ci if (rule->remoteIps.empty()) { 349b1b8bc3fSopenharmony_ci srcIp4Map_.OrForEach(bitmap); 350b1b8bc3fSopenharmony_ci srcIp6Map_.OrForEach(bitmap); 351b1b8bc3fSopenharmony_ci } 352b1b8bc3fSopenharmony_ci if (rule->localIps.empty()) { 353b1b8bc3fSopenharmony_ci dstIp4Map_.OrForEach(bitmap); 354b1b8bc3fSopenharmony_ci dstIp6Map_.OrForEach(bitmap); 355b1b8bc3fSopenharmony_ci } 356b1b8bc3fSopenharmony_ci if (rule->remotePorts.empty() || IsNotNeedPort(rule->protocol)) { 357b1b8bc3fSopenharmony_ci srcPortMap_.OrForEach(bitmap); 358b1b8bc3fSopenharmony_ci } 359b1b8bc3fSopenharmony_ci if (rule->localPorts.empty() || IsNotNeedPort(rule->protocol)) { 360b1b8bc3fSopenharmony_ci dstPortMap_.OrForEach(bitmap); 361b1b8bc3fSopenharmony_ci } 362b1b8bc3fSopenharmony_ci if (rule->protocol == (NetworkProtocol)0) { 363b1b8bc3fSopenharmony_ci protoMap_.OrForEach(bitmap); 364b1b8bc3fSopenharmony_ci } 365b1b8bc3fSopenharmony_ci if (rule->appUid < 1) { 366b1b8bc3fSopenharmony_ci appUidMap_.OrForEach(bitmap); 367b1b8bc3fSopenharmony_ci } 368b1b8bc3fSopenharmony_ci if (rule->userId < 1) { 369b1b8bc3fSopenharmony_ci uidMap_.OrForEach(bitmap); 370b1b8bc3fSopenharmony_ci } 371b1b8bc3fSopenharmony_ci index++; 372b1b8bc3fSopenharmony_ci } 373b1b8bc3fSopenharmony_ci} 374b1b8bc3fSopenharmony_ci 375b1b8bc3fSopenharmony_cibool BitmapManager::IsNotNeedPort(NetworkProtocol protocol) 376b1b8bc3fSopenharmony_ci{ 377b1b8bc3fSopenharmony_ci if (protocol == NetworkProtocol::ICMPV6 || protocol == NetworkProtocol::ICMP) { 378b1b8bc3fSopenharmony_ci return true; 379b1b8bc3fSopenharmony_ci } 380b1b8bc3fSopenharmony_ci return false; 381b1b8bc3fSopenharmony_ci} 382b1b8bc3fSopenharmony_ci 383b1b8bc3fSopenharmony_ciint32_t IpParamParser::GetIpUint32(const std::string &address, uint32_t &ipInt) 384b1b8bc3fSopenharmony_ci{ 385b1b8bc3fSopenharmony_ci in_addr out = { 0 }; 386b1b8bc3fSopenharmony_ci memset_s(&out, sizeof(out), 0, sizeof(out)); 387b1b8bc3fSopenharmony_ci if (inet_pton(AF_INET, address.c_str(), &out) != 1) { 388b1b8bc3fSopenharmony_ci return NETFIREWALL_IP_STR_ERR; 389b1b8bc3fSopenharmony_ci } 390b1b8bc3fSopenharmony_ci 391b1b8bc3fSopenharmony_ci ipInt = out.s_addr; 392b1b8bc3fSopenharmony_ci return NETFIREWALL_SUCCESS; 393b1b8bc3fSopenharmony_ci} 394b1b8bc3fSopenharmony_ci 395b1b8bc3fSopenharmony_civoid IpParamParser::AddIp(uint32_t ip, uint32_t mask, std::vector<Ip4Data> &ip4Vec) 396b1b8bc3fSopenharmony_ci{ 397b1b8bc3fSopenharmony_ci Ip4Data info; 398b1b8bc3fSopenharmony_ci info.data = ip; 399b1b8bc3fSopenharmony_ci info.mask = mask; 400b1b8bc3fSopenharmony_ci ip4Vec.emplace_back(info); 401b1b8bc3fSopenharmony_ci} 402b1b8bc3fSopenharmony_ci 403b1b8bc3fSopenharmony_cistd::string IpParamParser::Ip4ToStr(uint32_t ip) 404b1b8bc3fSopenharmony_ci{ 405b1b8bc3fSopenharmony_ci char str[INET_ADDRSTRLEN] = {0}; 406b1b8bc3fSopenharmony_ci in_addr ipv4; 407b1b8bc3fSopenharmony_ci memset_s(&ipv4, sizeof(ipv4), 0, sizeof(ipv4)); 408b1b8bc3fSopenharmony_ci ipv4.s_addr = ntohl(ip); 409b1b8bc3fSopenharmony_ci 410b1b8bc3fSopenharmony_ci if (inet_ntop(AF_INET, &ipv4, str, INET_ADDRSTRLEN) == NULL) { 411b1b8bc3fSopenharmony_ci return "error ip"; 412b1b8bc3fSopenharmony_ci } 413b1b8bc3fSopenharmony_ci return std::string(str); 414b1b8bc3fSopenharmony_ci} 415b1b8bc3fSopenharmony_ci 416b1b8bc3fSopenharmony_ciuint32_t IpParamParser::GetMask(uint32_t startIp, uint32_t endIp) 417b1b8bc3fSopenharmony_ci{ 418b1b8bc3fSopenharmony_ci int32_t i = static_cast<int32_t>(IPV4_BIT_COUNT - 1); 419b1b8bc3fSopenharmony_ci for (; i >= 0; --i) { 420b1b8bc3fSopenharmony_ci if (((startIp >> i) & VALUE_ONE) != ((endIp >> i) & VALUE_ONE)) { 421b1b8bc3fSopenharmony_ci return IPV4_BIT_COUNT - static_cast<uint32_t>(i) - 1; 422b1b8bc3fSopenharmony_ci } 423b1b8bc3fSopenharmony_ci } 424b1b8bc3fSopenharmony_ci return IPV4_BIT_COUNT; 425b1b8bc3fSopenharmony_ci} 426b1b8bc3fSopenharmony_ci 427b1b8bc3fSopenharmony_ciuint32_t IpParamParser::Rfind(uint32_t ip, uint32_t start, uint32_t end, uint32_t value) 428b1b8bc3fSopenharmony_ci{ 429b1b8bc3fSopenharmony_ci if (start > end || end >= IPV4_BIT_COUNT) { 430b1b8bc3fSopenharmony_ci return IPV4_BIT_COUNT; 431b1b8bc3fSopenharmony_ci } 432b1b8bc3fSopenharmony_ci uint32_t startIndex = IPV4_BIT_COUNT - end - 1; 433b1b8bc3fSopenharmony_ci uint32_t endIndex = IPV4_BIT_COUNT - start - 1; 434b1b8bc3fSopenharmony_ci for (uint32_t i = startIndex; i <= endIndex; ++i) { 435b1b8bc3fSopenharmony_ci if (((ip >> i) & VALUE_ONE) == value) { 436b1b8bc3fSopenharmony_ci return IPV4_BIT_COUNT - i - 1; 437b1b8bc3fSopenharmony_ci } 438b1b8bc3fSopenharmony_ci } 439b1b8bc3fSopenharmony_ci return IPV4_BIT_COUNT; 440b1b8bc3fSopenharmony_ci} 441b1b8bc3fSopenharmony_ci 442b1b8bc3fSopenharmony_ciuint32_t IpParamParser::Find(uint32_t ip, uint32_t start, uint32_t value) 443b1b8bc3fSopenharmony_ci{ 444b1b8bc3fSopenharmony_ci if (start >= IPV4_BIT_COUNT) { 445b1b8bc3fSopenharmony_ci return IPV4_BIT_COUNT; 446b1b8bc3fSopenharmony_ci } 447b1b8bc3fSopenharmony_ci int32_t i = static_cast<int32_t>(IPV4_BIT_COUNT - start - 1); 448b1b8bc3fSopenharmony_ci for (; i >= 0; --i) { 449b1b8bc3fSopenharmony_ci if (((ip >> i) & VALUE_ONE) == value) { 450b1b8bc3fSopenharmony_ci return IPV4_BIT_COUNT - static_cast<uint32_t>(i) - 1; 451b1b8bc3fSopenharmony_ci } 452b1b8bc3fSopenharmony_ci } 453b1b8bc3fSopenharmony_ci return IPV4_BIT_COUNT; 454b1b8bc3fSopenharmony_ci} 455b1b8bc3fSopenharmony_ci 456b1b8bc3fSopenharmony_civoid IpParamParser::ChangeStart(uint32_t mask, uint32_t &ip) 457b1b8bc3fSopenharmony_ci{ 458b1b8bc3fSopenharmony_ci bool needSetZero = true; 459b1b8bc3fSopenharmony_ci if (mask > IPV4_MAX_PREFIXLEN || mask >= IPV4_BIT_COUNT) { 460b1b8bc3fSopenharmony_ci return; 461b1b8bc3fSopenharmony_ci } else if (mask == IPV4_MAX_PREFIXLEN) { 462b1b8bc3fSopenharmony_ci needSetZero = false; 463b1b8bc3fSopenharmony_ci } 464b1b8bc3fSopenharmony_ci for (uint32_t i = 0; i <= (IPV4_BIT_COUNT - 1); ++i) { 465b1b8bc3fSopenharmony_ci uint32_t byte = (1 << i); 466b1b8bc3fSopenharmony_ci if (needSetZero && (i <= (IPV4_BIT_COUNT - mask - 1))) { 467b1b8bc3fSopenharmony_ci ip &= (~byte); 468b1b8bc3fSopenharmony_ci continue; 469b1b8bc3fSopenharmony_ci } 470b1b8bc3fSopenharmony_ci if (ip & byte) { 471b1b8bc3fSopenharmony_ci ip &= (~byte); 472b1b8bc3fSopenharmony_ci continue; 473b1b8bc3fSopenharmony_ci } 474b1b8bc3fSopenharmony_ci ip |= byte; 475b1b8bc3fSopenharmony_ci return; 476b1b8bc3fSopenharmony_ci } 477b1b8bc3fSopenharmony_ci} 478b1b8bc3fSopenharmony_ci 479b1b8bc3fSopenharmony_ciint32_t IpParamParser::GetIp4AndMask(const in_addr &startAddr, const in_addr &endAddr, std::vector<Ip4Data> &list) 480b1b8bc3fSopenharmony_ci{ 481b1b8bc3fSopenharmony_ci uint32_t startIpInt = ntohl(startAddr.s_addr); 482b1b8bc3fSopenharmony_ci uint32_t endIpInt = ntohl(endAddr.s_addr); 483b1b8bc3fSopenharmony_ci if (startIpInt > endIpInt) { 484b1b8bc3fSopenharmony_ci return NETFIREWALL_ERR; 485b1b8bc3fSopenharmony_ci } else if (startIpInt == endIpInt) { 486b1b8bc3fSopenharmony_ci AddIp(startIpInt, IPV4_MAX_PREFIXLEN, list); 487b1b8bc3fSopenharmony_ci return NETFIREWALL_SUCCESS; 488b1b8bc3fSopenharmony_ci } 489b1b8bc3fSopenharmony_ci uint32_t mask = GetMask(startIpInt, endIpInt); 490b1b8bc3fSopenharmony_ci uint32_t tmpStart = startIpInt; 491b1b8bc3fSopenharmony_ci uint32_t off = Rfind(tmpStart, mask, IPV4_BIT_COUNT - 1, 1); 492b1b8bc3fSopenharmony_ci if (off != IPV4_BIT_COUNT) { 493b1b8bc3fSopenharmony_ci AddIp(tmpStart, off + 1, list); 494b1b8bc3fSopenharmony_ci ChangeStart(off + 1, tmpStart); 495b1b8bc3fSopenharmony_ci off = Rfind(startIpInt, mask, off, 0); 496b1b8bc3fSopenharmony_ci while (off != IPV4_BIT_COUNT && off != mask) { 497b1b8bc3fSopenharmony_ci AddIp(tmpStart, off + 1, list); 498b1b8bc3fSopenharmony_ci ChangeStart(off + 1, tmpStart); 499b1b8bc3fSopenharmony_ci off = Rfind(startIpInt, mask, off - 1, 0); 500b1b8bc3fSopenharmony_ci } 501b1b8bc3fSopenharmony_ci } else if (Rfind(endIpInt, mask, IPV4_BIT_COUNT - 1, 0) == IPV4_BIT_COUNT) { 502b1b8bc3fSopenharmony_ci AddIp(startIpInt, mask, list); 503b1b8bc3fSopenharmony_ci return true; 504b1b8bc3fSopenharmony_ci } 505b1b8bc3fSopenharmony_ci off = Find(endIpInt, mask, 1); 506b1b8bc3fSopenharmony_ci if (off == IPV4_BIT_COUNT) { 507b1b8bc3fSopenharmony_ci return NETFIREWALL_ERR; 508b1b8bc3fSopenharmony_ci } 509b1b8bc3fSopenharmony_ci off = Find(endIpInt, off + 1, 1); 510b1b8bc3fSopenharmony_ci while (off != IPV4_BIT_COUNT) { 511b1b8bc3fSopenharmony_ci AddIp(tmpStart, off + 1, list); 512b1b8bc3fSopenharmony_ci ChangeStart(off + 1, tmpStart); 513b1b8bc3fSopenharmony_ci off = Find(endIpInt, off + 1, 1); 514b1b8bc3fSopenharmony_ci } 515b1b8bc3fSopenharmony_ci if (tmpStart == endIpInt) { 516b1b8bc3fSopenharmony_ci AddIp(tmpStart, IPV4_BIT_COUNT, list); 517b1b8bc3fSopenharmony_ci } 518b1b8bc3fSopenharmony_ci return NETFIREWALL_SUCCESS; 519b1b8bc3fSopenharmony_ci} 520b1b8bc3fSopenharmony_ci 521b1b8bc3fSopenharmony_ciint32_t IpParamParser::GetInAddr6(const std::string &ipStr, in6_addr &addr) 522b1b8bc3fSopenharmony_ci{ 523b1b8bc3fSopenharmony_ci int32_t ret = inet_pton(AF_INET6, ipStr.c_str(), &addr); 524b1b8bc3fSopenharmony_ci if (ret <= 0) { 525b1b8bc3fSopenharmony_ci return NETFIREWALL_IP_STR_ERR; 526b1b8bc3fSopenharmony_ci } 527b1b8bc3fSopenharmony_ci return NETFIREWALL_SUCCESS; 528b1b8bc3fSopenharmony_ci} 529b1b8bc3fSopenharmony_ci 530b1b8bc3fSopenharmony_cistd::string IpParamParser::Addr6ToStr(const in6_addr &v6Addr) 531b1b8bc3fSopenharmony_ci{ 532b1b8bc3fSopenharmony_ci char buf[INET6_ADDRSTRLEN] = { 0 }; 533b1b8bc3fSopenharmony_ci if (inet_ntop(AF_INET6, &v6Addr, buf, INET6_ADDRSTRLEN) == NULL) { 534b1b8bc3fSopenharmony_ci return "error in6_addr"; 535b1b8bc3fSopenharmony_ci } 536b1b8bc3fSopenharmony_ci return std::string(buf); 537b1b8bc3fSopenharmony_ci} 538b1b8bc3fSopenharmony_ci 539b1b8bc3fSopenharmony_ciuint32_t IpParamParser::GetIp6Prefixlen(const in6_addr &start, const in6_addr &end) 540b1b8bc3fSopenharmony_ci{ 541b1b8bc3fSopenharmony_ci uint32_t prefixlen = IPV6_MAX_PREFIXLEN; 542b1b8bc3fSopenharmony_ci for (uint32_t i = 0; i < IPV6_BIT_COUNT; i++) { 543b1b8bc3fSopenharmony_ci if (start.s6_addr[i] == end.s6_addr[i]) { 544b1b8bc3fSopenharmony_ci continue; 545b1b8bc3fSopenharmony_ci } 546b1b8bc3fSopenharmony_ci for (int32_t j = static_cast<int32_t>(BIT_PER_BYTE - 1); j >= 0; --j) { 547b1b8bc3fSopenharmony_ci uint8_t byte = (1 << j); 548b1b8bc3fSopenharmony_ci if ((start.s6_addr[i] & byte) == (end.s6_addr[i] & byte)) { 549b1b8bc3fSopenharmony_ci continue; 550b1b8bc3fSopenharmony_ci } else { 551b1b8bc3fSopenharmony_ci prefixlen = i * BIT_PER_BYTE + BIT_PER_BYTE - static_cast<uint32_t>(j) - 1; 552b1b8bc3fSopenharmony_ci return prefixlen; 553b1b8bc3fSopenharmony_ci } 554b1b8bc3fSopenharmony_ci } 555b1b8bc3fSopenharmony_ci } 556b1b8bc3fSopenharmony_ci return prefixlen; 557b1b8bc3fSopenharmony_ci} 558b1b8bc3fSopenharmony_ci 559b1b8bc3fSopenharmony_ciuint32_t IpParamParser::RfindIp6(const in6_addr &addr, uint32_t startBit, uint32_t endBit, uint8_t value) 560b1b8bc3fSopenharmony_ci{ 561b1b8bc3fSopenharmony_ci if (startBit > endBit) { 562b1b8bc3fSopenharmony_ci return IPV6_BIT_COUNT; 563b1b8bc3fSopenharmony_ci } 564b1b8bc3fSopenharmony_ci uint32_t startBits = startBit % BIT_PER_BYTE; 565b1b8bc3fSopenharmony_ci uint32_t startBytes = startBit / BIT_PER_BYTE; 566b1b8bc3fSopenharmony_ci uint32_t endBits = endBit % BIT_PER_BYTE; 567b1b8bc3fSopenharmony_ci uint32_t endBytes = endBit / BIT_PER_BYTE; 568b1b8bc3fSopenharmony_ci for (uint32_t i = endBytes; i >= startBytes; --i) { 569b1b8bc3fSopenharmony_ci uint32_t j = (i == endBytes) ? (BIT_PER_BYTE - endBits - 1) : 0; 570b1b8bc3fSopenharmony_ci uint32_t k = (i == startBytes) ? (BIT_PER_BYTE - startBits - 1) : (BIT_PER_BYTE - 1); 571b1b8bc3fSopenharmony_ci for (; j <= k; ++j) { 572b1b8bc3fSopenharmony_ci uint8_t byte = (1 << j); 573b1b8bc3fSopenharmony_ci uint8_t tmp = (addr.s6_addr[i] & byte) >> j; 574b1b8bc3fSopenharmony_ci if (tmp == value) { 575b1b8bc3fSopenharmony_ci return i * BIT_PER_BYTE + BIT_PER_BYTE - j - 1; 576b1b8bc3fSopenharmony_ci } 577b1b8bc3fSopenharmony_ci } 578b1b8bc3fSopenharmony_ci } 579b1b8bc3fSopenharmony_ci return IPV6_BIT_COUNT; 580b1b8bc3fSopenharmony_ci} 581b1b8bc3fSopenharmony_ci 582b1b8bc3fSopenharmony_ciuint32_t IpParamParser::FindIp6(const in6_addr &addr, uint32_t startBit, uint8_t value) 583b1b8bc3fSopenharmony_ci{ 584b1b8bc3fSopenharmony_ci if (startBit >= IPV6_BIT_COUNT) { 585b1b8bc3fSopenharmony_ci return IPV6_BIT_COUNT; 586b1b8bc3fSopenharmony_ci } 587b1b8bc3fSopenharmony_ci uint32_t startBits = startBit % BIT_PER_BYTE; 588b1b8bc3fSopenharmony_ci uint32_t startBytes = startBit / BIT_PER_BYTE; 589b1b8bc3fSopenharmony_ci for (uint32_t i = startBytes; i < IPV6_BYTE_COUNT; ++i) { 590b1b8bc3fSopenharmony_ci int32_t j = static_cast<int32_t>((i == startBytes) ? (BIT_PER_BYTE - startBits - 1) : (BIT_PER_BYTE - 1)); 591b1b8bc3fSopenharmony_ci for (; j >= 0; --j) { 592b1b8bc3fSopenharmony_ci uint8_t tmp = ((addr.s6_addr[i] >> j) & VALUE_ONE); 593b1b8bc3fSopenharmony_ci if (tmp == value) { 594b1b8bc3fSopenharmony_ci return i * BIT_PER_BYTE + BIT_PER_BYTE - static_cast<uint32_t>(j) - 1; 595b1b8bc3fSopenharmony_ci } 596b1b8bc3fSopenharmony_ci } 597b1b8bc3fSopenharmony_ci } 598b1b8bc3fSopenharmony_ci return IPV6_BIT_COUNT; 599b1b8bc3fSopenharmony_ci} 600b1b8bc3fSopenharmony_ci 601b1b8bc3fSopenharmony_civoid IpParamParser::AddIp6(const in6_addr &addr, uint32_t prefixlen, std::vector<Ip6Data> &list) 602b1b8bc3fSopenharmony_ci{ 603b1b8bc3fSopenharmony_ci Ip6Data info; 604b1b8bc3fSopenharmony_ci info.prefixlen = prefixlen; 605b1b8bc3fSopenharmony_ci info.data = addr; 606b1b8bc3fSopenharmony_ci list.emplace_back(info); 607b1b8bc3fSopenharmony_ci 608b1b8bc3fSopenharmony_ci std::string startIpStr = IpParamParser::Addr6ToStr(info.data); 609b1b8bc3fSopenharmony_ci NETNATIVE_LOG_D("AddIp6 ip[%{public}s], mask[%{public}u]", 610b1b8bc3fSopenharmony_ci CommonUtils::ToAnonymousIp(startIpStr).c_str(), info.prefixlen); 611b1b8bc3fSopenharmony_ci} 612b1b8bc3fSopenharmony_ci 613b1b8bc3fSopenharmony_civoid IpParamParser::ChangeIp6Start(uint32_t startBit, in6_addr &addr) 614b1b8bc3fSopenharmony_ci{ 615b1b8bc3fSopenharmony_ci uint32_t bits = startBit % BIT_PER_BYTE; 616b1b8bc3fSopenharmony_ci uint32_t bytes = startBit / BIT_PER_BYTE; 617b1b8bc3fSopenharmony_ci if (bytes < IPV6_BYTE_COUNT - 1) { 618b1b8bc3fSopenharmony_ci memset_s(addr.s6_addr + bytes + 1, IPV6_BYTE_COUNT - bytes - 1, 0, IPV6_BYTE_COUNT - bytes - 1); 619b1b8bc3fSopenharmony_ci } 620b1b8bc3fSopenharmony_ci 621b1b8bc3fSopenharmony_ci bool needSetZero = true; 622b1b8bc3fSopenharmony_ci if (bytes >= IPV6_BYTE_COUNT) { 623b1b8bc3fSopenharmony_ci bytes = IPV6_BYTE_COUNT - 1; 624b1b8bc3fSopenharmony_ci bits = BIT_PER_BYTE - 1; 625b1b8bc3fSopenharmony_ci needSetZero = false; 626b1b8bc3fSopenharmony_ci } 627b1b8bc3fSopenharmony_ci 628b1b8bc3fSopenharmony_ci uint32_t off = BIT_PER_BYTE - bits - 1; 629b1b8bc3fSopenharmony_ci for (int32_t i = static_cast<int32_t>(bytes); i >= 0; --i) { 630b1b8bc3fSopenharmony_ci for (uint32_t j = 0; j < BIT_PER_BYTE; ++j) { 631b1b8bc3fSopenharmony_ci uint8_t byte = (1 << j); 632b1b8bc3fSopenharmony_ci if (needSetZero && (i == static_cast<int32_t>(bytes) && j <= off)) { 633b1b8bc3fSopenharmony_ci addr.s6_addr[i] &= (~byte); 634b1b8bc3fSopenharmony_ci continue; 635b1b8bc3fSopenharmony_ci } 636b1b8bc3fSopenharmony_ci if (addr.s6_addr[i] & byte) { 637b1b8bc3fSopenharmony_ci addr.s6_addr[i] &= (~byte); 638b1b8bc3fSopenharmony_ci continue; 639b1b8bc3fSopenharmony_ci } else { 640b1b8bc3fSopenharmony_ci addr.s6_addr[i] |= byte; 641b1b8bc3fSopenharmony_ci return; 642b1b8bc3fSopenharmony_ci } 643b1b8bc3fSopenharmony_ci } 644b1b8bc3fSopenharmony_ci } 645b1b8bc3fSopenharmony_ci} 646b1b8bc3fSopenharmony_ci 647b1b8bc3fSopenharmony_ciint32_t IpParamParser::GetIp6AndMask(const in6_addr &addr6Start, const in6_addr &addr6End, std::vector<Ip6Data> &list) 648b1b8bc3fSopenharmony_ci{ 649b1b8bc3fSopenharmony_ci int32_t ret = memcmp(&addr6Start, &addr6End, sizeof(addr6Start)); 650b1b8bc3fSopenharmony_ci if (ret > 0) { 651b1b8bc3fSopenharmony_ci NETNATIVE_LOGW("GetIp6AndMask fail ret=%{public}d", ret); 652b1b8bc3fSopenharmony_ci return NETFIREWALL_ERR; 653b1b8bc3fSopenharmony_ci } else if (ret == 0) { 654b1b8bc3fSopenharmony_ci AddIp6(addr6Start, IPV6_MAX_PREFIXLEN, list); 655b1b8bc3fSopenharmony_ci return NETFIREWALL_SUCCESS; 656b1b8bc3fSopenharmony_ci } 657b1b8bc3fSopenharmony_ci uint32_t prefixlen = GetIp6Prefixlen(addr6Start, addr6End); 658b1b8bc3fSopenharmony_ci in6_addr tmpAddr; 659b1b8bc3fSopenharmony_ci memcpy_s(&tmpAddr, sizeof(tmpAddr), &addr6Start, sizeof(addr6Start)); 660b1b8bc3fSopenharmony_ci uint32_t off = RfindIp6(addr6Start, prefixlen, IPV6_BIT_COUNT - 1, 1); 661b1b8bc3fSopenharmony_ci if (off != IPV6_BIT_COUNT) { 662b1b8bc3fSopenharmony_ci AddIp6(tmpAddr, off + 1, list); 663b1b8bc3fSopenharmony_ci ChangeIp6Start(off + 1, tmpAddr); 664b1b8bc3fSopenharmony_ci off = RfindIp6(addr6Start, prefixlen, off, 0); 665b1b8bc3fSopenharmony_ci while (off != IPV6_BIT_COUNT && off != prefixlen) { 666b1b8bc3fSopenharmony_ci AddIp6(tmpAddr, off + 1, list); 667b1b8bc3fSopenharmony_ci ChangeIp6Start(off + 1, tmpAddr); 668b1b8bc3fSopenharmony_ci off = RfindIp6(addr6Start, prefixlen, off - 1, 0); 669b1b8bc3fSopenharmony_ci } 670b1b8bc3fSopenharmony_ci } else if (off == IPV6_BIT_COUNT) { 671b1b8bc3fSopenharmony_ci if (RfindIp6(addr6End, prefixlen, IPV6_BIT_COUNT - 1, 0) == IPV6_BIT_COUNT) { 672b1b8bc3fSopenharmony_ci AddIp6(addr6Start, prefixlen, list); 673b1b8bc3fSopenharmony_ci return NETFIREWALL_SUCCESS; 674b1b8bc3fSopenharmony_ci } 675b1b8bc3fSopenharmony_ci } 676b1b8bc3fSopenharmony_ci off = FindIp6(addr6End, prefixlen, 1); 677b1b8bc3fSopenharmony_ci if (off == IPV6_BIT_COUNT) { 678b1b8bc3fSopenharmony_ci NETNATIVE_LOGW("GetIp6AndMask off equal 128"); 679b1b8bc3fSopenharmony_ci return NETFIREWALL_ERR; 680b1b8bc3fSopenharmony_ci } 681b1b8bc3fSopenharmony_ci off = FindIp6(addr6End, off + 1, 1); 682b1b8bc3fSopenharmony_ci while (off != IPV6_BIT_COUNT) { 683b1b8bc3fSopenharmony_ci AddIp6(tmpAddr, off + 1, list); 684b1b8bc3fSopenharmony_ci ChangeIp6Start(off + 1, tmpAddr); 685b1b8bc3fSopenharmony_ci off = FindIp6(addr6End, off + 1, 1); 686b1b8bc3fSopenharmony_ci } 687b1b8bc3fSopenharmony_ci ret = memcmp(&tmpAddr, &addr6End, sizeof(addr6Start)); 688b1b8bc3fSopenharmony_ci if (ret == 0) { 689b1b8bc3fSopenharmony_ci AddIp6(tmpAddr, IPV6_MAX_PREFIXLEN, list); 690b1b8bc3fSopenharmony_ci } 691b1b8bc3fSopenharmony_ci return NETFIREWALL_SUCCESS; 692b1b8bc3fSopenharmony_ci} 693b1b8bc3fSopenharmony_ci} // namespace NetManagerStandard 694b1b8bc3fSopenharmony_ci} // namespace OHOS