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