1 /*
2 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <net/if.h>
17 #include <vector>
18
19 #include "bpf_path.h"
20 #include "bpf_def.h"
21 #include "bpf_stats.h"
22 #include "securec.h"
23 #include "netnative_log_wrapper.h"
24 #include "net_stats_constants.h"
25
26 namespace OHOS::NetManagerStandard {
GetNumberFromStatsValue(uint64_t & stats,StatsType statsType,const stats_value & value)27 int32_t NetsysBpfStats::GetNumberFromStatsValue(uint64_t &stats, StatsType statsType, const stats_value &value)
28 {
29 switch (statsType) {
30 case StatsType::STATS_TYPE_RX_BYTES:
31 stats = value.rxBytes;
32 break;
33 case StatsType::STATS_TYPE_RX_PACKETS:
34 stats = value.rxPackets;
35 break;
36 case StatsType::STATS_TYPE_TX_BYTES:
37 stats = value.txBytes;
38 break;
39 case StatsType::STATS_TYPE_TX_PACKETS:
40 stats = value.txPackets;
41 break;
42 default:
43 NETNATIVE_LOGE("invalid StatsType type %{public}d", statsType);
44 return STATS_ERR_READ_BPF_FAIL;
45 }
46 return NETSYS_SUCCESS;
47 }
48
GetTotalStats(uint64_t & stats,StatsType statsType)49 int32_t NetsysBpfStats::GetTotalStats(uint64_t &stats, StatsType statsType)
50 {
51 stats = 0;
52 BpfMapper<iface_stats_key, iface_stats_value> ifaceStatsMap(IFACE_STATS_MAP_PATH, BPF_F_RDONLY);
53 if (!ifaceStatsMap.IsValid()) {
54 NETNATIVE_LOGE("ifaceStatsMap IsValid");
55 return STATS_ERR_INVALID_IFACE_NAME_MAP;
56 }
57
58 iface_stats_value totalStats = {0};
59 auto keys = ifaceStatsMap.GetAllKeys();
60 for (const auto &k : keys) {
61 iface_stats_value v = {0};
62 if (ifaceStatsMap.Read(k, v) < NETSYS_SUCCESS) {
63 NETNATIVE_LOGE("Read ifaceStatsMap err");
64 return STATS_ERR_READ_BPF_FAIL;
65 }
66 totalStats.rxPackets += v.rxPackets;
67 totalStats.rxBytes += v.rxBytes;
68 totalStats.txPackets += v.txPackets;
69 totalStats.txBytes += v.txBytes;
70 }
71
72 return GetNumberFromStatsValue(stats, statsType, totalStats);
73 }
74
GetUidStats(uint64_t & stats,StatsType statsType,uint32_t uid)75 int32_t NetsysBpfStats::GetUidStats(uint64_t &stats, StatsType statsType, uint32_t uid)
76 {
77 stats = 0;
78 BpfMapper<app_uid_stats_key, app_uid_stats_value> appUidStatsMap(APP_UID_STATS_MAP_PATH, BPF_F_RDONLY);
79 if (!appUidStatsMap.IsValid()) {
80 return STATS_ERR_INVALID_IFACE_NAME_MAP;
81 }
82
83 app_uid_stats_value uidStats = {0};
84 if (appUidStatsMap.Read(uid, uidStats) < 0) {
85 return STATS_ERR_READ_BPF_FAIL;
86 }
87 return GetNumberFromStatsValue(stats, statsType, uidStats);
88 }
89
GetAllStatsInfo(std::vector<OHOS::NetManagerStandard::NetStatsInfo> & stats)90 int32_t NetsysBpfStats::GetAllStatsInfo(std::vector<OHOS::NetManagerStandard::NetStatsInfo> &stats)
91 {
92 BpfMapper<stats_key, stats_value> uidIfaceStatsMap(APP_UID_IF_STATS_MAP_PATH, BPF_F_RDONLY);
93 if (!uidIfaceStatsMap.IsValid()) {
94 return STATS_ERR_INVALID_IFACE_NAME_MAP;
95 }
96
97 stats.clear();
98 char if_name[IFNAME_SIZE] = {0};
99 auto keys = uidIfaceStatsMap.GetAllKeys();
100 for (const auto &k : keys) {
101 stats_value v = {};
102 if (uidIfaceStatsMap.Read(k, v) < 0) {
103 NETNATIVE_LOGE("Read ifaceStatsMap err");
104 return STATS_ERR_READ_BPF_FAIL;
105 }
106
107 NetStatsInfo tempStats;
108 tempStats.uid_ = k.uId;
109 if (memset_s(if_name, sizeof(if_name), 0, sizeof(if_name)) != EOK) {
110 return STATS_ERR_READ_BPF_FAIL;
111 }
112
113 char *pName = if_indextoname(k.ifIndex, if_name);
114 if (pName != nullptr) {
115 tempStats.iface_ = pName;
116 }
117 tempStats.rxBytes_ = v.rxBytes;
118 tempStats.txBytes_ = v.txBytes;
119 tempStats.rxPackets_ = v.rxPackets;
120 tempStats.txPackets_ = v.txPackets;
121 stats.emplace_back(tempStats);
122 }
123
124 return NETSYS_SUCCESS;
125 }
126
GetIfaceStats(uint64_t & stats,const StatsType statsType,const std::string & interfaceName)127 int32_t NetsysBpfStats::GetIfaceStats(uint64_t &stats, const StatsType statsType, const std::string &interfaceName)
128 {
129 stats = 0;
130 BpfMapper<iface_stats_key, iface_stats_value> ifaceStatsMap(IFACE_STATS_MAP_PATH, BPF_F_RDONLY);
131 if (!ifaceStatsMap.IsValid()) {
132 return STATS_ERR_INVALID_IFACE_NAME_MAP;
133 }
134
135 auto ifIndex = if_nametoindex(interfaceName.c_str());
136 if (ifIndex <= 0) {
137 return STATS_ERR_GET_IFACE_NAME_FAILED;
138 }
139
140 iface_stats_value ifaceStats = {0};
141 if (ifaceStatsMap.Read(ifIndex, ifaceStats) < 0) {
142 return STATS_ERR_READ_BPF_FAIL;
143 }
144 return GetNumberFromStatsValue(stats, statsType, ifaceStats);
145 }
146
GetCookieStats(uint64_t & stats,StatsType statsType,uint64_t cookie)147 int32_t NetsysBpfStats::GetCookieStats(uint64_t &stats, StatsType statsType, uint64_t cookie)
148 {
149 NETNATIVE_LOGI("GetCookieStats start");
150 stats = 0;
151 BpfMapper<socket_cookie_stats_key, app_cookie_stats_value> appUidCookieStatsMap(APP_COOKIE_STATS_MAP_PATH,
152 BPF_F_RDONLY);
153 if (!appUidCookieStatsMap.IsValid()) {
154 NETNATIVE_LOGE("GetCookieStats appUidCookieStatsMap is valid");
155 return NETMANAGER_ERR_INTERNAL;
156 }
157
158 app_cookie_stats_value cookieStats = {0};
159 if (appUidCookieStatsMap.Read(cookie, cookieStats) < 0) {
160 NETNATIVE_LOGE("GetCookieStats appUidCookieStatsMap read error");
161 return NETMANAGER_ERR_INTERNAL;
162 }
163
164 int32_t res = GetNumberFromStatsValue(stats, statsType, cookieStats);
165 if (res == STATS_ERR_READ_BPF_FAIL) {
166 NETNATIVE_LOGE("GetCookieStats GetNumberFromStatsValue error");
167 return NETMANAGER_ERR_INTERNAL;
168 }
169 return NETSYS_SUCCESS;
170 }
171 } // namespace OHOS::NetManagerStandard
172