1518678f8Sopenharmony_ci/*
2518678f8Sopenharmony_ci * Copyright (C) 2021-2022 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
16518678f8Sopenharmony_ci#include <errno.h>
17518678f8Sopenharmony_ci#include <signal.h>
18518678f8Sopenharmony_ci#include <stdint.h>
19518678f8Sopenharmony_ci#include <stdio.h>
20518678f8Sopenharmony_ci#include <stdlib.h>
21518678f8Sopenharmony_ci#include "dhcp_dhcpd.h"
22518678f8Sopenharmony_ci#include "securec.h"
23518678f8Sopenharmony_ci#include "address_utils.h"
24518678f8Sopenharmony_ci#include "dhcp_address_pool.h"
25518678f8Sopenharmony_ci#include "dhcp_argument.h"
26518678f8Sopenharmony_ci#include "dhcp_config.h"
27518678f8Sopenharmony_ci#include "dhcp_s_define.h"
28518678f8Sopenharmony_ci#include "dhcp_server_ipv4.h"
29518678f8Sopenharmony_ci#include "dhcp_logger.h"
30518678f8Sopenharmony_ci#include "dhcp_option.h"
31518678f8Sopenharmony_ci#include "dhcp_s_server.h"
32518678f8Sopenharmony_ci#include "dhcp_common_utils.h"
33518678f8Sopenharmony_ci
34518678f8Sopenharmony_ciDEFINE_DHCPLOG_DHCP_LABEL("DhcpServerMain");
35518678f8Sopenharmony_ci
36518678f8Sopenharmony_ci#define DEFAUTL_NET_MASK "255.255.255.0"
37518678f8Sopenharmony_ci
38518678f8Sopenharmony_cistatic DhcpConfig g_dhcpConfig;
39518678f8Sopenharmony_ci
40518678f8Sopenharmony_cistatic PDhcpServerContext g_dhcpServer = 0;
41518678f8Sopenharmony_cistatic DeviceConnectFun deviceConnectFun;
42518678f8Sopenharmony_cienum SignalEvent {
43518678f8Sopenharmony_ci    EXIT = 0,
44518678f8Sopenharmony_ci    RELOAD,
45518678f8Sopenharmony_ci    RESTART,
46518678f8Sopenharmony_ci};
47518678f8Sopenharmony_ci
48518678f8Sopenharmony_civoid LoadLocalConfig(DhcpAddressPool *pool)
49518678f8Sopenharmony_ci{
50518678f8Sopenharmony_ci    DHCP_LOGD("loading local configure ...");
51518678f8Sopenharmony_ci}
52518678f8Sopenharmony_ci
53518678f8Sopenharmony_civoid ReloadLocalConfig(DhcpAddressPool *pool)
54518678f8Sopenharmony_ci{
55518678f8Sopenharmony_ci    DHCP_LOGD("reloading local configure ...");
56518678f8Sopenharmony_ci}
57518678f8Sopenharmony_ci
58518678f8Sopenharmony_cistatic int InitNetworkAbout(DhcpConfig *config)
59518678f8Sopenharmony_ci{
60518678f8Sopenharmony_ci    ArgumentInfo *arg = GetArgument("netmask");
61518678f8Sopenharmony_ci    if (arg) {
62518678f8Sopenharmony_ci        DHCP_LOGI("subnet mask:%s", arg->value);
63518678f8Sopenharmony_ci        uint32_t argNetmask = ParseIpAddr(arg->value);
64518678f8Sopenharmony_ci        if (argNetmask) {
65518678f8Sopenharmony_ci            config->netmask = argNetmask;
66518678f8Sopenharmony_ci        } else {
67518678f8Sopenharmony_ci            DHCP_LOGW("error netmask argument.");
68518678f8Sopenharmony_ci            return RET_FAILED;
69518678f8Sopenharmony_ci        }
70518678f8Sopenharmony_ci    } else {
71518678f8Sopenharmony_ci        if (!config->netmask) {
72518678f8Sopenharmony_ci            config->netmask = ParseIpAddr(DEFAUTL_NET_MASK);
73518678f8Sopenharmony_ci        }
74518678f8Sopenharmony_ci    }
75518678f8Sopenharmony_ci    arg = GetArgument("gateway");
76518678f8Sopenharmony_ci    if (arg) {
77518678f8Sopenharmony_ci        DHCP_LOGI("gateway:%s", arg->value);
78518678f8Sopenharmony_ci        uint32_t argGateway = ParseIpAddr(arg->value);
79518678f8Sopenharmony_ci        if (argGateway) {
80518678f8Sopenharmony_ci            config->gateway = argGateway;
81518678f8Sopenharmony_ci        } else {
82518678f8Sopenharmony_ci            DHCP_LOGE("error gateway argument.");
83518678f8Sopenharmony_ci            return RET_FAILED;
84518678f8Sopenharmony_ci        }
85518678f8Sopenharmony_ci    } else {
86518678f8Sopenharmony_ci        config->gateway = config->serverId;
87518678f8Sopenharmony_ci        DHCP_LOGW("InitNetworkAbout, set gateway to serverId as default.");
88518678f8Sopenharmony_ci    }
89518678f8Sopenharmony_ci    return RET_SUCCESS;
90518678f8Sopenharmony_ci}
91518678f8Sopenharmony_ci
92518678f8Sopenharmony_cistatic int PareseAddreesRange(DhcpConfig *config)
93518678f8Sopenharmony_ci{
94518678f8Sopenharmony_ci    ArgumentInfo *arg = GetArgument("pool");
95518678f8Sopenharmony_ci    if (arg) {
96518678f8Sopenharmony_ci        DHCP_LOGD("pool info:%s", arg->value);
97518678f8Sopenharmony_ci        int index = 0;
98518678f8Sopenharmony_ci        char *src = arg->value;
99518678f8Sopenharmony_ci        constexpr const char *delim = ",";
100518678f8Sopenharmony_ci        char *pSave = nullptr;
101518678f8Sopenharmony_ci        char *poolPartArg;
102518678f8Sopenharmony_ci        poolPartArg = strtok_r(src, delim, &pSave);
103518678f8Sopenharmony_ci        while (poolPartArg) {
104518678f8Sopenharmony_ci            if (index == 0) {
105518678f8Sopenharmony_ci                config->pool.beginAddress = ParseIpAddr(poolPartArg);
106518678f8Sopenharmony_ci                DHCP_LOGD("address range begin of: %s", poolPartArg);
107518678f8Sopenharmony_ci            } else if (index == 1) {
108518678f8Sopenharmony_ci                config->pool.endAddress = ParseIpAddr(poolPartArg);
109518678f8Sopenharmony_ci                DHCP_LOGD("address range end of: %s", poolPartArg);
110518678f8Sopenharmony_ci            }
111518678f8Sopenharmony_ci            index++;
112518678f8Sopenharmony_ci            poolPartArg = strtok_r(nullptr, delim, &pSave);
113518678f8Sopenharmony_ci        }
114518678f8Sopenharmony_ci        if (!config->pool.beginAddress || !config->pool.endAddress) {
115518678f8Sopenharmony_ci            DHCP_LOGE("'pool' argument format error.");
116518678f8Sopenharmony_ci            return RET_FAILED;
117518678f8Sopenharmony_ci        }
118518678f8Sopenharmony_ci        return RET_SUCCESS;
119518678f8Sopenharmony_ci    }
120518678f8Sopenharmony_ci    DHCP_LOGW("failed to get 'pool' argument.");
121518678f8Sopenharmony_ci    return RET_FAILED;
122518678f8Sopenharmony_ci}
123518678f8Sopenharmony_ci
124518678f8Sopenharmony_cistatic int InitAddressRange(DhcpConfig *config)
125518678f8Sopenharmony_ci{
126518678f8Sopenharmony_ci    if (HasArgument("pool")) {
127518678f8Sopenharmony_ci        if (PareseAddreesRange(config) != RET_SUCCESS) {
128518678f8Sopenharmony_ci            DHCP_LOGW("dhcp range config error.");
129518678f8Sopenharmony_ci            return RET_FAILED;
130518678f8Sopenharmony_ci        }
131518678f8Sopenharmony_ci    } else {
132518678f8Sopenharmony_ci        if (!config->pool.beginAddress || !config->pool.endAddress) {
133518678f8Sopenharmony_ci            config->pool.beginAddress = FirstIpAddress(config->serverId, config->netmask);
134518678f8Sopenharmony_ci            config->pool.endAddress = LastIpAddress(config->serverId, config->netmask);
135518678f8Sopenharmony_ci        }
136518678f8Sopenharmony_ci    }
137518678f8Sopenharmony_ci    return RET_SUCCESS;
138518678f8Sopenharmony_ci}
139518678f8Sopenharmony_ci
140518678f8Sopenharmony_cistatic int InitDomainNameServer(DhcpConfig *config)
141518678f8Sopenharmony_ci{
142518678f8Sopenharmony_ci    DhcpOption argOpt = {DOMAIN_NAME_SERVER_OPTION, 0, {0}};
143518678f8Sopenharmony_ci    ArgumentInfo *arg = GetArgument("dns");
144518678f8Sopenharmony_ci    uint32_t dnsAddress = 0;
145518678f8Sopenharmony_ci    if (arg) {
146518678f8Sopenharmony_ci        char *pSave = nullptr;
147518678f8Sopenharmony_ci        char *pTok = strtok_r(arg->value, ",", &pSave);
148518678f8Sopenharmony_ci        if ((pTok == nullptr) || (strlen(pTok) == 0)) {
149518678f8Sopenharmony_ci            DHCP_LOGE("strtok_r pTok nullptr or len is 0!");
150518678f8Sopenharmony_ci            return RET_FAILED;
151518678f8Sopenharmony_ci        }
152518678f8Sopenharmony_ci        while (pTok != nullptr) {
153518678f8Sopenharmony_ci            if ((dnsAddress = ParseIpAddr(pTok)) == 0) {
154518678f8Sopenharmony_ci                DHCP_LOGE("ParseIpAddr %s failed, code:%d", pTok, argOpt.code);
155518678f8Sopenharmony_ci                return RET_FAILED;
156518678f8Sopenharmony_ci            }
157518678f8Sopenharmony_ci            if (AppendAddressOption(&argOpt, dnsAddress) != RET_SUCCESS) {
158518678f8Sopenharmony_ci                DHCP_LOGW("failed to append dns option.");
159518678f8Sopenharmony_ci            }
160518678f8Sopenharmony_ci            pTok = strtok_r(nullptr, ",", &pSave);
161518678f8Sopenharmony_ci        }
162518678f8Sopenharmony_ci    } else {
163518678f8Sopenharmony_ci        DHCP_LOGW("%{public}s, set dns to serverId as default.", __func__);
164518678f8Sopenharmony_ci        dnsAddress = config->serverId;
165518678f8Sopenharmony_ci        if (AppendAddressOption(&argOpt, dnsAddress) != RET_SUCCESS) {
166518678f8Sopenharmony_ci            DHCP_LOGW("failed to append dns option.");
167518678f8Sopenharmony_ci        }
168518678f8Sopenharmony_ci    }
169518678f8Sopenharmony_ci
170518678f8Sopenharmony_ci    if (GetOption(&config->options, argOpt.code) != nullptr) {
171518678f8Sopenharmony_ci        RemoveOption(&config->options, DOMAIN_NAME_SERVER_OPTION);
172518678f8Sopenharmony_ci    }
173518678f8Sopenharmony_ci    PushBackOption(&config->options, &argOpt);
174518678f8Sopenharmony_ci    return RET_SUCCESS;
175518678f8Sopenharmony_ci}
176518678f8Sopenharmony_ci
177518678f8Sopenharmony_cistatic int InitServerId(DhcpConfig *config)
178518678f8Sopenharmony_ci{
179518678f8Sopenharmony_ci    ArgumentInfo *arg = GetArgument("server");
180518678f8Sopenharmony_ci    if (arg) {
181518678f8Sopenharmony_ci        DHCP_LOGI("server id:%s", arg->value);
182518678f8Sopenharmony_ci        uint32_t argServerId = ParseIpAddr(arg->value);
183518678f8Sopenharmony_ci        if (argServerId) {
184518678f8Sopenharmony_ci            config->serverId = argServerId;
185518678f8Sopenharmony_ci        } else {
186518678f8Sopenharmony_ci            DHCP_LOGE("error server argument.");
187518678f8Sopenharmony_ci            return RET_FAILED;
188518678f8Sopenharmony_ci        }
189518678f8Sopenharmony_ci    } else {
190518678f8Sopenharmony_ci        if (!config->serverId) {
191518678f8Sopenharmony_ci            DHCP_LOGE("failed to get 'server' argument or config item.");
192518678f8Sopenharmony_ci            return RET_FAILED;
193518678f8Sopenharmony_ci        }
194518678f8Sopenharmony_ci    }
195518678f8Sopenharmony_ci    return RET_SUCCESS;
196518678f8Sopenharmony_ci}
197518678f8Sopenharmony_ci
198518678f8Sopenharmony_cistatic int InitLeaseTime(DhcpConfig *config)
199518678f8Sopenharmony_ci{
200518678f8Sopenharmony_ci    ArgumentInfo *arg = GetArgument("lease");
201518678f8Sopenharmony_ci    if (arg) {
202518678f8Sopenharmony_ci        std::string strValue = arg->value;
203518678f8Sopenharmony_ci        config->leaseTime = static_cast<uint32_t>(OHOS::DHCP::CheckDataLegal(strValue));
204518678f8Sopenharmony_ci    } else {
205518678f8Sopenharmony_ci        if (!config->leaseTime) {
206518678f8Sopenharmony_ci            config->leaseTime = DHCP_LEASE_TIME;
207518678f8Sopenharmony_ci        }
208518678f8Sopenharmony_ci    }
209518678f8Sopenharmony_ci    return RET_SUCCESS;
210518678f8Sopenharmony_ci}
211518678f8Sopenharmony_ci
212518678f8Sopenharmony_cistatic int InitRenewalTime(DhcpConfig *config)
213518678f8Sopenharmony_ci{
214518678f8Sopenharmony_ci    ArgumentInfo *arg = GetArgument("renewal");
215518678f8Sopenharmony_ci    if (arg) {
216518678f8Sopenharmony_ci        std::string strValue = arg->value;
217518678f8Sopenharmony_ci        config->renewalTime = static_cast<uint32_t>(OHOS::DHCP::CheckDataLegal(strValue));
218518678f8Sopenharmony_ci    } else {
219518678f8Sopenharmony_ci        if (!config->rebindingTime) {
220518678f8Sopenharmony_ci            config->rebindingTime = DHCP_RENEWAL_TIME;
221518678f8Sopenharmony_ci        }
222518678f8Sopenharmony_ci        config->renewalTime = DHCP_RENEWAL_TIME;
223518678f8Sopenharmony_ci    }
224518678f8Sopenharmony_ci    return RET_SUCCESS;
225518678f8Sopenharmony_ci}
226518678f8Sopenharmony_ci
227518678f8Sopenharmony_cistatic int InitRebindingTime(DhcpConfig *config)
228518678f8Sopenharmony_ci{
229518678f8Sopenharmony_ci    ArgumentInfo *arg = GetArgument("rebinding");
230518678f8Sopenharmony_ci    if (arg) {
231518678f8Sopenharmony_ci        std::string strValue = arg->value;
232518678f8Sopenharmony_ci        config->rebindingTime = static_cast<uint32_t>(OHOS::DHCP::CheckDataLegal(strValue));
233518678f8Sopenharmony_ci    } else {
234518678f8Sopenharmony_ci        if (!config->rebindingTime) {
235518678f8Sopenharmony_ci            config->rebindingTime =  DHCP_REBINDING_TIME;
236518678f8Sopenharmony_ci        }
237518678f8Sopenharmony_ci    }
238518678f8Sopenharmony_ci    return RET_SUCCESS;
239518678f8Sopenharmony_ci}
240518678f8Sopenharmony_cistatic int InitConfigByArguments(DhcpConfig *config)
241518678f8Sopenharmony_ci{
242518678f8Sopenharmony_ci    if (!config) {
243518678f8Sopenharmony_ci        DHCP_LOGE("dhcp configure pointer is null.");
244518678f8Sopenharmony_ci        return RET_FAILED;
245518678f8Sopenharmony_ci    }
246518678f8Sopenharmony_ci    if (InitServerId(config) != RET_SUCCESS) {
247518678f8Sopenharmony_ci        return RET_FAILED;
248518678f8Sopenharmony_ci    }
249518678f8Sopenharmony_ci    if (InitNetworkAbout(config) != RET_SUCCESS) {
250518678f8Sopenharmony_ci        return RET_FAILED;
251518678f8Sopenharmony_ci    }
252518678f8Sopenharmony_ci    if (InitAddressRange(config) != RET_SUCCESS) {
253518678f8Sopenharmony_ci        return RET_FAILED;
254518678f8Sopenharmony_ci    }
255518678f8Sopenharmony_ci    if (InitLeaseTime(config) != RET_SUCCESS) {
256518678f8Sopenharmony_ci        return RET_FAILED;
257518678f8Sopenharmony_ci    }
258518678f8Sopenharmony_ci    if (InitRenewalTime(config) != RET_SUCCESS) {
259518678f8Sopenharmony_ci        return RET_FAILED;
260518678f8Sopenharmony_ci    }
261518678f8Sopenharmony_ci    if (InitRebindingTime(config) != RET_SUCCESS) {
262518678f8Sopenharmony_ci        return RET_FAILED;
263518678f8Sopenharmony_ci    }
264518678f8Sopenharmony_ci    if (InitDomainNameServer(config) != RET_SUCCESS) {
265518678f8Sopenharmony_ci        return RET_FAILED;
266518678f8Sopenharmony_ci    }
267518678f8Sopenharmony_ci    return RET_SUCCESS;
268518678f8Sopenharmony_ci}
269518678f8Sopenharmony_ci
270518678f8Sopenharmony_ciint ServerActionCallback(int state, int code, const char *ifname)
271518678f8Sopenharmony_ci{
272518678f8Sopenharmony_ci    int ret = 0;
273518678f8Sopenharmony_ci    switch (state) {
274518678f8Sopenharmony_ci        case ST_STARTING: {
275518678f8Sopenharmony_ci            if (code == 0) {
276518678f8Sopenharmony_ci                DHCP_LOGD(" callback[%s] ==> server starting ...", ifname);
277518678f8Sopenharmony_ci            } else if (code == 1) {
278518678f8Sopenharmony_ci                DHCP_LOGD(" callback[%s] ==> server started.", ifname);
279518678f8Sopenharmony_ci            } else if (code == NUM_TWO) {
280518678f8Sopenharmony_ci                DHCP_LOGD(" callback[%s] ==> server start failed.", ifname);
281518678f8Sopenharmony_ci            }
282518678f8Sopenharmony_ci            break;
283518678f8Sopenharmony_ci        }
284518678f8Sopenharmony_ci        case ST_RELOADNG: {
285518678f8Sopenharmony_ci            DHCP_LOGD(" callback[%s] ==> reloading ...", ifname);
286518678f8Sopenharmony_ci            break;
287518678f8Sopenharmony_ci        }
288518678f8Sopenharmony_ci        case ST_STOPED: {
289518678f8Sopenharmony_ci            DHCP_LOGD(" callback[%s] ==> server stopped.", ifname);
290518678f8Sopenharmony_ci            break;
291518678f8Sopenharmony_ci        }
292518678f8Sopenharmony_ci        default:
293518678f8Sopenharmony_ci            break;
294518678f8Sopenharmony_ci    }
295518678f8Sopenharmony_ci    return ret;
296518678f8Sopenharmony_ci}
297518678f8Sopenharmony_ci
298518678f8Sopenharmony_cistatic int InitializeDhcpConfig(const char *ifname, DhcpConfig *config)
299518678f8Sopenharmony_ci{
300518678f8Sopenharmony_ci    if (!config) {
301518678f8Sopenharmony_ci        DHCP_LOGE("dhcp configure pointer is null.");
302518678f8Sopenharmony_ci        return RET_FAILED;
303518678f8Sopenharmony_ci    }
304518678f8Sopenharmony_ci    if (InitOptionList(&config->options) != RET_SUCCESS) {
305518678f8Sopenharmony_ci        DHCP_LOGE("failed to initialize options.");
306518678f8Sopenharmony_ci        return RET_FAILED;
307518678f8Sopenharmony_ci    }
308518678f8Sopenharmony_ci    char configFile[ARGUMENT_VALUE_SIZE] = DHCPD_CONFIG_FILE;
309518678f8Sopenharmony_ci    if (HasArgument("conf")) {
310518678f8Sopenharmony_ci        ArgumentInfo *configArg = GetArgument("conf");
311518678f8Sopenharmony_ci        if (configArg) {
312518678f8Sopenharmony_ci            if (memcpy_s(configFile, ARGUMENT_VALUE_SIZE, configArg->value, strlen(configArg->value)) != EOK) {
313518678f8Sopenharmony_ci                DHCP_LOGE("conf memcpy_s failed.");
314518678f8Sopenharmony_ci                return RET_FAILED;
315518678f8Sopenharmony_ci            }
316518678f8Sopenharmony_ci        } else {
317518678f8Sopenharmony_ci            DHCP_LOGE("failed to get config file name.");
318518678f8Sopenharmony_ci            return RET_FAILED;
319518678f8Sopenharmony_ci        }
320518678f8Sopenharmony_ci    }
321518678f8Sopenharmony_ci    DHCP_LOGI("load local dhcp config file:%{public}s", configFile);
322518678f8Sopenharmony_ci    if (LoadConfig(configFile, ifname, config) != RET_SUCCESS) {
323518678f8Sopenharmony_ci        DHCP_LOGE("failed to load configure file.");
324518678f8Sopenharmony_ci        return RET_FAILED;
325518678f8Sopenharmony_ci    }
326518678f8Sopenharmony_ci    DHCP_LOGI("init config by argument.");
327518678f8Sopenharmony_ci    if (InitConfigByArguments(config) != RET_SUCCESS) {
328518678f8Sopenharmony_ci        DHCP_LOGE("failed to parse arguments.");
329518678f8Sopenharmony_ci        return RET_FAILED;
330518678f8Sopenharmony_ci    }
331518678f8Sopenharmony_ci
332518678f8Sopenharmony_ci    return RET_SUCCESS;
333518678f8Sopenharmony_ci}
334518678f8Sopenharmony_ci
335518678f8Sopenharmony_cistatic void FreeLocalConfig(void)
336518678f8Sopenharmony_ci{
337518678f8Sopenharmony_ci    FreeOptionList(&g_dhcpConfig.options);
338518678f8Sopenharmony_ci}
339518678f8Sopenharmony_ci
340518678f8Sopenharmony_civoid FreeSeverResources(void)
341518678f8Sopenharmony_ci{
342518678f8Sopenharmony_ci    DHCP_LOGI("FreeSeverResources enter");
343518678f8Sopenharmony_ci    FreeArguments();
344518678f8Sopenharmony_ci    FreeLocalConfig();
345518678f8Sopenharmony_ci    if (FreeServerContext(&g_dhcpServer) != RET_SUCCESS) {
346518678f8Sopenharmony_ci        DHCP_LOGE("Free server context failed!");
347518678f8Sopenharmony_ci        return;
348518678f8Sopenharmony_ci    }
349518678f8Sopenharmony_ci}
350518678f8Sopenharmony_ci
351518678f8Sopenharmony_ciint StartDhcpServerMain(const std::string& ifName, const std::string& netMask, const std::string& ipRange,
352518678f8Sopenharmony_ci    const std::string& localIp)
353518678f8Sopenharmony_ci{
354518678f8Sopenharmony_ci    DHCP_LOGI("StartDhcpServerMain.");
355518678f8Sopenharmony_ci
356518678f8Sopenharmony_ci    if (InitArguments() != RET_SUCCESS) {
357518678f8Sopenharmony_ci        DHCP_LOGE("failed to init arguments table.");
358518678f8Sopenharmony_ci        return 1;
359518678f8Sopenharmony_ci    }
360518678f8Sopenharmony_ci    int ret = ParseArguments(ifName, netMask, ipRange, localIp);
361518678f8Sopenharmony_ci    if (ret != RET_SUCCESS) {DHCP_LOGE("error ParseArguments.");
362518678f8Sopenharmony_ci        FreeArguments();
363518678f8Sopenharmony_ci        return 1;
364518678f8Sopenharmony_ci    }
365518678f8Sopenharmony_ci    ArgumentInfo *ifaceName = GetArgument("ifname");
366518678f8Sopenharmony_ci    if (!ifaceName || strlen(ifaceName->value) == 0) {
367518678f8Sopenharmony_ci        printf("missing required parameters:\"ifname\"\n");
368518678f8Sopenharmony_ci        FreeArguments();
369518678f8Sopenharmony_ci        return 1;
370518678f8Sopenharmony_ci    }
371518678f8Sopenharmony_ci    if (InitializeDhcpConfig(ifaceName->value, &g_dhcpConfig) != RET_SUCCESS) {
372518678f8Sopenharmony_ci        DHCP_LOGW("failed to initialize config.");
373518678f8Sopenharmony_ci    }
374518678f8Sopenharmony_ci    if (strcpy_s(g_dhcpConfig.ifname, IFACE_NAME_SIZE, ifaceName->value) != EOK) {
375518678f8Sopenharmony_ci        DHCP_LOGE("cpy ifname failed!");
376518678f8Sopenharmony_ci        return 1;
377518678f8Sopenharmony_ci    }
378518678f8Sopenharmony_ci    g_dhcpServer = InitializeServer(&g_dhcpConfig);
379518678f8Sopenharmony_ci    if (g_dhcpServer == nullptr) {
380518678f8Sopenharmony_ci        DHCP_LOGE("failed to initialize dhcp server.");
381518678f8Sopenharmony_ci        FreeSeverResources();
382518678f8Sopenharmony_ci        return 1;
383518678f8Sopenharmony_ci    }
384518678f8Sopenharmony_ci
385518678f8Sopenharmony_ci    RegisterDhcpCallback(g_dhcpServer, ServerActionCallback);
386518678f8Sopenharmony_ci    RegisterDeviceChangedCallback(g_dhcpServer, deviceConnectFun);
387518678f8Sopenharmony_ci    if (StartDhcpServer(g_dhcpServer) != RET_SUCCESS) {
388518678f8Sopenharmony_ci        FreeSeverResources();
389518678f8Sopenharmony_ci        return 1;
390518678f8Sopenharmony_ci    }
391518678f8Sopenharmony_ci    return 0;
392518678f8Sopenharmony_ci}
393518678f8Sopenharmony_ci
394518678f8Sopenharmony_ciint StopDhcpServerMain()
395518678f8Sopenharmony_ci{
396518678f8Sopenharmony_ci    DHCP_LOGI("StopDhcpServerMain.");
397518678f8Sopenharmony_ci    if (StopDhcpServer(g_dhcpServer) != RET_SUCCESS) {
398518678f8Sopenharmony_ci        FreeSeverResources();
399518678f8Sopenharmony_ci        return 1;
400518678f8Sopenharmony_ci    }
401518678f8Sopenharmony_ci    FreeSeverResources();
402518678f8Sopenharmony_ci    return 0;
403518678f8Sopenharmony_ci}
404518678f8Sopenharmony_ci
405518678f8Sopenharmony_ciint RegisterDeviceConnectCallBack(DeviceConnectFun fun)
406518678f8Sopenharmony_ci{
407518678f8Sopenharmony_ci    DHCP_LOGI("RegisterDeviceConnectCallBack enter!");
408518678f8Sopenharmony_ci    deviceConnectFun = fun;
409518678f8Sopenharmony_ci    return 0;
410518678f8Sopenharmony_ci}