CNDP  22.08.0
cne_inet4.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 2016-2022 Intel Corporation
3  */
4 
5 #ifndef __CNE_INET4_H
6 #define __CNE_INET4_H
7 
13 #include <immintrin.h>
14 #include <stdbool.h>
15 #include <bsd/string.h>
16 #include <net/ethernet.h>
17 
18 #include <cne_common.h>
19 #include <cne_inet.h>
20 
21 #ifndef __CNE_INET_H
22 #error "Do not include this file directly use cne_inet.h instead."
23 #endif
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 /* Compare two IPv4 Addresses */
30 static inline int
31 inet_addr_cmp(struct in_addr *c1, struct in_addr *c2)
32 {
33  return c1->s_addr == c2->s_addr;
34 }
35 
36 /* Copy the inet address for IPv4 addresses */
37 static inline void
38 inet_addr_copy(struct in_addr *t, struct in_addr *f)
39 {
40  t->s_addr = f->s_addr;
41 }
42 
43 /* Swap the two words of an IPv4 address */
44 static inline void
45 inet_addr_swap(uint32_t *t, uint32_t *f)
46 {
47  uint32_t d;
48 
49  d = *t;
50  *t = *f;
51  *f = d;
52 }
53 
54 /* mask_size(uint32_t mask) - return the number of bits in mask */
55 static __inline__ int
56 __mask_size(uint32_t mask)
57 {
58  if (mask == 0)
59  return 0;
60  else if (mask == 0xFF000000)
61  return 8;
62  else if (mask == 0xFFFF0000)
63  return 16;
64  else if (mask == 0xFFFFFF00)
65  return 24;
66  else if (mask == 0xFFFFFFFF)
67  return 32;
68  else {
69  int i;
70  for (i = 0; i < 32; i++)
71  if ((mask & (1 << (31 - i))) == 0)
72  break;
73  return i;
74  }
75 }
76 
77 /* size_to_mask( int len ) - return the mask for the mask size */
78 static __inline__ uint32_t
79 __size_to_mask(int len)
80 {
81  uint32_t mask = 0;
82 
83  if (len > 32)
84  CNE_ERR_RET("Length is > 32\n");
85 
86  if (len == 0)
87  mask = 0x00000000;
88  else if (len == 8)
89  mask = 0xFF000000;
90  else if (len == 16)
91  mask = 0xFFFF0000;
92  else if (len == 24)
93  mask = 0xFFFFFF00;
94  else if (len == 32)
95  mask = 0xFFFFFFFF;
96  else {
97  int i;
98 
99  for (i = 0; i < len; i++)
100  mask |= (1 << (31 - i));
101  }
102  return mask;
103 }
104 
105 /* char * inet_ntop4(char * buff, int len, unsigned long ip_addr, unsigned long mask) - Convert
106  * IPv4 address to ascii */
107 static inline char *
108 inet_ntop4(char *buff, int len, struct in_addr *ip_addr, struct in_addr *mask)
109 {
110  char *orig = buff;
111  char b[IP4_ADDR_STRLEN] = {0};
112 
113  if (!buff || len < IP4_ADDR_STRLEN)
114  return NULL;
115 
116  memset(buff, 0, len);
117 
118  if (inet_ntop(AF_INET, ip_addr, b, sizeof(b)) == NULL)
119  return NULL;
120 
121  if (mask && mask->s_addr != 0xFFFFFFFF) {
122  char lbuf[64] = {0};
123  int n;
124 
125  snprintf(lbuf, sizeof(lbuf), "/%u", __mask_size(mask->s_addr));
126  n = strlcpy(buff, b, len);
127  buff += n;
128  len -= n;
129  strlcat(buff, lbuf, len);
130  } else
131  strlcpy(buff, b, len);
132 
133  return orig;
134 }
135 
136 /* convert a MAC address from network byte order to host 64bit number */
137 static inline uint64_t
138 inet_mtoh64(struct ether_addr *eaddr, uint64_t *value)
139 {
140  *value =
141  ((uint64_t)eaddr->ether_addr_octet[5] << 0) + ((uint64_t)eaddr->ether_addr_octet[4] << 8) +
142  ((uint64_t)eaddr->ether_addr_octet[3] << 16) +
143  ((uint64_t)eaddr->ether_addr_octet[2] << 24) +
144  ((uint64_t)eaddr->ether_addr_octet[1] << 32) + ((uint64_t)eaddr->ether_addr_octet[0] << 40);
145  return *value;
146 }
147 
148 /* convert a host 64bit number to MAC address in network byte order */
149 static inline struct ether_addr *
150 inet_h64tom(uint64_t value, struct ether_addr *eaddr)
151 {
152  eaddr->ether_addr_octet[5] = ((value >> 0) & 0xFF);
153  eaddr->ether_addr_octet[4] = ((value >> 8) & 0xFF);
154  eaddr->ether_addr_octet[3] = ((value >> 16) & 0xFF);
155  eaddr->ether_addr_octet[2] = ((value >> 24) & 0xFF);
156  eaddr->ether_addr_octet[1] = ((value >> 32) & 0xFF);
157  eaddr->ether_addr_octet[0] = ((value >> 40) & 0xFF);
158  return eaddr;
159 }
160 
161 /* Compare two IPv4 Addresses with a mask value */
162 static inline int
163 inet_addr_mask_cmp(struct in_addr *c1, struct in_addr *c2, struct in_addr *n1)
164 {
165  int val;
166 
167  if (n1->s_addr == 0)
168  return 0;
169 
170  val = (c1->s_addr & n1->s_addr) == (c2->s_addr & n1->s_addr);
171 
172  return val;
173 }
174 
175 /* Given an address to a in_caddr structure zero it */
176 static inline void
177 in_caddr_zero(struct in_caddr *f)
178 {
179  struct in_caddr z = {0};
180  *f = *(struct in_caddr *)&z;
181 }
182 
183 /* Copy the 'f' in_caddr structure to 't' in_caddr structure */
184 static inline void
185 in_caddr_copy(struct in_caddr *t, struct in_caddr *f)
186 {
187  *t = *f;
188 }
189 
190 /* Compare the two in_caddr structures to determine if equal */
191 static inline int
192 in_caddr_compare(struct in_caddr *p1, struct in_caddr *p2)
193 {
194 #ifdef USE_AVX_INSTRUCTIONS
195  __m256i v1, v2;
196 
197  v1 = _mm256_loadu_si256((__m256i const *)p1);
198  v2 = _mm256_loadu_si256((__m256i const *)p2);
199 
200  return vec_equal(v1, v2);
201 #else
202  return (p1->cin_len == p2->cin_len) && (p1->cin_family == p2->cin_family) &&
203  (p1->cin_addr.s_addr == p2->cin_addr.s_addr) && (p1->cin_port == p2->cin_port);
204 #endif
205 }
206 
207 #define in_caddr_eq(p1, p2) in_caddr_compare((p1), (p2))
208 
209 /* Compare the two in_caddr structures to determine if equal */
210 static inline int
211 in_caddr_neq(struct in_caddr *p1, struct in_caddr *p2)
212 {
213  return !in_caddr_compare(p1, p2);
214 }
215 
216 /* Compare the two in_caddr structures to determine if equal */
217 static inline int
218 in_caddr_gt(struct in_caddr *p1, struct in_caddr *p2)
219 {
220  return memcmp(p1, p2, p1->cin_len) > 0;
221 }
222 
223 /* Compare the two in_caddr structures to determine if equal */
224 static inline int
225 in_caddr_lt(struct in_caddr *p1, struct in_caddr *p2)
226 {
227  return memcmp(p1, p2, p1->cin_len) < 0;
228 }
229 
230 static inline void
231 in_caddr_and(struct in_caddr *p1, struct in_caddr *p2)
232 {
233  p1->cin_addr.s_addr &= p2->cin_addr.s_addr;
234 }
235 
236 static inline void
237 in_caddr_mask(struct in_caddr *na, struct in_caddr *da, struct in_caddr *ma)
238 {
239  na->cin_addr.s_addr = da->cin_addr.s_addr & ma->cin_addr.s_addr;
240 }
241 
242 /* Fill in the in_caddr structure information. */
243 static inline void
244 in_caddr_create(struct in_caddr *sa, struct in_addr *pa, int type, int len, int port)
245 {
246  uint32_t ip = pa->s_addr;
247 
248  in_caddr_zero(sa);
249 
250  if (len == 0)
251  len = cne_numbytes(ip);
252 
253  sa->cin_len = len;
254  sa->cin_family = type;
255  sa->cin_port = port;
256  sa->cin_addr.s_addr = ip;
257 }
258 
259 /* Fill in the in_caddr structure information. */
260 static inline void
261 in_caddr_init(struct in_caddr *sa, int type, int len, int port)
262 {
263  in_caddr_zero(sa);
264  sa->cin_len = len;
265  sa->cin_family = type;
266  sa->cin_port = port;
267 }
268 
269 /* Fill in the in_caddr structure information. */
270 static inline void
271 in_caddr_update(struct in_caddr *sa, int type, int len, int port)
272 {
273  sa->cin_len = len;
274  sa->cin_family = type;
275  sa->cin_port = port;
276 }
277 
278 #ifdef __cplusplus
279 }
280 #endif
281 
282 #endif /* __CNE_INET4_H */
#define CNE_ERR_RET(...)
Definition: cne_log.h:250
uint8_t ether_addr_octet[ETH_ALEN]
Definition: cne_ether.h:53