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