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