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 "address_utils.h"
17 #include <arpa/inet.h>
18 #include <netinet/in.h>
19 #include <securec.h>
20 #include <string.h>
21 #include <sys/socket.h>
22 #include "dhcp_s_define.h"
23
24 #define IPV4_ADDRESS_BITS 32
25 #define BIT_MAX_VALUE 2
26 #define IP_ADDRESS_LENGTH 4
27 #define MAD_ADDR_BUF_SIZE 50
28 #define MAC_STRING_SIZE 17
29 #define IP_ADDRESS_STRING_LENGTH 64
30
31 enum MacAddressIndex {
32 MAI_ZERO = 0,
33 MAI_ONE = 1,
34 MAI_TWO = 2,
35 MAI_THREE = 3,
36 MAI_FOUR = 4,
37 MAI_FIVE = 5
38 };
39
NetworkAddress(uint32_t ip,uint32_t netmask)40 uint32_t NetworkAddress(uint32_t ip, uint32_t netmask)
41 {
42 return (ip & netmask);
43 }
44
FirstIpAddress(uint32_t ip,uint32_t netmask)45 uint32_t FirstIpAddress(uint32_t ip, uint32_t netmask)
46 {
47 uint32_t network = NetworkAddress(ip, netmask);
48 uint32_t firstIp = htonl(network) + 1;
49 return htonl(firstIp);
50 }
51
HostBits(uint32_t netmask)52 static uint32_t HostBits(uint32_t netmask)
53 {
54 uint32_t bits = 0;
55 uint32_t net = htonl(netmask);
56 for (int i = IPV4_ADDRESS_BITS; i > 0; --i) {
57 bits++;
58 net >>= 1;
59 if ((net & 1) != 0) {
60 break;
61 }
62 }
63 return bits;
64 }
65
HostTotal(uint32_t netmask)66 uint32_t HostTotal(uint32_t netmask)
67 {
68 uint32_t hostBits = HostBits(netmask);
69 uint32_t total = 1;
70 for (size_t i = 0; i < (size_t)hostBits; i++) {
71 total *= BIT_MAX_VALUE;
72 }
73 total--;
74 return total;
75 }
76
NextIpAddress(uint32_t currIp,uint32_t netmask,uint32_t offset)77 uint32_t NextIpAddress(uint32_t currIp, uint32_t netmask, uint32_t offset)
78 {
79 uint32_t network = NetworkAddress(currIp, netmask);
80 uint32_t broadcast = BroadCastAddress(currIp, netmask);
81 uint32_t lastIp = LastIpAddress(currIp, netmask);
82 uint32_t hostTotal = HostTotal(netmask);
83 uint32_t next = offset;
84 if (currIp == lastIp || currIp == broadcast) {
85 return FirstIpAddress(currIp, netmask);
86 }
87 if (next > hostTotal && hostTotal > 0) {
88 next = next % hostTotal;
89 }
90 uint32_t nextIp = htonl(currIp) + next + 1;
91 if (next && nextIp > htonl(lastIp)) {
92 nextIp = htonl(network) + (nextIp - htonl(lastIp));
93 }
94 return htonl(nextIp);
95 }
96
FirstNetIpAddress(uint32_t network)97 uint32_t FirstNetIpAddress(uint32_t network)
98 {
99 uint32_t firstIp = htonl(network) + 1;
100 return htonl(firstIp);
101 }
102
LastIpAddress(uint32_t ip,uint32_t netmask)103 uint32_t LastIpAddress(uint32_t ip, uint32_t netmask)
104 {
105 uint32_t network = NetworkAddress(ip, netmask);
106 uint32_t lastIp = htonl(network) + HostTotal(netmask);
107 if (lastIp) {
108 lastIp -= 1;
109 }
110 return htonl(lastIp);
111 }
112
IpInNetwork(uint32_t ip,uint32_t network,uint32_t netmask)113 int IpInNetwork(uint32_t ip, uint32_t network, uint32_t netmask)
114 {
115 uint32_t firstNet = NetworkAddress(ip, netmask);
116 uint32_t secondNet = NetworkAddress(network, netmask);
117
118 uint32_t beginIp = FirstIpAddress(network, netmask);
119 uint32_t broadCast = BroadCastAddress(network, netmask);
120
121 if (firstNet == secondNet) {
122 if (ip >= beginIp && ip <= broadCast) {
123 return DHCP_TRUE;
124 }
125 }
126 return DHCP_FALSE;
127 }
128
IpInRange(uint32_t ip,uint32_t beginIp,uint32_t endIp,uint32_t netmask)129 int IpInRange(uint32_t ip, uint32_t beginIp, uint32_t endIp, uint32_t netmask)
130 {
131 uint32_t network = NetworkAddress(ip, netmask);
132 uint32_t firstNet = NetworkAddress(beginIp, netmask);
133 uint32_t secondNet = NetworkAddress(endIp, netmask);
134 if (network != firstNet || firstNet != secondNet) {
135 return 0;
136 }
137 if (ip >= beginIp && ip <= endIp) {
138 return DHCP_TRUE;
139 }
140 return DHCP_FALSE;
141 }
142
BroadCastAddress(uint32_t ip,uint32_t netmask)143 uint32_t BroadCastAddress(uint32_t ip, uint32_t netmask)
144 {
145 uint32_t network = NetworkAddress(ip, netmask);
146 uint32_t broadcast = htonl(network) + HostTotal(netmask);
147 return htonl(broadcast);
148 }
149
150
ParseIpAddr(const char * strIp)151 uint32_t ParseIpAddr(const char *strIp)
152 {
153 struct in_addr inAddr;
154 uint32_t ip = 0;
155 int ret = inet_aton(strIp, &inAddr);
156 if (ret != 0) {
157 if (memcpy_s(&ip, sizeof(uint32_t), &inAddr, sizeof(struct in_addr)) != EOK) {
158 return 0;
159 }
160 return ip;
161 }
162 return 0;
163 }
164
ParseIp(const uint8_t * ipAddr)165 uint32_t ParseIp(const uint8_t *ipAddr)
166 {
167 uint32_t ip = 0;
168 if (memcpy_s(&ip, IP_ADDRESS_LENGTH, ipAddr, IP_ADDRESS_LENGTH) != EOK) {
169 return 0;
170 }
171 return ip;
172 }
173
ParseStrIp(uint32_t ipAddr)174 const char *ParseStrIp(uint32_t ipAddr)
175 {
176 static char strIpAddr[IP_ADDRESS_STRING_LENGTH] = {0};
177 struct in_addr inAddr;
178 if (memcpy_s(&inAddr, sizeof(inAddr), &ipAddr, sizeof(ipAddr)) != EOK ||
179 memset_s(strIpAddr, sizeof(strIpAddr), 0, sizeof(strIpAddr)) != EOK) {
180 return "0.0.0.0";
181 }
182 if (inet_ntop(AF_INET, &inAddr, strIpAddr, sizeof(strIpAddr)) == NULL) {
183 return "0.0.0.0";
184 }
185 return strIpAddr;
186 }
187
ParseStrMac(const uint8_t * macAddr,size_t addrSize)188 char *ParseStrMac(const uint8_t *macAddr, size_t addrSize)
189 {
190 static char strMacAddr[MAD_ADDR_BUF_SIZE] = {0};
191 if (!macAddr || addrSize < MAC_ADDR_LENGTH) {
192 return 0;
193 }
194 if (memset_s(strMacAddr, MAD_ADDR_BUF_SIZE, '\0', sizeof(strMacAddr)) != EOK ||
195 sprintf_s(strMacAddr, MAD_ADDR_BUF_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x", macAddr[MAI_ZERO],
196 macAddr[MAI_ONE], macAddr[MAI_TWO], macAddr[MAI_THREE], macAddr[MAI_FOUR], macAddr[MAI_FIVE]) < 0) {
197 return 0;
198 }
199 return strMacAddr;
200 }
201
IsValidHexCharAndConvert(char c)202 static int8_t IsValidHexCharAndConvert(char c)
203 {
204 if (c >= '0' && c <= '9') {
205 return c - '0';
206 }
207 if (c >= 'a' && c <= 'f') {
208 return c - 'a' + ('9' - '0' + 1);
209 }
210 if (c >= 'A' && c <= 'F') {
211 return c - 'A' + ('9' - '0' + 1);
212 }
213 return -1;
214 }
215
ParseMacAddress(const char * strMac,uint8_t macAddr[DHCP_HWADDR_LENGTH])216 int ParseMacAddress(const char *strMac, uint8_t macAddr[DHCP_HWADDR_LENGTH])
217 {
218 if (strMac == NULL || strlen(strMac) != MAC_STRING_SIZE) {
219 return DHCP_FALSE;
220 }
221 size_t len = strlen(strMac);
222 const int shiftNum = 4;
223 const int macSpaceNum = 3;
224 unsigned char tmp = 0;
225 for (size_t i = 0, j = 0; i < len; ++i) {
226 if (j == 0 || j == 1) {
227 int8_t v = IsValidHexCharAndConvert(strMac[i]);
228 if (v < 0) {
229 return 0;
230 }
231 tmp <<= shiftNum;
232 tmp |= static_cast<unsigned char>(v);
233 ++j;
234 } else {
235 if (strMac[i] != ':') {
236 return 0;
237 }
238 macAddr[i / macSpaceNum] = tmp;
239 j = 0;
240 tmp = 0;
241 }
242 }
243 macAddr[MAC_STRING_SIZE / macSpaceNum] = tmp;
244 return DHCP_TRUE;
245 }
246
HostToNetwork(uint32_t host)247 uint32_t HostToNetwork(uint32_t host)
248 {
249 return htonl(host);
250 }
251
NetworkToHost(uint32_t network)252 uint32_t NetworkToHost(uint32_t network)
253 {
254 return ntohl(network);
255 }
256
ParseLogMac(uint8_t macAddr[DHCP_HWADDR_LENGTH])257 char *ParseLogMac(uint8_t macAddr[DHCP_HWADDR_LENGTH])
258 {
259 static char strLogMacAddr[MAD_ADDR_BUF_SIZE] = {0};
260 if (!macAddr) {
261 return 0;
262 }
263 if (memset_s(strLogMacAddr, MAD_ADDR_BUF_SIZE, '\0', MAD_ADDR_BUF_SIZE) != EOK ||
264 sprintf_s(strLogMacAddr, MAD_ADDR_BUF_SIZE, "??:%02x:??:??:%02x:%02x", macAddr[NUM_ONE], macAddr[MAI_FOUR],
265 macAddr[MAI_FIVE]) < 0) {
266 return 0;
267 }
268 return strLogMacAddr;
269 }
270
IsEmptyHWAddr(const uint8_t macAddr[DHCP_HWADDR_LENGTH])271 int IsEmptyHWAddr(const uint8_t macAddr[DHCP_HWADDR_LENGTH])
272 {
273 for (int i = 0; i < MAC_ADDR_LENGTH; i++) {
274 if (macAddr[i] != 0) {
275 return DHCP_FALSE;
276 }
277 }
278 return DHCP_TRUE;
279 }
280
AddrEquels(const uint8_t firstAddr[DHCP_HWADDR_LENGTH],uint8_t secondAddr[DHCP_HWADDR_LENGTH],int addrLength)281 int AddrEquels(const uint8_t firstAddr[DHCP_HWADDR_LENGTH], uint8_t secondAddr[DHCP_HWADDR_LENGTH], int addrLength)
282 {
283 int len = addrLength;
284 if (len > DHCP_HWADDR_LENGTH) {
285 len = DHCP_HWADDR_LENGTH;
286 }
287 for (int i = 0; i < len; i++) {
288 if ((firstAddr[i] != secondAddr[i])) {
289 return DHCP_FALSE;
290 }
291 }
292 return DHCP_TRUE;
293 }
294
ParseHostName(const char * strHostName,char hostName[DHCP_BOOT_FILE_LENGTH])295 int ParseHostName(const char *strHostName, char hostName[DHCP_BOOT_FILE_LENGTH])
296 {
297 if (strHostName == nullptr || hostName == nullptr) {
298 return DHCP_FALSE;
299 }
300 if (memcpy_s(hostName, DHCP_BOOT_FILE_LENGTH, strHostName, strlen(strHostName)) != EOK) {
301 return DHCP_FALSE;
302 }
303 return DHCP_TRUE;
304 }
305