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