1 /*
2 * Copyright (C) 2021-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 #include "dhcp_function.h"
16
17 #include <unistd.h>
18 #include <net/if.h>
19 #include <sys/ioctl.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <fcntl.h>
23 #include <vector>
24 #include <sys/wait.h>
25
26 #include "securec.h"
27 #include "dhcp_logger.h"
28
29 namespace OHOS {
30 namespace DHCP {
31 DEFINE_DHCPLOG_DHCP_LABEL("DhcpFunction");
32
33 const int MAX_RETEY_WAIT_COUNT = 60;
34 const int WAIT_SLEEP_50MS = 50;
35
Ip4StrConToInt(const std::string & strIp,uint32_t & uIp,bool bHost)36 bool DhcpFunction::Ip4StrConToInt(const std::string& strIp, uint32_t& uIp, bool bHost)
37 {
38 if (strIp.empty()) {
39 DHCP_LOGE("Ip4StrConToInt error, strIp is empty()!");
40 return false;
41 }
42
43 struct in_addr addr4;
44 int nRet = inet_pton(AF_INET, strIp.c_str(), &addr4);
45 if (nRet != 1) {
46 DHCP_LOGE("Ip4StrConToInt strIp:%{private}s failed, nRet:%{public}d!", strIp.c_str(), nRet);
47 if (nRet == 0) {
48 DHCP_LOGE("Ip4StrConToInt strIp:%{private}s not in presentation format!", strIp.c_str());
49 } else {
50 DHCP_LOGE("Ip4StrConToInt strIp:%{private}s inet_pton not contain a valid address!", strIp.c_str());
51 }
52 return false;
53 }
54
55 if (bHost) {
56 uIp = ntohl(addr4.s_addr);
57 } else {
58 uIp = addr4.s_addr;
59 }
60
61 return true;
62 }
63
Ip4IntConvertToStr(uint32_t uIp,bool bHost)64 std::string DhcpFunction::Ip4IntConvertToStr(uint32_t uIp, bool bHost)
65 {
66 char bufIp4[INET_ADDRSTRLEN] = {0};
67 struct in_addr addr4;
68 if (bHost) {
69 addr4.s_addr = htonl(uIp);
70 } else {
71 addr4.s_addr = uIp;
72 }
73
74 std::string strIp = "";
75 if (inet_ntop(AF_INET, &addr4, bufIp4, INET_ADDRSTRLEN) == nullptr) {
76 DHCP_LOGE("Ip4IntConvertToStr uIp:%{private}u failed, inet_ntop nullptr!", uIp);
77 } else {
78 strIp = bufIp4;
79 DHCP_LOGI("Ip4IntConvertToStr uIp:%{private}u -> strIp:%{private}s.", uIp, strIp.c_str());
80 }
81
82 return strIp;
83 }
84
Ip6StrConToChar(const std::string & strIp,uint8_t chIp[],size_t uSize)85 bool DhcpFunction::Ip6StrConToChar(const std::string& strIp, uint8_t chIp[], size_t uSize)
86 {
87 if (strIp.empty()) {
88 DHCP_LOGE("Ip6StrConToChar param error, strIp is empty()!");
89 return false;
90 }
91
92 struct in6_addr addr6;
93 if (memset_s(&addr6, sizeof(addr6), 0, sizeof(addr6)) != EOK) {
94 return false;
95 }
96 int nRet = inet_pton(AF_INET6, strIp.c_str(), &addr6);
97 if (nRet != 1) {
98 DHCP_LOGE("Ip6StrConToChar inet_pton strIp:%{private}s failed, nRet:%{public}d!", strIp.c_str(), nRet);
99 if (nRet == 0) {
100 DHCP_LOGE("Ip6StrConToChar strIp:%{private}s not in presentation format!", strIp.c_str());
101 } else {
102 DHCP_LOGE("Ip6StrConToChar strIp:%{private}s inet_pton not contain a valid address!", strIp.c_str());
103 }
104 return false;
105 }
106
107 for (size_t i = 0; i < uSize; i++) {
108 chIp[i] = addr6.s6_addr[i];
109 }
110
111 return true;
112 }
113
Ip6CharConToStr(uint8_t chIp[],int size)114 std::string DhcpFunction::Ip6CharConToStr(uint8_t chIp[], int size)
115 {
116 if (size <= 0) {
117 DHCP_LOGE("Ip6CharConToStr param error, size:%{public}d!", size);
118 return "";
119 }
120
121 std::string strIp = "";
122 char bufIp6[INET6_ADDRSTRLEN] = {0};
123 struct in6_addr addr6;
124 if (memcpy_s(addr6.s6_addr, sizeof(addr6.s6_addr), &chIp, size) != EOK) {
125 return "";
126 }
127 if (inet_ntop(AF_INET6, &addr6, bufIp6, INET6_ADDRSTRLEN) == nullptr) {
128 DHCP_LOGE("Ip6CharConToStr chIp failed, inet_ntop nullptr!");
129 } else {
130 strIp = bufIp6;
131 DHCP_LOGI("Ip6CharConToStr chIp -> strIp:%{private}s.", strIp.c_str());
132 }
133
134 return strIp;
135 }
136
CheckIpStr(const std::string & strIp)137 bool DhcpFunction::CheckIpStr(const std::string& strIp)
138 {
139 if (strIp.empty()) {
140 DHCP_LOGE("CheckIpStr param error, strIp is empty()!");
141 return false;
142 }
143
144 bool bIp4 = false;
145 bool bIp6 = false;
146 std::string::size_type idx = strIp.find(IP4_SEPARATOR);
147 if (idx != std::string::npos) {
148 bIp4 = true;
149 }
150 idx = strIp.find(IP6_SEPARATOR);
151 if (idx != std::string::npos) {
152 bIp6 = true;
153 }
154 if ((!bIp4 && !bIp6) || (bIp4 && bIp6)) {
155 DHCP_LOGE("CheckIpStr strIp:%{private}s error, bIp4:%{public}d,bIp6:%{public}d!", strIp.c_str(), bIp4, bIp6);
156 return false;
157 }
158
159 if (bIp4) {
160 uint32_t uIp = 0;
161 if (!Ip4StrConToInt(strIp, uIp)) {
162 DHCP_LOGE("CheckIpStr Ip4StrConToInt failed, strIp:%{private}s.", strIp.c_str());
163 return false;
164 }
165 } else {
166 uint8_t addr6[sizeof(struct in6_addr)] = {0};
167 if (!Ip6StrConToChar(strIp, addr6, sizeof(struct in6_addr))) {
168 DHCP_LOGE("CheckIpStr Ip6StrConToChar failed, strIp:%{private}s.", strIp.c_str());
169 return false;
170 }
171 }
172
173 return true;
174 }
175
GetLocalIp(const std::string strInf,std::string & strIp,std::string & strMask)176 int DhcpFunction::GetLocalIp(const std::string strInf, std::string& strIp, std::string& strMask)
177 {
178 if (strInf.empty()) {
179 DHCP_LOGE("GetLocalIp param error, strInf is empty!");
180 return DHCP_OPT_ERROR;
181 }
182
183 int fd;
184 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
185 DHCP_LOGE("GetLocalIp strInf:%{public}s failed, socket err:%{public}d!", strInf.c_str(), errno);
186 return DHCP_OPT_FAILED;
187 }
188
189 struct ifreq iface;
190 if (memset_s(&iface, sizeof(iface), 0, sizeof(iface)) != EOK) {
191 close(fd);
192 return DHCP_OPT_FAILED;
193 }
194 if (strncpy_s(iface.ifr_name, IFNAMSIZ, strInf.c_str(), IFNAMSIZ - 1) != EOK) {
195 close(fd);
196 return DHCP_OPT_FAILED;
197 }
198 iface.ifr_name[IFNAMSIZ - 1] = 0;
199
200 /* inet addr */
201 if (ioctl(fd, SIOCGIFADDR, &iface) < 0) {
202 DHCP_LOGE("GetLocalIp() %{public}s failed, SIOCGIFADDR err:%{public}d!", strInf.c_str(), errno);
203 close(fd);
204 return DHCP_OPT_FAILED;
205 }
206 struct sockaddr_in *pSockIn = (struct sockaddr_in *)&iface.ifr_addr;
207 char bufIp4[INET_ADDRSTRLEN] = {0};
208 if (inet_ntop(AF_INET, &(pSockIn->sin_addr), bufIp4, INET_ADDRSTRLEN) != nullptr) {
209 strIp = bufIp4;
210 }
211
212 /* netmask addr */
213 if (ioctl(fd, SIOCGIFNETMASK, &iface) < 0) {
214 DHCP_LOGE("GetLocalIp() %{public}s failed, SIOCGIFNETMASK err:%{public}d!", strInf.c_str(), errno);
215 close(fd);
216 return DHCP_OPT_FAILED;
217 }
218 pSockIn = (struct sockaddr_in *)&iface.ifr_addr;
219 char bufMask[INET_ADDRSTRLEN] = {0};
220 if (inet_ntop(AF_INET, &(pSockIn->sin_addr), bufMask, INET_ADDRSTRLEN) != nullptr) {
221 strMask = bufMask;
222 }
223
224 close(fd);
225 return DHCP_OPT_SUCCESS;
226 }
227
GetLocalMac(const std::string ethInf,std::string & ethMac)228 int DhcpFunction::GetLocalMac(const std::string ethInf, std::string& ethMac)
229 {
230 struct ifreq ifr;
231 int sd = 0;
232
233 bzero(&ifr, sizeof(struct ifreq));
234 if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
235 DHCP_LOGE("GetLocalMac socket ethInf:%{public}s,error:%{public}d!", ethInf.c_str(), errno);
236 return -1;
237 }
238
239 if (strncpy_s(ifr.ifr_name, IFNAMSIZ, ethInf.c_str(), IFNAMSIZ - 1) != EOK) {
240 close(sd);
241 return -1;
242 }
243
244 if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0) {
245 DHCP_LOGE("GetLocalMac ioctl ethInf:%{public}s,error:%{public}d!", ethInf.c_str(), errno);
246 close(sd);
247 return -1;
248 }
249
250 char mac[ETH_MAC_ADDR_LEN * ETH_MAC_ADDR_CHAR_NUM] = { 0 };
251 int nRes = snprintf_s(mac,
252 ETH_MAC_ADDR_LEN * ETH_MAC_ADDR_CHAR_NUM,
253 ETH_MAC_ADDR_LEN * ETH_MAC_ADDR_CHAR_NUM - 1,
254 "%02x:%02x:%02x:%02x:%02x:%02x",
255 (unsigned char)ifr.ifr_hwaddr.sa_data[ETH_MAC_ADDR_INDEX_0],
256 (unsigned char)ifr.ifr_hwaddr.sa_data[ETH_MAC_ADDR_INDEX_1],
257 (unsigned char)ifr.ifr_hwaddr.sa_data[ETH_MAC_ADDR_INDEX_2],
258 (unsigned char)ifr.ifr_hwaddr.sa_data[ETH_MAC_ADDR_INDEX_3],
259 (unsigned char)ifr.ifr_hwaddr.sa_data[ETH_MAC_ADDR_INDEX_4],
260 (unsigned char)ifr.ifr_hwaddr.sa_data[ETH_MAC_ADDR_INDEX_5]);
261 if (nRes < 0) {
262 DHCP_LOGE("GetLocalMac snprintf_s ethInf:%{public}s,error:%{public}d!", ethInf.c_str(), errno);
263 close(sd);
264 return -1;
265 }
266 ethMac = mac;
267 close(sd);
268 return 0;
269 }
270
CheckRangeNetwork(const std::string strInf,const std::string strBegin,const std::string strEnd)271 int DhcpFunction::CheckRangeNetwork(const std::string strInf, const std::string strBegin, const std::string strEnd)
272 {
273 if (strInf.empty() || strBegin.empty() || strEnd.empty()) {
274 DHCP_LOGE("CheckRangeNetwork param error, strInf or strBegin or strEnd is empty!");
275 return DHCP_OPT_ERROR;
276 }
277
278 std::string strIp, strMask;
279 if (GetLocalIp(strInf, strIp, strMask) != DHCP_OPT_SUCCESS) {
280 DHCP_LOGE("CheckRangeNetwork get %{public}s local ip failed", strInf.c_str());
281 return DHCP_OPT_FAILED;
282 }
283
284 uint32_t uIp, uMask, uBegin, uEnd;
285 if (!Ip4StrConToInt(strIp, uIp, false) || !Ip4StrConToInt(strMask, uMask, false) ||
286 !Ip4StrConToInt(strBegin, uBegin, false) || !Ip4StrConToInt(strEnd, uEnd, false)) {
287 DHCP_LOGE("CheckRangeNetwork %{public}s Ip4StrConToInt failed", strInf.c_str());
288 return DHCP_OPT_FAILED;
289 }
290
291 if (!CheckSameNetwork(uIp, uBegin, uMask)) {
292 DHCP_LOGE("Check %{public}s %{private}s %{public}s failed", strInf.c_str(), strIp.c_str(), strBegin.c_str());
293 return DHCP_OPT_FAILED;
294 }
295 if (!CheckSameNetwork(uIp, uEnd, uMask)) {
296 DHCP_LOGE("Check end %{public}s %{private}s %{public}s failed", strInf.c_str(), strIp.c_str(), strEnd.c_str());
297 return DHCP_OPT_FAILED;
298 }
299 return DHCP_OPT_SUCCESS;
300 }
301
CheckSameNetwork(const uint32_t srcIp,const uint32_t dstIp,const uint32_t maskIp)302 bool DhcpFunction::CheckSameNetwork(const uint32_t srcIp, const uint32_t dstIp, const uint32_t maskIp)
303 {
304 uint32_t srcNet = srcIp & maskIp;
305 uint32_t dstNet = dstIp & maskIp;
306 return (srcNet == dstNet);
307 }
308
IsExistFile(const std::string & filename)309 bool DhcpFunction::IsExistFile(const std::string& filename)
310 {
311 bool bExist = false;
312 std::fstream ioFile;
313 ioFile.open(filename.c_str(), std::ios::in);
314 if (ioFile) {
315 bExist = true;
316 }
317 DHCP_LOGE("IsExistFile %{public}s failed, err:%{public}d", filename.c_str(), errno);
318 ioFile.close();
319
320 return bExist;
321 }
322
CreateFile(const std::string & filename,const std::string & filedata)323 bool DhcpFunction::CreateFile(const std::string& filename, const std::string& filedata)
324 {
325 std::ofstream outFile;
326 outFile.open(filename.c_str());
327 outFile.flush();
328 outFile << filedata << std::endl;
329 outFile.close();
330 return true;
331 }
332
RemoveFile(const std::string & filename)333 bool DhcpFunction::RemoveFile(const std::string& filename)
334 {
335 if (std::remove(filename.c_str()) != 0) {
336 DHCP_LOGE("RemoveFile filename:%{public}s failed!", filename.c_str());
337 return false;
338 }
339 DHCP_LOGI("RemoveFile filename:%{public}s success.", filename.c_str());
340 return true;
341 }
342
AddFileLineData(const std::string & filename,const std::string & prevdata,const std::string & linedata)343 bool DhcpFunction::AddFileLineData(const std::string& filename, const std::string& prevdata, const std::string& linedata)
344 {
345 bool bAdd = false;
346 std::ifstream inFile;
347 inFile.open(filename.c_str());
348 std::string strFileData = "";
349 std::string strTemp = "";
350 char tmpLineData[1024] = {0};
351 while (inFile.getline(tmpLineData, sizeof(tmpLineData))) {
352 strTemp = tmpLineData;
353 strFileData += strTemp;
354 strFileData += "\n";
355 if (strTemp == prevdata) {
356 strFileData += linedata;
357 bAdd = true;
358 }
359 }
360 inFile.close();
361
362 if (bAdd) {
363 std::ofstream outFile;
364 outFile.open(filename.c_str());
365 outFile.flush();
366 DHCP_LOGI("AddFileLineData Reflush filename:%{public}s, strFileData:%{public}s.",
367 filename.c_str(), strFileData.c_str());
368 outFile << strFileData;
369 outFile.close();
370 }
371 return true;
372 }
373
DelFileLineData(const std::string & filename,const std::string & linedata)374 bool DhcpFunction::DelFileLineData(const std::string& filename, const std::string& linedata)
375 {
376 bool bDel = false;
377 std::ifstream inFile;
378 inFile.open(filename.c_str());
379 std::string strFileData = "";
380 std::string strTemp = "";
381 char tmpLineData[1024] = {0};
382 while (inFile.getline(tmpLineData, sizeof(tmpLineData))) {
383 strTemp = tmpLineData;
384 if (strTemp != linedata) {
385 strFileData += strTemp;
386 strFileData += "\n";
387 } else {
388 bDel = true;
389 }
390 }
391 inFile.close();
392
393 if (bDel) {
394 std::ofstream outFile;
395 outFile.open(filename.c_str());
396 outFile.flush();
397 DHCP_LOGI("DelFileLineData Reflush filename:%{public}s, strFileData:%{public}s.",
398 filename.c_str(), strFileData.c_str());
399 outFile << strFileData;
400 outFile.close();
401 }
402 return true;
403 }
404
ModifyFileLineData(const std::string & filename,const std::string & srcdata,const std::string & dstdata)405 bool DhcpFunction::ModifyFileLineData(const std::string& filename, const std::string& srcdata,
406 const std::string& dstdata)
407 {
408 bool bModify = false;
409 std::ifstream inFile;
410 inFile.open(filename.c_str());
411 std::string strFileData = "";
412 std::string strTemp = "";
413 char tmpLineData[1024] = {0};
414 while (inFile.getline(tmpLineData, sizeof(tmpLineData))) {
415 strTemp = tmpLineData;
416 if (strTemp != srcdata) {
417 strFileData += strTemp;
418 strFileData += "\n";
419 } else {
420 strFileData += dstdata;
421 strFileData += "\n";
422 bModify = true;
423 }
424 }
425 inFile.close();
426
427 if (bModify) {
428 std::ofstream outFile;
429 outFile.open(filename.c_str());
430 outFile.flush();
431 DHCP_LOGI("ModifyFileLineData Reflush filename:%{public}s, strFileData:%{public}s.",
432 filename.c_str(), strFileData.c_str());
433 outFile << strFileData;
434 outFile.close();
435 }
436 return true;
437 }
438
FormatString(struct DhcpPacketResult & result)439 int DhcpFunction::FormatString(struct DhcpPacketResult &result)
440 {
441 if (strncmp(result.strYiaddr, "*", 1) == 0) {
442 if (memset_s(result.strYiaddr, INET_ADDRSTRLEN, 0, INET_ADDRSTRLEN) != EOK) {
443 return -1;
444 }
445 }
446 if (strncmp(result.strOptServerId, "*", 1) == 0) {
447 if (memset_s(result.strOptServerId, INET_ADDRSTRLEN, 0, INET_ADDRSTRLEN) != EOK) {
448 return -1;
449 }
450 }
451 if (strncmp(result.strOptSubnet, "*", 1) == 0) {
452 if (memset_s(result.strOptSubnet, INET_ADDRSTRLEN, 0, INET_ADDRSTRLEN) != EOK) {
453 return -1;
454 }
455 }
456 if (strncmp(result.strOptDns1, "*", 1) == 0) {
457 if (memset_s(result.strOptDns1, INET_ADDRSTRLEN, 0, INET_ADDRSTRLEN) != EOK) {
458 return -1;
459 }
460 }
461 if (strncmp(result.strOptDns2, "*", 1) == 0) {
462 if (memset_s(result.strOptDns2, INET_ADDRSTRLEN, 0, INET_ADDRSTRLEN) != EOK) {
463 return -1;
464 }
465 }
466 if (strncmp(result.strOptRouter1, "*", 1) == 0) {
467 if (memset_s(result.strOptRouter1, INET_ADDRSTRLEN, 0, INET_ADDRSTRLEN) != EOK) {
468 return -1;
469 }
470 }
471 if (strncmp(result.strOptRouter2, "*", 1) == 0) {
472 if (memset_s(result.strOptRouter2, INET_ADDRSTRLEN, 0, INET_ADDRSTRLEN) != EOK) {
473 return -1;
474 }
475 }
476 if (strncmp(result.strOptVendor, "*", 1) == 0) {
477 if (memset_s(result.strOptVendor, DHCP_FILE_MAX_BYTES, 0, DHCP_FILE_MAX_BYTES) != EOK) {
478 return -1;
479 }
480 }
481 return 0;
482 }
483
484 #ifdef OHOS_ARCH_LITE
GetDhcpPacketResult(const std::string & filename,struct DhcpPacketResult & result)485 int DhcpFunction::GetDhcpPacketResult(const std::string& filename, struct DhcpPacketResult &result)
486 {
487 FILE *pFile = fopen(filename.c_str(), "r");
488 if (pFile == nullptr) {
489 DHCP_LOGE("GetDhcpPacketResult() fopen %{public}s fail, err:%{public}s!", filename.c_str(), strerror(errno));
490 return DHCP_OPT_FAILED;
491 }
492
493 char strIpFlag[DHCP_NUM_EIGHT];
494 if (memset_s(strIpFlag, sizeof(strIpFlag), 0, sizeof(strIpFlag)) != EOK) {
495 fclose(pFile);
496 return DHCP_OPT_FAILED;
497 }
498 /* Format: IpFlag AddTime cliIp servIp subnet dns1 dns2 router1 router2 vendor lease */
499 int nRes = fscanf_s(pFile, "%s %u %s %s %s %s %s %s %s %s %u\n", strIpFlag, DHCP_NUM_EIGHT, &result.uAddTime,
500 result.strYiaddr, INET_ADDRSTRLEN, result.strOptServerId, INET_ADDRSTRLEN, result.strOptSubnet, INET_ADDRSTRLEN,
501 result.strOptDns1, INET_ADDRSTRLEN, result.strOptDns2, INET_ADDRSTRLEN, result.strOptRouter1, INET_ADDRSTRLEN,
502 result.strOptRouter2, INET_ADDRSTRLEN, result.strOptVendor, DHCP_FILE_MAX_BYTES, &result.uOptLeasetime);
503 if (nRes == EOF) {
504 DHCP_LOGE("GetDhcpPacketResult() fscanf %{public}s err:%{public}s!", filename.c_str(), strerror(errno));
505 fclose(pFile);
506 return DHCP_OPT_FAILED;
507 } else if (nRes == 0) {
508 DHCP_LOGW("GetDhcpPacketResult() fscanf file:%{public}s nRes:0 nullptr!", filename.c_str());
509 fclose(pFile);
510 return DHCP_OPT_NULL;
511 } else if (nRes != EVENT_DATA_NUM) {
512 DHCP_LOGE("GetDhcpPacketResult() fscanf file:%{public}s nRes:%{public}d ERROR!", filename.c_str(), nRes);
513 fclose(pFile);
514 return DHCP_OPT_FAILED;
515 }
516
517 if (fclose(pFile) != 0) {
518 DHCP_LOGE("GetDhcpPacketResult() fclose file:%{public}s failed!", filename.c_str());
519 return DHCP_OPT_FAILED;
520 }
521
522 /* Format dhcp packet result */
523 if (FormatString(result) != 0) {
524 DHCP_LOGE("GetDhcpPacketResult() file:%{public}s failed, FormatString result error!", filename.c_str());
525 return DHCP_OPT_FAILED;
526 }
527
528 return DHCP_OPT_SUCCESS;
529 }
530 #endif
531
InitPidfile(const std::string & piddir,const std::string & pidfile)532 int DhcpFunction::InitPidfile(const std::string& piddir, const std::string& pidfile)
533 {
534 if (piddir.empty() || pidfile.empty()) {
535 DHCP_LOGE("InitPidfile() failed, piddir or pidfile is empty!");
536 return DHCP_OPT_FAILED;
537 }
538 DHCP_LOGI("InitPidfile() piddir:%{public}s, pidfile:%{public}s.", piddir.c_str(), pidfile.c_str());
539 unlink(pidfile.c_str());
540
541 int fd;
542 if ((fd = open(pidfile.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) {
543 DHCP_LOGE("InitPidfile() failed, open pidfile:%{public}s err:%{public}d!", pidfile.c_str(), errno);
544 return DHCP_OPT_FAILED;
545 }
546
547 char buf[PID_MAX_LEN] = {0};
548 if (snprintf_s(buf, PID_MAX_LEN, PID_MAX_LEN - 1, "%d", getpid()) < 0) {
549 DHCP_LOGE("InitPidfile() %{public}s failed, snprintf_s error:%{public}d!", pidfile.c_str(), errno);
550 close(fd);
551 return DHCP_OPT_FAILED;
552 }
553 ssize_t bytes;
554 if ((bytes = write(fd, buf, strlen(buf))) <= 0) {
555 DHCP_LOGE("InitPidfile() failed, write pidfile:%{public}s error:%{public}d, bytes:%{public}zd!",
556 pidfile.c_str(), errno, bytes);
557 close(fd);
558 return DHCP_OPT_FAILED;
559 }
560 DHCP_LOGI("InitPidfile() pid:%{public}s write %{public}s, bytes:%{public}zd!", buf, pidfile.c_str(), bytes);
561 close(fd);
562
563 if (chdir(piddir.c_str()) != 0) {
564 DHCP_LOGE("InitPidfile() failed, chdir piddir:%{public}s err:%{public}d!", piddir.c_str(), errno);
565 return DHCP_OPT_FAILED;
566 }
567
568 /* Set default permissions for the specified client process id files and directories. */
569 umask(DEFAULT_UMASK);
570
571 /* Change attribs to the specified client process id files: 644 (user=rw, group=r, other=r). */
572 chmod(pidfile.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
573
574 return DHCP_OPT_SUCCESS;
575 }
576
GetPID(const std::string & pidfile)577 pid_t DhcpFunction::GetPID(const std::string& pidfile)
578 {
579 /* Check pidfile is or not exists. */
580 struct stat sb;
581 if (stat(pidfile.c_str(), &sb) != 0) {
582 DHCP_LOGW("GetPID() pidfile:%{public}s stat:%{public}d!", pidfile.c_str(), errno);
583 return -1;
584 }
585 DHCP_LOGI("GetPID() pidfile:%{public}s stat st_size:%{public}d.", pidfile.c_str(), (int)sb.st_size);
586
587 int fd;
588 if ((fd = open(pidfile.c_str(), O_RDONLY)) < 0) {
589 DHCP_LOGE("GetPID() failed, open pidfile:%{public}s error!", pidfile.c_str());
590 return -1;
591 }
592
593 lseek(fd, 0, SEEK_SET);
594
595 char buf[PID_MAX_LEN] = {0};
596 ssize_t bytes;
597 if ((bytes = read(fd, buf, sb.st_size)) < 0) {
598 DHCP_LOGE("GetPID() failed, read pidfile:%{public}s error, bytes:%{public}zd!", pidfile.c_str(), bytes);
599 close(fd);
600 return -1;
601 }
602 DHCP_LOGI("GetPID() read pidfile:%{public}s, buf:%{public}s, bytes:%{public}zd.", pidfile.c_str(), buf, bytes);
603 close(fd);
604
605 return atoi(buf);
606 }
607
CheckProRunning(const pid_t proPid,const std::string & proName)608 int DhcpFunction::CheckProRunning(const pid_t proPid, const std::string& proName)
609 {
610 if ((proPid == 0) || proName.empty()) {
611 DHCP_LOGE("CheckProRunning %{public}s param error!", proName.c_str());
612 return -1;
613 }
614 char buf[DIR_MAX_LEN] = {0};
615 if (snprintf_s(buf, DIR_MAX_LEN, DIR_MAX_LEN - 1, "/proc/%ld", (long int)proPid) < 0) {
616 DHCP_LOGE("CheckProRunning %{public}s failed, snprintf_s errno:%{public}d!", proName.c_str(), errno);
617 return -1;
618 }
619 if (access(buf, F_OK) != 0) {
620 DHCP_LOGI("CheckProRunning %{public}s is not exist, %{public}s no running", buf, proName.c_str());
621 return 0;
622 }
623 if (strcat_s(buf, sizeof(buf), "/exe") != EOK) {
624 DHCP_LOGE("CheckProRunning %{public}s failed, strcat_s errno:%{public}d!", proName.c_str(), errno);
625 return -1;
626 }
627 char proBuf[DIR_MAX_LEN] = {0};
628 if (readlink(buf, proBuf, sizeof(proBuf)) < 0) {
629 DHCP_LOGE("CheckProRunning %{public}s failed, readlink errno:%{public}d!", proName.c_str(), errno);
630 return -1;
631 }
632 if (strstr(proBuf, proName.c_str()) == nullptr) {
633 DHCP_LOGI("CheckProRunning %{public}s exe -> %{public}s, %{public}s no running", buf, proBuf, proName.c_str());
634 return 0;
635 }
636 DHCP_LOGI("CheckProRunning %{public}s exe -> %{public}s, %{public}s is running", buf, proBuf, proName.c_str());
637 return 1;
638 }
639
CreateDirs(const std::string dirs,int mode)640 int DhcpFunction::CreateDirs(const std::string dirs, int mode)
641 {
642 if (dirs.empty() || (dirs.size() >= DIR_MAX_LEN)) {
643 DHCP_LOGE("CreateDirs() dirs:%{public}s error!", dirs.c_str());
644 return DHCP_OPT_FAILED;
645 }
646
647 int nSrcLen = (int)dirs.size();
648 char strDir[DIR_MAX_LEN] = {0};
649 if (strncpy_s(strDir, sizeof(strDir), dirs.c_str(), dirs.size()) != EOK) {
650 DHCP_LOGE("CreateDirs() strncpy_s dirs:%{public}s failed!", dirs.c_str());
651 return DHCP_OPT_FAILED;
652 }
653 if (strDir[nSrcLen - 1] != '/') {
654 if (nSrcLen == (DIR_MAX_LEN - 1)) {
655 DHCP_LOGE("CreateDirs() dirs:%{public}s len:%{public}d error!", dirs.c_str(), nSrcLen);
656 return DHCP_OPT_FAILED;
657 }
658 if (strcat_s(strDir, sizeof(strDir), "/") != EOK) {
659 DHCP_LOGE("CreateDirs() strcat_s strDir:%{public}s failed!", strDir);
660 return DHCP_OPT_FAILED;
661 }
662 nSrcLen++;
663 }
664
665 int i = (strDir[0] == '/') ? 1 : 0;
666 for (; i <= nSrcLen - 1; i++) {
667 if (strDir[i] == '/') {
668 strDir[i] = 0;
669 if ((access(strDir, F_OK) != 0) && (mkdir(strDir, mode) != 0)) {
670 DHCP_LOGE("CreateDirs() mkdir %{public}s %{public}.4o %{public}d!", strDir, mode, errno);
671 return DHCP_OPT_FAILED;
672 }
673 strDir[i] = '/';
674 }
675 }
676 DHCP_LOGI("CreateDirs() %{public}s %{public}.4o success.", dirs.c_str(), mode);
677 return DHCP_OPT_SUCCESS;
678 }
679
SplitString(const std::string src,const std::string delim,const int count,std::vector<std::string> & splits)680 bool DhcpFunction::SplitString(
681 const std::string src, const std::string delim, const int count, std::vector<std::string> &splits)
682 {
683 if (src.empty() || delim.empty()) {
684 DHCP_LOGE("SplitString() error, src or delim is empty!");
685 return false;
686 }
687
688 splits.clear();
689
690 std::string strData(src);
691 int nDelim = 0;
692 char *pSave = nullptr;
693 char *pTok = strtok_r(const_cast<char *>(strData.c_str()), delim.c_str(), &pSave);
694 while (pTok != nullptr) {
695 splits.push_back(std::string(pTok));
696 nDelim++;
697 pTok = strtok_r(nullptr, delim.c_str(), &pSave);
698 }
699 if (nDelim != count) {
700 DHCP_LOGE("SplitString() %{private}s failed, nDelim:%{public}d,count:%{public}d!", src.c_str(), nDelim, count);
701 return false;
702 }
703 DHCP_LOGI("SplitString() %{private}s success, delim:%{public}s, count:%{public}d, splits.size():%{public}d.",
704 src.c_str(), delim.c_str(), count, (int)splits.size());
705 return true;
706 }
707
WaitProcessExit(const pid_t & serverPid)708 int DhcpFunction::WaitProcessExit(const pid_t& serverPid)
709 {
710 int retryCount = 0;
711 while (retryCount < MAX_RETEY_WAIT_COUNT) {
712 pid_t ret = waitpid(serverPid, nullptr, WNOHANG);
713 if (ret == -1) {
714 DHCP_LOGE("WaitProcessExit() waitpid [%{public}d] failed, errno:%{public}d!", serverPid, errno);
715 return -1;
716 } else if (ret == 0) {
717 retryCount++;
718 usleep(WAIT_SLEEP_50MS);
719 }
720 return 0;
721 }
722 DHCP_LOGE("WaitProcessExit() timeout waitpid [%{public}d] failed!", serverPid);
723 return -1;
724 }
725 } // namespace DHCP
726 } // namespace OHOS