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