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