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