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