• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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 #include <sys/socket.h>
16 #include <sys/ioctl.h>
17 #include <net/if_arp.h>
18 #include <netinet/in.h>
19 #include <unistd.h>
20 
21 #include "dhcp_common_utils.h"
22 #include <arpa/inet.h>
23 #include <netinet/if_ether.h>
24 #include <regex>
25 #include "securec.h"
26 #include "dhcp_logger.h"
27 
28 namespace OHOS {
29 namespace DHCP {
30 DEFINE_DHCPLOG_DHCP_LABEL("DhcpCommonUtils");
31 
32 constexpr int32_t GATEWAY_MAC_LENTH = 18;
33 constexpr int32_t MAC_INDEX_0 = 0;
34 constexpr int32_t MAC_INDEX_1 = 1;
35 constexpr int32_t MAC_INDEX_2 = 2;
36 constexpr int32_t MAC_INDEX_3 = 3;
37 constexpr int32_t MAC_INDEX_4 = 4;
38 constexpr int32_t MAC_INDEX_5 = 5;
39 constexpr int32_t MAC_LENTH = 6;
40 constexpr int32_t MIN_DELIM_SIZE = 2;
41 constexpr int32_t MIN_KEEP_SIZE = 6;
42 
DataAnonymize(const std::string & str,char delim,char hiddenCh,int32_t startIdx=0)43 static std::string DataAnonymize(const std::string &str, char delim, char hiddenCh, int32_t startIdx = 0)
44 {
45     std::string s = str;
46     int32_t strLen = std::count(s.begin(), s.end(), delim);
47     if (strLen < MIN_DELIM_SIZE) {
48         if (s.size() <= MIN_KEEP_SIZE) {
49             return std::string(s.size(), hiddenCh);
50         }
51         int32_t idx1 = MIN_DELIM_SIZE;
52         int32_t idx2 = static_cast<int32_t>(s.size() - MAC_INDEX_4);
53         while (idx1++ < idx2) {
54             s[idx1] = hiddenCh;
55         }
56         return s;
57     }
58 
59     std::string::size_type begin = s.find_first_of(delim);
60     std::string::size_type end = s.find_last_of(delim);
61     int idx = 0;
62     while (idx++ < startIdx && begin < end) {
63         begin = s.find_first_of(delim, begin + 1);
64     }
65     while (begin++ != end) {
66         if (s[begin] != delim) {
67             s[begin] = hiddenCh;
68         }
69     }
70     return s;
71 }
72 
Ipv6Anonymize(const std::string & str)73 std::string Ipv6Anonymize(const std::string &str)
74 {
75     return DataAnonymize(str, ':', '*', 1);
76 }
77 
Ipv4Anonymize(const std::string str)78 std::string Ipv4Anonymize(const std::string str)
79 {
80     std::string strTemp = str;
81     std::string::size_type begin = strTemp.find_last_of('.');
82     while (begin < strTemp.length()) {
83         if (strTemp[begin] != '.') {
84             strTemp[begin] = '*';
85         }
86         begin++;
87     }
88     return strTemp;
89 }
90 
UintIp4ToStr(uint32_t uIp,bool bHost)91 char *UintIp4ToStr(uint32_t uIp, bool bHost)
92 {
93     char bufIp4[INET_ADDRSTRLEN] = {0};
94     struct in_addr addr4;
95     if (bHost) {
96         addr4.s_addr = htonl(uIp);
97     } else {
98         addr4.s_addr = uIp;
99     }
100     const char *p = inet_ntop(AF_INET, &addr4, bufIp4, INET_ADDRSTRLEN);
101     if (p == nullptr) {
102         DHCP_LOGE("UintIp4ToStr inet_ntop p == nullptr!");
103         return nullptr;
104     }
105     char *strIp = static_cast<char *>(malloc(INET_ADDRSTRLEN));
106     if (strIp == nullptr) {
107         DHCP_LOGE("UintIp4ToStr strIp malloc failed!");
108         return nullptr;
109     }
110     if (strncpy_s(strIp, INET_ADDRSTRLEN, bufIp4, strlen(bufIp4)) != EOK) {
111         DHCP_LOGE("UintIp4ToStr strIp strncpy_s failed!");
112         free(strIp);
113         strIp = nullptr;
114         return nullptr;
115     }
116     return strIp;
117 }
118 
IntIpv4ToAnonymizeStr(uint32_t ip)119 std::string IntIpv4ToAnonymizeStr(uint32_t ip)
120 {
121     std::string strTemp = "";
122     char *pIp = UintIp4ToStr(ip, false);
123     if (pIp != nullptr) {
124         strTemp = Ipv4Anonymize(pIp);
125         free(pIp);
126         pIp = nullptr;
127     }
128     return strTemp;
129 }
130 
MacArray2Str(uint8_t * macArray,int32_t len)131 std::string MacArray2Str(uint8_t *macArray, int32_t len)
132 {
133     if ((macArray == nullptr) || (len != ETH_ALEN)) {
134         DHCP_LOGE("MacArray2Str arg is invalid!");
135         return "";
136     }
137 
138     char gwMacAddr[GATEWAY_MAC_LENTH] = {0};
139     if (sprintf_s(gwMacAddr, sizeof(gwMacAddr), "%02x:%02x:%02x:%02x:%02x:%02x", macArray[MAC_INDEX_0],
140         macArray[MAC_INDEX_1], macArray[MAC_INDEX_2], macArray[MAC_INDEX_3], macArray[MAC_INDEX_4],
141         macArray[MAC_INDEX_5]) < 0) {
142         DHCP_LOGE("MacArray2Str sprintf_s err");
143         return "";
144     }
145     std::string ret = gwMacAddr;
146     return ret;
147 }
148 
CheckDataLegal(const std::string & data,int base)149 int CheckDataLegal(const std::string &data, int base)
150 {
151     std::regex pattern("\\d+");
152     if (!std::regex_search(data, pattern)) {
153         return 0;
154     }
155     errno = 0;
156     char *endptr = nullptr;
157     long int num = std::strtol(data.c_str(), &endptr, base);
158     if (errno == ERANGE) {
159         DHCP_LOGE("CheckDataLegal errno == ERANGE, data:%{private}s", data.c_str());
160         return 0;
161     }
162     return static_cast<int>(num);
163 }
164 
CheckDataToUint(const std::string & data,int base)165 unsigned int CheckDataToUint(const std::string &data, int base)
166 {
167     std::regex pattern("\\d+");
168     std::regex patternTmp("-\\d+");
169     if (!std::regex_search(data, pattern) || std::regex_search(data, patternTmp)) {
170         DHCP_LOGE("CheckDataToUint regex unsigned int value fail, data:%{private}s", data.c_str());
171         return 0;
172     }
173     errno = 0;
174     char *endptr = nullptr;
175     unsigned long int num = std::strtoul(data.c_str(), &endptr, base);
176     if (errno == ERANGE) {
177         DHCP_LOGE("CheckDataToUint errno == ERANGE, data:%{private}s", data.c_str());
178         return 0;
179     }
180     return static_cast<unsigned int>(num);
181 }
182 
CheckDataTolonglong(const std::string & data,int base)183 long long CheckDataTolonglong(const std::string &data, int base)
184 {
185     std::regex pattern("\\d+");
186     if (!std::regex_search(data, pattern)) {
187         return 0;
188     }
189     errno = 0;
190     char *endptr = nullptr;
191     long long int num = std::strtoll(data.c_str(), &endptr, base);
192     if (errno == ERANGE) {
193         DHCP_LOGE("CheckDataTolonglong errno == ERANGE, data:%{private}s", data.c_str());
194         return 0;
195     }
196     return num;
197 }
198 
CheckDataToUint64(const std::string & data,int base)199 uint64_t CheckDataToUint64(const std::string &data, int base)
200 {
201     std::regex pattern("\\d+");
202     if (!std::regex_search(data, pattern)) {
203         DHCP_LOGE("CheckDataToUint64 regex unsigned int value fail, data:%{private}s", data.c_str());
204         return 0;
205     }
206     errno = 0;
207     char *endptr = nullptr;
208     uint64_t num = std::strtoull(data.c_str(), &endptr, base);
209     if (errno == ERANGE) {
210         DHCP_LOGE("CheckDataToUint64 errno == ERANGE, data:%{private}s", data.c_str());
211         return 0;
212     }
213     return num;
214 }
215 
GetElapsedSecondsSinceBoot()216 int64_t GetElapsedSecondsSinceBoot()
217 {
218     struct timespec times = {0, 0};
219     clock_gettime(CLOCK_BOOTTIME, &times);
220     return static_cast<int64_t>(times.tv_sec);
221 }
222 
Ip4IntConvertToStr(uint32_t uIp,bool bHost)223 std::string Ip4IntConvertToStr(uint32_t uIp, bool bHost)
224 {
225     char bufIp4[INET_ADDRSTRLEN] = {0};
226     struct in_addr addr4;
227     if (bHost) {
228         addr4.s_addr = htonl(uIp);
229     } else {
230         addr4.s_addr = uIp;
231     }
232 
233     std::string strIp = "";
234     if (inet_ntop(AF_INET, &addr4, bufIp4, INET_ADDRSTRLEN) == nullptr) {
235         DHCP_LOGE("Ip4IntConvertToStr uIp:%{private}u failed, inet_ntop nullptr!", uIp);
236     } else {
237         strIp = bufIp4;
238         DHCP_LOGI("Ip4IntConvertToStr uIp:%{private}u -> strIp:%{private}s.", uIp, strIp.c_str());
239     }
240 
241     return strIp;
242 }
243 
GetMacAddr(char * buff,const char * macAddr)244 static int32_t GetMacAddr(char *buff, const char *macAddr)
245 {
246     unsigned int addr[MAC_LENTH] = {0};
247     if (buff == nullptr || macAddr == nullptr) {
248         DHCP_LOGE("buff or macAddr is nullptr");
249         return -1;
250     }
251 
252     if (sscanf_s(macAddr, "%x:%x:%x:%x:%x:%x", &addr[MAC_INDEX_0], &addr[MAC_INDEX_1], &addr[MAC_INDEX_2],
253         &addr[MAC_INDEX_3], &addr[MAC_INDEX_4], &addr[MAC_INDEX_5]) < MAC_LENTH) {
254         DHCP_LOGE("sscanf_s macAddr err");
255         return -1;
256     }
257 
258     for (int32_t i = 0; i < MAC_LENTH; i++) {
259         buff[i] = addr[i];
260     }
261     return 0;
262 }
263 
AddArpEntry(const std::string & iface,const std::string & ipAddr,const std::string & macAddr)264 int32_t AddArpEntry(const std::string& iface, const std::string& ipAddr, const std::string& macAddr)
265 {
266     DHCP_LOGI("AddArpEntry enter");
267     struct arpreq req;
268     struct sockaddr_in *sin = nullptr;
269 
270     if (iface.empty() || ipAddr.empty() || macAddr.empty()) {
271         DHCP_LOGE("AddArpEntry arg is invalid");
272         return -1;
273     }
274 
275     if (memset_s(&req, sizeof(struct arpreq), 0, sizeof(struct arpreq)) != EOK) {
276         DHCP_LOGE("DelStaticArp memset_s err");
277         return -1;
278     }
279     sin = reinterpret_cast<struct sockaddr_in *>(&req.arp_pa);
280     sin->sin_family = AF_INET;
281     sin->sin_addr.s_addr = inet_addr(ipAddr.c_str());
282     if (strncpy_s(req.arp_dev, sizeof(req.arp_dev), iface.c_str(), iface.size()) != EOK) {
283         DHCP_LOGE("strncpy_s req err");
284         return -1;
285     }
286 
287     req.arp_flags = ATF_PERM | ATF_COM;
288     if (GetMacAddr(reinterpret_cast<char *>(req.arp_ha.sa_data), macAddr.c_str()) < 0) {
289         DHCP_LOGE("AddArpEntry GetMacAddr error");
290         return -1;
291     }
292 
293     int32_t sockFd = socket(AF_INET, SOCK_DGRAM, 0);
294     if (sockFd < 0) {
295         DHCP_LOGE("DoArpItem socket creat error");
296         return -1;
297     }
298 
299     int32_t ret = ioctl(sockFd, SIOCSARP, &req);
300     if (ret < 0) {
301         DHCP_LOGE("DoArpItem ioctl error");
302     }
303     close(sockFd);
304     return ret;
305 }
306 
IsValidPath(const std::string & filePath)307 bool IsValidPath(const std::string &filePath)
308 {
309     if (filePath.empty()) {
310         return false;
311     }
312 
313     // filePath must be the full path of a file, so the last one character cannot be '/'
314     size_t index = filePath.find_last_of('/');
315     if (index == std::string::npos || index == filePath.length() - 1) {
316         return false;
317     }
318 
319     std::string path = filePath.substr(0, index);
320     char *realPaths = realpath(path.c_str(), nullptr);
321     if (realPaths == nullptr) {
322         return false;
323     }
324 
325     free(realPaths);
326     return true;
327 }
328 }
329 }
330