1518678f8Sopenharmony_ci/* 2518678f8Sopenharmony_ci * Copyright (C) 2021 Huawei Device Co., Ltd. 3518678f8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4518678f8Sopenharmony_ci * you may not use this file except in compliance with the License. 5518678f8Sopenharmony_ci * You may obtain a copy of the License at 6518678f8Sopenharmony_ci * 7518678f8Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8518678f8Sopenharmony_ci * 9518678f8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10518678f8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11518678f8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12518678f8Sopenharmony_ci * See the License for the specific language governing permissions and 13518678f8Sopenharmony_ci * limitations under the License. 14518678f8Sopenharmony_ci */ 15518678f8Sopenharmony_ci#include "dhcp_function.h" 16518678f8Sopenharmony_ci#include <arpa/inet.h> 17518678f8Sopenharmony_ci#include <time.h> 18518678f8Sopenharmony_ci#include <string.h> 19518678f8Sopenharmony_ci#include <sys/types.h> 20518678f8Sopenharmony_ci#include <sys/stat.h> 21518678f8Sopenharmony_ci#include <fcntl.h> 22518678f8Sopenharmony_ci#include <stdlib.h> 23518678f8Sopenharmony_ci#include <sys/socket.h> 24518678f8Sopenharmony_ci#include <unistd.h> 25518678f8Sopenharmony_ci#include <ifaddrs.h> 26518678f8Sopenharmony_ci#include <netdb.h> 27518678f8Sopenharmony_ci#include <net/if.h> 28518678f8Sopenharmony_ci#include <stdio.h> 29518678f8Sopenharmony_ci#include <errno.h> 30518678f8Sopenharmony_ci#include <netinet/in.h> 31518678f8Sopenharmony_ci#include <sys/ioctl.h> 32518678f8Sopenharmony_ci#include "securec.h" 33518678f8Sopenharmony_ci#include "dhcp_client_def.h" 34518678f8Sopenharmony_ci#include "dhcp_logger.h" 35518678f8Sopenharmony_ci 36518678f8Sopenharmony_ciDEFINE_DHCPLOG_DHCP_LABEL("DhcpFunction"); 37518678f8Sopenharmony_ci 38518678f8Sopenharmony_cibool Ip4StrConToInt(const char *strIp, uint32_t *uIp, bool bHost) 39518678f8Sopenharmony_ci{ 40518678f8Sopenharmony_ci if ((strIp == NULL) || (strlen(strIp) == 0)) { 41518678f8Sopenharmony_ci DHCP_LOGE("Ip4StrConToInt failed, strIp == NULL or \"\"!"); 42518678f8Sopenharmony_ci return false; 43518678f8Sopenharmony_ci } 44518678f8Sopenharmony_ci 45518678f8Sopenharmony_ci struct in_addr addr4; 46518678f8Sopenharmony_ci int nRet = inet_pton(AF_INET, strIp, &addr4); 47518678f8Sopenharmony_ci if (nRet != 1) { 48518678f8Sopenharmony_ci DHCP_LOGE("Ip4StrConToInt strIp:%{private}s failed, inet_pton nRet:%{public}d!", strIp, nRet); 49518678f8Sopenharmony_ci if (nRet == 0) { 50518678f8Sopenharmony_ci DHCP_LOGE("Ip4StrConToInt strIp:%{private}s not in presentation format!", strIp); 51518678f8Sopenharmony_ci } else { 52518678f8Sopenharmony_ci DHCP_LOGE("Ip4StrConToInt strIp:%{private}s inet_pton does not contain a valid address family!", strIp); 53518678f8Sopenharmony_ci } 54518678f8Sopenharmony_ci return false; 55518678f8Sopenharmony_ci } 56518678f8Sopenharmony_ci 57518678f8Sopenharmony_ci if (bHost) { 58518678f8Sopenharmony_ci *uIp = ntohl(addr4.s_addr); 59518678f8Sopenharmony_ci } else { 60518678f8Sopenharmony_ci *uIp = addr4.s_addr; 61518678f8Sopenharmony_ci } 62518678f8Sopenharmony_ci 63518678f8Sopenharmony_ci return true; 64518678f8Sopenharmony_ci} 65518678f8Sopenharmony_ci 66518678f8Sopenharmony_cistd::string Ip4IntConvertToStr(uint32_t ip, bool host) 67518678f8Sopenharmony_ci{ 68518678f8Sopenharmony_ci char bufIp4[INET_ADDRSTRLEN] = {0}; 69518678f8Sopenharmony_ci struct in_addr addr4; 70518678f8Sopenharmony_ci if (host) { 71518678f8Sopenharmony_ci addr4.s_addr = htonl(ip); 72518678f8Sopenharmony_ci } else { 73518678f8Sopenharmony_ci addr4.s_addr = ip; 74518678f8Sopenharmony_ci } 75518678f8Sopenharmony_ci 76518678f8Sopenharmony_ci std::string strIp = ""; 77518678f8Sopenharmony_ci if (inet_ntop(AF_INET, &addr4, bufIp4, INET_ADDRSTRLEN) == nullptr) { 78518678f8Sopenharmony_ci DHCP_LOGE("Ip4IntConvertToStr uIp:%{private}u failed, inet_ntop nullptr!", ip); 79518678f8Sopenharmony_ci } else { 80518678f8Sopenharmony_ci strIp = bufIp4; 81518678f8Sopenharmony_ci DHCP_LOGI("Ip4IntConvertToStr uIp:%{private}u -> strIp:%{private}s.", ip, strIp.c_str()); 82518678f8Sopenharmony_ci } 83518678f8Sopenharmony_ci 84518678f8Sopenharmony_ci return strIp; 85518678f8Sopenharmony_ci} 86518678f8Sopenharmony_ci 87518678f8Sopenharmony_cibool Ip6StrConToChar(const char *strIp, uint8_t chIp[], size_t chlen) 88518678f8Sopenharmony_ci{ 89518678f8Sopenharmony_ci if ((strIp == NULL) || (strlen(strIp) == 0)) { 90518678f8Sopenharmony_ci DHCP_LOGE("Ip6StrConToChar failed, strIp == NULL or \"\"!"); 91518678f8Sopenharmony_ci return false; 92518678f8Sopenharmony_ci } 93518678f8Sopenharmony_ci 94518678f8Sopenharmony_ci struct in6_addr addr6; 95518678f8Sopenharmony_ci if (memset_s(&addr6, sizeof(addr6), 0, sizeof(addr6)) != EOK) { 96518678f8Sopenharmony_ci return false; 97518678f8Sopenharmony_ci } 98518678f8Sopenharmony_ci int nRet = inet_pton(AF_INET6, strIp, &addr6); 99518678f8Sopenharmony_ci if (nRet != 1) { 100518678f8Sopenharmony_ci DHCP_LOGE("Ip6StrConToChar strIp:%{private}s failed, inet_pton nRet:%{public}d!", strIp, nRet); 101518678f8Sopenharmony_ci if (nRet == 0) { 102518678f8Sopenharmony_ci DHCP_LOGE("Ip6StrConToChar strIp:%{private}s not in presentation format!", strIp); 103518678f8Sopenharmony_ci } else { 104518678f8Sopenharmony_ci DHCP_LOGE("Ip6StrConToChar strIp:%{private}s inet_pton does not contain a valid address family!", strIp); 105518678f8Sopenharmony_ci } 106518678f8Sopenharmony_ci return false; 107518678f8Sopenharmony_ci } 108518678f8Sopenharmony_ci 109518678f8Sopenharmony_ci DHCP_LOGI("Ip6StrConToChar strIp:%{private}s -> ", strIp); 110518678f8Sopenharmony_ci for (size_t i = 0; (i < chlen) && (i < sizeof(addr6.s6_addr)); i++) { 111518678f8Sopenharmony_ci DHCP_LOGI("Ip6StrConToChar addr6.s6_addr: %{private}zu - %{private}02x", i, addr6.s6_addr[i]); 112518678f8Sopenharmony_ci chIp[i] = addr6.s6_addr[i]; 113518678f8Sopenharmony_ci } 114518678f8Sopenharmony_ci 115518678f8Sopenharmony_ci return true; 116518678f8Sopenharmony_ci} 117518678f8Sopenharmony_ci 118518678f8Sopenharmony_ciconst char *MacChConToMacStr(const unsigned char *pChMac, size_t chLen, char *pStrMac, size_t strLen) 119518678f8Sopenharmony_ci{ 120518678f8Sopenharmony_ci if ((pChMac == NULL) || (chLen == 0)) { 121518678f8Sopenharmony_ci DHCP_LOGE("MacChConToMacStr failed, pChMac == NULL or chLen == 0!"); 122518678f8Sopenharmony_ci return NULL; 123518678f8Sopenharmony_ci } 124518678f8Sopenharmony_ci 125518678f8Sopenharmony_ci if ((pStrMac == NULL) || (strLen < (chLen * MAC_ADDR_CHAR_NUM))) { 126518678f8Sopenharmony_ci DHCP_LOGE("MacChConToMacStr failed, pStrMac == NULL or strLen:%{public}d error!", (int)strLen); 127518678f8Sopenharmony_ci return NULL; 128518678f8Sopenharmony_ci } 129518678f8Sopenharmony_ci 130518678f8Sopenharmony_ci const unsigned char *pSrc = pChMac; 131518678f8Sopenharmony_ci const unsigned char *pSrcEnd = pSrc + chLen; 132518678f8Sopenharmony_ci char *pDest = pStrMac; 133518678f8Sopenharmony_ci for (; pSrc < pSrcEnd; pSrc++) { 134518678f8Sopenharmony_ci /* The first character of pStrMac starts with a letter, not ':'. */ 135518678f8Sopenharmony_ci if (pSrc != pChMac) { 136518678f8Sopenharmony_ci *(pDest++) = ':'; 137518678f8Sopenharmony_ci } 138518678f8Sopenharmony_ci pDest += snprintf_s(pDest, MAC_ADDR_CHAR_NUM, MAC_ADDR_CHAR_NUM - 1, "%.2x", *pSrc); 139518678f8Sopenharmony_ci } 140518678f8Sopenharmony_ci /* The last character of pStrMac ends with '\0'. */ 141518678f8Sopenharmony_ci *(pDest++) = '\0'; 142518678f8Sopenharmony_ci return pStrMac; 143518678f8Sopenharmony_ci} 144518678f8Sopenharmony_ci 145518678f8Sopenharmony_ciint GetLocalInterface(const char *ifname, int *ifindex, unsigned char *hwaddr, uint32_t *ifaddr4) 146518678f8Sopenharmony_ci{ 147518678f8Sopenharmony_ci if ((ifname == NULL) || (strlen(ifname) == 0) || hwaddr == NULL) { 148518678f8Sopenharmony_ci DHCP_LOGE("GetLocalInterface() failed, ifname == NULL or hwaddr is NULL"); 149518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 150518678f8Sopenharmony_ci } 151518678f8Sopenharmony_ci 152518678f8Sopenharmony_ci int fd; 153518678f8Sopenharmony_ci struct ifreq iface; 154518678f8Sopenharmony_ci struct sockaddr_in *pSockIn = NULL; 155518678f8Sopenharmony_ci 156518678f8Sopenharmony_ci if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 157518678f8Sopenharmony_ci DHCP_LOGE("GetLocalInterface() ifname:%{public}s failed, socket err:%{public}d!", ifname, errno); 158518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 159518678f8Sopenharmony_ci } 160518678f8Sopenharmony_ci 161518678f8Sopenharmony_ci if (memset_s(&iface, sizeof(iface), 0, sizeof(iface)) != EOK) { 162518678f8Sopenharmony_ci DHCP_LOGE("GetLocalInterface() ifname:%{public}s failed, memset_s error!", ifname); 163518678f8Sopenharmony_ci close(fd); 164518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 165518678f8Sopenharmony_ci } 166518678f8Sopenharmony_ci if (strncpy_s(iface.ifr_name, sizeof(iface.ifr_name), ifname, strlen(ifname)) != EOK) { 167518678f8Sopenharmony_ci DHCP_LOGE("GetLocalInterface() ifname:%{public}s failed, strncpy_s error!", ifname); 168518678f8Sopenharmony_ci close(fd); 169518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 170518678f8Sopenharmony_ci } 171518678f8Sopenharmony_ci 172518678f8Sopenharmony_ci if (ioctl(fd, SIOCGIFINDEX, &iface) != 0) { 173518678f8Sopenharmony_ci DHCP_LOGE("GetLocalInterface() %{public}s failed, SIOCGIFINDEX err:%{public}d!", ifname, errno); 174518678f8Sopenharmony_ci close(fd); 175518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 176518678f8Sopenharmony_ci } 177518678f8Sopenharmony_ci *ifindex = iface.ifr_ifindex; 178518678f8Sopenharmony_ci 179518678f8Sopenharmony_ci if (ioctl(fd, SIOCGIFHWADDR, &iface) != 0) { 180518678f8Sopenharmony_ci DHCP_LOGE("GetLocalInterface() %{public}s failed, SIOCGIFHWADDR err:%{public}d!", ifname, errno); 181518678f8Sopenharmony_ci close(fd); 182518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 183518678f8Sopenharmony_ci } 184518678f8Sopenharmony_ci if (memcpy_s(hwaddr, MAC_ADDR_LEN, iface.ifr_hwaddr.sa_data, MAC_ADDR_LEN) != EOK) { 185518678f8Sopenharmony_ci DHCP_LOGE("GetLocalInterface() ifname:%{public}s failed, memcpy_s error!", ifname); 186518678f8Sopenharmony_ci close(fd); 187518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 188518678f8Sopenharmony_ci } 189518678f8Sopenharmony_ci 190518678f8Sopenharmony_ci if (ifaddr4 != NULL) { 191518678f8Sopenharmony_ci if (ioctl(fd, SIOCGIFADDR, &iface) < 0) { 192518678f8Sopenharmony_ci DHCP_LOGE("GetLocalInterface() %{public}s failed, SIOCGIFADDR err:%{public}d!", ifname, errno); 193518678f8Sopenharmony_ci close(fd); 194518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 195518678f8Sopenharmony_ci } 196518678f8Sopenharmony_ci pSockIn = (struct sockaddr_in *)&iface.ifr_addr; 197518678f8Sopenharmony_ci *ifaddr4 = pSockIn->sin_addr.s_addr; 198518678f8Sopenharmony_ci } 199518678f8Sopenharmony_ci close(fd); 200518678f8Sopenharmony_ci return DHCP_OPT_SUCCESS; 201518678f8Sopenharmony_ci} 202518678f8Sopenharmony_ci 203518678f8Sopenharmony_ciint GetLocalIp(const char *ifname, uint32_t *ifaddr4) 204518678f8Sopenharmony_ci{ 205518678f8Sopenharmony_ci if ((ifname == NULL) || (strlen(ifname) == 0)) { 206518678f8Sopenharmony_ci DHCP_LOGE("GetLocalIp() failed, ifname == NULL or \"\"!"); 207518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 208518678f8Sopenharmony_ci } 209518678f8Sopenharmony_ci 210518678f8Sopenharmony_ci struct ifaddrs *ifaddr = NULL; 211518678f8Sopenharmony_ci struct ifaddrs *ifa = NULL; 212518678f8Sopenharmony_ci int family, s; 213518678f8Sopenharmony_ci char strIp[NI_MAXHOST]; 214518678f8Sopenharmony_ci 215518678f8Sopenharmony_ci if (getifaddrs(&ifaddr) == -1) { 216518678f8Sopenharmony_ci DHCP_LOGE("GetLocalIp() ifname:%{public}s failed, getifaddrs error:%{public}d!", ifname, errno); 217518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 218518678f8Sopenharmony_ci } 219518678f8Sopenharmony_ci 220518678f8Sopenharmony_ci for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { 221518678f8Sopenharmony_ci if (strcmp(ifa->ifa_name, ifname) != 0) { 222518678f8Sopenharmony_ci continue; 223518678f8Sopenharmony_ci } 224518678f8Sopenharmony_ci 225518678f8Sopenharmony_ci if (ifa->ifa_addr == NULL) { 226518678f8Sopenharmony_ci DHCP_LOGE("GetLocalIp() ifname:%{public}s failed, ifa->ifa_addr == NULL!", ifname); 227518678f8Sopenharmony_ci continue; 228518678f8Sopenharmony_ci } 229518678f8Sopenharmony_ci 230518678f8Sopenharmony_ci family = ifa->ifa_addr->sa_family; 231518678f8Sopenharmony_ci if ((family != AF_INET) && (family != AF_INET6)) { 232518678f8Sopenharmony_ci continue; 233518678f8Sopenharmony_ci } 234518678f8Sopenharmony_ci 235518678f8Sopenharmony_ci if (memset_s(strIp, sizeof(strIp), 0, sizeof(strIp)) != EOK) { 236518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 237518678f8Sopenharmony_ci } 238518678f8Sopenharmony_ci s = getnameinfo(ifa->ifa_addr, (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), 239518678f8Sopenharmony_ci strIp, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); 240518678f8Sopenharmony_ci if (s != 0) { 241518678f8Sopenharmony_ci DHCP_LOGE("GetLocalIp() %{public}s failed, getnameinfo error:%{public}s!", ifname, gai_strerror(s)); 242518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 243518678f8Sopenharmony_ci } 244518678f8Sopenharmony_ci 245518678f8Sopenharmony_ci /* Output all ip with ifa_name is ifname and family is AF_INET or AF_INET6. */ 246518678f8Sopenharmony_ci if (family == AF_INET) { 247518678f8Sopenharmony_ci uint32_t hostIp = 0; 248518678f8Sopenharmony_ci if (!Ip4StrConToInt(strIp, &hostIp, true)) { 249518678f8Sopenharmony_ci DHCP_LOGE("GetLocalIp() %{public}s failed, Ip4StrConToInt strIp:%{private}s error!", ifname, strIp); 250518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 251518678f8Sopenharmony_ci } 252518678f8Sopenharmony_ci DHCP_LOGI("GetLocalIp() %{public}s, AF_INET str:%{private}s -> host:%{private}u.", ifname, strIp, hostIp); 253518678f8Sopenharmony_ci *ifaddr4 = hostIp; 254518678f8Sopenharmony_ci } else { 255518678f8Sopenharmony_ci DHCP_LOGI("GetLocalIp() %{public}s, AF_INET6 strIp:%{private}s.", ifname, strIp); 256518678f8Sopenharmony_ci } 257518678f8Sopenharmony_ci } 258518678f8Sopenharmony_ci 259518678f8Sopenharmony_ci freeifaddrs(ifaddr); 260518678f8Sopenharmony_ci return DHCP_OPT_SUCCESS; 261518678f8Sopenharmony_ci} 262518678f8Sopenharmony_ci 263518678f8Sopenharmony_ciint SetIpOrMask(const char *ifname, int fd, uint32_t netAddr, unsigned long cmd) 264518678f8Sopenharmony_ci{ 265518678f8Sopenharmony_ci struct ifreq ifr; 266518678f8Sopenharmony_ci struct sockaddr_in sin; 267518678f8Sopenharmony_ci if (memset_s(&ifr, sizeof(struct ifreq), 0, sizeof(struct ifreq)) != EOK) { 268518678f8Sopenharmony_ci DHCP_LOGE("SetIpOrMask() failed, memset_s ifr error!"); 269518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 270518678f8Sopenharmony_ci } 271518678f8Sopenharmony_ci 272518678f8Sopenharmony_ci if (strncpy_s(ifr.ifr_name, sizeof(ifr.ifr_name), ifname, strlen(ifname)) != EOK) { 273518678f8Sopenharmony_ci DHCP_LOGE("SetIpOrMask() %{public}s failed, , strncpy_s ifr.ifr_name error!", ifname); 274518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 275518678f8Sopenharmony_ci } 276518678f8Sopenharmony_ci 277518678f8Sopenharmony_ci if (memset_s(&sin, sizeof(struct sockaddr_in), 0, sizeof(struct sockaddr_in)) != EOK) { 278518678f8Sopenharmony_ci DHCP_LOGE("SetIpOrMask() failed, memset_s sin error!"); 279518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 280518678f8Sopenharmony_ci } 281518678f8Sopenharmony_ci sin.sin_family = AF_INET; 282518678f8Sopenharmony_ci sin.sin_addr.s_addr = netAddr; 283518678f8Sopenharmony_ci if (memcpy_s(&ifr.ifr_addr, sizeof(ifr.ifr_addr), &sin, sizeof(struct sockaddr)) != EOK) { 284518678f8Sopenharmony_ci DHCP_LOGE("SetIpOrMask() failed, memcpy_s ifr.ifr_addr error!"); 285518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 286518678f8Sopenharmony_ci } 287518678f8Sopenharmony_ci 288518678f8Sopenharmony_ci if (ioctl(fd, cmd, &ifr) < 0) { 289518678f8Sopenharmony_ci DHCP_LOGE("SetIpOrMask() %{public}s failed!", ifname); 290518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 291518678f8Sopenharmony_ci } 292518678f8Sopenharmony_ci return DHCP_OPT_SUCCESS; 293518678f8Sopenharmony_ci} 294518678f8Sopenharmony_ci 295518678f8Sopenharmony_ciint SetLocalInterface(const char *ifname, uint32_t ipAddr, uint32_t netMask) 296518678f8Sopenharmony_ci{ 297518678f8Sopenharmony_ci if ((ifname == NULL) || (strlen(ifname) == 0)) { 298518678f8Sopenharmony_ci DHCP_LOGE("SetLocalInterface() failed, ifname == NULL or \"\"!"); 299518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 300518678f8Sopenharmony_ci } 301518678f8Sopenharmony_ci 302518678f8Sopenharmony_ci int fd = socket(AF_INET, SOCK_DGRAM, 0); 303518678f8Sopenharmony_ci if (fd < 0) { 304518678f8Sopenharmony_ci DHCP_LOGE("SetLocalInterface() ifname:%{public}s failed, socket error:%{public}d!", ifname, errno); 305518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 306518678f8Sopenharmony_ci } 307518678f8Sopenharmony_ci 308518678f8Sopenharmony_ci if (SetIpOrMask(ifname, fd, ipAddr, SIOCSIFADDR) != DHCP_OPT_SUCCESS) { 309518678f8Sopenharmony_ci close(fd); 310518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 311518678f8Sopenharmony_ci } 312518678f8Sopenharmony_ci 313518678f8Sopenharmony_ci if (SetIpOrMask(ifname, fd, netMask, SIOCSIFNETMASK) != DHCP_OPT_SUCCESS) { 314518678f8Sopenharmony_ci close(fd); 315518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 316518678f8Sopenharmony_ci } 317518678f8Sopenharmony_ci close(fd); 318518678f8Sopenharmony_ci return DHCP_OPT_SUCCESS; 319518678f8Sopenharmony_ci} 320518678f8Sopenharmony_ci 321518678f8Sopenharmony_ciint InitPidfile(const char *pidDir, const char *pidFile, pid_t pid) 322518678f8Sopenharmony_ci{ 323518678f8Sopenharmony_ci if ((pidDir == NULL) || (strlen(pidDir) == 0) || (pidFile == NULL) || (strlen(pidFile) == 0)) { 324518678f8Sopenharmony_ci DHCP_LOGE("InitPidfile() failed, pidDir or pidFile == NULL or \"\"!"); 325518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 326518678f8Sopenharmony_ci } 327518678f8Sopenharmony_ci DHCP_LOGI("InitPidfile() pidDir:%{public}s, pidFile:%{public}s.", pidDir, pidFile); 328518678f8Sopenharmony_ci unlink(pidFile); 329518678f8Sopenharmony_ci 330518678f8Sopenharmony_ci int fd; 331518678f8Sopenharmony_ci if ((fd = open(pidFile, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) { 332518678f8Sopenharmony_ci DHCP_LOGE("InitPidfile() failed, open pidFile:%{public}s error:%{public}d!", pidFile, errno); 333518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 334518678f8Sopenharmony_ci } 335518678f8Sopenharmony_ci 336518678f8Sopenharmony_ci char buf[PID_MAX_LEN] = {0}; 337518678f8Sopenharmony_ci if (snprintf_s(buf, PID_MAX_LEN, PID_MAX_LEN - 1, "%d", pid) < 0) { 338518678f8Sopenharmony_ci DHCP_LOGE("InitPidfile() pidFile:%{public}s failed, snprintf_s error:%{public}d!", pidFile, errno); 339518678f8Sopenharmony_ci close(fd); 340518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 341518678f8Sopenharmony_ci } 342518678f8Sopenharmony_ci ssize_t bytes; 343518678f8Sopenharmony_ci if ((bytes = write(fd, buf, strlen(buf))) <= 0) { 344518678f8Sopenharmony_ci DHCP_LOGE("InitPidfile() failed, write pidFile:%{public}s error:%{public}d, bytes:%{public}zd!", 345518678f8Sopenharmony_ci pidFile, errno, bytes); 346518678f8Sopenharmony_ci close(fd); 347518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 348518678f8Sopenharmony_ci } 349518678f8Sopenharmony_ci DHCP_LOGI("InitPidfile() buf:%{public}s write pidFile:%{public}s, bytes:%{public}zd!", buf, pidFile, bytes); 350518678f8Sopenharmony_ci close(fd); 351518678f8Sopenharmony_ci 352518678f8Sopenharmony_ci if (chdir(pidDir) != 0) { 353518678f8Sopenharmony_ci DHCP_LOGE("InitPidfile() failed, chdir pidDir:%{public}s error:%{public}d!", pidDir, errno); 354518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 355518678f8Sopenharmony_ci } 356518678f8Sopenharmony_ci 357518678f8Sopenharmony_ci /* Set default permissions for the specified client process id files and directories. */ 358518678f8Sopenharmony_ci umask(DEFAULT_UMASK); 359518678f8Sopenharmony_ci 360518678f8Sopenharmony_ci /* Change attribs to the specified client process id files: 644 (user=rw, group=r, other=r). */ 361518678f8Sopenharmony_ci chmod(pidFile, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 362518678f8Sopenharmony_ci 363518678f8Sopenharmony_ci return DHCP_OPT_SUCCESS; 364518678f8Sopenharmony_ci} 365518678f8Sopenharmony_ci 366518678f8Sopenharmony_cipid_t GetPID(const char *pidFile) 367518678f8Sopenharmony_ci{ 368518678f8Sopenharmony_ci /* Check pidFile is or not exists. */ 369518678f8Sopenharmony_ci struct stat sb; 370518678f8Sopenharmony_ci if (stat(pidFile, &sb) != 0) { 371518678f8Sopenharmony_ci DHCP_LOGW("GetPID() pidFile:%{public}s stat error:%{public}d!", pidFile, errno); 372518678f8Sopenharmony_ci return -1; 373518678f8Sopenharmony_ci } 374518678f8Sopenharmony_ci DHCP_LOGI("GetPID() pidFile:%{public}s stat st_size:%{public}d.", pidFile, (int)sb.st_size); 375518678f8Sopenharmony_ci 376518678f8Sopenharmony_ci int fd; 377518678f8Sopenharmony_ci if ((fd = open(pidFile, O_RDONLY)) < 0) { 378518678f8Sopenharmony_ci DHCP_LOGE("GetPID() failed, open pidFile:%{public}s error!", pidFile); 379518678f8Sopenharmony_ci return -1; 380518678f8Sopenharmony_ci } 381518678f8Sopenharmony_ci 382518678f8Sopenharmony_ci lseek(fd, 0, SEEK_SET); 383518678f8Sopenharmony_ci 384518678f8Sopenharmony_ci char buf[PID_MAX_LEN] = {0}; 385518678f8Sopenharmony_ci if (sb.st_size > PID_MAX_LEN) { 386518678f8Sopenharmony_ci DHCP_LOGE("GetPID() invalid length, size:%{public}d", (int)sb.st_size); 387518678f8Sopenharmony_ci return -1; 388518678f8Sopenharmony_ci } 389518678f8Sopenharmony_ci ssize_t bytes; 390518678f8Sopenharmony_ci if ((bytes = read(fd, buf, sb.st_size)) < 0) { 391518678f8Sopenharmony_ci DHCP_LOGE("GetPID() failed, read pidFile:%{public}s error, bytes:%{public}zd!", pidFile, bytes); 392518678f8Sopenharmony_ci close(fd); 393518678f8Sopenharmony_ci return -1; 394518678f8Sopenharmony_ci } 395518678f8Sopenharmony_ci DHCP_LOGI("GetPID() read pidFile:%{public}s, buf:%{public}s, bytes:%{public}zd.", pidFile, buf, bytes); 396518678f8Sopenharmony_ci close(fd); 397518678f8Sopenharmony_ci 398518678f8Sopenharmony_ci return atoi(buf); 399518678f8Sopenharmony_ci} 400518678f8Sopenharmony_ci 401518678f8Sopenharmony_ciint CreateDirs(const char *dirs, int mode) 402518678f8Sopenharmony_ci{ 403518678f8Sopenharmony_ci if ((dirs == NULL) || (strlen(dirs) == 0) || (strlen(dirs) >= DIR_MAX_LEN)) { 404518678f8Sopenharmony_ci DHCP_LOGE("CreateDirs() dirs:%{public}s error!", dirs); 405518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 406518678f8Sopenharmony_ci } 407518678f8Sopenharmony_ci 408518678f8Sopenharmony_ci int nSrcLen = (int)strlen(dirs); 409518678f8Sopenharmony_ci char strDir[DIR_MAX_LEN] = {0}; 410518678f8Sopenharmony_ci if (strncpy_s(strDir, sizeof(strDir), dirs, strlen(dirs)) != EOK) { 411518678f8Sopenharmony_ci DHCP_LOGE("CreateDirs() strncpy_s dirs:%{public}s failed!", dirs); 412518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 413518678f8Sopenharmony_ci } 414518678f8Sopenharmony_ci if (strDir[nSrcLen - 1] != '/') { 415518678f8Sopenharmony_ci if (nSrcLen == (DIR_MAX_LEN - 1)) { 416518678f8Sopenharmony_ci DHCP_LOGE("CreateDirs() dirs:%{public}s len:%{public}d error!", dirs, nSrcLen); 417518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 418518678f8Sopenharmony_ci } 419518678f8Sopenharmony_ci if (strcat_s(strDir, sizeof(strDir), "/") != EOK) { 420518678f8Sopenharmony_ci DHCP_LOGE("CreateDirs() strcat_s strDir:%{public}s failed!", strDir); 421518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 422518678f8Sopenharmony_ci } 423518678f8Sopenharmony_ci nSrcLen++; 424518678f8Sopenharmony_ci } 425518678f8Sopenharmony_ci 426518678f8Sopenharmony_ci int i = (strDir[0] == '/') ? 1 : 0; 427518678f8Sopenharmony_ci for (; i <= nSrcLen - 1; i++) { 428518678f8Sopenharmony_ci if (strDir[i] == '/') { 429518678f8Sopenharmony_ci strDir[i] = 0; 430518678f8Sopenharmony_ci if ((access(strDir, F_OK) != 0) && (mkdir(strDir, mode) != 0)) { 431518678f8Sopenharmony_ci DHCP_LOGE("CreateDirs() mkdir %{public}s %{public}.4o failed:%{public}d!", strDir, mode, errno); 432518678f8Sopenharmony_ci return DHCP_OPT_FAILED; 433518678f8Sopenharmony_ci } 434518678f8Sopenharmony_ci strDir[i] = '/'; 435518678f8Sopenharmony_ci } 436518678f8Sopenharmony_ci } 437518678f8Sopenharmony_ci DHCP_LOGI("CreateDirs() %{public}s %{public}.4o success.", dirs, mode); 438518678f8Sopenharmony_ci return DHCP_OPT_SUCCESS; 439518678f8Sopenharmony_ci} 440