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_address_pool.h"
17 #include <map>
18 #include <mutex>
19 #include <securec.h>
20 #include <stdint.h>
21 #include <cstdio>
22 #include <string.h>
23 #include "address_utils.h"
24 #include "common_util.h"
25 #include "dhcp_logger.h"
26 #include "dhcp_common_utils.h"
27
28 DEFINE_DHCPLOG_DHCP_LABEL("DhcpServerAddressPool");
29
30 #define DHCP_POOL_INIT_SIZE 10
31 #define DHCP_RELEASE_REMOVE_MODE 0
32
33 static int g_releaseRemoveMode = DHCP_RELEASE_REMOVE_MODE;
34 static std::map<std::size_t, AddressBinding> g_bindingRecoders;
35 static std::mutex g_bindingMapMutex;
36 static int g_distributeMode = 0;
37
38 #define HASH_DEFAULT_VALUE 5381
39 #define HASH_CAL_CODE_CAL 5
40 //Write a HASH FUNCTION FOR uint8_t macAddr[DHCP_HWADDR_LENGTH]
macAddrHash(uint8_t macAddr[DHCP_HWADDR_LENGTH])41 std::size_t macAddrHash(uint8_t macAddr[DHCP_HWADDR_LENGTH])
42 {
43 std::size_t hash = HASH_DEFAULT_VALUE;
44 for (std::size_t i = 0; i < DHCP_HWADDR_LENGTH; ++i) {
45 hash = ((hash << HASH_CAL_CODE_CAL) + hash) ^ static_cast<std::size_t>(macAddr[i]);
46 }
47 return hash;
48 }
49
50
GetBindingByMac(uint8_t macAddr[DHCP_HWADDR_LENGTH])51 AddressBinding *GetBindingByMac(uint8_t macAddr[DHCP_HWADDR_LENGTH])
52 {
53 std::size_t hash = macAddrHash(macAddr);
54 std::lock_guard<std::mutex> autoLock(g_bindingMapMutex);
55 if (g_bindingRecoders.count(hash) > 0) {
56 return &g_bindingRecoders[hash];
57 }
58 return nullptr;
59 }
60
QueryBinding(uint8_t macAddr[DHCP_HWADDR_LENGTH],PDhcpOptionList cliOptins)61 AddressBinding *QueryBinding(uint8_t macAddr[DHCP_HWADDR_LENGTH], PDhcpOptionList cliOptins)
62 {
63 return GetBindingByMac(macAddr);
64 }
65
AddNewBinding(uint8_t macAddr[DHCP_HWADDR_LENGTH],PDhcpOptionList cliOptins)66 AddressBinding *AddNewBinding(uint8_t macAddr[DHCP_HWADDR_LENGTH], PDhcpOptionList cliOptins)
67 {
68 AddressBinding newBind = {0};
69 newBind.bindingMode = BIND_MODE_DYNAMIC;
70 newBind.bindingStatus = BIND_PENDING;
71 if (memcpy_s(newBind.chaddr, DHCP_HWADDR_LENGTH, macAddr, DHCP_HWADDR_LENGTH) != EOK) {
72 DHCP_LOGE("newBind chaddr memcpy_s failed!");
73 return nullptr;
74 }
75 newBind.bindingTime = Tmspsec();
76 newBind.pendingTime = Tmspsec();
77 newBind.expireIn = newBind.bindingTime + DHCP_LEASE_TIME;
78 newBind.leaseTime = DHCP_LEASE_TIME;
79 {
80 std::lock_guard<std::mutex> autoLock(g_bindingMapMutex);
81 g_bindingRecoders[macAddrHash(macAddr)] = newBind;
82 }
83 return GetBindingByMac(macAddr);
84 }
85
CheckIpAvailability(DhcpAddressPool * pool,uint8_t macAddr[DHCP_HWADDR_LENGTH],uint32_t distIp)86 int CheckIpAvailability(DhcpAddressPool *pool, uint8_t macAddr[DHCP_HWADDR_LENGTH], uint32_t distIp)
87 {
88 if (!pool) {
89 DHCP_LOGE("pool pointer is null.");
90 return DHCP_FALSE;
91 }
92 if (IsReserved(macAddr)) {
93 DHCP_LOGW("client address(%s) is reserved address.", ParseLogMac(macAddr));
94 return DHCP_FALSE;
95 }
96 AddressBinding *lease = GetLease(pool, distIp);
97 if (lease) {
98 int same = AddrEquels(lease->chaddr, macAddr, MAC_ADDR_LENGTH);
99 if (distIp == pool->serverId || distIp == pool->gateway) {
100 return DHCP_FALSE;
101 }
102 if (lease->bindingMode == BIND_MODE_STATIC && !same) {
103 return DHCP_FALSE;
104 }
105 if (IsReservedIp(pool, distIp) && !same) {
106 return DHCP_FALSE;
107 }
108 if (same) {
109 lease->pendingTime = Tmspsec();
110 lease->bindingTime = lease->pendingTime;
111 return DHCP_TRUE;
112 }
113 if (IsExpire(lease)) {
114 DHCP_LOGD("the binding recoder has expired.");
115 lease->pendingTime = Tmspsec();
116 lease->bindingTime = lease->pendingTime;
117 RemoveBinding(lease->chaddr);
118 if (memcpy_s(lease->chaddr, DHCP_HWADDR_LENGTH, macAddr, MAC_ADDR_LENGTH) != EOK) {
119 DHCP_LOGD("failed to rewrite client address.");
120 }
121 return DHCP_TRUE;
122 }
123 return DHCP_FALSE;
124 }
125 return DHCP_TRUE;
126 }
127
CheckRangeAvailability(DhcpAddressPool * pool,uint8_t macAddr[DHCP_HWADDR_LENGTH],uint32_t distIp,int * outOfRange)128 int CheckRangeAvailability(
129 DhcpAddressPool *pool, uint8_t macAddr[DHCP_HWADDR_LENGTH], uint32_t distIp, int *outOfRange)
130 {
131 if (!pool || !pool->addressRange.beginAddress || !pool->addressRange.endAddress) {
132 DHCP_LOGE("pool beginAddress or endAddress pointer is null.");
133 return RET_ERROR;
134 }
135 if (!pool->netmask || IsEmptyHWAddr(macAddr)) {
136 DHCP_LOGE("pool netmask empty hwaddr pointer is null.");
137 return RET_ERROR;
138 }
139 uint32_t beginIp = pool->addressRange.beginAddress;
140 uint32_t endIp = pool->addressRange.endAddress;
141 if (IpInRange(distIp, beginIp, endIp, pool->netmask)) {
142 DHCP_LOGD("distribution IP address");
143 AddressBinding lease = {0};
144 lease.pendingTime = Tmspsec();
145 lease.bindingMode = BIND_PENDING;
146 lease.ipAddress = distIp;
147 lease.bindingTime = lease.pendingTime;
148 lease.leaseTime = pool->leaseTime;
149 if (memcpy_s(lease.chaddr, sizeof(lease.chaddr), macAddr, MAC_ADDR_LENGTH) != EOK) {
150 DHCP_LOGE("failed to set lease chaddr fields");
151 return RET_ERROR;
152 }
153 if (AddLease(pool, &lease) != RET_SUCCESS) {
154 DHCP_LOGE("failed to add lease.");
155 return RET_ERROR;
156 }
157 return RET_SUCCESS;
158 }
159 if (*outOfRange) {
160 DHCP_LOGD("address is out of range");
161 return RET_FAILED;
162 } else {
163 *outOfRange = 1;
164 }
165 return RET_FAILED;
166 }
167
NextIpOffset(uint32_t netmask)168 uint32_t NextIpOffset(uint32_t netmask)
169 {
170 uint32_t offset = 0;
171 if (g_distributeMode && netmask) {
172 uint32_t total = HostTotal(netmask);
173 if (total) {
174 offset = Tmspusec() % total;
175 }
176 DHCP_LOGD("next ip offset is: %u", offset);
177 }
178 return offset;
179 }
180
AddressDistribute(DhcpAddressPool * pool,uint8_t macAddr[DHCP_HWADDR_LENGTH])181 uint32_t AddressDistribute(DhcpAddressPool *pool, uint8_t macAddr[DHCP_HWADDR_LENGTH])
182 {
183 if (!pool || !pool->addressRange.beginAddress || !pool->addressRange.endAddress) {
184 return 0;
185 }
186 if (!pool->netmask || IsEmptyHWAddr(macAddr)) {
187 return 0;
188 }
189 if (pool->distribution == 0) {
190 pool->distribution = pool->addressRange.beginAddress;
191 }
192 uint32_t total = HostTotal(pool->netmask);
193 uint32_t distIp = pool->distribution;
194 if (!distIp || distIp < pool->addressRange.beginAddress) {
195 distIp = pool->addressRange.beginAddress;
196 }
197 int distSucess = 0;
198 int outOfRange = 0;
199 for (uint32_t i = 0; i < total; i++) {
200 uint32_t offset = 0;
201 if (i == 0) {
202 offset = NextIpOffset(pool->netmask);
203 }
204 distIp = NextIpAddress(distIp, pool->netmask, offset);
205 if (!CheckIpAvailability(pool, macAddr, distIp)) {
206 continue;
207 }
208 int ret = CheckRangeAvailability(pool, macAddr, distIp, &outOfRange);
209 if (ret == RET_ERROR) {
210 break;
211 }
212 if (ret == RET_SUCCESS) {
213 distSucess = 1;
214 break;
215 }
216 }
217 if (!distSucess || !distIp) {
218 return 0;
219 }
220 pool->distribution = distIp;
221 return pool->distribution;
222 }
223
InitAddressPool(DhcpAddressPool * pool,const char * ifname,PDhcpOptionList options)224 int InitAddressPool(DhcpAddressPool *pool, const char *ifname, PDhcpOptionList options)
225 {
226 if (!pool) {
227 DHCP_LOGD("address pool pointer is null.");
228 return RET_ERROR;
229 }
230 if (memset_s(pool, sizeof(DhcpAddressPool), 0, sizeof(DhcpAddressPool)) != EOK) {
231 DHCP_LOGD("failed to init dhcp pool.");
232 return RET_ERROR;
233 }
234 if (memset_s(pool->ifname, IFACE_NAME_SIZE, '\0', IFACE_NAME_SIZE) != EOK) {
235 DHCP_LOGD("failed to reset interface name.");
236 return RET_ERROR;
237 }
238 if (strncpy_s(pool->ifname, IFACE_NAME_SIZE, ifname, strlen(ifname)) != EOK) {
239 DHCP_LOGD("failed to set interface name.");
240 return RET_ERROR;
241 }
242 if (InitOptionList(&pool->fixedOptions) != RET_SUCCESS) {
243 DHCP_LOGD("failed to init options field for dhcp pool.");
244 return RET_FAILED;
245 }
246 std::lock_guard<std::mutex> autoLock(g_bindingMapMutex);
247 g_bindingRecoders.clear();
248
249 pool->distribue = AddressDistribute;
250 pool->binding = QueryBinding;
251 pool->newBinding = AddNewBinding;
252 pool->leaseTable.clear();
253 return RET_SUCCESS;
254 }
255
FreeAddressPool(DhcpAddressPool * pool)256 void FreeAddressPool(DhcpAddressPool *pool)
257 {
258 if (!pool) {
259 return;
260 }
261
262 if (pool->fixedOptions.size > 0) {
263 ClearOptions(&pool->fixedOptions);
264 }
265
266 if (pool) {
267 pool->leaseTable.clear();
268 }
269
270 if (pool && HasInitialized(&pool->fixedOptions)) {
271 FreeOptionList(&pool->fixedOptions);
272 }
273 }
274
FindBindingByIp(uint32_t ipAddress)275 AddressBinding *FindBindingByIp(uint32_t ipAddress)
276 {
277 std::lock_guard<std::mutex> autoLock(g_bindingMapMutex);
278 if (g_bindingRecoders.empty()) {
279 return nullptr;
280 }
281 for (auto current: g_bindingRecoders) {
282 AddressBinding *binding = ¤t.second;
283 if (binding && ipAddress == binding->ipAddress) {
284 return binding;
285 }
286 }
287 return nullptr;
288 }
289
IsReserved(uint8_t macAddr[DHCP_HWADDR_LENGTH])290 int IsReserved(uint8_t macAddr[DHCP_HWADDR_LENGTH])
291 {
292 std::lock_guard<std::mutex> autoLock(g_bindingMapMutex);
293 if (g_bindingRecoders.count(macAddrHash(macAddr)) > 0) {
294 AddressBinding *binding = &g_bindingRecoders[macAddrHash(macAddr)];
295 if (binding && binding->bindingMode == BIND_MODE_RESERVED) {
296 return DHCP_TRUE;
297 }
298 }
299 return DHCP_FALSE;
300 }
301
IsReservedIp(DhcpAddressPool * pool,uint32_t ipAddress)302 int IsReservedIp(DhcpAddressPool *pool, uint32_t ipAddress)
303 {
304 if (!pool) {
305 return DHCP_FALSE;
306 }
307 if (!ipAddress) {
308 return DHCP_FALSE;
309 }
310 if (pool->leaseTable.count(ipAddress) >0) {
311 AddressBinding *lease = &pool->leaseTable[ipAddress];
312 if (lease && lease->bindingMode == BIND_MODE_RESERVED) {
313 return DHCP_TRUE;
314 }
315 }
316 return DHCP_FALSE;
317 }
318
AddBinding(AddressBinding * binding)319 int AddBinding(AddressBinding *binding)
320 {
321 if (!binding) {
322 DHCP_LOGE("binding pointer is null.");
323 return RET_ERROR;
324 }
325 if (IsEmptyHWAddr(binding->chaddr)) {
326 DHCP_LOGE("binding address is empty.");
327 return RET_ERROR;
328 }
329 if (!binding->ipAddress) {
330 DHCP_LOGE("binding ip is empty.");
331 return RET_ERROR;
332 }
333 std::lock_guard<std::mutex> autoLock(g_bindingMapMutex);
334 if (g_bindingRecoders.count(macAddrHash(binding->chaddr)) > 0) {
335 DHCP_LOGW("binding recoder exist.");
336 return RET_FAILED;
337 }
338 g_bindingRecoders[macAddrHash(binding->chaddr)] = *binding;
339 return RET_SUCCESS;
340 }
341
AddReservedBinding(uint8_t macAddr[DHCP_HWADDR_LENGTH])342 int AddReservedBinding(uint8_t macAddr[DHCP_HWADDR_LENGTH])
343 {
344 AddressBinding *binding = GetBindingByMac(macAddr);
345 if (binding) {
346 binding->bindingMode = BIND_MODE_RESERVED;
347 } else {
348 AddressBinding bind = {0};
349 bind.bindingMode = BIND_MODE_RESERVED;
350 bind.bindingTime = Tmspsec();
351 bind.pendingTime = bind.bindingTime;
352 std::lock_guard<std::mutex> autoLock(g_bindingMapMutex);
353 g_bindingRecoders[macAddrHash(macAddr)] = bind;
354 }
355 return RET_SUCCESS;
356 }
357
RemoveBinding(uint8_t macAddr[DHCP_HWADDR_LENGTH])358 int RemoveBinding(uint8_t macAddr[DHCP_HWADDR_LENGTH])
359 {
360 std::lock_guard<std::mutex> autoLock(g_bindingMapMutex);
361 if (g_bindingRecoders.count(macAddrHash(macAddr)) > 0) {
362 g_bindingRecoders.erase(macAddrHash(macAddr));
363 return RET_SUCCESS;
364 }
365 return RET_FAILED;
366 }
367
RemoveReservedBinding(uint8_t macAddr[DHCP_HWADDR_LENGTH])368 int RemoveReservedBinding(uint8_t macAddr[DHCP_HWADDR_LENGTH])
369 {
370 std::lock_guard<std::mutex> autoLock(g_bindingMapMutex);
371 if (g_bindingRecoders.count(macAddrHash(macAddr)) > 0) {
372 AddressBinding *binding = &g_bindingRecoders[macAddrHash(macAddr)];
373 if (binding && binding->bindingMode == BIND_MODE_RESERVED) {
374 g_bindingRecoders.erase(macAddrHash(macAddr));
375 return RET_SUCCESS;
376 }
377 }
378 DHCP_LOGW("binding mode is not 'BIND_MODE_RESERVED'.");
379 return RET_FAILED;
380 }
381
ReleaseBinding(uint8_t macAddr[DHCP_HWADDR_LENGTH])382 int ReleaseBinding(uint8_t macAddr[DHCP_HWADDR_LENGTH])
383 {
384 std::lock_guard<std::mutex> autoLock(g_bindingMapMutex);
385 if (g_bindingRecoders.count(macAddrHash(macAddr)) > 0) {
386 if (g_releaseRemoveMode) {
387 g_bindingRecoders.erase(macAddrHash(macAddr));
388 return RET_SUCCESS;
389 }
390 AddressBinding *binding = &g_bindingRecoders[macAddrHash(macAddr)];
391 if (binding) {
392 binding->bindingStatus = BIND_RELEASED;
393 return RET_SUCCESS;
394 }
395 }
396 return RET_FAILED;
397 }
398
AddLease(DhcpAddressPool * pool,AddressBinding * lease)399 int AddLease(DhcpAddressPool *pool, AddressBinding *lease)
400 {
401 if (!pool) {
402 DHCP_LOGE("add lease pool pointer is null.");
403 return RET_ERROR;
404 }
405
406 if (!lease || !lease->ipAddress || IsEmptyHWAddr(lease->chaddr)) {
407 DHCP_LOGE("add lease pool ipAddress or chaddr pointer is null.");
408 return RET_ERROR;
409 }
410
411 if (pool->leaseTable.count(lease->ipAddress) > 0) {
412 DHCP_LOGI("update lease info.");
413 pool->leaseTable[lease->ipAddress] = *lease;
414 return RET_SUCCESS;
415 } else {
416 DHCP_LOGI("insert lease info.");
417 pool->leaseTable[lease->ipAddress] = *lease;
418 return RET_SUCCESS;
419 }
420 }
421
GetLease(DhcpAddressPool * pool,uint32_t ipAddress)422 AddressBinding *GetLease(DhcpAddressPool *pool, uint32_t ipAddress)
423 {
424 if (!ipAddress) {
425 DHCP_LOGE("get lease ipAddress pointer is null.");
426 return nullptr;
427 }
428 if (!pool) {
429 DHCP_LOGE("get lease pool pointer is null.");
430 return nullptr;
431 }
432 uint32_t ipAddr = ipAddress;
433 if (pool->leaseTable.count(ipAddr) > 0) {
434 return &pool->leaseTable[ipAddr];
435 }
436 DHCP_LOGE("get lease address binding pointer is null.");
437 return nullptr;
438 }
439
UpdateLease(DhcpAddressPool * pool,AddressBinding * lease)440 int UpdateLease(DhcpAddressPool *pool, AddressBinding *lease)
441 {
442 if (!pool) {
443 DHCP_LOGE("update lease pool pointer is null.");
444 return RET_ERROR;
445 }
446
447 if (!lease || !lease->ipAddress || IsEmptyHWAddr(lease->chaddr)) {
448 DHCP_LOGE("update lease pool ipAddress or chaddr pointer is null.");
449 return RET_ERROR;
450 }
451 if (pool->leaseTable.count(lease->ipAddress) > 0) {
452 pool->leaseTable[lease->ipAddress] = *lease;
453 return RET_SUCCESS;
454 }
455 DHCP_LOGE("update lease address binding pointer is null.");
456 return RET_FAILED;
457 }
458
RemoveLease(DhcpAddressPool * pool,AddressBinding * lease)459 int RemoveLease(DhcpAddressPool *pool, AddressBinding *lease)
460 {
461 if (!pool) {
462 DHCP_LOGE("remove lease pool pointer is null.");
463 return RET_ERROR;
464 }
465
466 if (!lease || !lease->ipAddress || IsEmptyHWAddr(lease->chaddr)) {
467 DHCP_LOGE("remove lease pool ipAddress or chaddr pointer is null.");
468 return RET_ERROR;
469 }
470
471 if (pool->leaseTable.count(lease->ipAddress) > 0) {
472 pool->leaseTable.erase(lease->ipAddress);
473 return RET_SUCCESS;
474 }
475 DHCP_LOGE("remove lease address binding pointer is null.");
476 return RET_FAILED;
477 }
478
LoadBindingRecoders(DhcpAddressPool * pool)479 int LoadBindingRecoders(DhcpAddressPool *pool)
480 {
481 if (pool == nullptr) {
482 DHCP_LOGE("loadbinding recorder pool pointer is null.");
483 return RET_FAILED;
484 }
485 char filePath[DHCP_LEASE_FILE_LENGTH] = {0};
486 if (snprintf_s(filePath, sizeof(filePath), sizeof(filePath) - 1, "%s.%s", DHCPD_LEASE_FILE, pool->ifname) < 0) {
487 DHCP_LOGE("Failed to get dhcp lease file path!");
488 return RET_FAILED;
489 }
490 FILE *fp = fopen(filePath, "r");
491 if (fp == nullptr) {
492 return RET_FAILED;
493 }
494 uint32_t beginIp = pool->addressRange.beginAddress;
495 uint32_t endIp = pool->addressRange.endAddress;
496 uint32_t netmask = pool->netmask;
497 char line[DHCP_FILE_LINE_LENGTH] = {0};
498 while (fgets(line, DHCP_FILE_LINE_LENGTH, fp) != nullptr) {
499 TrimString(line);
500 if (line[0] == '\0') { /* skip empty line */
501 continue;
502 }
503 AddressBinding bind = {0};
504 if (ParseAddressBinding(&bind, line) != 0) {
505 continue;
506 }
507 if (IpInRange(bind.ipAddress, beginIp, endIp, netmask)) {
508 pool->leaseTable[bind.ipAddress] = bind;
509 }
510 }
511
512 if (fclose(fp) != 0) {
513 DHCP_LOGE("LoadBindingRecoders fclose fp failed!");
514 }
515 return RET_SUCCESS;
516 }
517
SaveBindingRecoders(const DhcpAddressPool * pool,int force)518 int SaveBindingRecoders(const DhcpAddressPool *pool, int force)
519 {
520 if (pool == nullptr) {
521 DHCP_LOGE("Save binding record, pool is null");
522 return RET_FAILED;
523 }
524 static uint64_t lastTime = 0;
525 uint64_t currTime = Tmspsec();
526 if (force == 0 && currTime < lastTime + DHCP_REFRESH_LEASE_FILE_INTERVAL) {
527 DHCP_LOGE("Save binding record, time interval is not satisfied.");
528 return RET_WAIT_SAVE;
529 }
530 char filePath[DHCP_LEASE_FILE_LENGTH] = {0};
531 if (snprintf_s(filePath, sizeof(filePath), sizeof(filePath) - 1, "%s.%s", DHCPD_LEASE_FILE, pool->ifname) < 0) {
532 DHCP_LOGE("Failed to set dhcp lease file path!");
533 return RET_FAILED;
534 }
535 char line[DHCP_FILE_LINE_LENGTH] = {0};
536 if (!OHOS::DHCP::IsValidPath(filePath)) {
537 DHCP_LOGE("invalid path:%{public}s", filePath);
538 return RET_FAILED;
539 }
540
541 FILE *fp = fopen(filePath, "w");
542 if (fp == nullptr) {
543 DHCP_LOGE("Save binding records %{private}s failed: %{public}d", filePath, errno);
544 return RET_FAILED;
545 }
546 for (auto index: pool->leaseTable) {
547 AddressBinding *binding = &index.second;
548 if (binding && WriteAddressBinding(binding, line, sizeof(line)) != RET_SUCCESS) {
549 DHCP_LOGE("Failed to convert binding info to string");
550 } else {
551 fprintf(fp, "%s\n", line);
552 }
553 }
554
555 if (fclose(fp) != 0) {
556 DHCP_LOGE("SaveBindingRecoders fclose fp failed!");
557 }
558 lastTime = currTime;
559 return RET_SUCCESS;
560 }
561
SetDistributeMode(int mode)562 void SetDistributeMode(int mode)
563 {
564 g_distributeMode = mode;
565 }
GetDistributeMode(void)566 int GetDistributeMode(void)
567 {
568 return g_distributeMode;
569 }
570
DeleteMacInLease(DhcpAddressPool * pool,AddressBinding * lease)571 int DeleteMacInLease(DhcpAddressPool *pool, AddressBinding *lease)
572 {
573 if ((pool == nullptr) || (lease == nullptr)) {
574 DHCP_LOGE("DeleteMacInLease pointer is null.");
575 return RET_ERROR;
576 }
577 for (auto it = pool->leaseTable.begin(); it != pool->leaseTable.end();) {
578 AddressBinding *binding = &(it->second);
579 if (binding && AddrEquels(binding->chaddr, lease->chaddr, MAC_ADDR_LENGTH)) {
580 it = pool->leaseTable.erase(it);
581 } else {
582 ++it;
583 }
584 }
585 return RET_SUCCESS;
586 }
587