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