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