• 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_binding.h"
17 #include <securec.h>
18 #include <stdint.h>
19 #include <cstdlib>
20 #include <string.h>
21 #include <sys/time.h>
22 #include "address_utils.h"
23 #include "common_util.h"
24 #include "dhcp_s_define.h"
25 #include "dhcp_logger.h"
26 #include "dhcp_common_utils.h"
27 
28 DEFINE_DHCPLOG_DHCP_LABEL("DhcpServerBinding");
29 
30 #define PENDING_INTERVAL_MAX_TIME 1200
31 #define PENDING_INTERVAL_LEVEL0 3
32 #define PENDING_INTERVAL_LEVEL1 10
33 #define PENDING_INTERVAL_LEVEL2 30
34 #define PENDING_MIN_WAITING_TIMES 1
35 #define PENDING_INTERVAL_LEVEL1_TIMES 2
36 #define PENDING_INTERVAL_LEVEL2_TIMES 5
37 
NextPendingInterval(uint64_t pendingInterval)38 uint64_t NextPendingInterval(uint64_t pendingInterval)
39 {
40     uint64_t next = pendingInterval;
41     if (next < PENDING_INTERVAL_LEVEL0) {
42         next += PENDING_MIN_WAITING_TIMES;
43     } else if (next < PENDING_INTERVAL_LEVEL1) {
44         next += PENDING_INTERVAL_LEVEL1_TIMES;
45     } else if (next < PENDING_INTERVAL_LEVEL2) {
46         next += PENDING_INTERVAL_LEVEL2_TIMES;
47     } else {
48         next = PENDING_INTERVAL_MAX_TIME;
49     }
50     return next;
51 }
52 
IsExpire(AddressBinding * binding)53 int IsExpire(AddressBinding *binding)
54 {
55     if (!binding) {
56         DHCP_LOGE("binding is null.");
57         return DHCP_FALSE;
58     }
59     uint64_t leaseTime = binding->leaseTime;
60     if (!leaseTime) {
61         leaseTime = DHCP_LEASE_TIME;
62     }
63     uint64_t expireIn = binding->expireIn;
64     if (binding->bindingStatus == BIND_PENDING) {
65         expireIn = binding->pendingTime + leaseTime;
66     } else if (binding->bindingStatus == BIND_ASSOCIATED) {
67         expireIn = binding->bindingTime + leaseTime;
68     }
69     uint64_t curr = Tmspsec();
70     if (curr > expireIn) {
71         binding->bindingStatus = BIND_EXPIRED;
72         return DHCP_TRUE;
73     }
74     return DHCP_FALSE;
75 }
76 
77 #define BINDING_MAC_ADDR_POS 0
78 #define BINDING_IP_ADDR_POS 1
79 #define BINDING_LEASE_TIME_POS 2
80 #define BINDING_BINDING_TIME_POS 3
81 #define BINDING_PENDING_TIME_POS 4
82 #define BINDING_PENDING_INTERVAL_POS 5
83 #define BINDING_BINDING_MODE_POS 6
84 #define BINDING_BINDING_STATUS_POS 7
85 #define BINDING_DEVICE_NAME_POS 8
86 #define BINDING_STRING_SIZE 8
87 #define BINDING_STRING_MAX_SIZE 9
88 #define BINDING_MIN_LENGTH 20
WriteAddressBinding(const AddressBinding * binding,char * out,uint32_t size)89 int WriteAddressBinding(const AddressBinding *binding, char *out, uint32_t size)
90 {
91     if (!binding || !out) {
92         return RET_FAILED;
93     }
94     const char *mac = ParseStrMac(binding->chaddr, sizeof(binding->chaddr));
95     const char *ip = ParseStrIp(binding->ipAddress);
96     if (mac == nullptr || ip == nullptr) {
97         return RET_FAILED;
98     }
99     if (size < BINDING_MIN_LENGTH) {
100         DHCP_LOGE("WriteAddressBinding out buffer size is too small.");
101         return RET_FAILED;
102     }
103     if (snprintf_s(out, size, size - 1, "%s %s %llu %llu %llu %llu %d %d %s", mac, ip, binding->leaseTime,
104         binding->bindingTime, binding->pendingTime, binding->pendingInterval, binding->bindingMode,
105         binding->bindingStatus, binding->deviceName) < 0) {
106         return RET_FAILED;
107     }
108     return RET_SUCCESS;
109 }
110 
ReleaseStrings(char ** strs)111 static void ReleaseStrings(char **strs)
112 {
113     if (strs == nullptr) {
114         return;
115     }
116     int i = 0;
117     while (strs[i] != nullptr) {
118         free(strs[i]);
119         strs[i] = nullptr;
120         ++i;
121     }
122     free(strs);
123     strs = nullptr;
124     return;
125 }
126 
SplitString(const char * buf,const char * split)127 static char **SplitString(const char *buf, const char *split)
128 {
129     const char *pos = buf;
130     const char *p = nullptr;
131     size_t len = strlen(split);
132     int num = 0;
133     while ((p = strstr(pos, split)) != nullptr) {
134         if (p != pos) {
135             ++num;
136         }
137         pos = p + len;
138     }
139     if (*pos != '\0') {
140         ++num;
141     }
142     if (num == 0) {
143         return nullptr;
144     }
145     char **strs = (char **)calloc(num + 1, sizeof(char *));
146     if (strs == nullptr) {
147         return nullptr;
148     }
149     pos = buf;
150     num = 0;
151     while ((p = strstr(pos, split)) != nullptr) {
152         if (p != pos) {
153             size_t strLen = p - pos + 1;
154             strs[num] = (char *)calloc(strLen, sizeof(char));
155             if (strs[num] == nullptr || strncpy_s(strs[num], strLen, pos, p - pos) != EOK) {
156                 ReleaseStrings(strs);
157                 return nullptr;
158             }
159             ++num;
160         }
161         pos = p + len;
162     }
163     if (*pos != '\0') {
164         size_t strLen = strlen(pos) + 1;
165         strs[num] = (char *)calloc(strLen, sizeof(char));
166         if (strs[num] == nullptr || strncpy_s(strs[num], strLen, pos, strlen(pos)) != EOK) {
167             ReleaseStrings(strs);
168             return nullptr;
169         }
170     }
171     return strs;
172 }
173 
ParseAddressBinding(AddressBinding * binding,const char * buf)174 int ParseAddressBinding(AddressBinding *binding, const char *buf)
175 {
176     uint64_t curr = Tmspsec();
177     char **strs = SplitString(buf, " ");
178     if (strs == nullptr) {
179         return -1;
180     }
181     int num = 0;
182     while (strs[num] != nullptr) {
183         ++num;
184     }
185     int ret = -1;
186     do {
187         if (num < BINDING_STRING_SIZE) {
188             break;
189         }
190         ParseMacAddress(strs[BINDING_MAC_ADDR_POS], binding->chaddr);
191         binding->ipAddress = ParseIpAddr(strs[BINDING_IP_ADDR_POS]);
192         binding->leaseTime = OHOS::DHCP::CheckDataToUint64(strs[BINDING_LEASE_TIME_POS]);
193         binding->bindingTime = OHOS::DHCP::CheckDataToUint64(strs[BINDING_BINDING_TIME_POS]);
194         binding->pendingTime = OHOS::DHCP::CheckDataToUint64(strs[BINDING_PENDING_TIME_POS]);
195         if (binding->bindingTime && binding->bindingTime < binding->pendingTime) {
196             break;
197         }
198         if (binding->pendingTime > curr) { /* if pending time over than current system time */
199             binding->bindingTime = binding->bindingTime - binding->pendingTime + curr;
200             binding->pendingTime = curr;
201         }
202         binding->pendingInterval = OHOS::DHCP::CheckDataToUint64(strs[BINDING_PENDING_INTERVAL_POS]);
203         binding->bindingMode = OHOS::DHCP::CheckDataLegal(strs[BINDING_BINDING_MODE_POS]);
204         binding->bindingStatus = OHOS::DHCP::CheckDataLegal(strs[BINDING_BINDING_STATUS_POS]);
205         if (binding->bindingStatus == BIND_ASSOCIATED) {
206             binding->expireIn = binding->bindingTime + binding->leaseTime;
207         }
208         if (num >= BINDING_STRING_MAX_SIZE) {
209             ParseHostName(strs[BINDING_DEVICE_NAME_POS], binding->deviceName);
210             DHCP_LOGI("ParseHostName deviceName:%{private}s", binding->deviceName);
211         }
212         ret += 1; /* set ret = 0 */
213     } while (0);
214     ReleaseStrings(strs);
215     return ret;
216 }
217