1 /*
2  * Copyright (c) 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_diag_wrapper.h"
17 #include "net_manager_constants.h"
18 #include "netmanager_base_common_utils.h"
19 #include "netnative_log_wrapper.h"
20 
21 #include <algorithm>
22 #include <iomanip>
23 #include <pthread.h>
24 #include <sstream>
25 #include <thread>
26 
27 namespace OHOS {
28 namespace nmd {
29 namespace {
30 using namespace NetManagerStandard;
31 constexpr int32_t TIME_MS_TO_SEC = 1000;
32 constexpr int32_t PING_MAX_DURATION_TIME = 30;
33 constexpr int32_t PING_HEADER_MATCH_SIZE = 5;
34 constexpr int32_t PING_ICMP_SEQ_MATCH_SIZE = 6;
35 constexpr int32_t PING_STATISTICS_MATCH_SIZE = 4;
36 constexpr int32_t NETSTAT_NET_PROTOCOL_MATCH_SIZE = 10;
37 constexpr int32_t NETSTAT_UNIX_MATCH_SIZE = 8;
38 constexpr int32_t NETSTAT_ROUTE_TABLE_MATCH_SIZE = 9;
39 constexpr int32_t IFCONFIG_NAME_INFO_MATCH_SIZE = 6;
40 constexpr int32_t IFCONFIG_INET_INFO_MATCH_SIZE = 4;
41 constexpr int32_t IFCONFIG_INET6_INFO_MATCH_SIZE = 3;
42 constexpr int32_t IFCONFIG_MTU_MATCH_SIZE = 4;
43 constexpr int32_t IFCONFIG_TX_QUEUE_LEN_MATCH_SIZE = 2;
44 constexpr int32_t IFCONFIG_TRANS_BYTES_MATCH_SIZE = 3;
45 
46 constexpr const char *PING_CMD_PATH = "/system/bin/ping";
47 constexpr const char *NETSTAT_CMD_PATH = "/system/bin/netstat";
48 constexpr const char *IFCONFIG_CMD_PATH = "/system/bin/ifconfig";
49 constexpr const char *PING_THREAD_NAME = "NetDiagPingThread";
50 
51 constexpr const char *OPTION_SPACE = " ";
52 
53 constexpr const char *PING_OPTION_IPV4 = "-4";
54 constexpr const char *PING_OPTION_IPV6 = "-6";
55 constexpr const char *PING_OPTION_SOURCE = "-I";
56 constexpr const char *PING_OPTION_INTERVAL = "-i";
57 constexpr const char *PING_OPTION_COUNT = "-c";
58 constexpr const char *PING_OPTION_SIZE = "-s";
59 constexpr const char *PING_OPTION_FLOOD = "-f";
60 constexpr const char *PING_OPTION_TTL = "-t";
61 constexpr const char *PING_OPTION_MARK = "-m";
62 constexpr const char *PING_OPTION_TIMEOUT = "-W";
63 constexpr const char *PING_OPTION_DURATION = "-w";
64 
65 constexpr const char *NETSTAT_OPTION_ROUTE_TABLE = "-re";
66 constexpr const char *NETSTAT_OPTION_ALL_SOCKETS = "-ae";
67 constexpr const char *NETSTAT_OPTION_TCP_SOCKETS = "-atep";
68 constexpr const char *NETSTAT_OPTION_UDP_SOCKETS = "-auep";
69 constexpr const char *NETSTAT_OPTION_RAW_SOCKETS = "-arep";
70 constexpr const char *NETSTAT_OPTION_UNIX_SOCKETS = "-axe";
71 
72 constexpr const char *IFCONFIG_OPTION_ALL_IFACE = "-a";
73 constexpr const char *IFCONFIG_OPTION_ADD_IPV6 = "add";
74 constexpr const char *IFCONFIG_OPTION_DEL_IPV6 = "del";
75 constexpr const char *IFCONFIG_OPTION_DEL_IPV4 = "default";
76 constexpr const char *IFCONFIG_OPTION_SET_IPV4_MASK = "netmask";
77 constexpr const char *IFCONFIG_OPTION_SET_IPV4_BCAST = "broadcast";
78 constexpr const char *IFCONFIG_OPTION_SET_MTU_LEN = "mtu";
79 constexpr const char *IFCONFIG_OPTION_SET_TX_QUEUE_LEN = "txqueuelen";
80 constexpr const char *IFCONFIG_OPTION_IFACE_UP = "up";
81 constexpr const char *IFCONFIG_OPTION_IFACE_DOWN = "down";
82 
83 constexpr const char *PING_NAME_DOES_NOT_RESOLVED = "Name does not resolve";
84 constexpr const char *PING_NETWORK_UNREACHABLE = "Network unreachable";
85 } // namespace
86 
NetDiagWrapper()87 NetDiagWrapper::NetDiagWrapper() {}
88 
~NetDiagWrapper()89 __attribute__((no_sanitize("cfi"))) NetDiagWrapper::~NetDiagWrapper() {}
90 
PingHost(const NetDiagPingOption & pingOption,const sptr<INetDiagCallback> & callback)91 int32_t NetDiagWrapper::PingHost(const NetDiagPingOption &pingOption, const sptr<INetDiagCallback> &callback)
92 {
93     NETNATIVE_LOGI("Generate ping command: ");
94     std::string command;
95     int32_t ret = GeneratePingCommand(pingOption, command);
96     if (ret != NETMANAGER_SUCCESS) {
97         return ret;
98     }
99 
100     auto wrapper = shared_from_this();
101     std::thread pingThread([wrapper, command, callback]() {
102         if (wrapper == nullptr) {
103             NETNATIVE_LOGE("wrapper is nullptr");
104             return;
105         }
106         std::string result;
107         if (wrapper->ExecuteCommandForResult(command, result) != NETMANAGER_SUCCESS) {
108             return;
109         }
110         if (result.empty()) {
111             NETNATIVE_LOGE("Ping result is empty");
112             return;
113         }
114         wrapper->ExtractPingResult(result, callback);
115     });
116     pthread_setname_np(pingThread.native_handle(), PING_THREAD_NAME);
117     pingThread.detach();
118     return NETMANAGER_SUCCESS;
119 }
120 
GetRouteTable(std::list<NetDiagRouteTable> & routeTables)121 int32_t NetDiagWrapper::GetRouteTable(std::list<NetDiagRouteTable> &routeTables)
122 {
123     std::string command = std::string(NETSTAT_CMD_PATH) + OPTION_SPACE + NETSTAT_OPTION_ROUTE_TABLE;
124     std::string result;
125     int32_t ret = ExecuteCommandForResult(command, result);
126     if (ret != NETMANAGER_SUCCESS) {
127         return ret;
128     }
129 
130     std::regex routeRegex(R"(([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+([^\s]+))");
131     std::istringstream inStream(result);
132     std::string line;
133     while (std::getline(inStream, line)) {
134         std::smatch match;
135         if (!std::regex_search(line, match, routeRegex)) {
136             continue;
137         }
138         ExtractRouteTableInfo(match, routeTables);
139     }
140     return NETMANAGER_SUCCESS;
141 }
142 
GetSocketsInfo(NetDiagProtocolType socketType,NetDiagSocketsInfo & socketsInfo)143 int32_t NetDiagWrapper::GetSocketsInfo(NetDiagProtocolType socketType, NetDiagSocketsInfo &socketsInfo)
144 {
145     std::string command = std::string(NETSTAT_CMD_PATH) + OPTION_SPACE;
146     switch (socketType) {
147         case PROTOCOL_TYPE_ALL:
148             command = command + NETSTAT_OPTION_ALL_SOCKETS;
149             break;
150         case PROTOCOL_TYPE_TCP:
151             command = command + NETSTAT_OPTION_TCP_SOCKETS;
152             break;
153         case PROTOCOL_TYPE_UDP:
154             command = command + NETSTAT_OPTION_UDP_SOCKETS;
155             break;
156         case PROTOCOL_TYPE_UNIX:
157             command = command + NETSTAT_OPTION_UNIX_SOCKETS;
158             break;
159         case PROTOCOL_TYPE_RAW:
160             command = command + NETSTAT_OPTION_RAW_SOCKETS;
161             break;
162         default:
163             NETNATIVE_LOGE("Unknown protocol type: %{public}d", socketType);
164             return NETMANAGER_ERR_INTERNAL;
165     }
166     std::string result;
167     int32_t ret = ExecuteCommandForResult(command, result);
168     if (ret != NETMANAGER_SUCCESS) {
169         return ret;
170     }
171 
172     std::regex netProtoRegex(
173         R"(([^\s]+)\s+(\d+)\s+(\d+)\s+([^\s]+)\s+([^\s]+)\s*([^\s]*)\s+([^\s]+)\s+(\d+)\s+([^\s]+))");
174     std::regex unixRegex(R"(([^\s]+)\s+(\d+)\s+\[\s*([^\s]*)\s+\]\s+([^\s]+)\s*([^\s]*)\s+(\d+)\s*([^\s]*))");
175     std::istringstream inStream(result);
176     std::string line;
177     while (std::getline(inStream, line)) {
178         std::smatch match;
179         if (std::regex_search(line, match, netProtoRegex)) {
180             ExtractNetProtoSocketsInfo(match, socketsInfo);
181             continue;
182         }
183 
184         if (std::regex_search(line, match, unixRegex)) {
185             ExtractUnixSocketsInfo(match, socketsInfo);
186         }
187     }
188     return NETMANAGER_SUCCESS;
189 }
190 
GetInterfaceConfig(std::list<NetDiagIfaceConfig> & configs,const std::string & ifaceName)191 int32_t NetDiagWrapper::GetInterfaceConfig(std::list<NetDiagIfaceConfig> &configs, const std::string &ifaceName)
192 {
193     std::string command = std::string(IFCONFIG_CMD_PATH) + OPTION_SPACE;
194     command = command + (ifaceName.empty() ? IFCONFIG_OPTION_ALL_IFACE : ifaceName);
195     std::string result;
196     int32_t ret = ExecuteCommandForResult(command, result);
197     if (ret != NETMANAGER_SUCCESS) {
198         return ret;
199     }
200 
201     std::regex nameRegex(R"(([^\s]+)\s+Link encap:([^\s]+)\s+HWaddr\s+([^\s]+)|([^\s]+)\s+Link encap:(.*))");
202     std::regex inetRegex(R"(inet addr:([^\s]+)\s+(?:Bcast:([^\s]+)\s+)?(?:Mask:([^\s]+))?)");
203     std::regex inet6Regex(R"(inet6 addr:\s+([^\s]+)\s+Scope:\s+([^\s]+))");
204     std::regex mtuRegex(R"((UP)?(.*?)MTU:(\d+))");
205     std::regex txQueueLenRegex(R"(txqueuelen:(\d+))");
206     std::regex bytesRegex(R"(RX bytes:(\d+)\s+TX bytes:(\d+))");
207     NetDiagIfaceConfig config;
208     std::istringstream inStream(result);
209     for (std::string line; std::getline(inStream, line);) {
210         std::smatch match;
211         if (IsBlankLine(line)) {
212             configs.push_back(config);
213             config.Initialize();
214             continue;
215         }
216         if (std::regex_search(line, match, nameRegex)) {
217             ExtractIfaceName(match, config);
218             continue;
219         }
220         if (std::regex_search(line, match, inetRegex)) {
221             ExtractIfaceInet(match, config);
222             continue;
223         }
224         if (std::regex_search(line, match, inet6Regex)) {
225             ExtractIfaceInet6(match, config);
226             continue;
227         }
228         if (std::regex_search(line, match, mtuRegex)) {
229             ExtractIfaceMtu(match, config);
230             continue;
231         }
232         if (std::regex_search(line, match, txQueueLenRegex)) {
233             ExtractIfaceTxQueueLen(match, config);
234             continue;
235         }
236         if (std::regex_search(line, match, bytesRegex)) {
237             ExtractIfaceTransDataBytes(match, config);
238             continue;
239         }
240     }
241     return NETMANAGER_SUCCESS;
242 }
243 
UpdateInterfaceConfig(const NetDiagIfaceConfig & config,const std::string & ifaceName,bool add)244 int32_t NetDiagWrapper::UpdateInterfaceConfig(const NetDiagIfaceConfig &config, const std::string &ifaceName, bool add)
245 {
246     std::string command = std::string(IFCONFIG_CMD_PATH) + OPTION_SPACE + ifaceName + OPTION_SPACE;
247     if (add) {
248         if (!config.ipv4Addr_.empty()) {
249             command = command + config.ipv4Addr_ + OPTION_SPACE;
250         }
251         for (const auto &ipv6Addr : config.ipv6Addrs_) {
252             if (ipv6Addr.first.empty()) {
253                 continue;
254             }
255             command = command + IFCONFIG_OPTION_ADD_IPV6 + ipv6Addr.first + OPTION_SPACE;
256         }
257         if (!config.ipv4Bcast_.empty()) {
258             command = command + IFCONFIG_OPTION_SET_IPV4_BCAST + config.ipv4Bcast_ + OPTION_SPACE;
259         }
260         if (!config.ipv4Mask_.empty()) {
261             command = command + IFCONFIG_OPTION_SET_IPV4_MASK + config.ipv4Mask_ + OPTION_SPACE;
262         }
263         if (config.mtu_) {
264             command = command + IFCONFIG_OPTION_SET_MTU_LEN + std::to_string(config.mtu_) + OPTION_SPACE;
265         }
266         if (config.txQueueLen_) {
267             command = command + IFCONFIG_OPTION_SET_TX_QUEUE_LEN + std::to_string(config.txQueueLen_) + OPTION_SPACE;
268         }
269     } else {
270         if (!config.ipv4Addr_.empty()) {
271             command = command + IFCONFIG_OPTION_DEL_IPV4 + OPTION_SPACE;
272         }
273         for (const auto &ipv6Addr : config.ipv6Addrs_) {
274             if (ipv6Addr.first.empty()) {
275                 continue;
276             }
277             command = command + IFCONFIG_OPTION_DEL_IPV6 + ipv6Addr.first + OPTION_SPACE;
278         }
279     }
280     std::string result;
281     return ExecuteCommandForResult(command, result);
282 }
283 
SetInterfaceActiveState(const std::string & ifaceName,bool up)284 int32_t NetDiagWrapper::SetInterfaceActiveState(const std::string &ifaceName, bool up)
285 {
286     std::string command = std::string(IFCONFIG_CMD_PATH) + OPTION_SPACE + ifaceName + OPTION_SPACE;
287     command = command + (up ? IFCONFIG_OPTION_IFACE_UP : IFCONFIG_OPTION_IFACE_DOWN);
288     std::string result;
289     return ExecuteCommandForResult(command, result);
290 }
291 
ExecuteCommandForResult(const std::string & command,std::string & result)292 int32_t NetDiagWrapper::ExecuteCommandForResult(const std::string &command, std::string &result)
293 {
294     if (command.empty()) {
295         NETNATIVE_LOGE("ping command is empty.");
296         return NETMANAGER_ERR_INTERNAL;
297     }
298     std::string().swap(result);
299     if (CommonUtils::ForkExec(command, &result) == NETMANAGER_ERROR) {
300         NETNATIVE_LOGE("Execute command:[%{public}s] failed", command.c_str());
301         return NETMANAGER_ERR_INTERNAL;
302     }
303     return NETMANAGER_SUCCESS;
304 }
305 
GeneratePingCommand(const NetDiagPingOption & pingOption,std::string & command)306 int32_t NetDiagWrapper::GeneratePingCommand(const NetDiagPingOption &pingOption, std::string &command)
307 {
308     if (pingOption.destination_.empty()) {
309         NETNATIVE_LOGE("Ping destination is empty.");
310         return NETMANAGER_ERR_INVALID_PARAMETER;
311     }
312     std::string().swap(command);
313     command = command + PING_CMD_PATH + OPTION_SPACE;
314     command = command + ((pingOption.forceType_ == FORCE_TYPE_IPV6) ? PING_OPTION_IPV6 : PING_OPTION_IPV4);
315     command = command + OPTION_SPACE;
316     if (!pingOption.source_.empty()) {
317         command = command + PING_OPTION_SOURCE + OPTION_SPACE + pingOption.source_ + OPTION_SPACE;
318     }
319     if (pingOption.flood_) {
320         command = command + PING_OPTION_FLOOD + OPTION_SPACE;
321     }
322     if (pingOption.count_) {
323         command = command + PING_OPTION_COUNT + OPTION_SPACE + std::to_string(pingOption.count_) + OPTION_SPACE;
324     }
325     if (pingOption.interval_) {
326         std::ostringstream oss;
327         oss << std::fixed << std::setprecision(1) << (static_cast<float>(pingOption.interval_) / TIME_MS_TO_SEC);
328         command = command + PING_OPTION_INTERVAL + OPTION_SPACE + oss.str() + OPTION_SPACE;
329     }
330     if (pingOption.mark_) {
331         command = command + PING_OPTION_MARK + OPTION_SPACE + std::to_string(pingOption.mark_) + OPTION_SPACE;
332     }
333     if (pingOption.dataSize_) {
334         command = command + PING_OPTION_SIZE + OPTION_SPACE + std::to_string(pingOption.dataSize_) + OPTION_SPACE;
335     }
336     if (pingOption.ttl_) {
337         command = command + PING_OPTION_TTL + OPTION_SPACE + std::to_string(pingOption.ttl_) + OPTION_SPACE;
338     }
339     if (pingOption.timeOut_) {
340         command = command + PING_OPTION_TIMEOUT + OPTION_SPACE + std::to_string(pingOption.timeOut_) + OPTION_SPACE;
341     }
342 
343     uint32_t duration = (pingOption.duration_ != 0 && pingOption.duration_ < PING_MAX_DURATION_TIME)
344                             ? pingOption.duration_
345                             : PING_MAX_DURATION_TIME;
346     command = command + PING_OPTION_DURATION + OPTION_SPACE + std::to_string(duration) + OPTION_SPACE;
347     command = command + pingOption.destination_;
348     return NETMANAGER_SUCCESS;
349 }
350 
IsBlankLine(const std::string & line)351 bool NetDiagWrapper::IsBlankLine(const std::string &line)
352 {
353     std::string trimmed = line;
354     trimmed.erase(std::remove_if(trimmed.begin(), trimmed.end(), [](unsigned char chr) { return std::isspace(chr); }),
355                   trimmed.end());
356     return trimmed.empty();
357 }
358 
ExtractPingResult(const std::string & result,const sptr<INetDiagCallback> & callback)359 void NetDiagWrapper::ExtractPingResult(const std::string &result, const sptr<INetDiagCallback> &callback)
360 {
361     if (callback == nullptr) {
362         NETNATIVE_LOGE("PingHost callback is nullptr");
363         return;
364     }
365     std::regex headerRegex(R"(Ping\s+([^(\s]+)\s+\(([^)]+)\):\s+(\d+)\((\d+)\)\s+bytes)");
366     std::regex icmpSeqRegex(R"((\d+)\s+bytes\s+from\s+([^\s]+)\:\s+icmp_seq=(\d+)\s+ttl=(\d+)\s+time=(\d+)\s+ms)");
367     std::regex statisticsRegex(R"((\d+)\s+packets\s+transmitted,\s+(\d+)\s+received,\s+(\d+)\%\s+packet loss)");
368 
369     NetDiagPingResult pingResult;
370     std::istringstream inStream(result);
371     std::string line;
372     while (std::getline(inStream, line)) {
373         if (line.find(PING_NAME_DOES_NOT_RESOLVED) != std::string::npos ||
374             line.find(PING_NETWORK_UNREACHABLE) != std::string::npos) {
375             break;
376         }
377         std::smatch match;
378         if (std::regex_search(line, match, headerRegex)) {
379             ExtractPingHeader(match, pingResult);
380             continue;
381         }
382 
383         if (std::regex_search(line, match, icmpSeqRegex)) {
384             ExtractIcmpSeqInfo(match, pingResult);
385             continue;
386         }
387 
388         if (std::regex_search(line, match, statisticsRegex)) {
389             ExtractPingStatistics(match, pingResult);
390             break;
391         }
392     }
393 
394     int32_t ret = callback->OnNotifyPingResult(pingResult);
395     if (ret != NETMANAGER_SUCCESS) {
396         NETNATIVE_LOGE("Notify ping result failed.");
397     }
398 }
399 
ExtractPingHeader(const std::smatch & match,NetDiagPingResult & pingResult)400 void NetDiagWrapper::ExtractPingHeader(const std::smatch &match, NetDiagPingResult &pingResult)
401 {
402     if (match.size() < PING_HEADER_MATCH_SIZE) {
403         NETNATIVE_LOGE("Regex match size:[%{public}d] is too small than %{public}d",
404                        static_cast<uint32_t>(match.size()),
405                        PING_HEADER_MATCH_SIZE);
406         return;
407     }
408     constexpr int32_t hostPos = 1;
409     constexpr int32_t ipPos = 2;
410     constexpr int32_t dataSizePos = 3;
411     constexpr int32_t payloadSizePos = 4;
412 
413     pingResult.host_ = match[hostPos].str();
414     pingResult.ipAddr_ = match[ipPos].str();
415     pingResult.dateSize_ = static_cast<uint16_t>(CommonUtils::StrToUint(match[dataSizePos].str()));
416     pingResult.payloadSize_ = static_cast<uint16_t>(CommonUtils::StrToUint(match[payloadSizePos].str()));
417 }
418 
ExtractIcmpSeqInfo(const std::smatch & match,NetDiagPingResult & pingResult)419 void NetDiagWrapper::ExtractIcmpSeqInfo(const std::smatch &match, NetDiagPingResult &pingResult)
420 {
421     if (match.size() < PING_ICMP_SEQ_MATCH_SIZE) {
422         NETNATIVE_LOGE("Regex match size:[%{public}d] is too small than %{public}d",
423                        static_cast<uint32_t>(match.size()),
424                        PING_ICMP_SEQ_MATCH_SIZE);
425         return;
426     }
427 
428     constexpr int32_t bytesPos = 1;
429     constexpr int32_t fromPos = 2;
430     constexpr int32_t icmpSeqPos = 3;
431     constexpr int32_t ttlPos = 4;
432     constexpr int32_t timePos = 5;
433 
434     PingIcmpResponseInfo icmpRespInfo;
435     icmpRespInfo.bytes_ = static_cast<uint16_t>(CommonUtils::StrToUint(match[bytesPos].str()));
436     icmpRespInfo.from_ = match[fromPos].str();
437     icmpRespInfo.icmpSeq_ = static_cast<uint16_t>(CommonUtils::StrToUint(match[icmpSeqPos].str()));
438     icmpRespInfo.ttl_ = static_cast<uint16_t>(CommonUtils::StrToUint(match[ttlPos].str()));
439     icmpRespInfo.costTime_ = CommonUtils::StrToUint(match[timePos].str());
440     pingResult.icmpRespList_.push_back(icmpRespInfo);
441 }
442 
ExtractPingStatistics(const std::smatch & match,NetDiagPingResult & pingResult)443 void NetDiagWrapper::ExtractPingStatistics(const std::smatch &match, NetDiagPingResult &pingResult)
444 {
445     if (match.size() < PING_STATISTICS_MATCH_SIZE) {
446         NETNATIVE_LOGE("Regex match size:[%{public}d] is too small than %{public}d",
447                        static_cast<uint32_t>(match.size()),
448                        PING_STATISTICS_MATCH_SIZE);
449         return;
450     }
451     constexpr int32_t transPos = 1;
452     constexpr int32_t recvPos = 2;
453     pingResult.transCount_ = static_cast<uint16_t>(CommonUtils::StrToUint(match[transPos].str()));
454     pingResult.recvCount_ = static_cast<uint16_t>(CommonUtils::StrToUint(match[recvPos].str()));
455 }
456 
ExtractRouteTableInfo(const std::smatch & match,std::list<NetDiagRouteTable> & routeTables)457 void NetDiagWrapper::ExtractRouteTableInfo(const std::smatch &match, std::list<NetDiagRouteTable> &routeTables)
458 {
459     if (match.size() < NETSTAT_ROUTE_TABLE_MATCH_SIZE) {
460         NETNATIVE_LOGE("Regex match size:[%{public}d] is too small than %{public}d",
461                        static_cast<uint32_t>(match.size()),
462                        NETSTAT_ROUTE_TABLE_MATCH_SIZE);
463         return;
464     }
465     constexpr int32_t dstPos = 1;
466     constexpr int32_t gatewayPos = 2;
467     constexpr int32_t maskPos = 3;
468     constexpr int32_t flagsPos = 4;
469     constexpr int32_t metricPos = 5;
470     constexpr int32_t refPos = 6;
471     constexpr int32_t usePos = 7;
472     constexpr int32_t ifacePos = 8;
473 
474     NetDiagRouteTable routeTable;
475     routeTable.destination_ = match[dstPos].str();
476     routeTable.gateway_ = match[gatewayPos].str();
477     routeTable.mask_ = match[maskPos].str();
478     routeTable.flags_ = match[flagsPos].str();
479     routeTable.metric_ = static_cast<uint16_t>(CommonUtils::StrToUint(match[metricPos].str()));
480     routeTable.ref_ = static_cast<uint16_t>(CommonUtils::StrToUint(match[refPos].str()));
481     routeTable.use_ = static_cast<uint16_t>(CommonUtils::StrToUint(match[usePos].str()));
482     routeTable.iface_ = match[ifacePos].str();
483     routeTables.push_back(routeTable);
484     return;
485 }
486 
ExtractNetProtoSocketsInfo(const std::smatch & match,NetDiagSocketsInfo & socketsInfo)487 void NetDiagWrapper::ExtractNetProtoSocketsInfo(const std::smatch &match, NetDiagSocketsInfo &socketsInfo)
488 {
489     if (match.size() < NETSTAT_NET_PROTOCOL_MATCH_SIZE) {
490         NETNATIVE_LOGE("Regex match size:[%{public}d] is too small than %{public}d",
491                        static_cast<uint32_t>(match.size()),
492                        NETSTAT_NET_PROTOCOL_MATCH_SIZE);
493         return;
494     }
495     constexpr int32_t protoPos = 1;
496     constexpr int32_t recvPos = 2;
497     constexpr int32_t sendPos = 3;
498     constexpr int32_t localAddrPos = 4;
499     constexpr int32_t foreignAddrPos = 5;
500     constexpr int32_t statePos = 6;
501     constexpr int32_t userPos = 7;
502     constexpr int32_t iNodePos = 8;
503     constexpr int32_t programePos = 9;
504 
505     NeyDiagNetProtoSocketInfo socketInfo;
506     socketInfo.protocol_ = match[protoPos].str();
507     socketInfo.recvQueue_ = static_cast<uint16_t>(CommonUtils::StrToUint(match[recvPos].str()));
508     socketInfo.sendQueue_ = static_cast<uint16_t>(CommonUtils::StrToUint(match[sendPos].str()));
509     socketInfo.localAddr_ = match[localAddrPos].str();
510     socketInfo.foreignAddr_ = match[foreignAddrPos].str();
511     socketInfo.state_ = match[statePos].str();
512     socketInfo.user_ = match[userPos].str();
513     socketInfo.inode_ = static_cast<uint16_t>(CommonUtils::StrToUint(match[iNodePos].str()));
514     socketInfo.programName_ = match[programePos].str();
515     socketsInfo.netProtoSocketsInfo_.push_back(socketInfo);
516 }
517 
ExtractUnixSocketsInfo(const std::smatch & match,NetDiagSocketsInfo & socketsInfo)518 void NetDiagWrapper::ExtractUnixSocketsInfo(const std::smatch &match, NetDiagSocketsInfo &socketsInfo)
519 {
520     if (match.size() < NETSTAT_UNIX_MATCH_SIZE) {
521         NETNATIVE_LOGE("Regex match size:[%{public}d] is too small than %{public}d",
522                        static_cast<uint32_t>(match.size()),
523                        NETSTAT_UNIX_MATCH_SIZE);
524         return;
525     }
526     constexpr int32_t protoPos = 1;
527     constexpr int32_t refCntPos = 2;
528     constexpr int32_t flagsPos = 3;
529     constexpr int32_t typePos = 4;
530     constexpr int32_t statePos = 5;
531     constexpr int32_t iNodePos = 6;
532     constexpr int32_t pathPos = 7;
533 
534     NetDiagUnixSocketInfo socketInfo;
535     socketInfo.protocol_ = match[protoPos].str();
536     socketInfo.refCnt_ = static_cast<uint16_t>(CommonUtils::StrToUint(match[refCntPos].str()));
537     socketInfo.flags_ = match[flagsPos].str();
538     socketInfo.type_ = match[typePos].str();
539     socketInfo.state_ = match[statePos].str();
540     socketInfo.inode_ = static_cast<uint16_t>(CommonUtils::StrToUint(match[iNodePos].str()));
541     socketInfo.path_ = match[pathPos].str();
542     socketsInfo.unixSocketsInfo_.push_back(socketInfo);
543 }
544 
ExtractIfaceName(const std::smatch & match,NetDiagIfaceConfig & ifaceInfo)545 void NetDiagWrapper::ExtractIfaceName(const std::smatch &match, NetDiagIfaceConfig &ifaceInfo)
546 {
547     if (match.size() < IFCONFIG_NAME_INFO_MATCH_SIZE) {
548         NETNATIVE_LOGE("Regex match size:[%{public}d] is too small than %{public}d",
549                        static_cast<uint32_t>(match.size()),
550                        IFCONFIG_NAME_INFO_MATCH_SIZE);
551         return;
552     }
553     constexpr int32_t iFaceNamePos = 1;
554     constexpr int32_t linkEncapPos = 2;
555     constexpr int32_t matAddrPos = 3;
556     constexpr int32_t loIfacePos = 4;
557     constexpr int32_t loLinkEncapPos = 5;
558     if (!match[iFaceNamePos].str().empty()) {
559         ifaceInfo.ifaceName_ = match[iFaceNamePos].str();
560         ifaceInfo.linkEncap_ = match[linkEncapPos].str();
561         ifaceInfo.macAddr_ = match[matAddrPos].str();
562     } else if (!match[loIfacePos].str().empty()) {
563         ifaceInfo.ifaceName_ = match[loIfacePos].str();
564         ifaceInfo.linkEncap_ = match[loLinkEncapPos].str();
565         ifaceInfo.macAddr_ = "";
566     }
567 }
568 
ExtractIfaceInet(const std::smatch & match,NetDiagIfaceConfig & ifaceInfo)569 void NetDiagWrapper::ExtractIfaceInet(const std::smatch &match, NetDiagIfaceConfig &ifaceInfo)
570 {
571     if (match.size() < IFCONFIG_INET_INFO_MATCH_SIZE) {
572         NETNATIVE_LOGE("Regex match size:[%{public}d] is too small than %{public}d",
573                        static_cast<uint32_t>(match.size()),
574                        IFCONFIG_INET_INFO_MATCH_SIZE);
575         return;
576     }
577 
578     constexpr int32_t ifaceAddrPos = 0;
579     constexpr int32_t ifaceBcastPos = 1;
580     constexpr int32_t ifaceMaskPos = 2;
581 
582     ifaceInfo.ipv4Addr_ = match[ifaceAddrPos].str();
583     ifaceInfo.ipv4Bcast_ = match[ifaceBcastPos].str();
584     if (!match[ifaceMaskPos].str().empty()) {
585         ifaceInfo.ipv4Mask_ = match[ifaceMaskPos].str();
586     }
587 }
588 
ExtractIfaceInet6(const std::smatch & match,NetDiagIfaceConfig & ifaceInfo)589 void NetDiagWrapper::ExtractIfaceInet6(const std::smatch &match, NetDiagIfaceConfig &ifaceInfo)
590 {
591     if (match.size() < IFCONFIG_INET6_INFO_MATCH_SIZE) {
592         NETNATIVE_LOGE("Regex match size:[%{public}d] is too small than %{public}d",
593                        static_cast<uint32_t>(match.size()),
594                        IFCONFIG_INET6_INFO_MATCH_SIZE);
595         return;
596     }
597 }
598 
ExtractIfaceMtu(const std::smatch & match,NetDiagIfaceConfig & ifaceInfo)599 void NetDiagWrapper::ExtractIfaceMtu(const std::smatch &match, NetDiagIfaceConfig &ifaceInfo)
600 {
601     if (match.size() < IFCONFIG_MTU_MATCH_SIZE) {
602         NETNATIVE_LOGE("Regex match size:[%{public}d] is too small than %{public}d",
603                        static_cast<uint32_t>(match.size()),
604                        IFCONFIG_MTU_MATCH_SIZE);
605         return;
606     }
607     constexpr int32_t IFACE_MTU_POS = 0;
608     ifaceInfo.mtu_ = static_cast<uint16_t>(CommonUtils::StrToUint(match[IFACE_MTU_POS].str()));
609 }
610 
ExtractIfaceTxQueueLen(const std::smatch & match,NetDiagIfaceConfig & ifaceInfo)611 void NetDiagWrapper::ExtractIfaceTxQueueLen(const std::smatch &match, NetDiagIfaceConfig &ifaceInfo)
612 {
613     if (match.size() < IFCONFIG_TX_QUEUE_LEN_MATCH_SIZE) {
614         NETNATIVE_LOGE("Regex match size:[%{public}d] is too small than %{public}d",
615                        static_cast<uint32_t>(match.size()),
616                        IFCONFIG_TX_QUEUE_LEN_MATCH_SIZE);
617         return;
618     }
619 
620     constexpr int32_t ifaceQueenLenPos = 0;
621     ifaceInfo.txQueueLen_ = static_cast<uint16_t>(CommonUtils::StrToUint(match[ifaceQueenLenPos].str()));
622 }
623 
ExtractIfaceTransDataBytes(const std::smatch & match,NetDiagIfaceConfig & ifaceInfo)624 void NetDiagWrapper::ExtractIfaceTransDataBytes(const std::smatch &match, NetDiagIfaceConfig &ifaceInfo)
625 {
626     if (match.size() < IFCONFIG_TRANS_BYTES_MATCH_SIZE) {
627         NETNATIVE_LOGE("Regex match size:[%{public}d] is too small than %{public}d",
628                        static_cast<uint32_t>(match.size()),
629                        IFCONFIG_TRANS_BYTES_MATCH_SIZE);
630         return;
631     }
632     constexpr int32_t ifaceRxPos = 0;
633     constexpr int32_t ifaceTxPos = 1;
634     ifaceInfo.rxBytes_ = static_cast<uint16_t>(CommonUtils::StrToUint(match[ifaceRxPos].str()));
635     ifaceInfo.txBytes_ = static_cast<uint16_t>(CommonUtils::StrToUint(match[ifaceTxPos].str()));
636 }
637 } // namespace nmd
638 } // namespace OHOS
639