• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &regex)
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