1 /*
2 * Copyright (C) 2022-2024 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 "netmanager_base_common_utils.h"
17
18 #include <algorithm>
19 #include <arpa/inet.h>
20 #include <cstddef>
21 #include <cstdlib>
22 #include <netinet/in.h>
23 #include <regex>
24 #include <sstream>
25 #include <set>
26 #include <string>
27 #include <sys/socket.h>
28 #include <sys/wait.h>
29 #include <thread>
30 #include <type_traits>
31 #include <unistd.h>
32 #include <vector>
33 #include <numeric>
34 #include <fstream>
35 #include <random>
36 #include <arpa/inet.h>
37 #include <poll.h>
38
39 #include "net_manager_constants.h"
40 #include "net_mgr_log_wrapper.h"
41 #ifndef CROSS_PLATFORM
42 #include "parameters.h"
43 #include "dfx_kernel_stack.h"
44 #endif
45 #include "securec.h"
46 #include "datetime_ex.h"
47
48 namespace OHOS::NetManagerStandard::CommonUtils {
49 constexpr int32_t INET_OPTION_SUC = 1;
50 constexpr int32_t DECIMAL_SYSTEM = 10;
51 constexpr uint32_t CONST_MASK = 0x80000000;
52 constexpr size_t MAX_DISPLAY_NUM = 2;
53 constexpr uint32_t IPV4_DOT_NUM = 3;
54 constexpr int32_t MIN_BYTE = 0;
55 constexpr int32_t MAX_BYTE = 255;
56 constexpr int32_t BYTE_16 = 16;
57 constexpr uint32_t BIT_NUM_BYTE = 8;
58 constexpr int32_t BITS_32 = 32;
59 constexpr int32_t BITS_24 = 24;
60 constexpr int32_t BITS_16 = 16;
61 constexpr int32_t BITS_8 = 8;
62 constexpr uint32_t INTERFACE_NAME_MAX_SIZE = 16;
63 constexpr int32_t CHAR_ARRAY_SIZE_MAX = 1024;
64 constexpr int32_t PIPE_FD_NUM = 2;
65 constexpr int32_t PIPE_OUT = 0;
66 constexpr int32_t PIPE_IN = 1;
67 constexpr int32_t DOMAIN_VALID_MIN_PART_SIZE = 2;
68 constexpr int32_t DOMAIN_VALID_MAX_PART_SIZE = 5;
69 constexpr int32_t NET_MASK_MAX_LENGTH = 32;
70 constexpr int32_t NET_MASK_GROUP_COUNT = 4;
71 constexpr int32_t MAX_IPV6_PREFIX_LENGTH = 128;
72 constexpr int32_t WAIT_FOR_PID_TIME_MS = 20;
73 constexpr int32_t MAX_WAIT_PID_COUNT = 500;
74 constexpr int32_t IPTABLES_READ_TIME_OUT = 10000; // 10s
75 const std::string IPADDR_DELIMITER = ".";
76 constexpr const char *CMD_SEP = " ";
77 constexpr const char *DOMAIN_DELIMITER = ".";
78 constexpr const char *TLDS_SPLIT_SYMBOL = "|";
79 constexpr const char *HOST_DOMAIN_PATTERN_HEADER = "^(https?://)?[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*\\.(";
80 constexpr const char *HOST_DOMAIN_PATTERN_TAIL = ")$";
81 constexpr const char *DEFAULT_IPV6_ANY_INIT_ADDR = "::";
82 const std::string DISPLAY_TRAFFIC_ANCO_LIST = "const.netmanager.display_traffic_anco_list";
83 const std::regex IP_PATTERN{
84 "((2([0-4]\\d|5[0-5])|1\\d\\d|[1-9]\\d|\\d)\\.){3}(2([0-4]\\d|5[0-5])|1\\d\\d|[1-9]\\d|\\d)"};
85
86 const std::regex IP_MASK_PATTERN{
87 "((2([0-4]\\d|5[0-5])|1\\d\\d|[1-9]\\d|\\d)\\.){3}(2([0-4]\\d|5[0-5])|1\\d\\d|[1-9]\\d|\\d)/"
88 "(3[0-2]|[1-2]\\d|\\d)"};
89
90 const std::regex IPV6_PATTERN{"([\\da-fA-F]{0,4}:){2,7}([\\da-fA-F]{0,4})"};
91
92 const std::regex IPV6_MASK_PATTERN{"([\\da-fA-F]{0,4}:){2,7}([\\da-fA-F]{0,4})/(1[0-2][0-8]|[1-9]\\d|[1-9])"};
93
94 std::vector<std::string> HOST_DOMAIN_TLDS{"com", "net", "org", "edu", "gov", "mil", "cn", "hk", "tw",
95 "jp", "de", "uk", "fr", "au", "ca", "br", "ru", "it",
96 "es", "in", "online", "shop", "vip", "club", "xyz", "top", "icu",
97 "work", "website", "tech", "asia", "xin", "co", "mobi", "info"};
98 constexpr const char *BUNDLENAME_DELIMITER = ",";
99 constexpr const char *SIM_APP_BUNDLENAMES = "com.droi.iapps,com.droi.tong";
100 constexpr const char *INSTALL_SOURCE_FROM_SIM = "com.zhuoyi.appstore.lite";
101 constexpr const char *SIM2_BUNDLENAMES = "com.easy.abroadHarmony.temp,com.easy.hmos.abroad";
102 constexpr const char *INSTALL_SOURCE_FROM_SIM2 = "com.easy.abroad";
103 std::mutex g_commonUtilsMutex;
104
Strip(const std::string & str,char ch)105 std::string Strip(const std::string &str, char ch)
106 {
107 auto size = static_cast<int64_t>(str.size());
108 int64_t i = 0;
109 while (i < size && str[i] == ch) {
110 ++i;
111 }
112 int64_t j = size - 1;
113 while (j > 0 && str[j] == ch) {
114 --j;
115 }
116 if (i >= 0 && i < size && j >= 0 && j < size && j - i + 1 > 0) {
117 return str.substr(i, j - i + 1);
118 }
119 return "";
120 }
121
ToLower(const std::string & s)122 std::string ToLower(const std::string &s)
123 {
124 std::string res = s;
125 std::transform(res.begin(), res.end(), res.begin(), tolower);
126 return res;
127 }
128
IsValidIPV4(const std::string & ip)129 bool IsValidIPV4(const std::string &ip)
130 {
131 if (ip.empty()) {
132 return false;
133 }
134 struct in_addr s;
135 return inet_pton(AF_INET, ip.c_str(), reinterpret_cast<void *>(&s)) == INET_OPTION_SUC;
136 }
137
IsValidIPV6(const std::string & ip)138 bool IsValidIPV6(const std::string &ip)
139 {
140 if (ip.empty()) {
141 return false;
142 }
143 struct in6_addr s;
144 return inet_pton(AF_INET6, ip.c_str(), reinterpret_cast<void *>(&s)) == INET_OPTION_SUC;
145 }
146
GetAddrFamily(const std::string & ip)147 int8_t GetAddrFamily(const std::string &ip)
148 {
149 if (IsValidIPV4(ip)) {
150 return AF_INET;
151 }
152 if (IsValidIPV6(ip)) {
153 return AF_INET6;
154 }
155 return 0;
156 }
157
GetMaskLength(const std::string & mask)158 int GetMaskLength(const std::string &mask)
159 {
160 int netMask = 0;
161 unsigned int maskTmp = ntohl(static_cast<int>(inet_addr(mask.c_str())));
162 while (maskTmp & CONST_MASK) {
163 ++netMask;
164 maskTmp = (maskTmp << 1);
165 }
166 return netMask;
167 }
168
GetMaskByLength(uint32_t length)169 std::string GetMaskByLength(uint32_t length)
170 {
171 const uint32_t mask = length == 0 ? 0 : 0xFFFFFFFF << (NET_MASK_MAX_LENGTH - length);
172 auto maskGroup = new int[NET_MASK_GROUP_COUNT];
173 for (int i = 0; i < NET_MASK_GROUP_COUNT; i++) {
174 int pos = NET_MASK_GROUP_COUNT - 1 - i;
175 maskGroup[pos] = (static_cast<uint32_t>(mask) >> (i * BIT_NUM_BYTE)) & 0x000000ff;
176 }
177 std::string sMask = "" + std::to_string(maskGroup[0]);
178 for (int i = 1; i < NET_MASK_GROUP_COUNT; i++) {
179 sMask = sMask + "." + std::to_string(maskGroup[i]);
180 }
181 delete[] maskGroup;
182 return sMask;
183 }
184
GetIpv6Prefix(const std::string & ipv6Addr,uint8_t prefixLen)185 std::string GetIpv6Prefix(const std::string &ipv6Addr, uint8_t prefixLen)
186 {
187 if (prefixLen >= MAX_IPV6_PREFIX_LENGTH) {
188 return ipv6Addr;
189 }
190
191 in6_addr ipv6AddrBuf = IN6ADDR_ANY_INIT;
192 inet_pton(AF_INET6, ipv6Addr.c_str(), &ipv6AddrBuf);
193
194 char buf[INET6_ADDRSTRLEN] = {0};
195 if (inet_ntop(AF_INET6, &ipv6AddrBuf, buf, INET6_ADDRSTRLEN) == nullptr) {
196 return ipv6Addr;
197 }
198
199 in6_addr ipv6Prefix = IN6ADDR_ANY_INIT;
200 uint32_t byteIndex = prefixLen / BIT_NUM_BYTE;
201 if (memset_s(ipv6Prefix.s6_addr, sizeof(ipv6Prefix.s6_addr), 0, sizeof(ipv6Prefix.s6_addr)) != EOK ||
202 memcpy_s(ipv6Prefix.s6_addr, sizeof(ipv6Prefix.s6_addr), &ipv6AddrBuf, byteIndex) != EOK) {
203 return DEFAULT_IPV6_ANY_INIT_ADDR;
204 }
205 uint32_t bitOffset = prefixLen & 0x7;
206 if ((bitOffset != 0) && (byteIndex < INET_ADDRSTRLEN)) {
207 ipv6Prefix.s6_addr[byteIndex] = ipv6AddrBuf.s6_addr[byteIndex] & (0xff00 >> bitOffset);
208 }
209 char ipv6PrefixBuf[INET6_ADDRSTRLEN] = {0};
210 inet_ntop(AF_INET6, &ipv6Prefix, ipv6PrefixBuf, INET6_ADDRSTRLEN);
211 return ipv6PrefixBuf;
212 }
213
ConvertIpv4Address(uint32_t addressIpv4)214 std::string ConvertIpv4Address(uint32_t addressIpv4)
215 {
216 if (addressIpv4 == 0) {
217 return "";
218 }
219
220 std::ostringstream stream;
221 stream << ((addressIpv4 >> BITS_24) & 0xFF) << IPADDR_DELIMITER << ((addressIpv4 >> BITS_16) & 0xFF)
222 << IPADDR_DELIMITER << ((addressIpv4 >> BITS_8) & 0xFF) << IPADDR_DELIMITER << (addressIpv4 & 0xFF);
223 return stream.str();
224 }
225
ConvertIpv4Address(const std::string & address)226 uint32_t ConvertIpv4Address(const std::string &address)
227 {
228 std::string tmpAddress = address;
229 uint32_t addrInt = 0;
230 uint32_t i = 0;
231 for (i = 0; i < IPV4_DOT_NUM; i++) {
232 std::string::size_type npos = tmpAddress.find(IPADDR_DELIMITER);
233 if (npos == std::string::npos) {
234 break;
235 }
236 const auto &value = tmpAddress.substr(0, npos);
237 int32_t itmp = std::atoi(value.c_str());
238 if ((itmp < MIN_BYTE) || (itmp > MAX_BYTE)) {
239 break;
240 }
241 uint32_t utmp = static_cast<uint32_t>(itmp);
242 addrInt += utmp << ((IPV4_DOT_NUM - i) * BIT_NUM_BYTE);
243 tmpAddress = tmpAddress.substr(npos + 1);
244 }
245
246 if (i != IPV4_DOT_NUM) {
247 return 0;
248 }
249 int32_t itmp = std::atoi(tmpAddress.c_str());
250 if ((itmp < MIN_BYTE) || (itmp > MAX_BYTE)) {
251 return 0;
252 }
253 uint32_t utmp = static_cast<uint32_t>(itmp);
254 addrInt += utmp;
255
256 return addrInt;
257 }
258
Ipv4PrefixLen(const std::string & ip)259 int32_t Ipv4PrefixLen(const std::string &ip)
260 {
261 if (ip.empty()) {
262 return 0;
263 }
264 int32_t ret = 0;
265 uint32_t ipNum = 0;
266 uint8_t c1 = 0;
267 uint8_t c2 = 0;
268 uint8_t c3 = 0;
269 uint8_t c4 = 0;
270 int32_t cnt = 0;
271 ret = sscanf_s(ip.c_str(), "%hhu.%hhu.%hhu.%hhu", &c1, &c2, &c3, &c4);
272 if (ret != sizeof(int32_t)) {
273 return 0;
274 }
275 ipNum = (c1 << static_cast<uint32_t>(BITS_24)) | (c2 << static_cast<uint32_t>(BITS_16)) |
276 (c3 << static_cast<uint32_t>(BITS_8)) | c4;
277 if (ipNum == 0xFFFFFFFF) {
278 return BITS_32;
279 }
280 if (ipNum == 0xFFFFFF00) {
281 return BITS_24;
282 }
283 if (ipNum == 0xFFFF0000) {
284 return BITS_16;
285 }
286 if (ipNum == 0xFF000000) {
287 return BITS_8;
288 }
289 for (int32_t i = 0; i < BITS_32; i++) {
290 if ((ipNum << i) & 0x80000000) {
291 cnt++;
292 } else {
293 break;
294 }
295 }
296 return cnt;
297 }
298
Ipv6PrefixLen(const std::string & ip)299 int32_t Ipv6PrefixLen(const std::string &ip)
300 {
301 constexpr int32_t LENGTH_8 = 8;
302 constexpr int32_t LENGTH_7 = 7;
303 constexpr int32_t LENGTH_6 = 6;
304 constexpr int32_t LENGTH_5 = 5;
305 constexpr int32_t LENGTH_4 = 4;
306 constexpr int32_t LENGTH_3 = 3;
307 constexpr int32_t LENGTH_2 = 2;
308 constexpr int32_t LENGTH_1 = 1;
309 if (ip.empty()) {
310 return 0;
311 }
312 in6_addr addr{};
313 inet_pton(AF_INET6, ip.c_str(), &addr);
314 int32_t prefixLen = 0;
315 for (int32_t i = 0; i < BYTE_16; ++i) {
316 if (addr.s6_addr[i] == 0xFF) {
317 prefixLen += LENGTH_8;
318 } else if (addr.s6_addr[i] == 0xFE) {
319 prefixLen += LENGTH_7;
320 break;
321 } else if (addr.s6_addr[i] == 0xFC) {
322 prefixLen += LENGTH_6;
323 break;
324 } else if (addr.s6_addr[i] == 0xF8) {
325 prefixLen += LENGTH_5;
326 break;
327 } else if (addr.s6_addr[i] == 0xF0) {
328 prefixLen += LENGTH_4;
329 break;
330 } else if (addr.s6_addr[i] == 0xE0) {
331 prefixLen += LENGTH_3;
332 break;
333 } else if (addr.s6_addr[i] == 0xC0) {
334 prefixLen += LENGTH_2;
335 break;
336 } else if (addr.s6_addr[i] == 0x80) {
337 prefixLen += LENGTH_1;
338 break;
339 } else {
340 break;
341 }
342 }
343 return prefixLen;
344 }
345
ParseInt(const std::string & str,int32_t * value)346 bool ParseInt(const std::string &str, int32_t *value)
347 {
348 char *end;
349 long long v = strtoll(str.c_str(), &end, 10);
350 if (std::string(end) == str || *end != '\0' || v < INT_MIN || v > INT_MAX) {
351 return false;
352 }
353 *value = v;
354 return true;
355 }
356
ConvertToInt64(const std::string & str)357 int64_t ConvertToInt64(const std::string &str)
358 {
359 return strtoll(str.c_str(), nullptr, DECIMAL_SYSTEM);
360 }
361
MaskIpv4(std::string & maskedResult)362 std::string MaskIpv4(std::string &maskedResult)
363 {
364 int maxDisplayNum = MAX_DISPLAY_NUM;
365 for (char &i : maskedResult) {
366 if (i == '/') {
367 break;
368 }
369 if (maxDisplayNum > 0) {
370 if (i == '.') {
371 maxDisplayNum--;
372 }
373 } else {
374 if (i != '.') {
375 i = '*';
376 }
377 }
378 }
379 return maskedResult;
380 }
381
MaskIpv6(std::string & maskedResult)382 std::string MaskIpv6(std::string &maskedResult)
383 {
384 size_t colonCount = 0;
385 for (char &i : maskedResult) {
386 if (i == '/') {
387 break;
388 }
389 if (i == ':') {
390 colonCount++;
391 }
392
393 if (colonCount >= MAX_DISPLAY_NUM) { // An legal ipv6 address has at least 2 ':'.
394 if (i != ':' && i != '/') {
395 i = '*';
396 }
397 }
398 }
399 return maskedResult;
400 }
401
ToAnonymousIp(const std::string & input)402 std::string ToAnonymousIp(const std::string &input)
403 {
404 std::lock_guard<std::mutex> lock(g_commonUtilsMutex);
405 std::string maskedResult{input};
406 // Mask ipv4 address.
407 if (std::regex_match(maskedResult, IP_PATTERN) || std::regex_match(maskedResult, IP_MASK_PATTERN)) {
408 return MaskIpv4(maskedResult);
409 }
410 // Mask ipv6 address.
411 if (std::regex_match(maskedResult, IPV6_PATTERN) || std::regex_match(maskedResult, IPV6_MASK_PATTERN)) {
412 return MaskIpv6(maskedResult);
413 }
414 return input;
415 }
416
AnonymousIpInStr(const std::string & input)417 std::string AnonymousIpInStr(const std::string &input)
418 {
419 std::string result;
420 // Mask ipv4 address.
421 result = std::regex_replace(input, IP_PATTERN, "X.X.X.X");
422 // Mask ipv6 address.
423 result = std::regex_replace(result, IPV6_PATTERN, "X:X:X:X");
424 return result;
425 }
426
AnonymizeIptablesCommand(const std::string & command)427 std::string AnonymizeIptablesCommand(const std::string &command)
428 {
429 std::string temp{command};
430 std::transform(temp.cbegin(), temp.cend(), temp.begin(), [](char c) {
431 return std::isdigit(c) ? 'x' : c;
432 });
433 return temp;
434 }
435
StrToInt(const std::string & value,int32_t defaultErr)436 int32_t StrToInt(const std::string &value, int32_t defaultErr)
437 {
438 errno = 0;
439 char *pEnd = nullptr;
440 int64_t result = std::strtol(value.c_str(), &pEnd, 0);
441 if (pEnd == value.c_str() || (result < INT_MIN || result > INT_MAX) || errno == ERANGE) {
442 return defaultErr;
443 }
444 return static_cast<int32_t>(result);
445 }
446
StrToUint(const std::string & value,uint32_t defaultErr)447 uint32_t StrToUint(const std::string &value, uint32_t defaultErr)
448 {
449 errno = 0;
450 char *pEnd = nullptr;
451 uint64_t result = std::strtoul(value.c_str(), &pEnd, 0);
452 if (pEnd == value.c_str() || result > UINT32_MAX || errno == ERANGE) {
453 return defaultErr;
454 }
455 return result;
456 }
457
StrToBool(const std::string & value,bool defaultErr)458 bool StrToBool(const std::string &value, bool defaultErr)
459 {
460 errno = 0;
461 char *pEnd = nullptr;
462 uint64_t result = std::strtoul(value.c_str(), &pEnd, 0);
463 if (pEnd == value.c_str() || result > UINT32_MAX || errno == ERANGE) {
464 return defaultErr;
465 }
466 return static_cast<bool>(result);
467 }
468
StrToLong(const std::string & value,int64_t defaultErr)469 int64_t StrToLong(const std::string &value, int64_t defaultErr)
470 {
471 errno = 0;
472 char *pEnd = nullptr;
473 int64_t result = std::strtoll(value.c_str(), &pEnd, 0);
474 if (pEnd == value.c_str() || errno == ERANGE) {
475 return defaultErr;
476 }
477 return result;
478 }
479
StrToUint64(const std::string & value,uint64_t defaultErr)480 uint64_t StrToUint64(const std::string &value, uint64_t defaultErr)
481 {
482 errno = 0;
483 char *pEnd = nullptr;
484 uint64_t result = std::strtoull(value.c_str(), &pEnd, 0);
485 if (pEnd == value.c_str() || errno == ERANGE) {
486 return defaultErr;
487 }
488 return result;
489 }
490
CheckIfaceName(const std::string & name)491 bool CheckIfaceName(const std::string &name)
492 {
493 uint32_t index = 0;
494 if (name.empty()) {
495 return false;
496 }
497 size_t len = name.size();
498 if (len > INTERFACE_NAME_MAX_SIZE) {
499 return false;
500 }
501 while (index < len) {
502 if ((index == 0) && !isalnum(name[index])) {
503 return false;
504 }
505 if (!isalnum(name[index]) && (name[index] != '-') && (name[index] != '_') && (name[index] != '.') &&
506 (name[index] != ':')) {
507 return false;
508 }
509 index++;
510 }
511 return true;
512 }
513
FormatCmd(const std::vector<std::string> & cmd)514 std::vector<const char *> FormatCmd(const std::vector<std::string> &cmd)
515 {
516 std::vector<const char *> res;
517 res.reserve(cmd.size() + 1);
518
519 // string is converted to char * and the result is saved in res
520 std::transform(cmd.begin(), cmd.end(), std::back_inserter(res), [](const std::string &str) { return str.c_str(); });
521 res.emplace_back(nullptr);
522 return res;
523 }
524
ForkExecChildProcess(const int32_t * pipeFd,int32_t count,const std::vector<const char * > & args)525 int32_t ForkExecChildProcess(const int32_t *pipeFd, int32_t count, const std::vector<const char *> &args)
526 {
527 if (count != PIPE_FD_NUM) {
528 _exit(-1);
529 }
530 if (close(pipeFd[PIPE_OUT]) != 0) {
531 _exit(-1);
532 }
533 if (dup2(pipeFd[PIPE_IN], STDOUT_FILENO) == -1) {
534 _exit(-1);
535 }
536 if (close(pipeFd[PIPE_IN]) != 0) {
537 _exit(-1);
538 }
539 if (execv(args[0], const_cast<char *const *>(&args[0])) == -1) {
540 NETMGR_LOG_E("execv command failed, errorno:%{public}d, errormsg:%{public}s", errno, strerror(errno));
541 }
542 NETMGR_LOG_D("execv done");
543 _exit(-1);
544 }
545
ReadFromChildProcess(const int32_t * pipeFd,pid_t childPid,std::string * out)546 int32_t ReadFromChildProcess(const int32_t *pipeFd, pid_t childPid, std::string *out)
547 {
548 char buf[CHAR_ARRAY_SIZE_MAX] = {0};
549 out->clear();
550 NETMGR_LOG_D("ready for read");
551
552 int fd = pipeFd[PIPE_OUT];
553 int64_t start = GetTickCount();
554 int ret;
555 while (true) {
556 struct pollfd fds[1];
557 fds[0].fd = fd;
558 fds[0].events = POLLIN;
559
560 int64_t now = GetTickCount();
561 int64_t elapsed = now - start;
562 if (elapsed < 0 || elapsed > IPTABLES_READ_TIME_OUT) {
563 ret = 0;
564 break;
565 }
566 int64_t timeout = IPTABLES_READ_TIME_OUT - elapsed;
567 ret = poll(fds, 1, timeout);
568 if (ret == -1 && errno == EINTR) {
569 continue;
570 } else {
571 break;
572 }
573 }
574
575 int result = NETMANAGER_SUCCESS;
576 if (ret <= 0) {
577 NETMGR_LOG_E("iptables select fail, ret %{public}d, pid %{public}d", ret, childPid);
578 #ifndef CROSS_PLATFORM
579 std::string childStack;
580 HiviewDFX::DfxGetKernelStack(childPid, childStack);
581 NETMGR_LOG_E("child process stack %{public}s", childStack.c_str());
582 #endif
583 result = NETMANAGER_ERROR;
584 } else {
585 while (read(fd, buf, CHAR_ARRAY_SIZE_MAX - 1) > 0) {
586 out->append(buf);
587 (void)memset_s(buf, sizeof(buf), 0, sizeof(buf));
588 }
589 }
590 return result;
591 }
592
ForkExecParentProcess(const int32_t * pipeFd,int32_t count,pid_t childPid,std::string * out)593 int32_t ForkExecParentProcess(const int32_t *pipeFd, int32_t count, pid_t childPid, std::string *out)
594 {
595 if (count != PIPE_FD_NUM) {
596 NETMGR_LOG_E("fork exec parent process failed");
597 return NETMANAGER_ERROR;
598 }
599 if (close(pipeFd[PIPE_IN]) != 0) {
600 NETMGR_LOG_E("close failed, errorno:%{public}d, errormsg:%{public}s", errno, strerror(errno));
601 }
602 if (out != nullptr) {
603 int32_t res = ReadFromChildProcess(pipeFd, childPid, out);
604 if (res != NETMANAGER_SUCCESS) {
605 close(pipeFd[PIPE_OUT]);
606 return res;
607 }
608 }
609 NETMGR_LOG_D("read done");
610 if (close(pipeFd[PIPE_OUT]) != 0) {
611 NETMGR_LOG_E("close failed, errorno:%{public}d, errormsg:%{public}s", errno, strerror(errno));
612 }
613 int status = 0;
614 pid_t pidRet;
615 int waitCount;
616 for (waitCount = 0; waitCount < MAX_WAIT_PID_COUNT; waitCount++) {
617 pidRet = waitpid(childPid, &status, WNOHANG);
618 if (pidRet == 0) {
619 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_FOR_PID_TIME_MS));
620 } else {
621 break;
622 }
623 }
624 if (waitCount == MAX_WAIT_PID_COUNT) {
625 NETMGR_LOG_E("waitpid[%{public}d] timeout", childPid);
626 #ifndef CROSS_PLATFORM
627 std::string childStack;
628 HiviewDFX::DfxGetKernelStack(childPid, childStack);
629 NETMGR_LOG_E("child process stack %{public}s", childStack.c_str());
630 #endif
631 return NETMANAGER_ERROR;
632 }
633 if (pidRet != childPid) {
634 NETMGR_LOG_E("waitpid[%{public}d] failed, pidRet:%{public}d", childPid, pidRet);
635 return NETMANAGER_ERROR;
636 }
637 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
638 // child process abnormal exit
639 NETMGR_LOG_E("child process abnormal exit, status:%{public}d", status);
640 }
641 NETMGR_LOG_I("waitpid %{public}d done", childPid);
642 return NETMANAGER_SUCCESS;
643 }
644
ForkExec(const std::string & command,std::string * out)645 int32_t ForkExec(const std::string &command, std::string *out)
646 {
647 const std::vector<std::string> cmd = Split(command, CMD_SEP);
648 std::vector<const char *> args = FormatCmd(cmd);
649 int32_t pipeFd[PIPE_FD_NUM] = {0};
650 if (pipe(pipeFd) < 0) {
651 NETMGR_LOG_E("creat pipe failed, errorno:%{public}d, errormsg:%{public}s", errno, strerror(errno));
652 return NETMANAGER_ERROR;
653 }
654 NETMGR_LOG_D("ForkExec");
655 pid_t pid = fork();
656 if (pid < 0) {
657 return NETMANAGER_ERROR;
658 }
659 if (pid == 0) {
660 ForkExecChildProcess(pipeFd, PIPE_FD_NUM, args);
661 return NETMANAGER_SUCCESS;
662 } else {
663 NETMGR_LOG_I("ForkDone %{public}d", pid);
664 return ForkExecParentProcess(pipeFd, PIPE_FD_NUM, pid, out);
665 }
666 }
667
IsValidDomain(const std::string & domain)668 bool IsValidDomain(const std::string &domain)
669 {
670 if (domain.empty()) {
671 return false;
672 }
673
674 std::string pattern = HOST_DOMAIN_PATTERN_HEADER;
675 pattern = std::accumulate(HOST_DOMAIN_TLDS.begin(), HOST_DOMAIN_TLDS.end(), pattern,
676 [](const std::string &pattern, const std::string &tlds) { return pattern + tlds + TLDS_SPLIT_SYMBOL; });
677 pattern = pattern.replace(pattern.size() - 1, 1, "") + HOST_DOMAIN_PATTERN_TAIL;
678 std::regex reg(pattern);
679 if (!std::regex_match(domain, reg)) {
680 NETMGR_LOG_E("Domain regex match failed.");
681 return false;
682 }
683
684 std::vector<std::string> parts = Split(domain, DOMAIN_DELIMITER);
685 if (parts.size() < DOMAIN_VALID_MIN_PART_SIZE || parts.size() > DOMAIN_VALID_MAX_PART_SIZE) {
686 NETMGR_LOG_E("The domain parts size:[%{public}d] is invalid", static_cast<int>(parts.size()));
687 return false;
688 }
689
690 std::set<std::string> tldsList;
691 for (const auto &item : parts) {
692 if (std::find(HOST_DOMAIN_TLDS.begin(), HOST_DOMAIN_TLDS.end(), item) == HOST_DOMAIN_TLDS.end()) {
693 continue;
694 }
695 if (tldsList.find(item) != tldsList.end()) {
696 NETMGR_LOG_E("Domain has duplicate tlds:%{public}s", item.c_str());
697 return false;
698 }
699 tldsList.insert(item);
700 }
701 return true;
702 }
703
WriteFile(const std::string & filePath,const std::string & fileContent)704 bool WriteFile(const std::string &filePath, const std::string &fileContent)
705 {
706 std::ofstream file(filePath, std::ios::out | std::ios::trunc);
707 if (!file.is_open()) {
708 NETMGR_LOG_E("write file=%{public}s fstream failed. err %{public}d %{public}s",
709 filePath.c_str(), errno, strerror(errno));
710 return false;
711 }
712 file << fileContent;
713 file.close();
714 return true;
715 }
716
HasInternetPermission()717 bool HasInternetPermission()
718 {
719 int testSock = socket(AF_INET, SOCK_STREAM, 0);
720 if (testSock < 0 && errno == EPERM) {
721 NETMGR_LOG_E("make tcp testSock failed errno is %{public}d %{public}s", errno, strerror(errno));
722 return false;
723 }
724 if (testSock > 0) {
725 close(testSock);
726 }
727 return true;
728 }
729
Trim(const std::string & str)730 std::string Trim(const std::string &str)
731 {
732 size_t start = str.find_first_not_of(" \t\n\r");
733 size_t end = str.find_last_not_of(" \t\n\r");
734 if (start == std::string::npos || end == std::string::npos) {
735 return "";
736 }
737 return str.substr(start, end - start + 1);
738 }
739
IsUrlRegexValid(const std::string & regex)740 bool IsUrlRegexValid(const std::string ®ex)
741 {
742 if (Trim(regex).empty()) {
743 return false;
744 }
745 return regex_match(regex, std::regex("^[a-zA-Z0-9\\-_\\.*]+$"));
746 }
747
InsertCharBefore(const std::string & input,const char from,const char preChar,const char nextChar)748 std::string InsertCharBefore(const std::string &input, const char from, const char preChar, const char nextChar)
749 {
750 std::ostringstream output;
751 for (size_t i = 0; i < input.size(); ++i) {
752 if (input[i] == from && (i == input.size() - 1 || input[i + 1] != nextChar)) {
753 output << preChar;
754 }
755 output << input[i];
756 }
757 return output.str();
758 }
759
ReplaceCharacters(const std::string & input)760 std::string ReplaceCharacters(const std::string &input)
761 {
762 std::string output = InsertCharBefore(input, '*', '.', '\0');
763 output = InsertCharBefore(output, '.', '\\', '*');
764 return output;
765 }
766
UrlRegexParse(const std::string & str,const std::string & patternStr)767 bool UrlRegexParse(const std::string &str, const std::string &patternStr)
768 {
769 if (patternStr.empty()) {
770 return false;
771 }
772 if (patternStr == "*") {
773 return true;
774 }
775 if (!IsUrlRegexValid(patternStr)) {
776 return patternStr == str;
777 }
778 std::regex pattern(ReplaceCharacters(patternStr));
779 return !patternStr.empty() && std::regex_match(str, pattern);
780 }
781
GenRandomNumber()782 uint64_t GenRandomNumber()
783 {
784 static std::random_device rd;
785 static std::uniform_int_distribution<uint64_t> dist(0ULL, UINT64_MAX);
786 uint64_t num = dist(rd);
787 return num;
788 }
789
IsSim(const std::string & bundleName)790 bool IsSim(const std::string &bundleName)
791 {
792 std::vector<std::string> list = Split(SIM_APP_BUNDLENAMES, BUNDLENAME_DELIMITER);
793 auto findRet =
794 std::find_if(list.begin(), list.end(), [&bundleName](const auto &item) { return item == bundleName; });
795 return findRet != list.end();
796 }
797
IsInstallSourceFromSim(const std::string & installSource)798 bool IsInstallSourceFromSim(const std::string &installSource)
799 {
800 return installSource == INSTALL_SOURCE_FROM_SIM;
801 }
802
GetHostnameFromURL(const std::string & url)803 std::string GetHostnameFromURL(const std::string &url)
804 {
805 if (url.empty()) {
806 return "";
807 }
808 std::string delimiter = "://";
809 std::string tempUrl = url;
810 std::replace(tempUrl.begin(), tempUrl.end(), '\\', '/');
811 size_t posStart = tempUrl.find(delimiter);
812 if (posStart != std::string::npos) {
813 posStart += delimiter.length();
814 } else {
815 posStart = 0;
816 }
817 size_t notSlash = tempUrl.find_first_not_of('/', posStart);
818 if (notSlash != std::string::npos) {
819 posStart = notSlash;
820 }
821 size_t posEnd = std::min({ tempUrl.find(':', posStart),
822 tempUrl.find('/', posStart), tempUrl.find('?', posStart) });
823 if (posEnd != std::string::npos) {
824 return tempUrl.substr(posStart, posEnd - posStart);
825 }
826 return tempUrl.substr(posStart);
827 }
828
IsSim2(const std::string & bundleName)829 bool IsSim2(const std::string &bundleName)
830 {
831 std::vector<std::string> list = Split(SIM2_BUNDLENAMES, BUNDLENAME_DELIMITER);
832 auto findRet =
833 std::find_if(list.begin(), list.end(), [&bundleName](const auto &item) { return item == bundleName; });
834 return findRet != list.end();
835 }
836
IsInstallSourceFromSim2(const std::string & installSource)837 bool IsInstallSourceFromSim2(const std::string &installSource)
838 {
839 return installSource == INSTALL_SOURCE_FROM_SIM2;
840 }
841
IsNeedDisplayTrafficAncoList()842 bool IsNeedDisplayTrafficAncoList()
843 {
844 #ifndef CROSS_PLATFORM
845 NETMGR_LOG_D("Is need display traffic anco list: %{public}s",
846 system::GetParameter(DISPLAY_TRAFFIC_ANCO_LIST, "false").c_str());
847 return system::GetParameter(DISPLAY_TRAFFIC_ANCO_LIST, "false") == "true";
848 #else
849 return false;
850 #endif
851 }
852
IsSimAnco(const std::string & bundleName)853 bool IsSimAnco(const std::string &bundleName)
854 {
855 return bundleName == INSTALL_SOURCE_FROM_SIM;
856 }
857
IsSim2Anco(const std::string & bundleName)858 bool IsSim2Anco(const std::string &bundleName)
859 {
860 return bundleName == INSTALL_SOURCE_FROM_SIM2;
861 }
862
GetGatewayAddr(const std::string & ipAddr,const std::string & subnetMask)863 std::string GetGatewayAddr(const std::string& ipAddr, const std::string& subnetMask)
864 {
865 uint32_t ipIntAddr;
866 if (!IpToInt(ipAddr, ipIntAddr)) {
867 NETMGR_LOG_E("virNicAddr is not valid");
868 return "";
869 }
870
871 uint32_t maskIntAddr;
872 if (!IpToInt(subnetMask, maskIntAddr)) {
873 NETMGR_LOG_E("subnetMask is not valid");
874 return "";
875 }
876
877 uint32_t networkAddr = ipIntAddr & maskIntAddr;
878 uint32_t gatewayAddr = networkAddr + 1;
879 std::string gatewayStrAddr;
880 if (!IpToString(gatewayAddr, gatewayStrAddr)) {
881 return "";
882 }
883 return gatewayStrAddr;
884 }
885
IpToInt(const std::string & ipAddr,uint32_t & ipIntAddr)886 bool IpToInt(const std::string& ipAddr, uint32_t &ipIntAddr)
887 {
888 in_addr addr;
889 if (inet_pton(AF_INET, ipAddr.c_str(), &addr) != INET_OPTION_SUC) {
890 NETMGR_LOG_E("IpToInt failed for invalid IP address");
891 return false;
892 }
893
894 ipIntAddr = ntohl(addr.s_addr);
895 return true;
896 }
897
IpToString(uint32_t ipAddr,std::string & ipStrAddr)898 bool IpToString(uint32_t ipAddr, std::string &ipStrAddr)
899 {
900 in_addr addr;
901 addr.s_addr = htonl(ipAddr);
902 char bufIp[INET_ADDRSTRLEN];
903 if (inet_ntop(AF_INET, &addr, bufIp, sizeof(bufIp)) == nullptr) {
904 NETMGR_LOG_E("IpToString conversion failed");
905 return false;
906 }
907
908 ipStrAddr = std::string(bufIp);
909 return true;
910 }
911
GetTodayMidnightTimestamp(int hour,int min,int sec)912 int32_t GetTodayMidnightTimestamp(int hour, int min, int sec)
913 {
914 auto now = std::chrono::system_clock::now();
915 std::time_t nowClock = std::chrono::system_clock::to_time_t(now);
916 std::tm* localTime = std::localtime(&nowClock);
917 if (localTime == nullptr) {
918 NETMGR_LOG_E("localTime is nullptr");
919 return 0;
920 }
921 localTime->tm_hour = hour;
922 localTime->tm_min = min;
923 localTime->tm_sec = sec;
924
925 std::time_t endOfDayTime = std::mktime(localTime);
926 auto timeXth = std::chrono::system_clock::from_time_t(endOfDayTime);
927 auto timestamp = std::chrono::system_clock::to_time_t(timeXth);
928
929 return timestamp;
930 }
931
DeleteFile(const std::string & filePath)932 void DeleteFile(const std::string &filePath)
933 {
934 #ifndef CROSS_PLATFORM
935 std::filesystem::path path = filePath;
936 if (std::filesystem::exists(path)) {
937 std::filesystem::remove(path);
938 NETMGR_LOG_I("file deleted success.");
939 } else {
940 NETMGR_LOG_E("file does not exist.");
941 }
942 #else
943 NETMGR_LOG_E("CROSS_PLATFORM not support");
944 #endif
945 }
946
IsSameNaturalDay(uint32_t current,uint32_t another)947 bool IsSameNaturalDay(uint32_t current, uint32_t another)
948 {
949 std::time_t tt1 =
950 std::chrono::system_clock::to_time_t(std::chrono::system_clock::time_point(std::chrono::seconds(current)));
951 std::time_t tt2 =
952 std::chrono::system_clock::to_time_t(std::chrono::system_clock::time_point(std::chrono::seconds(another)));
953 struct std::tm tempTm1;
954 struct std::tm tempTm2;
955 std::tm *tm1 = std::localtime(&tt1);
956 if (tm1 == nullptr) {
957 return false;
958 }
959 tempTm1 = *tm1;
960 std::tm *tm2 = std::localtime(&tt2);
961 if (tm2 == nullptr) {
962 return false;
963 }
964 tempTm2 = *tm2;
965 return tempTm1.tm_year == tempTm2.tm_year &&
966 tempTm1.tm_mon == tempTm2.tm_mon && tempTm1.tm_mday == tempTm2.tm_mday;
967 }
968 } // namespace OHOS::NetManagerStandard::CommonUtils
969