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