1b1b8bc3fSopenharmony_ci/*
2b1b8bc3fSopenharmony_ci * Copyright (C) 2021-2022 Huawei Device Co., Ltd.
3b1b8bc3fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4b1b8bc3fSopenharmony_ci * you may not use this file except in compliance with the License.
5b1b8bc3fSopenharmony_ci * You may obtain a copy of the License at
6b1b8bc3fSopenharmony_ci *
7b1b8bc3fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8b1b8bc3fSopenharmony_ci *
9b1b8bc3fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10b1b8bc3fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11b1b8bc3fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12b1b8bc3fSopenharmony_ci * See the License for the specific language governing permissions and
13b1b8bc3fSopenharmony_ci * limitations under the License.
14b1b8bc3fSopenharmony_ci */
15b1b8bc3fSopenharmony_ci
16b1b8bc3fSopenharmony_ci#include "dhcp_controller.h"
17b1b8bc3fSopenharmony_ci
18b1b8bc3fSopenharmony_ci#include "dhcp_result_parcel.h"
19b1b8bc3fSopenharmony_ci#include "netnative_log_wrapper.h"
20b1b8bc3fSopenharmony_ci#include "netmanager_base_common_utils.h"
21b1b8bc3fSopenharmony_ci#include <securec.h>
22b1b8bc3fSopenharmony_ci
23b1b8bc3fSopenharmony_cinamespace OHOS {
24b1b8bc3fSopenharmony_cinamespace nmd {
25b1b8bc3fSopenharmony_cistatic constexpr const char *DEFAULT_STR_SUBNET = "255.255.255.0";
26b1b8bc3fSopenharmony_cistatic constexpr const char *DEFAULT_STR_STARTIP = ".3";
27b1b8bc3fSopenharmony_cistatic constexpr const char *DEFAULT_STR_ENDIP = ".254";
28b1b8bc3fSopenharmony_ciDhcpController *DhcpController::DhcpControllerResultNotify::dhcpController_ = nullptr;
29b1b8bc3fSopenharmony_ci
30b1b8bc3fSopenharmony_ciDhcpController::DhcpControllerResultNotify::DhcpControllerResultNotify() {}
31b1b8bc3fSopenharmony_ci
32b1b8bc3fSopenharmony_ciDhcpController::DhcpControllerResultNotify::~DhcpControllerResultNotify() {}
33b1b8bc3fSopenharmony_ci
34b1b8bc3fSopenharmony_civoid DhcpController::DhcpControllerResultNotify::SetDhcpController(DhcpController *dhcpController)
35b1b8bc3fSopenharmony_ci{
36b1b8bc3fSopenharmony_ci    dhcpController_ = dhcpController;
37b1b8bc3fSopenharmony_ci}
38b1b8bc3fSopenharmony_ci
39b1b8bc3fSopenharmony_civoid DhcpController::DhcpControllerResultNotify::OnSuccess(int status, const char *ifname,
40b1b8bc3fSopenharmony_ci                                                           DhcpResult *result)
41b1b8bc3fSopenharmony_ci{
42b1b8bc3fSopenharmony_ci    if (ifname == nullptr || result == nullptr) {
43b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("ifname or result is nullptr!");
44b1b8bc3fSopenharmony_ci        return;
45b1b8bc3fSopenharmony_ci    }
46b1b8bc3fSopenharmony_ci    NETNATIVE_LOGI(
47b1b8bc3fSopenharmony_ci        "Enter DhcpController::DhcpControllerResultNotify::OnSuccess "
48b1b8bc3fSopenharmony_ci        "ifname=[%{public}s], iptype=[%{public}d], strYourCli=[%{public}s], "
49b1b8bc3fSopenharmony_ci        "strServer=[%{public}s], strSubnet=[%{public}s], strDns1=[%{public}s], "
50b1b8bc3fSopenharmony_ci        "strDns2=[%{public}s] strRouter1=[%{public}s] strRouter2=[%{public}s]",
51b1b8bc3fSopenharmony_ci        ifname, result->iptype, result->strOptClientId,
52b1b8bc3fSopenharmony_ci        NetManagerStandard::CommonUtils::ToAnonymousIp(result->strOptServerId).c_str(),
53b1b8bc3fSopenharmony_ci        NetManagerStandard::CommonUtils::ToAnonymousIp(result->strOptSubnet).c_str(),
54b1b8bc3fSopenharmony_ci        NetManagerStandard::CommonUtils::ToAnonymousIp(result->strOptDns1).c_str(),
55b1b8bc3fSopenharmony_ci        NetManagerStandard::CommonUtils::ToAnonymousIp(result->strOptDns2).c_str(),
56b1b8bc3fSopenharmony_ci        NetManagerStandard::CommonUtils::ToAnonymousIp(result->strOptRouter1).c_str(),
57b1b8bc3fSopenharmony_ci        NetManagerStandard::CommonUtils::ToAnonymousIp(result->strOptRouter2).c_str());
58b1b8bc3fSopenharmony_ci    dhcpController_->Process(ifname, result);
59b1b8bc3fSopenharmony_ci}
60b1b8bc3fSopenharmony_ci
61b1b8bc3fSopenharmony_civoid DhcpController::DhcpControllerResultNotify::OnFailed(int status, const char *ifname,
62b1b8bc3fSopenharmony_ci                                                          const char *reason)
63b1b8bc3fSopenharmony_ci{
64b1b8bc3fSopenharmony_ci    NETNATIVE_LOGE("Enter DhcpController::DhcpControllerResultNotify::OnFailed");
65b1b8bc3fSopenharmony_ci}
66b1b8bc3fSopenharmony_ci
67b1b8bc3fSopenharmony_ciDhcpController::DhcpController()
68b1b8bc3fSopenharmony_ci{
69b1b8bc3fSopenharmony_ci    dhcpResultNotify_ = std::make_unique<DhcpControllerResultNotify>();
70b1b8bc3fSopenharmony_ci}
71b1b8bc3fSopenharmony_ci
72b1b8bc3fSopenharmony_ciDhcpController::~DhcpController() {}
73b1b8bc3fSopenharmony_ci
74b1b8bc3fSopenharmony_ciint32_t DhcpController::RegisterNotifyCallback(sptr<OHOS::NetsysNative::INotifyCallback> &callback)
75b1b8bc3fSopenharmony_ci{
76b1b8bc3fSopenharmony_ci    NETNATIVE_LOGI("DhcpController RegisterNotifyCallback");
77b1b8bc3fSopenharmony_ci    callback_ = callback;
78b1b8bc3fSopenharmony_ci    return 0;
79b1b8bc3fSopenharmony_ci}
80b1b8bc3fSopenharmony_ci
81b1b8bc3fSopenharmony_civoid DhcpController::StartClient(const std::string &iface, bool bIpv6)
82b1b8bc3fSopenharmony_ci{
83b1b8bc3fSopenharmony_ci    clientEvent.OnIpSuccessChanged = DhcpControllerResultNotify::OnSuccess;
84b1b8bc3fSopenharmony_ci    clientEvent.OnIpFailChanged = DhcpControllerResultNotify::OnFailed;
85b1b8bc3fSopenharmony_ci    dhcpResultNotify_->SetDhcpController(this);
86b1b8bc3fSopenharmony_ci    if (RegisterDhcpClientCallBack(iface.c_str(), &clientEvent) != DHCP_SUCCESS) {
87b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("RegisterDhcpClientCallBack failed.");
88b1b8bc3fSopenharmony_ci        return;
89b1b8bc3fSopenharmony_ci    }
90b1b8bc3fSopenharmony_ci
91b1b8bc3fSopenharmony_ci    NETNATIVE_LOGI("DhcpController StartDhcpClient iface[%{public}s] ipv6[%{public}d]", iface.c_str(), bIpv6);
92b1b8bc3fSopenharmony_ci    if (StartDhcpClient(iface.c_str(), bIpv6) != DHCP_SUCCESS) {
93b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("Start dhcp client failed");
94b1b8bc3fSopenharmony_ci    }
95b1b8bc3fSopenharmony_ci}
96b1b8bc3fSopenharmony_ci
97b1b8bc3fSopenharmony_civoid DhcpController::StopClient(const std::string &iface, bool bIpv6)
98b1b8bc3fSopenharmony_ci{
99b1b8bc3fSopenharmony_ci    NETNATIVE_LOGI("DhcpController StopDhcpClient iface[%{public}s] ipv6[%{public}d]", iface.c_str(), bIpv6);
100b1b8bc3fSopenharmony_ci    if (StopDhcpClient(iface.c_str(), bIpv6) != DHCP_SUCCESS) {
101b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("Stop dhcp client failed");
102b1b8bc3fSopenharmony_ci    }
103b1b8bc3fSopenharmony_ci}
104b1b8bc3fSopenharmony_ci
105b1b8bc3fSopenharmony_civoid DhcpController::Process(const std::string &iface, DhcpResult *result)
106b1b8bc3fSopenharmony_ci{
107b1b8bc3fSopenharmony_ci    NETNATIVE_LOGI("DhcpController Process");
108b1b8bc3fSopenharmony_ci    sptr<OHOS::NetsysNative::DhcpResultParcel> ptr = new (std::nothrow) OHOS::NetsysNative::DhcpResultParcel();
109b1b8bc3fSopenharmony_ci    if (ptr == nullptr) {
110b1b8bc3fSopenharmony_ci        return;
111b1b8bc3fSopenharmony_ci    }
112b1b8bc3fSopenharmony_ci    ptr->iface_ = iface;
113b1b8bc3fSopenharmony_ci    ptr->ipAddr_ = result->strOptClientId;
114b1b8bc3fSopenharmony_ci    ptr->gateWay_ = result->strOptServerId;
115b1b8bc3fSopenharmony_ci    ptr->subNet_ = result->strOptSubnet;
116b1b8bc3fSopenharmony_ci    ptr->route1_ = result->strOptRouter1;
117b1b8bc3fSopenharmony_ci    ptr->route2_ = result->strOptRouter2;
118b1b8bc3fSopenharmony_ci    ptr->dns1_ = result->strOptDns1;
119b1b8bc3fSopenharmony_ci    ptr->dns2_ = result->strOptDns2;
120b1b8bc3fSopenharmony_ci    NETNATIVE_LOGI("DhcpController Process iface[%{public}s]", iface.c_str());
121b1b8bc3fSopenharmony_ci    callback_->OnDhcpSuccess(ptr);
122b1b8bc3fSopenharmony_ci}
123b1b8bc3fSopenharmony_ci
124b1b8bc3fSopenharmony_cibool DhcpController::StartDhcpService(const std::string &iface, const std::string &ipv4addr)
125b1b8bc3fSopenharmony_ci{
126b1b8bc3fSopenharmony_ci    constexpr int32_t IP_V4 = 0;
127b1b8bc3fSopenharmony_ci    std::string ipAddr = ipv4addr;
128b1b8bc3fSopenharmony_ci    std::string::size_type pos = ipAddr.rfind(".");
129b1b8bc3fSopenharmony_ci    if (pos == std::string::npos) {
130b1b8bc3fSopenharmony_ci        return false;
131b1b8bc3fSopenharmony_ci    }
132b1b8bc3fSopenharmony_ci
133b1b8bc3fSopenharmony_ci    std::string ipHead = ipAddr.substr(0, pos);
134b1b8bc3fSopenharmony_ci    std::string strStartip = ipHead + DEFAULT_STR_STARTIP;
135b1b8bc3fSopenharmony_ci    std::string strEndip = ipHead + DEFAULT_STR_ENDIP;
136b1b8bc3fSopenharmony_ci    std::string strSubnet = DEFAULT_STR_SUBNET;
137b1b8bc3fSopenharmony_ci
138b1b8bc3fSopenharmony_ci    DhcpRange range;
139b1b8bc3fSopenharmony_ci    range.iptype = IP_V4;
140b1b8bc3fSopenharmony_ci    if (strcpy_s(range.strTagName, DHCP_MAX_FILE_BYTES, iface.c_str()) != 0) {
141b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("strcpy_s strTagName failed!");
142b1b8bc3fSopenharmony_ci        return false;
143b1b8bc3fSopenharmony_ci    }
144b1b8bc3fSopenharmony_ci
145b1b8bc3fSopenharmony_ci    if (strcpy_s(range.strStartip, INET_ADDRSTRLEN, strStartip.c_str()) != 0) {
146b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("strcpy_s strStartip failed!");
147b1b8bc3fSopenharmony_ci        return false;
148b1b8bc3fSopenharmony_ci    }
149b1b8bc3fSopenharmony_ci
150b1b8bc3fSopenharmony_ci    if (strcpy_s(range.strEndip, INET_ADDRSTRLEN, strEndip.c_str()) != 0) {
151b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("strcpy_s strEndip failed!");
152b1b8bc3fSopenharmony_ci        return false;
153b1b8bc3fSopenharmony_ci    }
154b1b8bc3fSopenharmony_ci
155b1b8bc3fSopenharmony_ci    if (strcpy_s(range.strSubnet, INET_ADDRSTRLEN, strSubnet.c_str()) != 0) {
156b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("strcpy_s strSubnet failed!");
157b1b8bc3fSopenharmony_ci        return false;
158b1b8bc3fSopenharmony_ci    }
159b1b8bc3fSopenharmony_ci
160b1b8bc3fSopenharmony_ci    if (SetDhcpRange(iface.c_str(), &range) != DHCP_SUCCESS) {
161b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("SetDhcpRange failed!");
162b1b8bc3fSopenharmony_ci        return false;
163b1b8bc3fSopenharmony_ci    }
164b1b8bc3fSopenharmony_ci    NETNATIVE_LOGI(
165b1b8bc3fSopenharmony_ci        "Set dhcp range : ifaceName[%{public}s] TagName[%{public}s] start ip[%{public}s] end ip[%{public}s]",
166b1b8bc3fSopenharmony_ci        iface.c_str(), range.strTagName, range.strStartip, range.strEndip);
167b1b8bc3fSopenharmony_ci    if (StartDhcpServer(iface.c_str()) != DHCP_SUCCESS) {
168b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("Start dhcp server failed!, iface:[%{public}s]", iface.c_str());
169b1b8bc3fSopenharmony_ci        return false;
170b1b8bc3fSopenharmony_ci    }
171b1b8bc3fSopenharmony_ci    return true;
172b1b8bc3fSopenharmony_ci}
173b1b8bc3fSopenharmony_ci
174b1b8bc3fSopenharmony_cibool DhcpController::StopDhcpService(const std::string &iface)
175b1b8bc3fSopenharmony_ci{
176b1b8bc3fSopenharmony_ci    if (RemoveAllDhcpRange(iface.c_str()) != DHCP_SUCCESS) {
177b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("failed to remove [%{public}s] dhcp range.", iface.c_str());
178b1b8bc3fSopenharmony_ci    }
179b1b8bc3fSopenharmony_ci
180b1b8bc3fSopenharmony_ci    if (StopDhcpServer(iface.c_str()) != DHCP_SUCCESS) {
181b1b8bc3fSopenharmony_ci        NETNATIVE_LOGE("Stop dhcp server failed!");
182b1b8bc3fSopenharmony_ci        return false;
183b1b8bc3fSopenharmony_ci    }
184b1b8bc3fSopenharmony_ci    NETNATIVE_LOGI("StopDhcpService ifaceName[%{public}s]", iface.c_str());
185b1b8bc3fSopenharmony_ci    return true;
186b1b8bc3fSopenharmony_ci}
187b1b8bc3fSopenharmony_ci} // namespace nmd
188b1b8bc3fSopenharmony_ci} // namespace OHOS
189