1 /*
2  * Copyright (C) 2021-2023 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 "kits/c/dhcp_c_api.h"
16 #include "inner_api/dhcp_client.h"
17 #include "inner_api/dhcp_server.h"
18 #include "dhcp_sdk_define.h"
19 #include "dhcp_c_utils.h"
20 #include "dhcp_event.h"
21 #include "dhcp_logger.h"
22 #ifndef OHOS_ARCH_LITE
23 #include <string_ex.h>
24 #endif
25 DEFINE_DHCPLOG_DHCP_LABEL("DhcpCService");
26 std::shared_ptr<OHOS::DHCP::DhcpClient> dhcpClientPtr = nullptr;
27 std::shared_ptr<OHOS::DHCP::DhcpServer> dhcpServerPtr = nullptr;
28 
29 #ifdef OHOS_ARCH_LITE
30     static std::shared_ptr<DhcpClientCallBack> dhcpClientCallBack = nullptr;
31     static std::shared_ptr<DhcpServerCallBack> dhcpServerCallBack = nullptr;
32 #else
33     static OHOS::sptr<DhcpClientCallBack> dhcpClientCallBack = nullptr;
34     static OHOS::sptr<DhcpServerCallBack> dhcpServerCallBack = nullptr;
35 #endif
36 
RegisterDhcpClientCallBack(const char * ifname,const ClientCallBack * event)37 NO_SANITIZE("cfi")  DhcpErrorCode RegisterDhcpClientCallBack(const char *ifname, const ClientCallBack *event)
38 {
39     CHECK_PTR_RETURN(ifname, DHCP_INVALID_PARAM);
40     CHECK_PTR_RETURN(event, DHCP_INVALID_PARAM);
41     if (dhcpClientPtr == nullptr) {
42         dhcpClientPtr = OHOS::DHCP::DhcpClient::GetInstance(DHCP_CLIENT_ABILITY_ID);
43     }
44     CHECK_PTR_RETURN(dhcpClientPtr, DHCP_INVALID_PARAM);
45 #ifdef OHOS_ARCH_LITE
46     if (dhcpClientCallBack == nullptr) {
47         dhcpClientCallBack = std::shared_ptr<DhcpClientCallBack>(new (std::nothrow)DhcpClientCallBack());
48     }
49 #else
50     if (dhcpClientCallBack == nullptr) {
51         dhcpClientCallBack = OHOS::sptr<DhcpClientCallBack>(new (std::nothrow)DhcpClientCallBack());
52     }
53 #endif
54     CHECK_PTR_RETURN(dhcpClientCallBack, DHCP_INVALID_PARAM);
55     dhcpClientCallBack->RegisterCallBack(ifname, event);
56     return GetCErrorCode(dhcpClientPtr->RegisterDhcpClientCallBack(ifname, dhcpClientCallBack));
57 }
58 
RegisterDhcpClientReportCallBack(const char * ifname,const DhcpClientReport * event)59 DhcpErrorCode RegisterDhcpClientReportCallBack(const char *ifname, const DhcpClientReport *event)
60 {
61     CHECK_PTR_RETURN(ifname, DHCP_INVALID_PARAM);
62     CHECK_PTR_RETURN(event, DHCP_INVALID_PARAM);
63 #ifdef OHOS_ARCH_LITE
64     if (dhcpClientCallBack == nullptr) {
65         dhcpClientCallBack = std::make_shared<DhcpClientCallBack>();
66     }
67 #else
68     if (dhcpClientCallBack == nullptr) {
69         dhcpClientCallBack = OHOS::sptr<DhcpClientCallBack>(new (std::nothrow)DhcpClientCallBack());
70     }
71 #endif
72     CHECK_PTR_RETURN(dhcpClientCallBack, DHCP_INVALID_PARAM);
73     dhcpClientCallBack->RegisterDhcpClientReportCallBack(ifname, event);
74     return DHCP_SUCCESS;
75 }
76 
StartDhcpClient(const char * ifname,bool bIpv6)77 NO_SANITIZE("cfi") DhcpErrorCode StartDhcpClient(const char *ifname, bool bIpv6)
78 {
79     CHECK_PTR_RETURN(ifname, DHCP_INVALID_PARAM);
80     CHECK_PTR_RETURN(dhcpClientPtr, DHCP_INVALID_PARAM);
81     return GetCErrorCode(dhcpClientPtr->StartDhcpClient(ifname, bIpv6));
82 }
83 
SetConfiguration(const char * ifname,const RouterConfig config)84 DhcpErrorCode SetConfiguration(const char *ifname, const RouterConfig config)
85 {
86     CHECK_PTR_RETURN(ifname, DHCP_INVALID_PARAM);
87     CHECK_PTR_RETURN(dhcpClientPtr, DHCP_INVALID_PARAM);
88     OHOS::DHCP::RouterConfig routerConfig;
89     routerConfig.bssid = config.bssid;
90     routerConfig.prohibitUseCacheIp = config.prohibitUseCacheIp;
91     return GetCErrorCode(dhcpClientPtr->SetConfiguration(ifname, routerConfig));
92 }
93 
StopDhcpClient(const char * ifname,bool bIpv6)94 NO_SANITIZE("cfi") DhcpErrorCode StopDhcpClient(const char *ifname, bool bIpv6)
95 {
96     CHECK_PTR_RETURN(ifname, DHCP_INVALID_PARAM);
97     CHECK_PTR_RETURN(dhcpClientPtr, DHCP_INVALID_PARAM);
98     CHECK_PTR_RETURN(dhcpClientCallBack, DHCP_INVALID_PARAM);
99     dhcpClientCallBack->UnRegisterCallBack(ifname);
100     return  GetCErrorCode(dhcpClientPtr->StopDhcpClient(ifname, bIpv6));
101 }
102 
RegisterDhcpServerCallBack(const char * ifname,const ServerCallBack * event)103 NO_SANITIZE("cfi") DhcpErrorCode RegisterDhcpServerCallBack(const char *ifname, const ServerCallBack *event)
104 {
105     CHECK_PTR_RETURN(ifname, DHCP_INVALID_PARAM);
106     CHECK_PTR_RETURN(event, DHCP_INVALID_PARAM);
107     if (dhcpServerPtr == nullptr) {
108         dhcpServerPtr = OHOS::DHCP::DhcpServer::GetInstance(DHCP_SERVER_ABILITY_ID);
109     }
110     CHECK_PTR_RETURN(dhcpServerPtr, DHCP_INVALID_PARAM);
111 #ifdef OHOS_ARCH_LITE
112     if (dhcpServerCallBack == nullptr) {
113         dhcpServerCallBack = std::shared_ptr<DhcpServerCallBack>(new (std::nothrow)DhcpServerCallBack());
114     }
115 #else
116     if (dhcpServerCallBack == nullptr) {
117         dhcpServerCallBack = OHOS::sptr<DhcpServerCallBack>(new (std::nothrow)DhcpServerCallBack());
118     }
119 #endif
120     CHECK_PTR_RETURN(dhcpServerCallBack, DHCP_INVALID_PARAM);
121     dhcpServerCallBack->RegisterCallBack(ifname, event);
122     return GetCErrorCode(dhcpServerPtr->RegisterDhcpServerCallBack(ifname, dhcpServerCallBack));
123 }
124 
StartDhcpServer(const char * ifname)125 NO_SANITIZE("cfi") DhcpErrorCode StartDhcpServer(const char *ifname)
126 {
127     if (dhcpServerPtr == nullptr) {
128         dhcpServerPtr = OHOS::DHCP::DhcpServer::GetInstance(DHCP_SERVER_ABILITY_ID);
129     }
130     CHECK_PTR_RETURN(ifname, DHCP_INVALID_PARAM);
131     CHECK_PTR_RETURN(dhcpServerPtr, DHCP_INVALID_PARAM);
132     return GetCErrorCode(dhcpServerPtr->StartDhcpServer(ifname));
133 }
134 
StopDhcpServer(const char * ifname)135 NO_SANITIZE("cfi") DhcpErrorCode StopDhcpServer(const char *ifname)
136 {
137     if (dhcpServerPtr == nullptr) {
138         dhcpServerPtr = OHOS::DHCP::DhcpServer::GetInstance(DHCP_SERVER_ABILITY_ID);
139     }
140     CHECK_PTR_RETURN(ifname, DHCP_INVALID_PARAM);
141     CHECK_PTR_RETURN(dhcpServerPtr, DHCP_INVALID_PARAM);
142 #ifdef OHOS_ARCH_LITE
143     if (dhcpServerCallBack == nullptr) {
144         dhcpServerCallBack = std::make_shared<DhcpServerCallBack>();
145     }
146 #else
147     if (dhcpServerCallBack == nullptr) {
148         dhcpServerCallBack = OHOS::sptr<DhcpServerCallBack>(new (std::nothrow)DhcpServerCallBack());
149     }
150 #endif
151     CHECK_PTR_RETURN(dhcpServerCallBack, DHCP_INVALID_PARAM);
152     dhcpServerCallBack->UnRegisterCallBack(ifname);
153     return GetCErrorCode(dhcpServerPtr->StopDhcpServer(ifname));
154 }
155 
SetDhcpRange(const char * ifname,const DhcpRange * range)156 NO_SANITIZE("cfi") DhcpErrorCode SetDhcpRange(const char *ifname, const DhcpRange *range)
157 {
158     if (dhcpServerPtr == nullptr) {
159         dhcpServerPtr = OHOS::DHCP::DhcpServer::GetInstance(DHCP_SERVER_ABILITY_ID);
160     }
161     CHECK_PTR_RETURN(ifname, DHCP_INVALID_PARAM);
162     CHECK_PTR_RETURN(range, DHCP_INVALID_PARAM);
163     CHECK_PTR_RETURN(dhcpServerPtr, DHCP_INVALID_PARAM);
164     OHOS::DHCP::DhcpRange rangeNew;
165     rangeNew.iptype = range->iptype;
166     rangeNew.strStartip = range->strStartip;
167     rangeNew.strEndip = range->strEndip;
168     rangeNew.strSubnet = range->strSubnet;
169     rangeNew.strTagName = range->strTagName;
170     return GetCErrorCode(dhcpServerPtr->SetDhcpRange(ifname, rangeNew));
171 }
172 
SetDhcpName(const char * ifname,const char * tagName)173 NO_SANITIZE("cfi") DhcpErrorCode SetDhcpName(const char *ifname, const char *tagName)
174 {
175     if (dhcpServerPtr == nullptr) {
176         dhcpServerPtr = OHOS::DHCP::DhcpServer::GetInstance(DHCP_SERVER_ABILITY_ID);
177     }
178     CHECK_PTR_RETURN(ifname, DHCP_INVALID_PARAM);
179     CHECK_PTR_RETURN(tagName, DHCP_INVALID_PARAM);
180     CHECK_PTR_RETURN(dhcpServerPtr, DHCP_INVALID_PARAM);
181     return GetCErrorCode(dhcpServerPtr->SetDhcpName(ifname, tagName));
182 }
183 
PutDhcpRange(const char * tagName,const DhcpRange * range)184 NO_SANITIZE("cfi") DhcpErrorCode PutDhcpRange(const char *tagName, const DhcpRange *range)
185 {
186     if (dhcpServerPtr == nullptr) {
187         dhcpServerPtr = OHOS::DHCP::DhcpServer::GetInstance(DHCP_SERVER_ABILITY_ID);
188     }
189     CHECK_PTR_RETURN(tagName, DHCP_INVALID_PARAM);
190     CHECK_PTR_RETURN(range, DHCP_INVALID_PARAM);
191     CHECK_PTR_RETURN(dhcpServerPtr, DHCP_INVALID_PARAM);
192     OHOS::DHCP::DhcpRange rangeNew;
193     rangeNew.iptype = range->iptype;
194     rangeNew.strStartip = range->strStartip;
195     rangeNew.strEndip = range->strEndip;
196     rangeNew.strSubnet = range->strSubnet;
197     rangeNew.strTagName = range->strTagName;
198     return GetCErrorCode(dhcpServerPtr->PutDhcpRange(tagName, rangeNew));
199 }
200 
RemoveAllDhcpRange(const char * tagName)201 NO_SANITIZE("cfi") DhcpErrorCode RemoveAllDhcpRange(const char *tagName)
202 {
203     if (dhcpServerPtr == nullptr) {
204         dhcpServerPtr = OHOS::DHCP::DhcpServer::GetInstance(DHCP_SERVER_ABILITY_ID);
205     }
206     CHECK_PTR_RETURN(tagName, DHCP_INVALID_PARAM);
207     CHECK_PTR_RETURN(dhcpServerPtr, DHCP_INVALID_PARAM);
208     return GetCErrorCode(dhcpServerPtr->RemoveAllDhcpRange(tagName));
209 }
210 
RemoveDhcpRange(const char * tagName,const void * range)211 DhcpErrorCode RemoveDhcpRange(const char *tagName, const void *range)
212 {
213     if (dhcpServerPtr == nullptr) {
214         dhcpServerPtr = OHOS::DHCP::DhcpServer::GetInstance(DHCP_SERVER_ABILITY_ID);
215     }
216     CHECK_PTR_RETURN(tagName, DHCP_INVALID_PARAM);
217     CHECK_PTR_RETURN(range, DHCP_INVALID_PARAM);
218     CHECK_PTR_RETURN(dhcpServerPtr, DHCP_INVALID_PARAM);
219     return GetCErrorCode(dhcpServerPtr->RemoveDhcpRange(tagName, *(OHOS::DHCP::DhcpRange *)range));
220 }
221 
ParseClientInfos(int staNumber,DhcpStationInfo * staInfo,int * staSize,std::vector<std::string> & vecInfo)222 DhcpErrorCode ParseClientInfos(int staNumber, DhcpStationInfo *staInfo, int *staSize, std::vector<std::string> &vecInfo)
223 {
224     int size = (int)vecInfo.size();
225     DHCP_LOGI("ParseClientInfos staNumber:%{public}d size:%{public}d", staNumber, size);
226     int i = 0;
227     for (i = 0; i < size; i++) {
228         std::vector<std::string> tmp;
229         std::string str = vecInfo[i];
230         OHOS::SplitStr(str, " ", tmp);
231         if (tmp.empty()) {
232             continue;
233         }
234         if (tmp[DHCP_LEASE_MAC_ADDR_POS] == "duid") {
235             break;
236         }
237         if (tmp.size() < DHCP_LEASE_FORMAT_SIZE) {
238             continue;
239         }
240         std::string mac = tmp[DHCP_LEASE_MAC_ADDR_POS];
241         std::string ipAddr = tmp[DHCP_LEASE_IP_ADDR_POS];
242         std::string deviceName = "";
243         if (tmp.size() >= DHCP_LEASE_FORMAT_MAX_SIZE) {
244             deviceName = tmp[DHCP_LEASE_HOSTNAME_POS];
245         }
246         if (i >= staNumber) {
247             break;
248         }
249         if (strcpy_s(staInfo[i].macAddr, MAC_ADDR_MAX_LEN, mac.c_str()) != EOK) {
250             DHCP_LOGE("get dhcp client info, cpy mac failed! srclen=%{public}zu", strlen(mac.c_str()));
251             return DHCP_FAILED;
252         }
253         if (strcpy_s(staInfo[i].ipAddr, INET_ADDRSTRLEN, ipAddr.c_str()) != EOK) {
254             DHCP_LOGE("get dhcp client info, cpy ip failed!");
255             return DHCP_FAILED;
256         }
257         if (strcpy_s(staInfo[i].deviceName, DHCP_LEASE_DATA_MAX_LEN, deviceName.c_str()) != EOK) {
258             DHCP_LOGE("get dhcp client info, cpy name failed!");
259             return DHCP_FAILED;
260         }
261     }
262     *staSize = i;
263     DHCP_LOGI("GetDhcpClientInfos staNumber:%{public}d staSize:%{public}d", staNumber, *staSize);
264     return DHCP_SUCCESS;
265 }
266 
GetDhcpClientInfos(const char * ifname,int staNumber,DhcpStationInfo * staInfo,int * staSize)267 DhcpErrorCode GetDhcpClientInfos(const char *ifname, int staNumber, DhcpStationInfo *staInfo, int *staSize)
268 {
269     if (dhcpServerPtr == nullptr) {
270         dhcpServerPtr = OHOS::DHCP::DhcpServer::GetInstance(DHCP_SERVER_ABILITY_ID);
271     }
272     CHECK_PTR_RETURN(ifname, DHCP_INVALID_PARAM);
273     CHECK_PTR_RETURN(staInfo, DHCP_INVALID_PARAM);
274     CHECK_PTR_RETURN(staSize, DHCP_INVALID_PARAM);
275     CHECK_PTR_RETURN(dhcpServerPtr, DHCP_INVALID_PARAM);
276     std::vector<std::string> vecInfo;
277     DhcpErrorCode ret = GetCErrorCode(dhcpServerPtr->GetDhcpClientInfos(ifname, vecInfo));
278     if (ret != DHCP_SUCCESS) {
279         DHCP_LOGE("GetDhcpClientInfos failed!");
280         return DHCP_FAILED;
281     }
282     return ParseClientInfos(staNumber, staInfo, staSize, vecInfo);
283 }
284 
UpdateLeasesTime(const char * leaseTime)285 NO_SANITIZE("cfi") DhcpErrorCode UpdateLeasesTime(const char *leaseTime)
286 {
287     if (dhcpServerPtr == nullptr) {
288         dhcpServerPtr = OHOS::DHCP::DhcpServer::GetInstance(DHCP_SERVER_ABILITY_ID);
289     }
290     CHECK_PTR_RETURN(leaseTime, DHCP_INVALID_PARAM);
291     CHECK_PTR_RETURN(dhcpServerPtr, DHCP_INVALID_PARAM);
292     return GetCErrorCode(dhcpServerPtr->UpdateLeasesTime(leaseTime));
293 }
294