• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 = &current.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