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