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