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