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