1b1b8bc3fSopenharmony_ci/*
2b1b8bc3fSopenharmony_ci * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3b1b8bc3fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4b1b8bc3fSopenharmony_ci * you may not use this file except in compliance with the License.
5b1b8bc3fSopenharmony_ci * You may obtain a copy of the License at
6b1b8bc3fSopenharmony_ci *
7b1b8bc3fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8b1b8bc3fSopenharmony_ci *
9b1b8bc3fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10b1b8bc3fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11b1b8bc3fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12b1b8bc3fSopenharmony_ci * See the License for the specific language governing permissions and
13b1b8bc3fSopenharmony_ci * limitations under the License.
14b1b8bc3fSopenharmony_ci */
15b1b8bc3fSopenharmony_ci
16b1b8bc3fSopenharmony_ci#include <net/if.h>
17b1b8bc3fSopenharmony_ci#include <vector>
18b1b8bc3fSopenharmony_ci
19b1b8bc3fSopenharmony_ci#include "bpf_path.h"
20b1b8bc3fSopenharmony_ci#include "bpf_def.h"
21b1b8bc3fSopenharmony_ci#include "bpf_stats.h"
22b1b8bc3fSopenharmony_ci#include "securec.h"
23b1b8bc3fSopenharmony_ci#include "netnative_log_wrapper.h"
24b1b8bc3fSopenharmony_ci#include "net_stats_constants.h"
25b1b8bc3fSopenharmony_ci
26b1b8bc3fSopenharmony_cinamespace OHOS::NetManagerStandard {
27b1b8bc3fSopenharmony_cinamespace {
28b1b8bc3fSopenharmony_ciconstexpr const char *CELLULAR_IFACE = "rmnet0";
29b1b8bc3fSopenharmony_ciconstexpr const char *WIFI_IFACE = "wlan0";
30b1b8bc3fSopenharmony_ci}
31b1b8bc3fSopenharmony_ciint32_t NetsysBpfStats::GetNumberFromStatsValue(uint64_t &stats, StatsType statsType, const stats_value &value)
32b1b8bc3fSopenharmony_ci{
33b1b8bc3fSopenharmony_ci    switch (statsType) {
34b1b8bc3fSopenharmony_ci        case StatsType::STATS_TYPE_RX_BYTES:
35b1b8bc3fSopenharmony_ci            stats = value.rxBytes;
36b1b8bc3fSopenharmony_ci            break;
37b1b8bc3fSopenharmony_ci        case StatsType::STATS_TYPE_RX_PACKETS:
38b1b8bc3fSopenharmony_ci            stats = value.rxPackets;
39b1b8bc3fSopenharmony_ci            break;
40b1b8bc3fSopenharmony_ci        case StatsType::STATS_TYPE_TX_BYTES:
41b1b8bc3fSopenharmony_ci            stats = value.txBytes;
42b1b8bc3fSopenharmony_ci            break;
43b1b8bc3fSopenharmony_ci        case StatsType::STATS_TYPE_TX_PACKETS:
44b1b8bc3fSopenharmony_ci            stats = value.txPackets;
45b1b8bc3fSopenharmony_ci            break;
46b1b8bc3fSopenharmony_ci        default:
47b1b8bc3fSopenharmony_ci            NETNATIVE_LOGE("invalid StatsType type %{public}d", statsType);
48b1b8bc3fSopenharmony_ci            return STATS_ERR_READ_BPF_FAIL;
49b1b8bc3fSopenharmony_ci    }
50b1b8bc3fSopenharmony_ci    return NETSYS_SUCCESS;
51b1b8bc3fSopenharmony_ci}
52b1b8bc3fSopenharmony_ci
53b1b8bc3fSopenharmony_ciint32_t NetsysBpfStats::GetTotalStats(uint64_t &stats, StatsType statsType)
54b1b8bc3fSopenharmony_ci{
55b1b8bc3fSopenharmony_ci    stats = 0;
56b1b8bc3fSopenharmony_ci    BpfMapper<iface_stats_key, iface_stats_value> ifaceStatsMap(IFACE_STATS_MAP_PATH, BPF_F_RDONLY);
57b1b8bc3fSopenharmony_ci    if (!ifaceStatsMap.IsValid()) {
58b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("ifaceStatsMap IsValid");
59b1b8bc3fSopenharmony_ci        return STATS_ERR_INVALID_IFACE_NAME_MAP;
60b1b8bc3fSopenharmony_ci    }
61b1b8bc3fSopenharmony_ci
62b1b8bc3fSopenharmony_ci    iface_stats_value totalStats = {0};
63b1b8bc3fSopenharmony_ci    auto keys = ifaceStatsMap.GetAllKeys();
64b1b8bc3fSopenharmony_ci    for (const auto &k : keys) {
65b1b8bc3fSopenharmony_ci        iface_stats_value v = {0};
66b1b8bc3fSopenharmony_ci        if (ifaceStatsMap.Read(k, v) < NETSYS_SUCCESS) {
67b1b8bc3fSopenharmony_ci            NETNATIVE_LOGE("Read ifaceStatsMap err");
68b1b8bc3fSopenharmony_ci            return STATS_ERR_READ_BPF_FAIL;
69b1b8bc3fSopenharmony_ci        }
70b1b8bc3fSopenharmony_ci        totalStats.rxPackets += v.rxPackets;
71b1b8bc3fSopenharmony_ci        totalStats.rxBytes += v.rxBytes;
72b1b8bc3fSopenharmony_ci        totalStats.txPackets += v.txPackets;
73b1b8bc3fSopenharmony_ci        totalStats.txBytes += v.txBytes;
74b1b8bc3fSopenharmony_ci    }
75b1b8bc3fSopenharmony_ci
76b1b8bc3fSopenharmony_ci    return GetNumberFromStatsValue(stats, statsType, totalStats);
77b1b8bc3fSopenharmony_ci}
78b1b8bc3fSopenharmony_ci
79b1b8bc3fSopenharmony_ciint32_t NetsysBpfStats::GetUidStats(uint64_t &stats, StatsType statsType, uint32_t uid)
80b1b8bc3fSopenharmony_ci{
81b1b8bc3fSopenharmony_ci    stats = 0;
82b1b8bc3fSopenharmony_ci    BpfMapper<app_uid_stats_key, app_uid_stats_value> appUidStatsMap(APP_UID_STATS_MAP_PATH, BPF_F_RDONLY);
83b1b8bc3fSopenharmony_ci    if (!appUidStatsMap.IsValid()) {
84b1b8bc3fSopenharmony_ci        return STATS_ERR_INVALID_IFACE_NAME_MAP;
85b1b8bc3fSopenharmony_ci    }
86b1b8bc3fSopenharmony_ci
87b1b8bc3fSopenharmony_ci    app_uid_stats_value uidStats = {0};
88b1b8bc3fSopenharmony_ci    if (appUidStatsMap.Read(uid, uidStats) < 0) {
89b1b8bc3fSopenharmony_ci        return STATS_ERR_READ_BPF_FAIL;
90b1b8bc3fSopenharmony_ci    }
91b1b8bc3fSopenharmony_ci    return GetNumberFromStatsValue(stats, statsType, uidStats);
92b1b8bc3fSopenharmony_ci}
93b1b8bc3fSopenharmony_ci
94b1b8bc3fSopenharmony_ciint32_t NetsysBpfStats::GetAllSimStatsInfo(std::vector<OHOS::NetManagerStandard::NetStatsInfo> &stats)
95b1b8bc3fSopenharmony_ci{
96b1b8bc3fSopenharmony_ci    BpfMapper<stats_key, stats_value> uidSimStatsMap(APP_UID_SIM_STATS_MAP_PATH, BPF_F_RDONLY);
97b1b8bc3fSopenharmony_ci    if (!uidSimStatsMap.IsValid()) {
98b1b8bc3fSopenharmony_ci        return STATS_ERR_INVALID_IFACE_NAME_MAP;
99b1b8bc3fSopenharmony_ci    }
100b1b8bc3fSopenharmony_ci
101b1b8bc3fSopenharmony_ci    stats.clear();
102b1b8bc3fSopenharmony_ci    char if_name[IFNAME_SIZE] = {0};
103b1b8bc3fSopenharmony_ci    auto keys = uidSimStatsMap.GetAllKeys();
104b1b8bc3fSopenharmony_ci    for (const auto &k : keys) {
105b1b8bc3fSopenharmony_ci        stats_value v = {};
106b1b8bc3fSopenharmony_ci        if (uidSimStatsMap.Read(k, v) < 0) {
107b1b8bc3fSopenharmony_ci            NETNATIVE_LOGE("Read uid_sim_map err");
108b1b8bc3fSopenharmony_ci            return STATS_ERR_READ_BPF_FAIL;
109b1b8bc3fSopenharmony_ci        }
110b1b8bc3fSopenharmony_ci
111b1b8bc3fSopenharmony_ci        NetStatsInfo tempStats;
112b1b8bc3fSopenharmony_ci        tempStats.uid_ = k.uId;
113b1b8bc3fSopenharmony_ci        if (memset_s(if_name, sizeof(if_name), 0, sizeof(if_name)) != EOK) {
114b1b8bc3fSopenharmony_ci            return STATS_ERR_READ_BPF_FAIL;
115b1b8bc3fSopenharmony_ci        }
116b1b8bc3fSopenharmony_ci
117b1b8bc3fSopenharmony_ci        char *pName = if_indextoname(k.ifIndex, if_name);
118b1b8bc3fSopenharmony_ci        if (pName != nullptr) {
119b1b8bc3fSopenharmony_ci            tempStats.iface_ = pName;
120b1b8bc3fSopenharmony_ci        }
121b1b8bc3fSopenharmony_ci        if (k.ifType == IFACE_TYPE_WIFI) {
122b1b8bc3fSopenharmony_ci            tempStats.iface_ = WIFI_IFACE;
123b1b8bc3fSopenharmony_ci        } else if (k.ifType == IFACE_TYPE_CELLULAR) {
124b1b8bc3fSopenharmony_ci            tempStats.iface_ = CELLULAR_IFACE;
125b1b8bc3fSopenharmony_ci        }
126b1b8bc3fSopenharmony_ci        tempStats.rxBytes_ = v.rxBytes;
127b1b8bc3fSopenharmony_ci        tempStats.txBytes_ = v.txBytes;
128b1b8bc3fSopenharmony_ci        tempStats.rxPackets_ = v.rxPackets;
129b1b8bc3fSopenharmony_ci        tempStats.txPackets_ = v.txPackets;
130b1b8bc3fSopenharmony_ci        auto findRet = std::find_if(stats.begin(), stats.end(),
131b1b8bc3fSopenharmony_ci                                    [&tempStats](const NetStatsInfo &info) { return info.Equals(tempStats); });
132b1b8bc3fSopenharmony_ci        if (findRet == stats.end()) {
133b1b8bc3fSopenharmony_ci            stats.push_back(std::move(tempStats));
134b1b8bc3fSopenharmony_ci        } else {
135b1b8bc3fSopenharmony_ci            *findRet += tempStats;
136b1b8bc3fSopenharmony_ci        }
137b1b8bc3fSopenharmony_ci    }
138b1b8bc3fSopenharmony_ci
139b1b8bc3fSopenharmony_ci    return NETSYS_SUCCESS;
140b1b8bc3fSopenharmony_ci}
141b1b8bc3fSopenharmony_ci
142b1b8bc3fSopenharmony_ciint32_t NetsysBpfStats::GetAllStatsInfo(std::vector<OHOS::NetManagerStandard::NetStatsInfo> &stats)
143b1b8bc3fSopenharmony_ci{
144b1b8bc3fSopenharmony_ci    BpfMapper<stats_key, stats_value> uidIfaceStatsMap(APP_UID_IF_STATS_MAP_PATH, BPF_F_RDONLY);
145b1b8bc3fSopenharmony_ci    if (!uidIfaceStatsMap.IsValid()) {
146b1b8bc3fSopenharmony_ci        return STATS_ERR_INVALID_IFACE_NAME_MAP;
147b1b8bc3fSopenharmony_ci    }
148b1b8bc3fSopenharmony_ci
149b1b8bc3fSopenharmony_ci    stats.clear();
150b1b8bc3fSopenharmony_ci    char if_name[IFNAME_SIZE] = {0};
151b1b8bc3fSopenharmony_ci    auto keys = uidIfaceStatsMap.GetAllKeys();
152b1b8bc3fSopenharmony_ci    for (const auto &k : keys) {
153b1b8bc3fSopenharmony_ci        stats_value v = {};
154b1b8bc3fSopenharmony_ci        if (uidIfaceStatsMap.Read(k, v) < 0) {
155b1b8bc3fSopenharmony_ci            NETNATIVE_LOGE("Read ifaceStatsMap err");
156b1b8bc3fSopenharmony_ci            return STATS_ERR_READ_BPF_FAIL;
157b1b8bc3fSopenharmony_ci        }
158b1b8bc3fSopenharmony_ci
159b1b8bc3fSopenharmony_ci        NetStatsInfo tempStats;
160b1b8bc3fSopenharmony_ci        tempStats.uid_ = k.uId;
161b1b8bc3fSopenharmony_ci        if (memset_s(if_name, sizeof(if_name), 0, sizeof(if_name)) != EOK) {
162b1b8bc3fSopenharmony_ci            return STATS_ERR_READ_BPF_FAIL;
163b1b8bc3fSopenharmony_ci        }
164b1b8bc3fSopenharmony_ci
165b1b8bc3fSopenharmony_ci        char *pName = if_indextoname(k.ifIndex, if_name);
166b1b8bc3fSopenharmony_ci        if (pName != nullptr) {
167b1b8bc3fSopenharmony_ci            tempStats.iface_ = pName;
168b1b8bc3fSopenharmony_ci        }
169b1b8bc3fSopenharmony_ci        tempStats.rxBytes_ = v.rxBytes;
170b1b8bc3fSopenharmony_ci        tempStats.txBytes_ = v.txBytes;
171b1b8bc3fSopenharmony_ci        tempStats.rxPackets_ = v.rxPackets;
172b1b8bc3fSopenharmony_ci        tempStats.txPackets_ = v.txPackets;
173b1b8bc3fSopenharmony_ci        stats.emplace_back(std::move(tempStats));
174b1b8bc3fSopenharmony_ci    }
175b1b8bc3fSopenharmony_ci
176b1b8bc3fSopenharmony_ci    return NETSYS_SUCCESS;
177b1b8bc3fSopenharmony_ci}
178b1b8bc3fSopenharmony_ci
179b1b8bc3fSopenharmony_ciint32_t NetsysBpfStats::DeleteStatsInfo(const std::string &path, uint32_t uid)
180b1b8bc3fSopenharmony_ci{
181b1b8bc3fSopenharmony_ci    if (path != APP_UID_IF_STATS_MAP_PATH && path != APP_UID_SIM_STATS_MAP_PATH) {
182b1b8bc3fSopenharmony_ci        NETNATIVE_LOGI("DeleteStatsInfo invalid path");
183b1b8bc3fSopenharmony_ci        return NETSYS_SUCCESS;
184b1b8bc3fSopenharmony_ci    }
185b1b8bc3fSopenharmony_ci    BpfMapper<stats_key, stats_value> uidStatsMap(path, BPF_ANY);
186b1b8bc3fSopenharmony_ci    if (!uidStatsMap.IsValid()) {
187b1b8bc3fSopenharmony_ci        return STATS_ERR_INVALID_IFACE_NAME_MAP;
188b1b8bc3fSopenharmony_ci    }
189b1b8bc3fSopenharmony_ci    auto keys = uidStatsMap.GetAllKeys();
190b1b8bc3fSopenharmony_ci    for (const auto &k : keys) {
191b1b8bc3fSopenharmony_ci        if (k.uId == uid) {
192b1b8bc3fSopenharmony_ci            if (uidStatsMap.Delete(k) < 0) {
193b1b8bc3fSopenharmony_ci                NETNATIVE_LOGE("Delete uidStatsMap err");
194b1b8bc3fSopenharmony_ci                return STATS_ERR_WRITE_BPF_FAIL;
195b1b8bc3fSopenharmony_ci            }
196b1b8bc3fSopenharmony_ci        }
197b1b8bc3fSopenharmony_ci    }
198b1b8bc3fSopenharmony_ci    return NETSYS_SUCCESS;
199b1b8bc3fSopenharmony_ci}
200b1b8bc3fSopenharmony_ci
201b1b8bc3fSopenharmony_ciint32_t NetsysBpfStats::GetIfaceStats(uint64_t &stats, const StatsType statsType, const std::string &interfaceName)
202b1b8bc3fSopenharmony_ci{
203b1b8bc3fSopenharmony_ci    stats = 0;
204b1b8bc3fSopenharmony_ci    BpfMapper<iface_stats_key, iface_stats_value> ifaceStatsMap(IFACE_STATS_MAP_PATH, BPF_F_RDONLY);
205b1b8bc3fSopenharmony_ci    if (!ifaceStatsMap.IsValid()) {
206b1b8bc3fSopenharmony_ci        return STATS_ERR_INVALID_IFACE_NAME_MAP;
207b1b8bc3fSopenharmony_ci    }
208b1b8bc3fSopenharmony_ci
209b1b8bc3fSopenharmony_ci    auto ifIndex = if_nametoindex(interfaceName.c_str());
210b1b8bc3fSopenharmony_ci    if (ifIndex <= 0) {
211b1b8bc3fSopenharmony_ci        return STATS_ERR_GET_IFACE_NAME_FAILED;
212b1b8bc3fSopenharmony_ci    }
213b1b8bc3fSopenharmony_ci
214b1b8bc3fSopenharmony_ci    iface_stats_value ifaceStats = {0};
215b1b8bc3fSopenharmony_ci    if (ifaceStatsMap.Read(ifIndex, ifaceStats) < 0) {
216b1b8bc3fSopenharmony_ci        return STATS_ERR_READ_BPF_FAIL;
217b1b8bc3fSopenharmony_ci    }
218b1b8bc3fSopenharmony_ci    return GetNumberFromStatsValue(stats, statsType, ifaceStats);
219b1b8bc3fSopenharmony_ci}
220b1b8bc3fSopenharmony_ci
221b1b8bc3fSopenharmony_ciint32_t NetsysBpfStats::GetCookieStats(uint64_t &stats, StatsType statsType, uint64_t cookie)
222b1b8bc3fSopenharmony_ci{
223b1b8bc3fSopenharmony_ci    NETNATIVE_LOGI("GetCookieStats start");
224b1b8bc3fSopenharmony_ci    stats = 0;
225b1b8bc3fSopenharmony_ci    BpfMapper<socket_cookie_stats_key, app_cookie_stats_value> appUidCookieStatsMap(APP_COOKIE_STATS_MAP_PATH,
226b1b8bc3fSopenharmony_ci                                                                                    BPF_F_RDONLY);
227b1b8bc3fSopenharmony_ci    if (!appUidCookieStatsMap.IsValid()) {
228b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("GetCookieStats appUidCookieStatsMap is valid");
229b1b8bc3fSopenharmony_ci        return NETMANAGER_ERR_INTERNAL;
230b1b8bc3fSopenharmony_ci    }
231b1b8bc3fSopenharmony_ci
232b1b8bc3fSopenharmony_ci    app_cookie_stats_value cookieStats = {0};
233b1b8bc3fSopenharmony_ci    if (appUidCookieStatsMap.Read(cookie, cookieStats) < 0) {
234b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("GetCookieStats appUidCookieStatsMap read error");
235b1b8bc3fSopenharmony_ci        return NETMANAGER_ERR_INTERNAL;
236b1b8bc3fSopenharmony_ci    }
237b1b8bc3fSopenharmony_ci
238b1b8bc3fSopenharmony_ci    int32_t res = GetNumberFromStatsValue(stats, statsType, cookieStats);
239b1b8bc3fSopenharmony_ci    if (res == STATS_ERR_READ_BPF_FAIL) {
240b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("GetCookieStats GetNumberFromStatsValue error");
241b1b8bc3fSopenharmony_ci        return NETMANAGER_ERR_INTERNAL;
242b1b8bc3fSopenharmony_ci    }
243b1b8bc3fSopenharmony_ci    return NETSYS_SUCCESS;
244b1b8bc3fSopenharmony_ci}
245b1b8bc3fSopenharmony_ci} // namespace OHOS::NetManagerStandard
246