1 /*
2 * Copyright (c) 2022 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 "traffic_manager.h"
17
18 #include <algorithm>
19 #include <dirent.h>
20 #include <fcntl.h>
21 #include <net/if.h>
22 #include <sys/socket.h>
23 #include <sys/types.h>
24 #include <sys/un.h>
25 #include <unistd.h>
26
27 #include "net_manager_native.h"
28 #include "netnative_log_wrapper.h"
29 #include "securec.h"
30
31 namespace OHOS {
32 namespace nmd {
33 namespace {
34 constexpr const char *INTERFACE_LIST_DIR = "/sys/class/net/";
35 constexpr const char *STATISTICS = "statistics";
36 constexpr const char *RX_BYTES = "rx_bytes";
37 constexpr const char *TX_BYTES = "tx_bytes";
38 constexpr const char *RX_PACKETS = "rx_packets";
39 constexpr const char *TX_PACKETS = "tx_packets";
40 } // namespace
41
GetInterfaceList()42 std::vector<std::string> GetInterfaceList()
43 {
44 DIR *dir(nullptr);
45 struct dirent *ptr(nullptr);
46 std::vector<std::string> ifList;
47
48 dir = opendir(INTERFACE_LIST_DIR);
49 if (dir == nullptr) {
50 NETNATIVE_LOGE("GetInterfaceList open %{private}s failed", INTERFACE_LIST_DIR);
51 return ifList;
52 }
53
54 ptr = readdir(dir);
55 while (ptr != nullptr) {
56 if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) {
57 ifList.push_back(ptr->d_name);
58 }
59 ptr = readdir(dir);
60 }
61 closedir(dir);
62
63 return ifList;
64 }
65
GetInterfaceTrafficByType(const std::string & path,const std::string & type)66 long GetInterfaceTrafficByType(const std::string &path, const std::string &type)
67 {
68 if (path.empty()) {
69 return -1;
70 }
71
72 std::string trafficPath = path + type;
73
74 char tmpPath[PATH_MAX] = {0};
75 if (!realpath(trafficPath.c_str(), tmpPath)) {
76 NETNATIVE_LOGE("file name is illegal");
77 return -1;
78 }
79
80 int fd = open(tmpPath, 0, 0666);
81 if (fd == -1) {
82 NETNATIVE_LOGE("GetInterfaceTrafficByType open %{private}s failed", INTERFACE_LIST_DIR);
83 return -1;
84 }
85
86 char buf[100] = {0};
87 int nread = read(fd, buf, sizeof(long));
88 if (nread == -1) {
89 NETNATIVE_LOGE("GetInterfaceTrafficByType read %{private}s failed", INTERFACE_LIST_DIR);
90 close(fd);
91 return -1;
92 }
93 close(fd);
94
95 return atol(buf);
96 }
97
GetAllRxTraffic()98 long TrafficManager::GetAllRxTraffic()
99 {
100 std::vector<std::string> ifNameList = GetInterfaceList();
101 if (ifNameList.empty()) {
102 return 0;
103 }
104
105 long allRxBytes = 0;
106 for (auto iter = ifNameList.begin(); iter != ifNameList.end(); iter++) {
107 if (*iter != "lo") {
108 std::string baseTrafficPath = INTERFACE_LIST_DIR + (*iter) + "/" + STATISTICS + "/";
109 long rxBytes = GetInterfaceTrafficByType(baseTrafficPath, RX_BYTES);
110 allRxBytes += rxBytes;
111 }
112 }
113 return allRxBytes;
114 }
115
GetAllTxTraffic()116 long TrafficManager::GetAllTxTraffic()
117 {
118 std::vector<std::string> ifNameList = GetInterfaceList();
119 if (ifNameList.empty()) {
120 return 0;
121 }
122
123 long allTxBytes = 0;
124 for (auto iter = ifNameList.begin(); iter != ifNameList.end(); iter++) {
125 if (*iter != "lo") {
126 std::string baseTrafficPath = INTERFACE_LIST_DIR + (*iter) + "/" + STATISTICS + "/";
127 long txBytes = GetInterfaceTrafficByType(baseTrafficPath, TX_BYTES);
128 allTxBytes = allTxBytes + txBytes;
129 }
130 }
131 return allTxBytes;
132 }
133
GetInterfaceTraffic(const std::string & ifName)134 TrafficStatsParcel TrafficManager::GetInterfaceTraffic(const std::string &ifName)
135 {
136 nmd::TrafficStatsParcel interfaceTrafficBytes = {"", 0, 0, 0, 0, 0};
137 std::vector<std::string> ifNameList = GetInterfaceList();
138 if (ifNameList.empty()) {
139 return interfaceTrafficBytes;
140 }
141 for (auto iter = ifNameList.begin(); iter != ifNameList.end(); iter++) {
142 if (ifName != *iter) {
143 continue;
144 }
145 std::string baseTrafficPath = INTERFACE_LIST_DIR + (*iter) + "/" + STATISTICS + "/";
146 long infRxBytes = GetInterfaceTrafficByType(baseTrafficPath, RX_BYTES);
147 long infRxPackets = GetInterfaceTrafficByType(baseTrafficPath, RX_PACKETS);
148 long infTxBytes = GetInterfaceTrafficByType(baseTrafficPath, TX_BYTES);
149 long infTxPackets = GetInterfaceTrafficByType(baseTrafficPath, TX_PACKETS);
150
151 interfaceTrafficBytes.iface = ifName;
152 interfaceTrafficBytes.ifIndex = if_nametoindex(ifName.c_str());
153
154 interfaceTrafficBytes.rxBytes = infRxBytes == -1 ? 0 : infRxBytes;
155 interfaceTrafficBytes.rxPackets = infRxPackets == -1 ? 0 : infRxPackets;
156 interfaceTrafficBytes.txBytes = infTxBytes == -1 ? 0 : infTxBytes;
157 interfaceTrafficBytes.txPackets = infTxPackets == -1 ? 0 : infTxPackets;
158 }
159 return interfaceTrafficBytes;
160 }
161 } // namespace nmd
162 } // namespace OHOS
163