• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2022 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 
16 #include "dhcp_server_service_impl.h"
17 #ifndef OHOS_ARCH_LITE
18 #include <file_ex.h>
19 #endif
20 #include <cstdio>
21 #include <unistd.h>
22 #include <csignal>
23 #include <sys/prctl.h>
24 #ifndef OHOS_ARCH_LITE
25 #include "dhcp_server_death_recipient.h"
26 #endif
27 #include "dhcp_define.h"
28 #include "dhcp_errcode.h"
29 #include "dhcp_logger.h"
30 #include "dhcp_dhcpd.h"
31 #include "securec.h"
32 #include "dhcp_function.h"
33 #include "dhcp_permission_utils.h"
34 #ifndef OHOS_ARCH_LITE
35 #include "dhcp_sa_manager.h"
36 #include "ipc_skeleton.h"
37 #endif
38 
39 DEFINE_DHCPLOG_DHCP_LABEL("DhcpServerServiceImpl");
40 
41 namespace OHOS {
42 namespace DHCP {
43 namespace {
44 constexpr uint32_t MAX_REGISTER_SERVER_NUM = 1000;
45 }
46 std::mutex DhcpServerServiceImpl::g_instanceLock;
47 #ifdef OHOS_ARCH_LITE
48 std::shared_ptr<DhcpServerServiceImpl> DhcpServerServiceImpl::g_instance = nullptr;
GetInstance()49 std::shared_ptr<DhcpServerServiceImpl> DhcpServerServiceImpl::GetInstance()
50 {
51     if (g_instance == nullptr) {
52         std::lock_guard<std::mutex> autoLock(g_instanceLock);
53         if (g_instance == nullptr) {
54             std::shared_ptr<DhcpServerServiceImpl> service = std::make_shared<DhcpServerServiceImpl>();
55             g_instance = service;
56         }
57     }
58     return g_instance;
59 }
60 #else
61 sptr<DhcpServerServiceImpl> DhcpServerServiceImpl::g_instance;
62 std::map<std::string, DhcpServerInfo> DhcpServerServiceImpl::m_mapDhcpServer;
63 const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(DhcpServerServiceImpl::GetInstance().GetRefPtr());
GetInstance()64 sptr<DhcpServerServiceImpl> DhcpServerServiceImpl::GetInstance()
65 {
66     if (g_instance == nullptr) {
67         std::lock_guard<std::mutex> autoLock(g_instanceLock);
68         if (g_instance == nullptr) {
69             sptr<DhcpServerServiceImpl> service = new (std::nothrow) DhcpServerServiceImpl;
70             g_instance = service;
71         }
72     }
73     return g_instance;
74 }
75 #endif
76 
DhcpServerServiceImpl()77 DhcpServerServiceImpl::DhcpServerServiceImpl()
78 #ifndef OHOS_ARCH_LITE
79     : SystemAbility(DHCP_SERVER_ABILITY_ID, true), mPublishFlag(false),
80         mState(ServerServiceRunningState::STATE_NOT_START)
81 #endif
82 {}
83 
~DhcpServerServiceImpl()84 DhcpServerServiceImpl::~DhcpServerServiceImpl()
85 {}
86 
OnStart()87 void DhcpServerServiceImpl::OnStart()
88 {
89     DHCP_LOGI("enter Server OnStart");
90     if (mState == ServerServiceRunningState::STATE_RUNNING) {
91         DHCP_LOGW("Service has already started.");
92         return;
93     }
94     if (!Init()) {
95         DHCP_LOGE("Failed to init dhcp server service");
96         OnStop();
97         return;
98     }
99     mState = ServerServiceRunningState::STATE_RUNNING;
100     DHCP_LOGI("Server Service has started.");
101 }
102 
OnStop()103 void DhcpServerServiceImpl::OnStop()
104 {
105     mPublishFlag = false;
106     DHCP_LOGI("OnStop dhcp server service!");
107 }
108 
Init()109 bool DhcpServerServiceImpl::Init()
110 {
111     DHCP_LOGI("enter server Init");
112     if (!mPublishFlag) {
113 #ifdef OHOS_ARCH_LITE
114         bool ret = true;
115 #else
116         bool ret = Publish(DhcpServerServiceImpl::GetInstance());
117 #endif
118         if (!ret) {
119             DHCP_LOGE("Failed to publish dhcp server service!");
120             return false;
121         }
122         DHCP_LOGI("success to publish dhcp server service!");
123         mPublishFlag = true;
124     }
125     return true;
126 }
127 
128 #ifdef OHOS_ARCH_LITE
RegisterDhcpServerCallBack(const std::string & ifname,const std::shared_ptr<IDhcpServerCallBack> & serverCallback)129 ErrCode DhcpServerServiceImpl::RegisterDhcpServerCallBack(const std::string& ifname,
130     const std::shared_ptr<IDhcpServerCallBack> &serverCallback)
131 #else
132 ErrCode DhcpServerServiceImpl::RegisterDhcpServerCallBack(const std::string& ifname,
133     const sptr<IDhcpServerCallBack> &serverCallback)
134 #endif
135 {
136     DHCP_LOGI("RegisterDhcpServerCallBack");
137     if (!DhcpPermissionUtils::VerifyIsNativeProcess()) {
138         DHCP_LOGE("RegisterDhcpServerCallBack:NOT NATIVE PROCESS, PERMISSION_DENIED!");
139         return DHCP_E_PERMISSION_DENIED;
140     }
141     if (!DhcpPermissionUtils::VerifyDhcpNetworkPermission("ohos.permission.NETWORK_DHCP")) {
142         DHCP_LOGE("RegisterDhcpServerCallBack:VerifyDhcpNetworkPermission PERMISSION_DENIED!");
143         return DHCP_E_PERMISSION_DENIED;
144     }
145     std::lock_guard<std::mutex> autoLock(m_serverCallBackMutex);
146     auto iter = m_mapServerCallBack.find(ifname);
147     if (iter != m_mapServerCallBack.end()) {
148         (iter->second) = serverCallback;
149         DHCP_LOGI("RegisterDhcpServerCallBack m_mapServerCallBack find one update, ifname:%{public}s", ifname.c_str());
150     } else {
151         uint32_t registerNum = m_mapServerCallBack.size();
152         if (registerNum > MAX_REGISTER_SERVER_NUM) {
153             DHCP_LOGI("RegisterDhcpServerCallBack, ifname:%{public}s register failed, num over limit", ifname.c_str());
154             return DHCP_E_FAILED;
155         }
156 #ifdef OHOS_ARCH_LITE
157         std::shared_ptr<IDhcpServerCallBack> callback = serverCallback;
158 #else
159         sptr<IDhcpServerCallBack> callback = serverCallback;
160 #endif
161         m_mapServerCallBack.emplace(std::make_pair(ifname, callback));
162         DHCP_LOGI("RegisterDhcpServerCallBack m_mapServerCallBack add one new, ifname:%{public}s", ifname.c_str());
163     }
164     return DHCP_E_SUCCESS;
165 }
166 
StartDhcpServer(const std::string & ifname)167 ErrCode DhcpServerServiceImpl::StartDhcpServer(const std::string& ifname)
168 {
169     DHCP_LOGI("StartDhcpServer ifname:%{public}s", ifname.c_str());
170     if (!DhcpPermissionUtils::VerifyIsNativeProcess()) {
171         DHCP_LOGE("StartDhcpServer:NOT NATIVE PROCESS, PERMISSION_DENIED!");
172         return DHCP_E_PERMISSION_DENIED;
173     }
174     if (!DhcpPermissionUtils::VerifyDhcpNetworkPermission("ohos.permission.NETWORK_DHCP")) {
175         DHCP_LOGE("StartDhcpServer:VerifyDhcpNetworkPermission PERMISSION_DENIED!");
176         return DHCP_E_PERMISSION_DENIED;
177     }
178     if (ifname.empty()) {
179         DHCP_LOGE("StartDhcpServer error, ifname is empty!");
180         return DHCP_E_FAILED;
181     }
182     /* Add the specified interface. */
183     if (AddSpecifiedInterface(ifname) != DHCP_OPT_SUCCESS) {
184         return DHCP_E_FAILED;
185     }
186 
187     if (CreateDefaultConfigFile(DHCP_SERVER_CONFIG_FILE) != DHCP_OPT_SUCCESS) {
188         return DHCP_E_FAILED;
189     }
190 
191     std::string localIp, netmask, ipRange;
192     if (DhcpFunction::GetLocalIp(ifname, localIp, netmask) != DHCP_OPT_SUCCESS) {
193         DHCP_LOGE("ifname:%{public}s get ip mask failed.", ifname.c_str());
194         return DHCP_E_FAILED;
195     }
196     if (GetUsingIpRange(ifname, ipRange) != DHCP_OPT_SUCCESS) {
197         DHCP_LOGE("ifname:%{public}s get ip range failed.", ifname.c_str());
198         return DHCP_E_FAILED;
199     }
200     DHCP_LOGD("localIp:%{public}s netmask:%{public}s  ipRange:%{public}s.", localIp.c_str(), netmask.c_str(),
201         ipRange.c_str());
202 
203     int ret = RegisterDeviceConnectCallBack(DeviceConnectCallBack);
204     ret = StartDhcpServerMain(ifname, netmask, ipRange, localIp);
205     std::lock_guard<std::mutex> autoLock(m_serverCallBackMutex);
206     auto iter = m_mapServerCallBack.find(ifname);
207     if (iter != m_mapServerCallBack.end()) {
208         if ((iter->second) != nullptr) {
209             if (ret == static_cast<int>(DHCP_E_SUCCESS)) {
210                 (iter->second)->OnServerStatusChanged(static_cast<int>(DHCP_SERVER_ON));
211             } else {
212                 (iter->second)->OnServerStatusChanged(static_cast<int>(DHCP_SERVER_OFF));
213             }
214         }
215     }
216     return ErrCode(ret);
217 }
218 
DeviceInfoCallBack(const std::string & ifname)219 void DhcpServerServiceImpl::DeviceInfoCallBack(const std::string& ifname)
220 {
221     DHCP_LOGI("DeviceInfoCallBack ifname:%{public}s.", ifname.c_str());
222     std::vector<std::string> leases;
223     std::vector<DhcpStationInfo> stationInfos;
224     GetDhcpClientInfos(ifname, leases);
225     ConvertLeasesToStationInfos(leases, stationInfos);
226     auto iter = m_mapServerCallBack.find(ifname);
227     if (iter != m_mapServerCallBack.end()) {
228         if ((iter->second) != nullptr) {
229             (iter->second)->OnServerSuccess(ifname, stationInfos);
230             return;
231         } else {
232             DHCP_LOGE("callbackFunc is null, ifname:%{public}s.", ifname.c_str());
233             return;
234         }
235     } else {
236         DHCP_LOGE("can't find ifname:%{public}s.", ifname.c_str());
237         return;
238     }
239 }
240 
ConvertLeasesToStationInfos(std::vector<std::string> & leases,std::vector<DhcpStationInfo> & stationInfos)241 void DhcpServerServiceImpl::ConvertLeasesToStationInfos(std::vector<std::string> &leases,
242     std::vector<DhcpStationInfo>& stationInfos)
243 {
244     DHCP_LOGI("ConvertLeasesToStationInfos ");
245     for (const std::string& lease : leases) {
246         DhcpStationInfo info;
247         const int length = 128;
248         char leaseTime[length], bindingTime[length], pendingTime[length];
249         char pendingInterval[length], bindingMode[length], bindingStatus[length];
250         const int nSize = 9;
251         if (sscanf_s(lease.c_str(), "%17s %15s %127s %127s %127s %127s %127s %127s %127s",
252             info.macAddr, MAC_ADDR_MAX_LEN,
253             info.ipAddr, INET_ADDRSTRLEN,
254             leaseTime, length,
255             bindingTime, length,
256             pendingTime, length,
257             pendingInterval, length,
258             bindingMode, length,
259             bindingStatus, length,
260             info.deviceName, length) != nSize) {
261             DHCP_LOGE("ConvertLeasesToStationInfos sscanf_s failed, continue!");
262             continue;
263         }
264         DHCP_LOGI("stationInfos deviceName:%{public}s", info.deviceName);
265         stationInfos.push_back(info);
266     }
267 }
268 
DeviceConnectCallBack(const char * ifname)269 void DeviceConnectCallBack(const char* ifname)
270 {
271     DHCP_LOGI("DeviceConnectCallBack ifname:%{public}s.", ifname);
272     if (ifname == nullptr) {
273         DHCP_LOGE("DeviceConnectCallBack ifname is nullptr!");
274         return;
275     }
276     auto instance = DhcpServerServiceImpl::GetInstance();
277     if (instance == nullptr) {
278         DHCP_LOGE("DeviceConnectCallBack instance is nullptr!");
279         return;
280     }
281     instance->DeviceInfoCallBack(ifname);
282 }
283 
StopDhcpServer(const std::string & ifname)284 ErrCode DhcpServerServiceImpl::StopDhcpServer(const std::string& ifname)
285 {
286     if (!DhcpPermissionUtils::VerifyIsNativeProcess()) {
287         DHCP_LOGE("StopDhcpServer:NOT NATIVE PROCESS, PERMISSION_DENIED!");
288         return DHCP_E_PERMISSION_DENIED;
289     }
290     if (!DhcpPermissionUtils::VerifyDhcpNetworkPermission("ohos.permission.NETWORK_DHCP")) {
291         DHCP_LOGE("StopDhcpServer:VerifyDhcpNetworkPermission PERMISSION_DENIED!");
292         return DHCP_E_PERMISSION_DENIED;
293     }
294     if (ifname.empty()) {
295         DHCP_LOGE("StopDhcpServer() error, ifname is empty!");
296         return DHCP_E_FAILED;
297     }
298 
299     auto iterRangeMap = m_mapInfDhcpRange.find(ifname);
300     if (iterRangeMap != m_mapInfDhcpRange.end()) {
301         m_mapInfDhcpRange.erase(iterRangeMap);
302     }
303     if (RemoveAllDhcpRange(ifname) != DHCP_E_SUCCESS) {
304         return DHCP_E_FAILED;
305     }
306     StopDhcpServerMain();
307     /* Del the specified interface. */
308     if (DelSpecifiedInterface(ifname) != DHCP_OPT_SUCCESS) {
309         return DHCP_E_FAILED;
310     }
311     std::lock_guard<std::mutex> autoLock(m_serverCallBackMutex);
312     auto iter = m_mapServerCallBack.find(ifname);
313     if (iter != m_mapServerCallBack.end()) {
314         if ((iter->second) != nullptr) {
315             (iter->second)->OnServerStatusChanged(static_cast<int>(DHCP_SERVER_OFF));
316         }
317     }
318     return DHCP_E_SUCCESS;
319 }
320 
StopServerSa(void)321 ErrCode DhcpServerServiceImpl::StopServerSa(void)
322 {
323     if (!DhcpPermissionUtils::VerifyIsNativeProcess()) {
324         DHCP_LOGE("PutDhcpRange:NOT NATIVE PROCESS, PERMISSION_DENIED!");
325         return DHCP_E_PERMISSION_DENIED;
326     }
327     if (!DhcpPermissionUtils::VerifyDhcpNetworkPermission("ohos.permission.NETWORK_DHCP")) {
328         DHCP_LOGE("PutDhcpRange:VerifyDhcpNetworkPermission PERMISSION_DENIED!");
329         return DHCP_E_PERMISSION_DENIED;
330     }
331 #ifdef OHOS_ARCH_LITE
332     return DHCP_E_SUCCESS;
333 #else
334     return DhcpSaLoadManager::GetInstance().UnloadWifiSa(DHCP_SERVER_ABILITY_ID);
335 #endif
336 }
337 
PutDhcpRange(const std::string & tagName,const DhcpRange & range)338 ErrCode DhcpServerServiceImpl::PutDhcpRange(const std::string& tagName, const DhcpRange& range)
339 {
340     if (!DhcpPermissionUtils::VerifyIsNativeProcess()) {
341         DHCP_LOGE("PutDhcpRange:NOT NATIVE PROCESS, PERMISSION_DENIED!");
342         return DHCP_E_PERMISSION_DENIED;
343     }
344     if (!DhcpPermissionUtils::VerifyDhcpNetworkPermission("ohos.permission.NETWORK_DHCP")) {
345         DHCP_LOGE("PutDhcpRange:VerifyDhcpNetworkPermission PERMISSION_DENIED!");
346         return DHCP_E_PERMISSION_DENIED;
347     }
348     if (tagName.empty()) {
349         DHCP_LOGE("PutDhcpRange param error, tagName is empty!");
350         return DHCP_E_FAILED;
351     }
352     if (!CheckIpAddrRange(range)) {
353         DHCP_LOGE("PutDhcpRange tag:%{public}s check range failed.", tagName.c_str());
354         return DHCP_E_FAILED;
355     }
356 
357     DHCP_LOGI("PutDhcpRange tag:%{public}s.", tagName.c_str());
358 
359     /* add dhcp range */
360     auto iterRangeMap = m_mapTagDhcpRange.find(tagName);
361     if (iterRangeMap != m_mapTagDhcpRange.end()) {
362         int nSize = (int)iterRangeMap->second.size();
363         if (nSize > 1) {
364             DHCP_LOGE("PutDhcpRange failed, %{public}s range size:%{public}d error!", tagName.c_str(), nSize);
365             return DHCP_E_FAILED;
366         } else if (nSize == 0) {
367             DHCP_LOGI("PutDhcpRange m_mapTagDhcpRange find tagName:%{public}s, need push_back.", tagName.c_str());
368             iterRangeMap->second.push_back(range);
369             return DHCP_E_SUCCESS;
370         } else {
371             for (auto tagRange : iterRangeMap->second) {
372                 if ((tagRange.iptype != range.iptype) ||
373                     (tagRange.strStartip != range.strStartip) || (tagRange.strEndip != range.strEndip)) {
374                     continue;
375                 }
376                 DHCP_LOGW("PutDhcpRange success, %{public}s range already exist", tagName.c_str());
377                 return DHCP_E_SUCCESS;
378             }
379             DHCP_LOGE("PutDhcpRange failed, %{public}s range size:%{public}d already exist!", tagName.c_str(), nSize);
380             return DHCP_E_FAILED;
381         }
382     } else {
383         std::list<DhcpRange> listDhcpRange;
384         listDhcpRange.push_back(range);
385         m_mapTagDhcpRange.emplace(std::make_pair(tagName, listDhcpRange));
386         DHCP_LOGI("PutDhcpRange m_mapTagDhcpRange no find tagName:%{public}s, need emplace.", tagName.c_str());
387         return DHCP_E_SUCCESS;
388     }
389     return DHCP_E_SUCCESS;
390 }
391 
RemoveDhcpRange(const std::string & tagName,const DhcpRange & range)392 ErrCode DhcpServerServiceImpl::RemoveDhcpRange(const std::string& tagName, const DhcpRange& range)
393 {
394     if (!DhcpPermissionUtils::VerifyIsNativeProcess()) {
395         DHCP_LOGE("RemoveDhcpRange:NOT NATIVE PROCESS, PERMISSION_DENIED!");
396         return DHCP_E_PERMISSION_DENIED;
397     }
398     if (!DhcpPermissionUtils::VerifyDhcpNetworkPermission("ohos.permission.NETWORK_DHCP")) {
399         DHCP_LOGE("RemoveDhcpRange:VerifyDhcpNetworkPermission PERMISSION_DENIED!");
400         return DHCP_E_PERMISSION_DENIED;
401     }
402     if (tagName.empty()) {
403         DHCP_LOGE("RemoveDhcpRange param error, tagName is empty!");
404         return DHCP_E_FAILED;
405     }
406 
407     /* remove dhcp range */
408     auto iterRangeMap = m_mapTagDhcpRange.find(tagName);
409     if (iterRangeMap != m_mapTagDhcpRange.end()) {
410         auto iterRange = m_mapTagDhcpRange[tagName].begin();
411         while (iterRange != m_mapTagDhcpRange[tagName].end()) {
412             if ((iterRange->iptype == range.iptype) && (iterRange->strStartip == range.strStartip) &&
413                 (iterRange->strEndip == range.strEndip)) {
414                 m_mapTagDhcpRange[tagName].erase(iterRange++);
415                 DHCP_LOGI("RemoveDhcpRange find tagName:%{public}s, "
416                           "range.iptype:%{public}d,strStartip:%{private}s,strEndip:%{private}s, erase.",
417                     tagName.c_str(),
418                     range.iptype,
419                     range.strStartip.c_str(),
420                     range.strEndip.c_str());
421                 return DHCP_E_SUCCESS;
422             }
423             iterRange++;
424         }
425         DHCP_LOGE("RemoveDhcpRange find tagName:%{public}s, second no find range, erase failed!", tagName.c_str());
426     } else {
427         DHCP_LOGE("RemoveDhcpRange no find tagName:%{public}s, erase failed!", tagName.c_str());
428     }
429 
430     return DHCP_E_SUCCESS;
431 }
432 
RemoveAllDhcpRange(const std::string & tagName)433 ErrCode DhcpServerServiceImpl::RemoveAllDhcpRange(const std::string& tagName)
434 {
435     if (!DhcpPermissionUtils::VerifyIsNativeProcess()) {
436         DHCP_LOGE("RemoveAllDhcpRange:NOT NATIVE PROCESS, PERMISSION_DENIED!");
437         return DHCP_E_PERMISSION_DENIED;
438     }
439     if (!DhcpPermissionUtils::VerifyDhcpNetworkPermission("ohos.permission.NETWORK_DHCP")) {
440         DHCP_LOGE("RemoveAllDhcpRange:VerifyDhcpNetworkPermission PERMISSION_DENIED!");
441         return DHCP_E_PERMISSION_DENIED;
442     }
443     if (tagName.empty()) {
444         DHCP_LOGE("RemoveAllDhcpRange param error, tagName is empty!");
445         return DHCP_E_FAILED;
446     }
447 
448     /* remove all dhcp range */
449     auto iterRangeMap = m_mapTagDhcpRange.find(tagName);
450     if (iterRangeMap != m_mapTagDhcpRange.end()) {
451         m_mapTagDhcpRange.erase(iterRangeMap);
452         DHCP_LOGI("RemoveAllDhcpRange find tagName:%{public}s, erase success.", tagName.c_str());
453     } else {
454         DHCP_LOGI("RemoveAllDhcpRange no find tagName:%{public}s, not need erase!", tagName.c_str());
455     }
456 
457     return DHCP_E_SUCCESS;
458 }
459 
SetDhcpRange(const std::string & ifname,const DhcpRange & range)460 ErrCode DhcpServerServiceImpl::SetDhcpRange(const std::string& ifname, const DhcpRange& range)
461 {
462     if (!DhcpPermissionUtils::VerifyIsNativeProcess()) {
463         DHCP_LOGE("SetDhcpRange:NOT NATIVE PROCESS, PERMISSION_DENIED!");
464         return DHCP_E_PERMISSION_DENIED;
465     }
466     if (!DhcpPermissionUtils::VerifyDhcpNetworkPermission("ohos.permission.NETWORK_DHCP")) {
467         DHCP_LOGE("SetDhcpRange:VerifyDhcpNetworkPermission PERMISSION_DENIED!");
468         return DHCP_E_PERMISSION_DENIED;
469     }
470     /* put dhcp range */
471     if (PutDhcpRange(ifname, range) != DHCP_E_SUCCESS) {
472         DHCP_LOGE("SetDhcpRange PutDhcpRange failed, ifname:%{public}s.", ifname.c_str());
473         return DHCP_E_FAILED;
474     }
475 
476     /* check same network */
477     if (DhcpFunction::CheckRangeNetwork(ifname, range.strStartip, range.strEndip) != DHCP_OPT_SUCCESS) {
478         DHCP_LOGE("SetDhcpRange CheckRangeNetwork failed, ifname:%{public}s.", ifname.c_str());
479         RemoveDhcpRange(ifname, range);
480         return DHCP_E_FAILED;
481     }
482 
483     /* add dhcp range */
484     auto iterRangeMap = m_mapInfDhcpRange.find(ifname);
485     if (iterRangeMap != m_mapInfDhcpRange.end()) {
486         int nSize = (int)iterRangeMap->second.size();
487         if (nSize > 1) {
488             DHCP_LOGE("SetDhcpRange failed, %{public}s range size:%{public}d error!", ifname.c_str(), nSize);
489             RemoveDhcpRange(ifname, range);
490             return DHCP_E_FAILED;
491         }
492         if (nSize == 1) {
493             DHCP_LOGW("SetDhcpRange %{public}s range size:%{public}d already exist.", ifname.c_str(), nSize);
494             iterRangeMap->second.clear();
495         }
496         DHCP_LOGI("SetDhcpRange m_mapInfDhcpRange find ifname:%{public}s, need push_back.", ifname.c_str());
497         iterRangeMap->second.push_back(range);
498     } else {
499         std::list<DhcpRange> listDhcpRange;
500         listDhcpRange.push_back(range);
501         m_mapInfDhcpRange.emplace(std::make_pair(ifname, listDhcpRange));
502         DHCP_LOGI("SetDhcpRange m_mapInfDhcpRange no find ifname:%{public}s, need emplace.", ifname.c_str());
503     }
504 
505     if (CheckAndUpdateConf(ifname) != DHCP_E_SUCCESS) {
506         DHCP_LOGE("SetDhcpRange() CheckAndUpdateConf failed, ifname:%{public}s.", ifname.c_str());
507         RemoveDhcpRange(ifname, range);
508         return DHCP_E_FAILED;
509     }
510 
511     return DHCP_E_SUCCESS;
512 }
513 
SetDhcpName(const std::string & ifname,const std::string & tagName)514 ErrCode DhcpServerServiceImpl::SetDhcpName(const std::string& ifname, const std::string& tagName)
515 {
516     if (!DhcpPermissionUtils::VerifyIsNativeProcess()) {
517         DHCP_LOGE("SetDhcpName:NOT NATIVE PROCESS, PERMISSION_DENIED!");
518         return DHCP_E_PERMISSION_DENIED;
519     }
520     if (!DhcpPermissionUtils::VerifyDhcpNetworkPermission("ohos.permission.NETWORK_DHCP")) {
521         DHCP_LOGE("SetDhcpName:VerifyDhcpNetworkPermission PERMISSION_DENIED!");
522         return DHCP_E_PERMISSION_DENIED;
523     }
524     if (ifname.empty() || tagName.empty()) {
525         DHCP_LOGE("SetDhcpName failed, ifname or tagName is empty!");
526         return DHCP_E_FAILED;
527     }
528     return SetDhcpNameExt(ifname, tagName);
529 }
530 
SetDhcpNameExt(const std::string & ifname,const std::string & tagName)531 ErrCode DhcpServerServiceImpl::SetDhcpNameExt(const std::string& ifname, const std::string& tagName)
532 {
533     auto iterTag = m_mapTagDhcpRange.find(tagName);
534     if (iterTag == m_mapTagDhcpRange.end()) {
535         DHCP_LOGE("SetDhcpName tag m_mapTagDhcpRange no find tagName:%{public}s.", tagName.c_str());
536         return DHCP_E_FAILED;
537     }
538 
539     int nSize = (int)iterTag->second.size();
540     if (nSize != 1) {
541         DHCP_LOGE("SetDhcpName tag %{public}s range size:%{public}d error.", tagName.c_str(), nSize);
542         return DHCP_E_FAILED;
543     }
544 
545     /* check same network */
546     for (auto iterTagValue : iterTag->second) {
547         if (DhcpFunction::CheckRangeNetwork(ifname, iterTagValue.strStartip, iterTagValue.strEndip) !=
548             DHCP_OPT_SUCCESS) {
549             DHCP_LOGE("SetDhcpName tag CheckRangeNetwork failed, ifname:%{public}s.", ifname.c_str());
550             return DHCP_E_FAILED;
551         }
552     }
553 
554     auto iterRangeMap = m_mapInfDhcpRange.find(ifname);
555     if (iterRangeMap != m_mapInfDhcpRange.end()) {
556         nSize = (int)iterRangeMap->second.size();
557         if (nSize > 1) {
558             DHCP_LOGE("SetDhcpName tag failed, %{public}s range size:%{public}d error!", ifname.c_str(), nSize);
559             return DHCP_E_FAILED;
560         }
561         if (nSize == 1) {
562             DHCP_LOGW("SetDhcpName tag %{public}s range size:%{public}d already exist.", ifname.c_str(), nSize);
563             iterRangeMap->second.clear();
564         }
565         DHCP_LOGI("SetDhcpName tag m_mapInfDhcpRange find ifname:%{public}s, need push_back.", ifname.c_str());
566         for (auto iterTagValue : iterTag->second) {
567             iterRangeMap->second.push_back(iterTagValue);
568         }
569     } else {
570         m_mapInfDhcpRange.emplace(std::make_pair(ifname, iterTag->second));
571         DHCP_LOGI("SetDhcpName tag no find %{public}s, need emplace %{public}s.", ifname.c_str(), tagName.c_str());
572     }
573 
574     /* update or reload interface config file */
575     if (CheckAndUpdateConf(ifname) != DHCP_E_SUCCESS) {
576         DHCP_LOGE("SetDhcpName tag CheckAndUpdateConf failed, ifname:%{public}s.", ifname.c_str());
577         return DHCP_E_FAILED;
578     }
579     return DHCP_E_SUCCESS;
580 }
581 
GetDhcpClientInfos(const std::string & ifname,std::vector<std::string> & leases)582 ErrCode DhcpServerServiceImpl::GetDhcpClientInfos(const std::string& ifname, std::vector<std::string>& leases)
583 {
584     if (!DhcpPermissionUtils::VerifyIsNativeProcess()) {
585         DHCP_LOGE("GetDhcpClientInfos:NOT NATIVE PROCESS, PERMISSION_DENIED!");
586         return DHCP_E_PERMISSION_DENIED;
587     }
588     if (!DhcpPermissionUtils::VerifyDhcpNetworkPermission("ohos.permission.NETWORK_DHCP")) {
589         DHCP_LOGE("GetDhcpClientInfos:VerifyDhcpNetworkPermission PERMISSION_DENIED!");
590         return DHCP_E_PERMISSION_DENIED;
591     }
592     if (ifname.empty()) {
593         DHCP_LOGE("DhcpServerService::GetDhcpClientInfos error, ifname is empty!");
594         return DHCP_E_FAILED;
595     }
596 
597     std::string strFile = DHCP_SERVER_LEASES_FILE + "." + ifname;
598     if (!DhcpFunction::IsExistFile(strFile)) {
599         DHCP_LOGE("GetDhcpClientInfos() failed, dhcp leasefile:%{public}s no exist!", strFile.c_str());
600         return DHCP_E_FAILED;
601     }
602     leases.clear();
603     char *realPaths = realpath(strFile.c_str(), nullptr);
604     if (realPaths == nullptr) {
605         DHCP_LOGE("realpath failed error");
606         return DHCP_E_FAILED;
607     }
608     FILE *inFile = fopen(realPaths, "r");
609     if (!inFile) {
610         DHCP_LOGE("GetDhcpClientInfos() failed, unable to open file: %{public}s", strFile.c_str());
611         free(realPaths);
612         return DHCP_E_FAILED;
613     }
614 
615     char tmpLineData[FILE_LINE_MAX_SIZE] = {0};
616     while (fgets(tmpLineData, sizeof(tmpLineData), inFile) != nullptr) {
617         std::string strTemp = tmpLineData;
618         // Remove the newline character at the end of the line
619         if (!strTemp.empty() && strTemp.back() == '\n') {
620             strTemp.pop_back();
621         }
622         if (!strTemp.empty()) {
623             leases.push_back(strTemp);
624         }
625     }
626     (void)fclose(inFile);
627     DHCP_LOGI("GetDhcpClientInfos leases.size:%{public}d.", (int)leases.size());
628     free(realPaths);
629     return DHCP_E_SUCCESS;
630 }
631 
UpdateLeasesTime(const std::string & leaseTime)632 ErrCode DhcpServerServiceImpl::UpdateLeasesTime(const std::string& leaseTime)
633 {
634     DHCP_LOGI("UpdateLeasesTime");
635     if (!DhcpPermissionUtils::VerifyIsNativeProcess()) {
636         DHCP_LOGE("UpdateLeasesTime:NOT NATIVE PROCESS, PERMISSION_DENIED!");
637         return DHCP_E_PERMISSION_DENIED;
638     }
639     if (!DhcpPermissionUtils::VerifyDhcpNetworkPermission("ohos.permission.NETWORK_DHCP")) {
640         DHCP_LOGE("UpdateLeasesTime:VerifyDhcpNetworkPermission PERMISSION_DENIED!");
641         return DHCP_E_PERMISSION_DENIED;
642     }
643     std::string strData = "leaseTime=" + leaseTime + "\n";
644     std::string strFile = DHCP_SERVER_CONFIG_FILE;
645     if (!DhcpFunction::IsExistFile(strFile)) {
646         DhcpFunction::CreateFile(strFile, strData);
647     } else {
648         DhcpFunction::RemoveFile(strFile);
649         DhcpFunction::CreateFile(strFile, strData);
650     }
651 
652     return DHCP_E_SUCCESS;
653 }
654 
IsRemoteDied(void)655 bool DhcpServerServiceImpl::IsRemoteDied(void)
656 {
657     DHCP_LOGE("IsRemoteDied");
658     return true;
659 }
660 
CheckAndUpdateConf(const std::string & ifname)661 int DhcpServerServiceImpl::CheckAndUpdateConf(const std::string &ifname)
662 {
663     if (ifname.empty()) {
664         DHCP_LOGE("CheckAndUpdateConf error, ifname is empty!");
665         return DHCP_OPT_ERROR;
666     }
667 
668     auto iterRangeMap = m_mapInfDhcpRange.find(ifname);
669     if ((iterRangeMap == m_mapInfDhcpRange.end()) || (iterRangeMap->second).empty()) {
670         return DHCP_OPT_SUCCESS;
671     }
672     int nSize = (int)iterRangeMap->second.size();
673     if (nSize > 1) {
674         DHCP_LOGE("CheckAndUpdateConf failed, %{public}s range size:%{public}d error!", ifname.c_str(), nSize);
675         return DHCP_OPT_FAILED;
676     }
677 
678     for (auto iterRange : iterRangeMap->second) {
679         if (((iterRange.iptype != 0) && (iterRange.iptype != 1)) || (iterRange.leaseHours <= 0) ||
680             (iterRange.strStartip.size() == 0) || (iterRange.strEndip.size() == 0)) {
681             DHCP_LOGE("CheckAndUpdateConf failed, "
682                       "iptype:%{public}d,leaseHours:%{public}d,strStartip:%{private}s,strEndip:%{private}s error!",
683                 iterRange.iptype, iterRange.leaseHours, iterRange.strStartip.c_str(), iterRange.strEndip.c_str());
684             return DHCP_OPT_FAILED;
685         }
686     }
687 
688     return DHCP_OPT_SUCCESS;
689 }
690 
CheckIpAddrRange(const DhcpRange & range)691 bool DhcpServerServiceImpl::CheckIpAddrRange(const DhcpRange &range)
692 {
693     if (((range.iptype != 0) && (range.iptype != 1)) || range.strStartip.empty() || range.strEndip.empty()) {
694         DHCP_LOGE("CheckIpAddrRange range.iptype:%{public}d,strStartip:%{private}s,strEndip:%{private}s error!",
695             range.iptype, range.strStartip.c_str(), range.strEndip.c_str());
696         return false;
697     }
698 
699     if (range.iptype == 0) {
700         uint32_t uStartIp = 0;
701         if (!DhcpFunction::Ip4StrConToInt(range.strStartip, uStartIp)) {
702             DHCP_LOGE("CheckIpAddrRange Ip4StrConToInt failed, range.iptype:%{public}d,strStartip:%{private}s!",
703                 range.iptype, range.strStartip.c_str());
704             return false;
705         }
706         uint32_t uEndIp = 0;
707         if (!DhcpFunction::Ip4StrConToInt(range.strEndip, uEndIp)) {
708             DHCP_LOGE("CheckIpAddrRange Ip4StrConToInt failed, range.iptype:%{public}d,strEndip:%{private}s!",
709                 range.iptype, range.strEndip.c_str());
710             return false;
711         }
712         /* check ip4 start and end ip */
713         if (uStartIp >= uEndIp) {
714             DHCP_LOGE("CheckIpAddrRange failed, start:%{private}u not less end:%{private}u!", uStartIp, uEndIp);
715             return false;
716         }
717     } else {
718         uint8_t uStartIp6[sizeof(struct in6_addr)] = {0};
719         if (!DhcpFunction::Ip6StrConToChar(range.strStartip, uStartIp6, sizeof(struct in6_addr))) {
720             return false;
721         }
722         uint8_t uEndIp6[sizeof(struct in6_addr)] = {0};
723         if (!DhcpFunction::Ip6StrConToChar(range.strEndip, uEndIp6, sizeof(struct in6_addr))) {
724             return false;
725         }
726         /* check ip6 start and end ip */
727     }
728 
729     return true;
730 }
731 
AddSpecifiedInterface(const std::string & ifname)732 int DhcpServerServiceImpl::AddSpecifiedInterface(const std::string& ifname)
733 {
734     if (ifname.empty()) {
735         DHCP_LOGE("AddSpecifiedInterface param error, ifname is empty!");
736         return DHCP_OPT_ERROR;
737     }
738 
739     if (m_setInterfaces.find(ifname) == m_setInterfaces.end()) {
740         m_setInterfaces.insert(ifname);
741         DHCP_LOGI("AddSpecifiedInterface started interfaces add %{public}s success.", ifname.c_str());
742     }
743     return DHCP_OPT_SUCCESS;
744 }
745 
GetUsingIpRange(const std::string ifname,std::string & ipRange)746 int DhcpServerServiceImpl::GetUsingIpRange(const std::string ifname, std::string& ipRange)
747 {
748     if (ifname.empty()) {
749         DHCP_LOGE("GetUsingIpRange param error, ifname is empty!");
750         return DHCP_OPT_ERROR;
751     }
752 
753     auto iterRangeMap = m_mapInfDhcpRange.find(ifname);
754     if (iterRangeMap == m_mapInfDhcpRange.end()) {
755         DHCP_LOGE("GetUsingIpRange failed, inf range map no find %{public}s!", ifname.c_str());
756         return DHCP_OPT_FAILED;
757     }
758     int nSize = (int)iterRangeMap->second.size();
759     if (nSize != 1) {
760         DHCP_LOGE("GetUsingIpRange failed, %{public}s range size:%{public}d error!", ifname.c_str(), nSize);
761         return DHCP_OPT_FAILED;
762     }
763 
764     for (auto iterRange : iterRangeMap->second) {
765         if (((iterRange.iptype != 0) && (iterRange.iptype != 1)) || (iterRange.leaseHours <= 0) ||
766             (iterRange.strStartip.size() == 0) || (iterRange.strEndip.size() == 0)) {
767             DHCP_LOGE("GetUsingIpRange type:%{public}d,lease:%{public}d,start:%{private}s,end:%{private}s error!",
768                 iterRange.iptype, iterRange.leaseHours, iterRange.strStartip.c_str(), iterRange.strEndip.c_str());
769             return DHCP_OPT_FAILED;
770         }
771         ipRange.clear();
772         ipRange = iterRange.strStartip + "," + iterRange.strEndip;
773         return DHCP_OPT_SUCCESS;
774     }
775     DHCP_LOGE("GetUsingIpRange failed, %{public}s range size:%{public}d", ifname.c_str(), nSize);
776     return DHCP_OPT_FAILED;
777 }
778 
CreateDefaultConfigFile(const std::string strFile)779 int DhcpServerServiceImpl::CreateDefaultConfigFile(const std::string strFile)
780 {
781     if (strFile.empty()) {
782         DHCP_LOGE("CreateDefaultConfigFile param error, strFile is empty!");
783         return DHCP_OPT_ERROR;
784     }
785 
786 
787     if (!DhcpFunction::IsExistFile(strFile)) {
788         DHCP_LOGI("CreateDefaultConfigFile!");
789         DhcpFunction::CreateDirs(DHCP_SERVER_CONFIG_DIR);
790         std::string strData = "leaseTime=" + std::to_string(LEASETIME_DEFAULT_SERVER * ONE_HOURS_SEC) + "\n";
791         DhcpFunction::CreateFile(strFile, strData);
792     }
793     return DHCP_OPT_SUCCESS;
794 }
795 
DelSpecifiedInterface(const std::string & ifname)796 int DhcpServerServiceImpl::DelSpecifiedInterface(const std::string& ifname)
797 {
798     if (ifname.empty()) {
799         DHCP_LOGE("DelSpecifiedInterface param error, ifname is empty!");
800         return DHCP_OPT_ERROR;
801     }
802 
803     auto iterInterfaces = m_setInterfaces.find(ifname);
804     if (iterInterfaces != m_setInterfaces.end()) {
805         m_setInterfaces.erase(iterInterfaces);
806         DHCP_LOGI("DelSpecifiedInterface started interfaces del %{public}s success.", ifname.c_str());
807     }
808     return DHCP_OPT_SUCCESS;
809 }
810 
DeleteLeaseFile(const std::string & ifname)811 ErrCode DhcpServerServiceImpl::DeleteLeaseFile(const std::string& ifname)
812 {
813     std::string strFile = DHCP_SERVER_LEASES_FILE + "." + ifname;
814     if (!DhcpFunction::IsExistFile(strFile)) {
815         DHCP_LOGE("DeleteLeaseFile failed, dhcp leasefile:%{public}s no exist!", strFile.c_str());
816         return DHCP_E_FAILED;
817     }
818     if (!DhcpFunction::RemoveFile(strFile)) {
819         DHCP_LOGE("DeleteLeaseFile RemoveFile failed, leasefile:%{public}s", strFile.c_str());
820         return DHCP_E_FAILED;
821     }
822     DHCP_LOGI("DeleteLeaseFile RemoveFile ok");
823     return DHCP_E_SUCCESS;
824 }
825 }
826 }