1 /*
2 * Copyright (C) 2022 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 <string>
25 #include <sys/socket.h>
26 #include <sys/wait.h>
27 #include <type_traits>
28 #include <unistd.h>
29 #include <vector>
30
31 #include "net_manager_constants.h"
32 #include "net_mgr_log_wrapper.h"
33 #include "securec.h"
34
35 namespace OHOS::NetManagerStandard::CommonUtils {
36 constexpr int32_t INET_OPTION_SUC = 1;
37 constexpr int32_t DECIMAL_SYSTEM = 10;
38 constexpr uint32_t CONST_MASK = 0x80000000;
39 constexpr size_t MAX_DISPLAY_NUM = 2;
40 constexpr uint32_t IPV4_DOT_NUM = 3;
41 constexpr int32_t MIN_BYTE = 0;
42 constexpr int32_t MAX_BYTE = 255;
43 constexpr uint32_t BIT_NUM_BYTE = 8;
44 constexpr int32_t BITS_24 = 24;
45 constexpr int32_t BITS_16 = 16;
46 constexpr int32_t BITS_8 = 8;
47 constexpr uint32_t INTERFACE_NAME_MAX_SIZE = 16;
48 constexpr int32_t CHAR_ARRAY_SIZE_MAX = 1024;
49 constexpr int32_t PIPE_FD_NUM = 2;
50 constexpr int32_t PIPE_OUT = 0;
51 constexpr int32_t PIPE_IN = 1;
52 const std::string IPADDR_DELIMITER = ".";
53 constexpr const char *CMD_SEP = " ";
54 const std::regex IP_PATTERN{
55 "((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)"};
56
57 const std::regex IP_MASK_PATTERN{
58 "((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)/"
59 "(3[0-2]|[1-2]\\d|\\d)"};
60
61 const std::regex IPV6_PATTERN{"([\\da-fA-F]{0,4}:){2,7}([\\da-fA-F]{0,4})"};
62
63 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])"};
64
65 constexpr int32_t NET_MASK_MAX_LENGTH = 32;
66 constexpr int32_t NET_MASK_GROUP_COUNT = 4;
67 std::mutex g_commonUtilsMutex;
68 std::mutex g_forkExecMutex;
69
Strip(const std::string & str,char ch)70 std::string Strip(const std::string &str, char ch)
71 {
72 auto size = static_cast<int64_t>(str.size());
73 int64_t i = 0;
74 while (i < size && str[i] == ch) {
75 ++i;
76 }
77 int64_t j = size - 1;
78 while (j > 0 && str[j] == ch) {
79 --j;
80 }
81 if (i >= 0 && i < size && j >= 0 && j < size && j - i + 1 > 0) {
82 return str.substr(i, j - i + 1);
83 }
84 return "";
85 }
86
ToLower(const std::string & s)87 std::string ToLower(const std::string &s)
88 {
89 std::string res = s;
90 std::transform(res.begin(), res.end(), res.begin(), tolower);
91 return res;
92 }
93
IsValidIPV4(const std::string & ip)94 bool IsValidIPV4(const std::string &ip)
95 {
96 if (ip.empty()) {
97 return false;
98 }
99 struct in_addr s;
100 return inet_pton(AF_INET, ip.c_str(), reinterpret_cast<void *>(&s)) == INET_OPTION_SUC;
101 }
102
IsValidIPV6(const std::string & ip)103 bool IsValidIPV6(const std::string &ip)
104 {
105 if (ip.empty()) {
106 return false;
107 }
108 struct in6_addr s;
109 return inet_pton(AF_INET6, ip.c_str(), reinterpret_cast<void *>(&s)) == INET_OPTION_SUC;
110 }
111
GetAddrFamily(const std::string & ip)112 int8_t GetAddrFamily(const std::string &ip)
113 {
114 if (IsValidIPV4(ip)) {
115 return AF_INET;
116 }
117 if (IsValidIPV6(ip)) {
118 return AF_INET6;
119 }
120 return 0;
121 }
122
GetMaskLength(const std::string & mask)123 int GetMaskLength(const std::string &mask)
124 {
125 int netMask = 0;
126 unsigned int maskTmp = ntohl(static_cast<int>(inet_addr(mask.c_str())));
127 while (maskTmp & CONST_MASK) {
128 ++netMask;
129 maskTmp = (maskTmp << 1);
130 }
131 return netMask;
132 }
133
GetMaskByLength(uint32_t length)134 std::string GetMaskByLength(uint32_t length)
135 {
136 const auto mask = length == 0 ? 0 : -1 << (NET_MASK_MAX_LENGTH - length);
137 auto maskGroup = new int[NET_MASK_GROUP_COUNT];
138 for (int i = 0; i < NET_MASK_GROUP_COUNT; i++) {
139 int pos = NET_MASK_GROUP_COUNT - 1 - i;
140 maskGroup[pos] = (static_cast<uint32_t>(mask) >> (i * BIT_NUM_BYTE)) & 0x000000ff;
141 }
142 std::string sMask = "" + std::to_string(maskGroup[0]);
143 for (int i = 1; i < NET_MASK_GROUP_COUNT; i++) {
144 sMask = sMask + "." + std::to_string(maskGroup[i]);
145 }
146 delete[] maskGroup;
147 return sMask;
148 }
149
ConvertIpv4Address(uint32_t addressIpv4)150 std::string ConvertIpv4Address(uint32_t addressIpv4)
151 {
152 if (addressIpv4 == 0) {
153 return "";
154 }
155
156 std::ostringstream stream;
157 stream << ((addressIpv4 >> BITS_24) & 0xFF) << IPADDR_DELIMITER << ((addressIpv4 >> BITS_16) & 0xFF)
158 << IPADDR_DELIMITER << ((addressIpv4 >> BITS_8) & 0xFF) << IPADDR_DELIMITER << (addressIpv4 & 0xFF);
159 return stream.str();
160 }
161
ConvertIpv4Address(const std::string & address)162 uint32_t ConvertIpv4Address(const std::string &address)
163 {
164 std::string tmpAddress = address;
165 uint32_t addrInt = 0;
166 uint32_t i = 0;
167 for (i = 0; i < IPV4_DOT_NUM; i++) {
168 std::string::size_type npos = tmpAddress.find(IPADDR_DELIMITER);
169 if (npos == std::string::npos) {
170 break;
171 }
172 const auto &value = tmpAddress.substr(0, npos);
173 int32_t itmp = std::atoi(value.c_str());
174 if ((itmp < MIN_BYTE) || (itmp > MAX_BYTE)) {
175 break;
176 }
177 uint32_t utmp = static_cast<uint32_t>(itmp);
178 addrInt += utmp << ((IPV4_DOT_NUM - i) * BIT_NUM_BYTE);
179 tmpAddress = tmpAddress.substr(npos + 1);
180 }
181
182 if (i != IPV4_DOT_NUM) {
183 return 0;
184 }
185 int32_t itmp = std::atoi(tmpAddress.c_str());
186 if ((itmp < MIN_BYTE) || (itmp > MAX_BYTE)) {
187 return 0;
188 }
189 uint32_t utmp = static_cast<uint32_t>(itmp);
190 addrInt += utmp;
191
192 return addrInt;
193 }
194
Ipv4PrefixLen(const std::string & ip)195 int32_t Ipv4PrefixLen(const std::string &ip)
196 {
197 constexpr int32_t BIT32 = 32;
198 constexpr int32_t BIT24 = 24;
199 constexpr int32_t BIT16 = 16;
200 constexpr int32_t BIT8 = 8;
201 if (ip.empty()) {
202 return 0;
203 }
204 int32_t ret = 0;
205 uint32_t ipNum = 0;
206 uint8_t c1 = 0;
207 uint8_t c2 = 0;
208 uint8_t c3 = 0;
209 uint8_t c4 = 0;
210 int32_t cnt = 0;
211 ret = sscanf_s(ip.c_str(), "%hhu.%hhu.%hhu.%hhu", &c1, &c2, &c3, &c4);
212 if (ret != sizeof(int32_t)) {
213 return 0;
214 }
215 ipNum = (c1 << static_cast<uint32_t>(BIT24)) | (c2 << static_cast<uint32_t>(BIT16)) |
216 (c3 << static_cast<uint32_t>(BIT8)) | c4;
217 if (ipNum == 0xFFFFFFFF) {
218 return BIT32;
219 }
220 if (ipNum == 0xFFFFFF00) {
221 return BIT24;
222 }
223 if (ipNum == 0xFFFF0000) {
224 return BIT16;
225 }
226 if (ipNum == 0xFF000000) {
227 return BIT8;
228 }
229 for (int32_t i = 0; i < BIT32; i++) {
230 if ((ipNum << i) & 0x80000000) {
231 cnt++;
232 } else {
233 break;
234 }
235 }
236 return cnt;
237 }
238
ParseInt(const std::string & str,int32_t * value)239 bool ParseInt(const std::string &str, int32_t *value)
240 {
241 char *end;
242 long long v = strtoll(str.c_str(), &end, 10);
243 if (std::string(end) == str || *end != '\0' || v < INT_MIN || v > INT_MAX) {
244 return false;
245 }
246 *value = v;
247 return true;
248 }
249
ConvertToInt64(const std::string & str)250 int64_t ConvertToInt64(const std::string &str)
251 {
252 return strtoll(str.c_str(), nullptr, DECIMAL_SYSTEM);
253 }
254
MaskIpv4(std::string & maskedResult)255 std::string MaskIpv4(std::string &maskedResult)
256 {
257 int maxDisplayNum = MAX_DISPLAY_NUM;
258 for (char &i : maskedResult) {
259 if (i == '/') {
260 break;
261 }
262 if (maxDisplayNum > 0) {
263 if (i == '.') {
264 maxDisplayNum--;
265 }
266 } else {
267 if (i != '.') {
268 i = '*';
269 }
270 }
271 }
272 return maskedResult;
273 }
274
MaskIpv6(std::string & maskedResult)275 std::string MaskIpv6(std::string &maskedResult)
276 {
277 size_t colonCount = 0;
278 for (char &i : maskedResult) {
279 if (i == '/') {
280 break;
281 }
282 if (i == ':') {
283 colonCount++;
284 }
285
286 if (colonCount >= MAX_DISPLAY_NUM) { // An legal ipv6 address has at least 2 ':'.
287 if (i != ':' && i != '/') {
288 i = '*';
289 }
290 }
291 }
292 return maskedResult;
293 }
294
ToAnonymousIp(const std::string & input)295 std::string ToAnonymousIp(const std::string &input)
296 {
297 std::lock_guard<std::mutex> lock(g_commonUtilsMutex);
298 std::string maskedResult{input};
299 // Mask ipv4 address.
300 if (std::regex_match(maskedResult, IP_PATTERN) || std::regex_match(maskedResult, IP_MASK_PATTERN)) {
301 return MaskIpv4(maskedResult);
302 }
303 // Mask ipv6 address.
304 if (std::regex_match(maskedResult, IPV6_PATTERN) || std::regex_match(maskedResult, IPV6_MASK_PATTERN)) {
305 return MaskIpv6(maskedResult);
306 }
307 return input;
308 }
309
StrToInt(const std::string & str)310 int32_t StrToInt(const std::string &str)
311 {
312 return std::strtol(str.c_str(), nullptr, 0);
313 }
314
StrToUint(const std::string & str)315 uint32_t StrToUint(const std::string &str)
316 {
317 return std::strtoul(str.c_str(), nullptr, 0);
318 }
319
StrToBool(const std::string & str)320 bool StrToBool(const std::string &str)
321 {
322 return static_cast<bool>(std::strtoul(str.c_str(), nullptr, 0));
323 }
324
StrToLong(const std::string & str)325 int64_t StrToLong(const std::string &str)
326 {
327 return std::strtol(str.c_str(), nullptr, 0);
328 }
329
CheckIfaceName(const std::string & name)330 bool CheckIfaceName(const std::string &name)
331 {
332 uint32_t index = 0;
333 if (name.empty()) {
334 return false;
335 }
336 size_t len = name.size();
337 if (len > INTERFACE_NAME_MAX_SIZE) {
338 return false;
339 }
340 while (index < len) {
341 if ((index == 0) && !isalnum(name[index])) {
342 return false;
343 }
344 if (!isalnum(name[index]) && (name[index] != '-') && (name[index] != '_') && (name[index] != '.') &&
345 (name[index] != ':')) {
346 return false;
347 }
348 index++;
349 }
350 return true;
351 }
352
FormatCmd(const std::vector<std::string> & cmd)353 std::vector<const char *> FormatCmd(const std::vector<std::string> &cmd)
354 {
355 std::vector<const char *> res;
356 res.reserve(cmd.size() + 1);
357
358 // string is converted to char * and the result is saved in res
359 std::transform(cmd.begin(), cmd.end(), std::back_inserter(res), [](const std::string &str) { return str.c_str(); });
360 res.emplace_back(nullptr);
361 return res;
362 }
363
ForkExecChildProcess(const int32_t * pipeFd,int32_t count,const std::vector<const char * > & args)364 int32_t ForkExecChildProcess(const int32_t *pipeFd, int32_t count, const std::vector<const char *> &args)
365 {
366 if (count != PIPE_FD_NUM) {
367 NETMGR_LOG_E("fork exec parent process failed");
368 _exit(-1);
369 }
370 if (close(pipeFd[PIPE_OUT]) != 0) {
371 NETMGR_LOG_E("close failed, errorno:%{public}d, errormsg:%{public}s", errno, strerror(errno));
372 _exit(-1);
373 }
374 if (dup2(pipeFd[PIPE_IN], STDOUT_FILENO) == -1) {
375 NETMGR_LOG_E("dup2 failed, errorno:%{public}d, errormsg:%{public}s", errno, strerror(errno));
376 _exit(-1);
377 }
378 if (execv(args[0], const_cast<char *const *>(&args[0])) == -1) {
379 NETMGR_LOG_E("execv command failed, errorno:%{public}d, errormsg:%{public}s", errno, strerror(errno));
380 }
381 _exit(-1);
382 }
383
ForkExecParentProcess(const int32_t * pipeFd,int32_t count,pid_t childPid,std::string * out)384 int32_t ForkExecParentProcess(const int32_t *pipeFd, int32_t count, pid_t childPid, std::string *out)
385 {
386 if (count != PIPE_FD_NUM) {
387 NETMGR_LOG_E("fork exec parent process failed");
388 return NETMANAGER_ERROR;
389 }
390 if (out != nullptr) {
391 char buf[CHAR_ARRAY_SIZE_MAX] = {0};
392 out->clear();
393 if (close(pipeFd[PIPE_IN]) != 0) {
394 NETMGR_LOG_E("close failed, errorno:%{public}d, errormsg:%{public}s", errno, strerror(errno));
395 }
396 while (read(pipeFd[PIPE_OUT], buf, CHAR_ARRAY_SIZE_MAX - 1) > 0) {
397 out->append(buf);
398 }
399 return NETMANAGER_SUCCESS;
400 }
401 pid_t pidRet = waitpid(childPid, nullptr, 0);
402 if (pidRet != childPid) {
403 NETMGR_LOG_E("waitpid[%{public}d] failed, pidRet:%{public}d", childPid, pidRet);
404 return NETMANAGER_ERROR;
405 }
406 return NETMANAGER_SUCCESS;
407 }
408
ForkExec(const std::string & command,std::string * out)409 int32_t ForkExec(const std::string &command, std::string *out)
410 {
411 std::unique_lock<std::mutex> lock(g_forkExecMutex);
412 const std::vector<std::string> cmd = Split(command, CMD_SEP);
413 std::vector<const char *> args = FormatCmd(cmd);
414 int32_t pipeFd[PIPE_FD_NUM] = {0};
415 if (pipe(pipeFd) < 0) {
416 NETMGR_LOG_E("creat pipe failed, errorno:%{public}d, errormsg:%{public}s", errno, strerror(errno));
417 return NETMANAGER_ERROR;
418 }
419 pid_t pid = fork();
420 if (pid < 0) {
421 NETMGR_LOG_E("fork failed, errorno:%{public}d, errormsg:%{public}s", errno, strerror(errno));
422 return NETMANAGER_ERROR;
423 }
424 if (pid == 0) {
425 ForkExecChildProcess(pipeFd, PIPE_FD_NUM, args);
426 return NETMANAGER_SUCCESS;
427 } else {
428 return ForkExecParentProcess(pipeFd, PIPE_FD_NUM, pid, out);
429 }
430 }
431 } // namespace OHOS::NetManagerStandard::CommonUtils
432