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 }