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 29namespace OHOS { 30namespace DHCP { 31DEFINE_DHCPLOG_DHCP_LABEL("DhcpFunction"); 32 33const int MAX_RETEY_WAIT_COUNT = 60; 34const int WAIT_SLEEP_50MS = 50; 35 36bool 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 64std::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 85bool 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 114std::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 137bool 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 176int 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 228int 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 271int 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 302bool 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 309bool 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 323bool 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 333bool 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 343bool 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 374bool 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 405bool 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 439int 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 485int 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 532int 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 577pid_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 608int 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 640int 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 680bool 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 708int 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