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