1 /** @file
2  * @brief IPv6 and IPv4 definitions
3  *
4  * Generic IPv6 and IPv4 address definitions.
5  */
6 
7 /*
8  * Copyright (c) 2016 Intel Corporation
9  *
10  * SPDX-License-Identifier: Apache-2.0
11  */
12 
13 #ifndef ZEPHYR_INCLUDE_NET_NET_IP_H_
14 #define ZEPHYR_INCLUDE_NET_NET_IP_H_
15 
16 /**
17  * @brief IPv4/IPv6 primitives and helpers
18  * @defgroup ip_4_6 IPv4/IPv6 primitives and helpers
19  * @since 1.0
20  * @version 1.0.0
21  * @ingroup networking
22  * @{
23  */
24 
25 #include <string.h>
26 #include <zephyr/types.h>
27 #include <stdbool.h>
28 #include <zephyr/sys/util.h>
29 #include <zephyr/sys/byteorder.h>
30 #include <zephyr/toolchain.h>
31 
32 #include <zephyr/net/net_linkaddr.h>
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 /** @cond INTERNAL_HIDDEN */
39 /* Specifying VLAN tag here in order to avoid circular dependencies */
40 #define NET_VLAN_TAG_UNSPEC 0x0fff
41 /** @endcond */
42 
43 /* Protocol families. */
44 #define NET_PF_UNSPEC   0            /**< Unspecified protocol family.  */
45 #define NET_PF_INET     1            /**< IP protocol family version 4. */
46 #define NET_PF_INET6    2            /**< IP protocol family version 6. */
47 #define NET_PF_PACKET   3            /**< Packet family.                */
48 #define NET_PF_CAN      4            /**< Controller Area Network.      */
49 #define NET_PF_NET_MGMT 5            /**< Network management info.      */
50 #define NET_PF_LOCAL    6            /**< Inter-process communication   */
51 #define NET_PF_UNIX     NET_PF_LOCAL /**< Inter-process communication   */
52 
53 /* Address families. */
54 #define NET_AF_UNSPEC      NET_PF_UNSPEC   /**< Unspecified address family.   */
55 #define NET_AF_INET        NET_PF_INET     /**< IP protocol family version 4. */
56 #define NET_AF_INET6       NET_PF_INET6    /**< IP protocol family version 6. */
57 #define NET_AF_PACKET      NET_PF_PACKET   /**< Packet family.                */
58 #define NET_AF_CAN         NET_PF_CAN      /**< Controller Area Network.      */
59 #define NET_AF_NET_MGMT    NET_PF_NET_MGMT /**< Network management info.      */
60 #define NET_AF_LOCAL       NET_PF_LOCAL    /**< Inter-process communication   */
61 #define NET_AF_UNIX        NET_PF_UNIX     /**< Inter-process communication   */
62 
63 /** Protocol numbers from IANA/BSD */
64 enum net_ip_protocol {
65 	NET_IPPROTO_IP = 0,            /**< IP protocol (pseudo-val for setsockopt() */
66 	NET_IPPROTO_ICMP = 1,          /**< ICMP protocol   */
67 	NET_IPPROTO_IGMP = 2,          /**< IGMP protocol   */
68 	NET_IPPROTO_ETH_P_ALL = 3,     /**< Every packet. from linux if_ether.h   */
69 	NET_IPPROTO_IPIP = 4,          /**< IPIP tunnels    */
70 	NET_IPPROTO_TCP = 6,           /**< TCP protocol    */
71 	NET_IPPROTO_UDP = 17,          /**< UDP protocol    */
72 	NET_IPPROTO_IPV6 = 41,         /**< IPv6 protocol   */
73 	NET_IPPROTO_ICMPV6 = 58,       /**< ICMPv6 protocol */
74 	NET_IPPROTO_RAW = 255,         /**< RAW IP packets  */
75 };
76 
77 /** Protocol numbers for TLS protocols */
78 enum net_ip_protocol_secure {
79 	NET_IPPROTO_TLS_1_0 = 256,     /**< TLS 1.0 protocol */
80 	NET_IPPROTO_TLS_1_1 = 257,     /**< TLS 1.1 protocol */
81 	NET_IPPROTO_TLS_1_2 = 258,     /**< TLS 1.2 protocol */
82 	NET_IPPROTO_TLS_1_3 = 259,     /**< TLS 1.3 protocol */
83 	NET_IPPROTO_DTLS_1_0 = 272,    /**< DTLS 1.0 protocol */
84 	NET_IPPROTO_DTLS_1_2 = 273,    /**< DTLS 1.2 protocol */
85 };
86 
87 /** Socket type */
88 enum net_sock_type {
89 	NET_SOCK_STREAM = 1,           /**< Stream socket type   */
90 	NET_SOCK_DGRAM,                /**< Datagram socket type */
91 	NET_SOCK_RAW                   /**< RAW socket type      */
92 };
93 
94 /** @brief Convert 16-bit value from network to host byte order.
95  *
96  * @param x The network byte order value to convert.
97  *
98  * @return Host byte order value.
99  */
100 #define net_ntohs(x) sys_be16_to_cpu(x)
101 
102 /** @brief Convert 32-bit value from network to host byte order.
103  *
104  * @param x The network byte order value to convert.
105  *
106  * @return Host byte order value.
107  */
108 #define net_ntohl(x) sys_be32_to_cpu(x)
109 
110 /** @brief Convert 64-bit value from network to host byte order.
111  *
112  * @param x The network byte order value to convert.
113  *
114  * @return Host byte order value.
115  */
116 #define net_ntohll(x) sys_be64_to_cpu(x)
117 
118 /** @brief Convert 16-bit value from host to network byte order.
119  *
120  * @param x The host byte order value to convert.
121  *
122  * @return Network byte order value.
123  */
124 #define net_htons(x) sys_cpu_to_be16(x)
125 
126 /** @brief Convert 32-bit value from host to network byte order.
127  *
128  * @param x The host byte order value to convert.
129  *
130  * @return Network byte order value.
131  */
132 #define net_htonl(x) sys_cpu_to_be32(x)
133 
134 /** @brief Convert 64-bit value from host to network byte order.
135  *
136  * @param x The host byte order value to convert.
137  *
138  * @return Network byte order value.
139  */
140 #define net_htonll(x) sys_cpu_to_be64(x)
141 
142 /** IPv6 address struct */
143 struct net_in6_addr {
144 	union {
145 		uint8_t s6_addr[16];   /**< IPv6 address buffer */
146 		uint16_t s6_addr16[8]; /**< In big endian */
147 		uint32_t s6_addr32[4]; /**< In big endian */
148 	};
149 };
150 
151 /** Binary size of the IPv6 address */
152 #define NET_IPV6_ADDR_SIZE 16
153 
154 /** IPv4 address struct */
155 struct net_in_addr {
156 	union {
157 		uint8_t s4_addr[4];    /**< IPv4 address buffer */
158 		uint16_t s4_addr16[2]; /**< In big endian */
159 		uint32_t s4_addr32[1]; /**< In big endian */
160 		uint32_t s_addr; /**< In big endian, for POSIX compatibility. */
161 	};
162 };
163 
164 /** Binary size of the IPv4 address */
165 #define NET_IPV4_ADDR_SIZE 4
166 
167 /** Socket address family type */
168 typedef unsigned short int net_sa_family_t;
169 
170 /** Length of a socket address */
171 typedef uint32_t net_socklen_t;
172 
173 /*
174  * Note that the sin_port and sin6_port are in network byte order
175  * in various net_sockaddr* structs.
176  */
177 
178 /** Socket address struct for IPv6. */
179 struct net_sockaddr_in6 {
180 	net_sa_family_t		sin6_family;   /**< NET_AF_INET6           */
181 	uint16_t		sin6_port;     /**< Port number            */
182 	struct net_in6_addr	sin6_addr;     /**< IPv6 address           */
183 	uint8_t			sin6_scope_id; /**< Interfaces for a scope */
184 };
185 
186 /** Socket address struct for IPv4. */
187 struct net_sockaddr_in {
188 	net_sa_family_t		sin_family;    /**< NET_AF_INET  */
189 	uint16_t		sin_port;      /**< Port number  */
190 	struct net_in_addr	sin_addr;      /**< IPv4 address */
191 };
192 
193 /** Socket address struct for packet socket. */
194 struct net_sockaddr_ll {
195 	net_sa_family_t sll_family;   /**< Always NET_AF_PACKET               */
196 	uint16_t        sll_protocol; /**< Physical-layer protocol            */
197 	int             sll_ifindex;  /**< Interface number                   */
198 	uint16_t        sll_hatype;   /**< ARP hardware type                  */
199 	uint8_t         sll_pkttype;  /**< Packet type                        */
200 	uint8_t         sll_halen;    /**< Length of address                  */
201 	uint8_t         sll_addr[8];  /**< Physical-layer address, big endian */
202 };
203 
204 /** @cond INTERNAL_HIDDEN */
205 
206 /** Socket address struct for IPv6 where address is a pointer */
207 struct net_sockaddr_in6_ptr {
208 	net_sa_family_t		sin6_family;   /**< NET_AF_INET6           */
209 	uint16_t		sin6_port;     /**< Port number            */
210 	struct net_in6_addr    *sin6_addr;     /**< IPv6 address           */
211 	uint8_t			sin6_scope_id; /**< interfaces for a scope */
212 };
213 
214 /** Socket address struct for IPv4 where address is a pointer */
215 struct net_sockaddr_in_ptr {
216 	net_sa_family_t		sin_family;    /**< NET_AF_INET  */
217 	uint16_t		sin_port;      /**< Port number  */
218 	struct net_in_addr     *sin_addr;      /**< IPv4 address */
219 };
220 
221 /** Socket address struct for packet socket where address is a pointer */
222 struct net_sockaddr_ll_ptr {
223 	net_sa_family_t sll_family;   /**< Always NET_AF_PACKET               */
224 	uint16_t        sll_protocol; /**< Physical-layer protocol            */
225 	int             sll_ifindex;  /**< Interface number                   */
226 	uint16_t        sll_hatype;   /**< ARP hardware type                  */
227 	uint8_t         sll_pkttype;  /**< Packet type                        */
228 	uint8_t         sll_halen;    /**< Length of address                  */
229 	uint8_t        *sll_addr;     /**< Physical-layer address, big endian */
230 };
231 
232 /** Socket address struct for unix socket where address is a pointer */
233 struct net_sockaddr_un_ptr {
234 	net_sa_family_t sun_family;   /**< Always NET_AF_UNIX */
235 	char           *sun_path;     /**< Pathname           */
236 };
237 
238 struct net_sockaddr_can_ptr {
239 	net_sa_family_t can_family;
240 	int             can_ifindex;
241 };
242 
243 /** @endcond */
244 
245 #if !defined(HAVE_IOVEC)
246 /** IO vector array element */
247 struct net_iovec {
248 	void  *iov_base; /**< Pointer to data */
249 	size_t iov_len;  /**< Length of the data */
250 };
251 #endif
252 
253 /** Message struct */
254 struct net_msghdr {
255 	void             *msg_name;       /**< Optional socket address, big endian */
256 	net_socklen_t     msg_namelen;    /**< Size of socket address */
257 	struct net_iovec *msg_iov;        /**< Scatter/gather array */
258 	size_t            msg_iovlen;     /**< Number of elements in msg_iov */
259 	void             *msg_control;    /**< Ancillary data */
260 	size_t            msg_controllen; /**< Ancillary data buffer len */
261 	int               msg_flags;      /**< Flags on received message */
262 };
263 
264 /** Control message ancillary data */
265 struct net_cmsghdr {
266 	net_socklen_t cmsg_len;    /**< Number of bytes, including header */
267 	int           cmsg_level;  /**< Originating protocol */
268 	int           cmsg_type;   /**< Protocol-specific type */
269 	z_max_align_t cmsg_data[]; /**< Flexible array member to force alignment of net_cmsghdr */
270 };
271 
272 /** @cond INTERNAL_HIDDEN */
273 
274 /* Alignment for headers and data. These are arch specific but define
275  * them here atm if not found already.
276  */
277 #if !defined(NET_ALIGN_H)
278 #define NET_ALIGN_H(x) ROUND_UP(x, __alignof__(struct net_cmsghdr))
279 #endif
280 #if !defined(NET_ALIGN_D)
281 #define NET_ALIGN_D(x) ROUND_UP(x, __alignof__(z_max_align_t))
282 #endif
283 
284 /** @endcond */
285 
286 #if !defined(NET_CMSG_FIRSTHDR)
287 /**
288  * Returns a pointer to the first cmsghdr in the ancillary data buffer
289  * associated with the passed msghdr.  It returns NULL if there isn't
290  * enough space for a cmsghdr in the buffer.
291  */
292 #define NET_CMSG_FIRSTHDR(msghdr)				  \
293 	((msghdr)->msg_controllen >= sizeof(struct net_cmsghdr) ? \
294 	 (struct net_cmsghdr *)((msghdr)->msg_control) : NULL)
295 #endif
296 
297 #if !defined(NET_CMSG_NXTHDR)
298 /**
299  * Returns the next valid cmsghdr after the passed cmsghdr. It returns NULL
300  * when there isn't enough space left in the buffer.
301  */
302 #define NET_CMSG_NXTHDR(msghdr, cmsg)					 \
303 	(((cmsg) == NULL) ? NET_CMSG_FIRSTHDR(msghdr) :			 \
304 	 (((uint8_t *)(cmsg) + NET_ALIGN_H((cmsg)->cmsg_len) +		 \
305 	   NET_ALIGN_D(sizeof(struct net_cmsghdr)) >			 \
306 	   (uint8_t *)((msghdr)->msg_control) + (msghdr)->msg_controllen) ? \
307 	  NULL :							 \
308 	  (struct net_cmsghdr *)((uint8_t *)(cmsg) +			 \
309 				 NET_ALIGN_H((cmsg)->cmsg_len))))
310 #endif
311 
312 #if !defined(NET_CMSG_DATA)
313 /**
314  * Returns a pointer to the data portion of a cmsghdr.  The pointer returned
315  * cannot be assumed to be suitably aligned for accessing arbitrary payload
316  * data types. Applications should not cast it to a pointer type matching
317  * the payload, but should instead use memcpy(3) to copy data to or from a
318  * suitably declared object.
319  */
320 #define NET_CMSG_DATA(cmsg) ((uint8_t *)(cmsg) + NET_ALIGN_D(sizeof(struct net_cmsghdr)))
321 #endif
322 
323 #if !defined(NET_CMSG_SPACE)
324 /**
325  * Returns the number of bytes an ancillary element with payload of the passed
326  * data length occupies.
327  */
328 #define NET_CMSG_SPACE(length) (NET_ALIGN_D(sizeof(struct net_cmsghdr)) + NET_ALIGN_H(length))
329 #endif
330 
331 #if !defined(NET_CMSG_LEN)
332 /**
333  * Returns the value to store in the cmsg_len member of the net_cmsghdr structure,
334  * taking into account any necessary alignment.
335  * It takes the data length as an argument.
336  */
337 #define NET_CMSG_LEN(length) (NET_ALIGN_D(sizeof(struct net_cmsghdr)) + length)
338 #endif
339 
340 /** @cond INTERNAL_HIDDEN */
341 
342 /* Packet types.  */
343 #define NET_PACKET_HOST         0     /* To us            */
344 #define NET_PACKET_BROADCAST    1     /* To all           */
345 #define NET_PACKET_MULTICAST    2     /* To group         */
346 #define NET_PACKET_OTHERHOST    3     /* To someone else  */
347 #define NET_PACKET_OUTGOING     4     /* Originated by us */
348 #define NET_PACKET_LOOPBACK     5
349 #define NET_PACKET_FASTROUTE    6
350 
351 /* ARP protocol HARDWARE identifiers. */
352 #define NET_ARPHRD_ETHER 1
353 #define NET_ARPHRD_PPP   512
354 
355 /* Note: These macros are defined in a specific order.
356  * The largest sockaddr size is the last one.
357  */
358 #if defined(CONFIG_NET_IPV4)
359 #undef NET_SOCKADDR_MAX_SIZE
360 #undef NET_SOCKADDR_PTR_MAX_SIZE
361 #define NET_SOCKADDR_MAX_SIZE (sizeof(struct net_sockaddr_in))
362 #define NET_SOCKADDR_PTR_MAX_SIZE (sizeof(struct net_sockaddr_in_ptr))
363 #endif
364 
365 #if defined(CONFIG_NET_SOCKETS_PACKET)
366 #undef NET_SOCKADDR_MAX_SIZE
367 #undef NET_SOCKADDR_PTR_MAX_SIZE
368 #define NET_SOCKADDR_MAX_SIZE (sizeof(struct net_sockaddr_ll))
369 #define NET_SOCKADDR_PTR_MAX_SIZE (sizeof(struct net_sockaddr_ll_ptr))
370 #endif
371 
372 #if defined(CONFIG_NET_IPV6)
373 #undef NET_SOCKADDR_MAX_SIZE
374 #define NET_SOCKADDR_MAX_SIZE (sizeof(struct net_sockaddr_in6))
375 #if !defined(CONFIG_NET_SOCKETS_PACKET)
376 #undef NET_SOCKADDR_PTR_MAX_SIZE
377 #define NET_SOCKADDR_PTR_MAX_SIZE (sizeof(struct net_sockaddr_in6_ptr))
378 #endif
379 #endif
380 
381 #if defined(CONFIG_NET_NATIVE_OFFLOADED_SOCKETS)
382 #define UNIX_PATH_MAX 108
383 #undef NET_SOCKADDR_MAX_SIZE
384 /* Define NET_SOCKADDR_MAX_SIZE to be struct of net_sa_family_t + char[UNIX_PATH_MAX] */
385 #define NET_SOCKADDR_MAX_SIZE (UNIX_PATH_MAX+sizeof(net_sa_family_t))
386 #if !defined(CONFIG_NET_SOCKETS_PACKET)
387 #undef NET_SOCKADDR_PTR_MAX_SIZE
388 #define NET_SOCKADDR_PTR_MAX_SIZE (sizeof(struct net_sockaddr_un_ptr))
389 #endif
390 #endif
391 
392 #if !defined(CONFIG_NET_IPV4)
393 #if !defined(CONFIG_NET_IPV6)
394 #if !defined(CONFIG_NET_SOCKETS_PACKET)
395 #if !defined(CONFIG_NET_NATIVE_OFFLOADED_SOCKETS)
396 #define NET_SOCKADDR_MAX_SIZE (sizeof(struct net_sockaddr_in6))
397 #define NET_SOCKADDR_PTR_MAX_SIZE (sizeof(struct net_sockaddr_in6_ptr))
398 #endif
399 #endif
400 #endif
401 #endif
402 
403 /** @endcond */
404 
405 #define SOCKADDR_ALIGN (4)
406 
407 /** Generic sockaddr struct. Must be cast to proper type. */
408 struct net_sockaddr {
409 	net_sa_family_t sa_family; /**< Address family */
410 /** @cond INTERNAL_HIDDEN */
411 	char data[NET_SOCKADDR_MAX_SIZE - sizeof(net_sa_family_t)];
412 /** @endcond */
413 } __aligned(SOCKADDR_ALIGN);
414 
415 /** @cond INTERNAL_HIDDEN */
416 
417 struct net_sockaddr_ptr {
418 	net_sa_family_t family;
419 	char data[NET_SOCKADDR_PTR_MAX_SIZE - sizeof(net_sa_family_t)];
420 } __aligned(SOCKADDR_ALIGN);
421 
422 /* Same as sockaddr in our case */
423 struct net_sockaddr_storage {
424 	net_sa_family_t ss_family;
425 	char data[NET_SOCKADDR_MAX_SIZE - sizeof(net_sa_family_t)];
426 } __aligned(SOCKADDR_ALIGN);
427 
428 /* Socket address struct for UNIX domain sockets */
429 struct net_sockaddr_un {
430 	net_sa_family_t sun_family;    /* NET_AF_UNIX */
431 	char            sun_path[NET_SOCKADDR_MAX_SIZE - sizeof(net_sa_family_t)];
432 };
433 
434 struct net_addr {
435 	net_sa_family_t family;
436 	union {
437 #if defined(CONFIG_NET_NAMESPACE_COMPAT_MODE)
438 		struct net_in6_addr net_in6_addr;
439 		struct net_in_addr net_in_addr;
440 #else
441 		struct net_in6_addr in6_addr;
442 		struct net_in_addr in_addr;
443 #endif
444 	};
445 };
446 
447 /** A pointer to IPv6 any address (all values zero) */
448 extern const struct net_in6_addr net_in6addr_any;
449 
450 /** A pointer to IPv6 loopback address (::1) */
451 extern const struct net_in6_addr net_in6addr_loopback;
452 
453 /** @endcond */
454 
455 /** IPv6 address initializer */
456 #define NET_IN6ADDR_ANY_INIT { { { 0, 0, 0, 0, 0, 0, 0, 0,	\
457 				   0, 0, 0, 0, 0, 0, 0, 0 } } }
458 
459 /** IPv6 loopback address initializer */
460 #define NET_IN6ADDR_LOOPBACK_INIT { { { 0, 0, 0, 0, 0, 0, 0, 0,	\
461 					0, 0, 0, 0, 0, 0, 0, 1 } } }
462 
463 /** IPv4 any address */
464 #define NET_INADDR_ANY 0
465 
466 /** IPv4 broadcast address */
467 #define NET_INADDR_BROADCAST 0xffffffff
468 
469 /** IPv4 address initializer */
470 #define NET_INADDR_ANY_INIT { { { NET_INADDR_ANY } } }
471 
472 /** IPv6 loopback address initializer */
473 #define NET_INADDR_LOOPBACK_INIT  { { { 127, 0, 0, 1 } } }
474 
475 /** Max length of the IPv4 address as a string. Defined by POSIX. */
476 #define NET_INET_ADDRSTRLEN 16
477 
478 /** Max length of the IPv6 address as a string. Takes into account possible
479  * mapped IPv4 addresses.
480  */
481 #define NET_INET6_ADDRSTRLEN 46
482 
483 /** @cond INTERNAL_HIDDEN */
484 
485 /* These are for internal usage of the stack */
486 #define NET_IPV6_ADDR_LEN sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxx.xxx.xxx.xxx")
487 #define NET_IPV4_ADDR_LEN sizeof("xxx.xxx.xxx.xxx")
488 
489 /** @endcond */
490 
491 /** @brief IP Maximum Transfer Unit */
492 enum net_ip_mtu {
493 	/** IPv6 MTU length. We must be able to receive this size IPv6 packet
494 	 * without fragmentation.
495 	 */
496 #if defined(CONFIG_NET_NATIVE_IPV6)
497 	NET_IPV6_MTU = CONFIG_NET_IPV6_MTU,
498 #else
499 	NET_IPV6_MTU = 1280,
500 #endif
501 
502 	/** IPv4 MTU length. We must be able to receive this size IPv4 packet
503 	 * without fragmentation.
504 	 */
505 #if defined(CONFIG_NET_NATIVE_IPV4)
506 	NET_IPV4_MTU = CONFIG_NET_IPV4_MTU,
507 #else
508 	NET_IPV4_MTU = 576,
509 #endif
510 };
511 
512 /** @brief Network packet priority settings described in IEEE 802.1Q Annex I.1 */
513 enum net_priority {
514 	NET_PRIORITY_BK = 1, /**< Background (lowest)                */
515 	NET_PRIORITY_BE = 0, /**< Best effort (default)              */
516 	NET_PRIORITY_EE = 2, /**< Excellent effort                   */
517 	NET_PRIORITY_CA = 3, /**< Critical applications              */
518 	NET_PRIORITY_VI = 4, /**< Video, < 100 ms latency and jitter */
519 	NET_PRIORITY_VO = 5, /**< Voice, < 10 ms latency and jitter  */
520 	NET_PRIORITY_IC = 6, /**< Internetwork control               */
521 	NET_PRIORITY_NC = 7  /**< Network control (highest)          */
522 } __packed;
523 
524 #define NET_MAX_PRIORITIES 8 /**< How many priority values there are */
525 
526 /** @brief IPv6/IPv4 network connection tuple */
527 struct net_tuple {
528 	struct net_addr *remote_addr;  /**< IPv6/IPv4 remote address */
529 	struct net_addr *local_addr;   /**< IPv6/IPv4 local address  */
530 	uint16_t remote_port;          /**< UDP/TCP remote port      */
531 	uint16_t local_port;           /**< UDP/TCP local port       */
532 	enum net_ip_protocol ip_proto; /**< IP protocol              */
533 };
534 
535 /** @brief What is the current state of the network address */
536 enum net_addr_state {
537 	NET_ADDR_ANY_STATE = -1, /**< Default (invalid) address type */
538 	NET_ADDR_TENTATIVE = 0,  /**< Tentative address              */
539 	NET_ADDR_PREFERRED,      /**< Preferred address              */
540 	NET_ADDR_DEPRECATED,     /**< Deprecated address             */
541 } __packed;
542 
543 /** @brief How the network address is assigned to network interface */
544 enum net_addr_type {
545 	/** Default value. This is not a valid value. */
546 	NET_ADDR_ANY = 0,
547 	/** Auto configured address */
548 	NET_ADDR_AUTOCONF,
549 	/** Address is from DHCP */
550 	NET_ADDR_DHCP,
551 	/** Manually set address */
552 	NET_ADDR_MANUAL,
553 	/** Manually set address which is overridable by DHCP */
554 	NET_ADDR_OVERRIDABLE,
555 } __packed;
556 
557 /** @cond INTERNAL_HIDDEN */
558 
559 struct net_ipv6_hdr {
560 	uint8_t vtc;
561 	uint8_t tcflow;
562 	uint16_t flow;
563 	uint16_t len;
564 	uint8_t nexthdr;
565 	uint8_t hop_limit;
566 	uint8_t src[NET_IPV6_ADDR_SIZE];
567 	uint8_t dst[NET_IPV6_ADDR_SIZE];
568 } __packed;
569 
570 struct net_ipv6_frag_hdr {
571 	uint8_t nexthdr;
572 	uint8_t reserved;
573 	uint16_t offset;
574 	uint32_t id;
575 } __packed;
576 
577 struct net_ipv4_hdr {
578 	uint8_t vhl;
579 	uint8_t tos;
580 	uint16_t len;
581 	uint8_t id[2];
582 	uint8_t offset[2];
583 	uint8_t ttl;
584 	uint8_t proto;
585 	uint16_t chksum;
586 	uint8_t src[NET_IPV4_ADDR_SIZE];
587 	uint8_t dst[NET_IPV4_ADDR_SIZE];
588 } __packed;
589 
590 struct net_icmp_hdr {
591 	uint8_t type;
592 	uint8_t code;
593 	uint16_t chksum;
594 } __packed;
595 
596 struct net_udp_hdr {
597 	uint16_t src_port;
598 	uint16_t dst_port;
599 	uint16_t len;
600 	uint16_t chksum;
601 } __packed;
602 
603 struct net_tcp_hdr {
604 	uint16_t src_port;
605 	uint16_t dst_port;
606 	uint8_t seq[4];
607 	uint8_t ack[4];
608 	uint8_t offset;
609 	uint8_t flags;
610 	uint8_t wnd[2];
611 	uint16_t chksum;
612 	uint8_t urg[2];
613 	uint8_t optdata[0];
614 } __packed;
615 
net_addr_type2str(enum net_addr_type type)616 static inline const char *net_addr_type2str(enum net_addr_type type)
617 {
618 	switch (type) {
619 	case NET_ADDR_AUTOCONF:
620 		return "AUTO";
621 	case NET_ADDR_DHCP:
622 		return "DHCP";
623 	case NET_ADDR_MANUAL:
624 		return "MANUAL";
625 	case NET_ADDR_OVERRIDABLE:
626 		return "OVERRIDE";
627 	case NET_ADDR_ANY:
628 	default:
629 		break;
630 	}
631 
632 	return "<unknown>";
633 }
634 
635 /* IPv6 extension headers types */
636 #define NET_IPV6_NEXTHDR_HBHO        0
637 #define NET_IPV6_NEXTHDR_DESTO       60
638 #define NET_IPV6_NEXTHDR_ROUTING     43
639 #define NET_IPV6_NEXTHDR_FRAG        44
640 #define NET_IPV6_NEXTHDR_NONE        59
641 
642 /**
643  * This 2 unions are here temporarily, as long as net_context.h will
644  * be still public and not part of the core only.
645  */
646 union net_ip_header {
647 	struct net_ipv4_hdr *ipv4;
648 	struct net_ipv6_hdr *ipv6;
649 };
650 
651 union net_proto_header {
652 	struct net_udp_hdr *udp;
653 	struct net_tcp_hdr *tcp;
654 };
655 
656 #define NET_UDPH_LEN	8			/* Size of UDP header */
657 #define NET_TCPH_LEN	20			/* Size of TCP header */
658 #define NET_ICMPH_LEN	4			/* Size of ICMP header */
659 
660 #define NET_IPV6H_LEN	   40			/* Size of IPv6 header */
661 #define NET_ICMPV6H_LEN	   NET_ICMPH_LEN	/* Size of ICMPv6 header */
662 #define NET_IPV6UDPH_LEN   (NET_UDPH_LEN + NET_IPV6H_LEN) /* IPv6 + UDP */
663 #define NET_IPV6TCPH_LEN   (NET_TCPH_LEN + NET_IPV6H_LEN) /* IPv6 + TCP */
664 #define NET_IPV6ICMPH_LEN  (NET_IPV6H_LEN + NET_ICMPH_LEN) /* ICMPv6 + IPv6 */
665 #define NET_IPV6_FRAGH_LEN 8
666 
667 #define NET_IPV4H_LEN	   20			/* Size of IPv4 header */
668 #define NET_ICMPV4H_LEN	   NET_ICMPH_LEN	/* Size of ICMPv4 header */
669 #define NET_IPV4UDPH_LEN   (NET_UDPH_LEN + NET_IPV4H_LEN) /* IPv4 + UDP */
670 #define NET_IPV4TCPH_LEN   (NET_TCPH_LEN + NET_IPV4H_LEN) /* IPv4 + TCP */
671 #define NET_IPV4ICMPH_LEN  (NET_IPV4H_LEN + NET_ICMPH_LEN) /* ICMPv4 + IPv4 */
672 
673 #define NET_IPV6H_LENGTH_OFFSET		0x04	/* Offset of the Length field in the IPv6 header */
674 
675 #define NET_IPV6_FRAGH_OFFSET_MASK	0xfff8	/* Mask for the 13-bit Fragment Offset field */
676 #define NET_IPV4_FRAGH_OFFSET_MASK	0x1fff	/* Mask for the 13-bit Fragment Offset field */
677 #define NET_IPV4_MORE_FRAG_MASK		0x2000	/* Mask for the 1-bit More Fragments field */
678 #define NET_IPV4_DO_NOT_FRAG_MASK	0x4000	/* Mask for the 1-bit Do Not Fragment field */
679 
680 /** Network interface name length */
681 #if defined(CONFIG_NET_INTERFACE_NAME)
682 #define NET_IFNAMSIZ CONFIG_NET_INTERFACE_NAME_LEN
683 #else
684 #if defined(Z_DEVICE_MAX_NAME_LEN)
685 #define NET_IFNAMSIZ Z_DEVICE_MAX_NAME_LEN
686 #else
687 #define NET_IFNAMSIZ 1
688 #endif /* Z_DEVICE_MAX_NAME_LEN */
689 #endif /* CONFIG_NET_INTERFACE_NAME */
690 
691 /** @endcond */
692 
693 /**
694  * @name Network interface name description
695  * @{
696  */
697 
698 /** Interface description structure */
699 struct net_ifreq {
700 	char ifr_name[NET_IFNAMSIZ]; /**< Network interface name */
701 };
702 /** @} */
703 
704 /**
705  * @brief Incoming IPv4 packet information.
706  *
707  * Used as ancillary data when calling recvmsg() and IP_PKTINFO socket
708  * option is set.
709  */
710 struct net_in_pktinfo {
711 	unsigned int       ipi_ifindex;   /**< Network interface index    */
712 	struct net_in_addr ipi_spec_dst;  /**< Local address              */
713 	struct net_in_addr ipi_addr;      /**< Header Destination address */
714 };
715 
716 /**
717  * @brief Struct used when joining or leaving a IPv4 multicast group.
718  */
719 struct net_ip_mreqn {
720 	struct net_in_addr imr_multiaddr; /**< IP multicast group address    */
721 	struct net_in_addr imr_address;   /**< IP address of local interface */
722 	int                imr_ifindex;   /**< Network interface index       */
723 };
724 
725 /**
726  * @brief Struct used when setting a IPv4 multicast network interface.
727  */
728 struct net_ip_mreq  {
729 	struct net_in_addr imr_multiaddr; /**< IP multicast group address    */
730 	struct net_in_addr imr_interface; /**< IP address of local interface */
731 };
732 
733 /**
734  * @brief Struct used when joining or leaving a IPv6 multicast group.
735  */
736 struct net_ipv6_mreq {
737 	/** IPv6 multicast address of group */
738 	struct net_in6_addr ipv6mr_multiaddr;
739 
740 	/** Network interface index of the local IPv6 address */
741 	int ipv6mr_ifindex;
742 };
743 
744 /**
745  * @brief Incoming IPv6 packet information.
746  *
747  * Used as ancillary data when calling recvmsg() and IPV6_RECVPKTINFO socket
748  * option is set.
749  */
750 struct net_in6_pktinfo {
751 	struct net_in6_addr ipi6_addr;    /**< Destination IPv6 address */
752 	unsigned int        ipi6_ifindex; /**< Receive interface index */
753 };
754 
755 /** @cond INTERNAL_HIDDEN */
net_ipv6_is_addr_loopback_raw(const uint8_t * addr)756 static inline bool net_ipv6_is_addr_loopback_raw(const uint8_t *addr)
757 {
758 	return UNALIGNED_GET((uint32_t *)addr) == 0 &&
759 	       UNALIGNED_GET((uint32_t *)addr + 1) == 0 &&
760 	       UNALIGNED_GET((uint32_t *)addr + 2) == 0 &&
761 	       net_ntohl(UNALIGNED_GET((uint32_t *)addr + 3)) == 1;
762 }
763 /** @endcond */
764 
765 /**
766  * @brief Check if the IPv6 address is a loopback address (::1).
767  *
768  * @param addr IPv6 address
769  *
770  * @return True if address is a loopback address, False otherwise.
771  */
net_ipv6_is_addr_loopback(const struct net_in6_addr * addr)772 static inline bool net_ipv6_is_addr_loopback(const struct net_in6_addr *addr)
773 {
774 	return net_ipv6_is_addr_loopback_raw(addr->s6_addr);
775 }
776 
777 /** @cond INTERNAL_HIDDEN */
net_ipv6_is_addr_mcast_raw(const uint8_t * addr)778 static inline bool net_ipv6_is_addr_mcast_raw(const uint8_t *addr)
779 {
780 	return addr[0] == 0xff;
781 }
782 /** @endcond */
783 
784 /**
785  * @brief Check if the IPv6 address is a multicast address.
786  *
787  * @param addr IPv6 address
788  *
789  * @return True if address is multicast address, False otherwise.
790  */
net_ipv6_is_addr_mcast(const struct net_in6_addr * addr)791 static inline bool net_ipv6_is_addr_mcast(const struct net_in6_addr *addr)
792 {
793 	return net_ipv6_is_addr_mcast_raw(addr->s6_addr);
794 }
795 
796 struct net_if;
797 struct net_if_config;
798 
799 /** @cond INTERNAL_HIDDEN */
800 extern struct net_if_addr *net_if_ipv6_addr_lookup_raw(const uint8_t *addr,
801 						       struct net_if **ret);
802 
net_ipv6_is_my_addr_raw(const uint8_t * addr)803 static inline bool net_ipv6_is_my_addr_raw(const uint8_t *addr)
804 {
805 	return net_if_ipv6_addr_lookup_raw(addr, NULL) != NULL;
806 }
807 /** @endcond */
808 
809 extern struct net_if_addr *net_if_ipv6_addr_lookup(const struct net_in6_addr *addr,
810 						   struct net_if **iface);
811 
812 /**
813  * @brief Check if IPv6 address is found in one of the network interfaces.
814  *
815  * @param addr IPv6 address
816  *
817  * @return True if address was found, False otherwise.
818  */
net_ipv6_is_my_addr(struct net_in6_addr * addr)819 static inline bool net_ipv6_is_my_addr(struct net_in6_addr *addr)
820 {
821 	return net_if_ipv6_addr_lookup(addr, NULL) != NULL;
822 }
823 
824 extern struct net_if_mcast_addr *net_if_ipv6_maddr_lookup(
825 	const struct net_in6_addr *addr, struct net_if **iface);
826 
827 /**
828  * @brief Check if IPv6 multicast address is found in one of the
829  * network interfaces.
830  *
831  * @param maddr Multicast IPv6 address
832  *
833  * @return True if address was found, False otherwise.
834  */
net_ipv6_is_my_maddr(struct net_in6_addr * maddr)835 static inline bool net_ipv6_is_my_maddr(struct net_in6_addr *maddr)
836 {
837 	return net_if_ipv6_maddr_lookup(maddr, NULL) != NULL;
838 }
839 
840 /**
841  * @brief Check if two IPv6 addresses are same when compared after prefix mask.
842  *
843  * @param addr1 First IPv6 address.
844  * @param addr2 Second IPv6 address.
845  * @param length Prefix length (max length is 128).
846  *
847  * @return True if IPv6 prefixes are the same, False otherwise.
848  */
net_ipv6_is_prefix(const uint8_t * addr1,const uint8_t * addr2,uint8_t length)849 static inline bool net_ipv6_is_prefix(const uint8_t *addr1,
850 				      const uint8_t *addr2,
851 				      uint8_t length)
852 {
853 	uint8_t bits = 128 - length;
854 	uint8_t bytes = length / 8U;
855 	uint8_t remain = bits % 8;
856 	uint8_t mask;
857 
858 	if (length > 128) {
859 		return false;
860 	}
861 
862 	if (memcmp(addr1, addr2, bytes)) {
863 		return false;
864 	}
865 
866 	if (!remain) {
867 		/* No remaining bits, the prefixes are the same as first
868 		 * bytes are the same.
869 		 */
870 		return true;
871 	}
872 
873 	/* Create a mask that has remaining most significant bits set */
874 	mask = (uint8_t)((0xff << (8 - remain)) ^ 0xff) << remain;
875 
876 	return (addr1[bytes] & mask) == (addr2[bytes] & mask);
877 }
878 
879 
880 /**
881  * @brief Get the IPv6 network address via the unicast address and the prefix mask.
882  *
883  * @param inaddr Unicast IPv6 address.
884  * @param outaddr Prefix masked IPv6 address (network address).
885  * @param prefix_len Prefix length (max length is 128).
886  */
net_ipv6_addr_prefix_mask(const uint8_t * inaddr,uint8_t * outaddr,uint8_t prefix_len)887 static inline void net_ipv6_addr_prefix_mask(const uint8_t *inaddr,
888 					     uint8_t *outaddr,
889 					     uint8_t prefix_len)
890 {
891 	uint8_t bits = 128 - prefix_len;
892 	uint8_t bytes = prefix_len / 8U;
893 	uint8_t remain = bits % 8;
894 	uint8_t mask;
895 
896 	memset(outaddr, 0, 16U);
897 	memcpy(outaddr, inaddr, bytes);
898 
899 	if (!remain) {
900 		/* No remaining bits, the prefixes are the same as first
901 		 * bytes are the same.
902 		 */
903 		return;
904 	}
905 
906 	/* Create a mask that has remaining most significant bits set */
907 	mask = (uint8_t)((0xff << (8 - remain)) ^ 0xff) << remain;
908 	outaddr[bytes] = inaddr[bytes] & mask;
909 }
910 
911 /** @cond INTERNAL_HIDDEN */
net_ipv4_is_addr_loopback_raw(const uint8_t * addr)912 static inline bool net_ipv4_is_addr_loopback_raw(const uint8_t *addr)
913 {
914 	return addr[0] == 127U;
915 }
916 /** @endcond */
917 
918 /**
919  * @brief Check if the IPv4 address is a loopback address (127.0.0.0/8).
920  *
921  * @param addr IPv4 address
922  *
923  * @return True if address is a loopback address, False otherwise.
924  */
net_ipv4_is_addr_loopback(const struct net_in_addr * addr)925 static inline bool net_ipv4_is_addr_loopback(const struct net_in_addr *addr)
926 {
927 	return net_ipv4_is_addr_loopback_raw(addr->s4_addr);
928 }
929 
930 /** @cond INTERNAL_HIDDEN */
net_ipv4_is_addr_unspecified_raw(const uint8_t * addr)931 static inline bool net_ipv4_is_addr_unspecified_raw(const uint8_t *addr)
932 {
933 	return UNALIGNED_GET((uint32_t *)addr) == 0;
934 }
935 /** @endcond */
936 
937 /**
938  *  @brief Check if the IPv4 address is unspecified (all bits zero)
939  *
940  *  @param addr IPv4 address.
941  *
942  *  @return True if the address is unspecified, false otherwise.
943  */
net_ipv4_is_addr_unspecified(const struct net_in_addr * addr)944 static inline bool net_ipv4_is_addr_unspecified(const struct net_in_addr *addr)
945 {
946 	return net_ipv4_is_addr_unspecified_raw(addr->s4_addr);
947 }
948 
949 /** @cond INTERNAL_HIDDEN */
net_ipv4_is_addr_mcast_raw(const uint8_t * addr)950 static inline bool net_ipv4_is_addr_mcast_raw(const uint8_t *addr)
951 {
952 	return (net_ntohl(UNALIGNED_GET((uint32_t *)addr)) & 0xF0000000) == 0xE0000000;
953 }
954 /** @endcond */
955 
956 /**
957  * @brief Check if the IPv4 address is a multicast address.
958  *
959  * @param addr IPv4 address
960  *
961  * @return True if address is multicast address, False otherwise.
962  */
net_ipv4_is_addr_mcast(const struct net_in_addr * addr)963 static inline bool net_ipv4_is_addr_mcast(const struct net_in_addr *addr)
964 {
965 	return net_ipv4_is_addr_mcast_raw(addr->s4_addr);
966 }
967 
968 /** @cond INTERNAL_HIDDEN */
net_ipv4_is_ll_addr_raw(const uint8_t * addr)969 static inline bool net_ipv4_is_ll_addr_raw(const uint8_t *addr)
970 {
971 	return (net_ntohl(UNALIGNED_GET((uint32_t *)addr)) & 0xFFFF0000) == 0xA9FE0000;
972 }
973 /** @endcond */
974 
975 /**
976  * @brief Check if the given IPv4 address is a link local address.
977  *
978  * @param addr A valid pointer on an IPv4 address
979  *
980  * @return True if it is, false otherwise.
981  */
net_ipv4_is_ll_addr(const struct net_in_addr * addr)982 static inline bool net_ipv4_is_ll_addr(const struct net_in_addr *addr)
983 {
984 	return net_ipv4_is_ll_addr_raw(addr->s4_addr);
985 }
986 
987 /**
988  * @brief Check if the given IPv4 address is from a private address range.
989  *
990  * See https://en.wikipedia.org/wiki/Reserved_IP_addresses for details.
991  *
992  * @param addr A valid pointer on an IPv4 address
993  *
994  * @return True if it is, false otherwise.
995  */
net_ipv4_is_private_addr(const struct net_in_addr * addr)996 static inline bool net_ipv4_is_private_addr(const struct net_in_addr *addr)
997 {
998 	uint32_t masked_24, masked_16, masked_12, masked_10, masked_8;
999 
1000 	masked_24 = net_ntohl(UNALIGNED_GET(&addr->s_addr)) & 0xFFFFFF00;
1001 	masked_16 = masked_24 & 0xFFFF0000;
1002 	masked_12 = masked_24 & 0xFFF00000;
1003 	masked_10 = masked_24 & 0xFFC00000;
1004 	masked_8 = masked_24 & 0xFF000000;
1005 
1006 	return masked_8  == 0x0A000000 || /* 10.0.0.0/8      */
1007 	       masked_10 == 0x64400000 || /* 100.64.0.0/10   */
1008 	       masked_12 == 0xAC100000 || /* 172.16.0.0/12   */
1009 	       masked_16 == 0xC0A80000 || /* 192.168.0.0/16  */
1010 	       masked_24 == 0xC0000200 || /* 192.0.2.0/24    */
1011 	       masked_24 == 0xC0336400 || /* 192.51.100.0/24 */
1012 	       masked_24 == 0xCB007100;   /* 203.0.113.0/24  */
1013 }
1014 
1015 /**
1016  *  @brief Copy an IPv4 or IPv6 address
1017  *
1018  *  @param dest Destination IP address.
1019  *  @param src Source IP address.
1020  *
1021  *  @return Destination address.
1022  */
1023 #define net_ipaddr_copy(dest, src) \
1024 	UNALIGNED_PUT(UNALIGNED_GET(src), dest)
1025 
1026 /**
1027  *  @brief Copy an IPv4 address raw buffer
1028  *
1029  *  @param dest Destination IP address.
1030  *  @param src Source IP address.
1031  */
net_ipv4_addr_copy_raw(uint8_t * dest,const uint8_t * src)1032 static inline void net_ipv4_addr_copy_raw(uint8_t *dest,
1033 					  const uint8_t *src)
1034 {
1035 	net_ipaddr_copy((struct net_in_addr *)dest, (const struct net_in_addr *)src);
1036 }
1037 
1038 /**
1039  *  @brief Copy an IPv6 address raw buffer
1040  *
1041  *  @param dest Destination IP address.
1042  *  @param src Source IP address.
1043  */
net_ipv6_addr_copy_raw(uint8_t * dest,const uint8_t * src)1044 static inline void net_ipv6_addr_copy_raw(uint8_t *dest,
1045 					  const uint8_t *src)
1046 {
1047 	memcpy(dest, src, sizeof(struct net_in6_addr));
1048 }
1049 
1050 /**
1051  *  @brief Compare two raw IPv4 address buffers
1052  *
1053  *  @param addr1 Pointer to IPv4 address buffer.
1054  *  @param addr2 Pointer to IPv4 address buffer.
1055  *
1056  *  @return True if the addresses are the same, false otherwise.
1057  */
net_ipv4_addr_cmp_raw(const uint8_t * addr1,const uint8_t * addr2)1058 static inline bool net_ipv4_addr_cmp_raw(const uint8_t *addr1,
1059 					 const uint8_t *addr2)
1060 {
1061 	return UNALIGNED_GET((uint32_t *)addr1) == UNALIGNED_GET((uint32_t *)addr2);
1062 }
1063 
1064 /**
1065  *  @brief Compare two IPv4 addresses
1066  *
1067  *  @param addr1 Pointer to IPv4 address.
1068  *  @param addr2 Pointer to IPv4 address.
1069  *
1070  *  @return True if the addresses are the same, false otherwise.
1071  */
net_ipv4_addr_cmp(const struct net_in_addr * addr1,const struct net_in_addr * addr2)1072 static inline bool net_ipv4_addr_cmp(const struct net_in_addr *addr1,
1073 				     const struct net_in_addr *addr2)
1074 {
1075 	return net_ipv4_addr_cmp_raw(addr1->s4_addr, addr2->s4_addr);
1076 }
1077 
1078 /**
1079  *  @brief Compare two IPv6 addresses
1080  *
1081  *  @param addr1 Pointer to IPv6 address.
1082  *  @param addr2 Pointer to IPv6 address.
1083  *
1084  *  @return True if the addresses are the same, false otherwise.
1085  */
net_ipv6_addr_cmp(const struct net_in6_addr * addr1,const struct net_in6_addr * addr2)1086 static inline bool net_ipv6_addr_cmp(const struct net_in6_addr *addr1,
1087 				     const struct net_in6_addr *addr2)
1088 {
1089 	return !memcmp(addr1, addr2, sizeof(struct net_in6_addr));
1090 }
1091 
1092 /**
1093  *  @brief Compare two raw IPv6 address buffers
1094  *
1095  *  @param addr1 Pointer to IPv6 address buffer.
1096  *  @param addr2 Pointer to IPv6 address buffer.
1097  *
1098  *  @return True if the addresses are the same, false otherwise.
1099  */
net_ipv6_addr_cmp_raw(const uint8_t * addr1,const uint8_t * addr2)1100 static inline bool net_ipv6_addr_cmp_raw(const uint8_t *addr1,
1101 					 const uint8_t *addr2)
1102 {
1103 	return net_ipv6_addr_cmp((const struct net_in6_addr *)addr1,
1104 				 (const struct net_in6_addr *)addr2);
1105 }
1106 
1107 /** @cond INTERNAL_HIDDEN */
net_ipv6_is_ll_addr_raw(const uint8_t * addr)1108 static inline bool net_ipv6_is_ll_addr_raw(const uint8_t *addr)
1109 {
1110 	return UNALIGNED_GET((uint16_t *)addr) == net_htons(0xFE80);
1111 }
1112 /** @endcond */
1113 
1114 /**
1115  * @brief Check if the given IPv6 address is a link local address.
1116  *
1117  * @param addr A valid pointer on an IPv6 address
1118  *
1119  * @return True if it is, false otherwise.
1120  */
net_ipv6_is_ll_addr(const struct net_in6_addr * addr)1121 static inline bool net_ipv6_is_ll_addr(const struct net_in6_addr *addr)
1122 {
1123 	return net_ipv6_is_ll_addr_raw(addr->s6_addr);
1124 }
1125 
1126 /**
1127  * @brief Check if the given IPv6 address is a site local address.
1128  *
1129  * @param addr A valid pointer on an IPv6 address
1130  *
1131  * @return True if it is, false otherwise.
1132  */
net_ipv6_is_sl_addr(const struct net_in6_addr * addr)1133 static inline bool net_ipv6_is_sl_addr(const struct net_in6_addr *addr)
1134 {
1135 	return UNALIGNED_GET(&addr->s6_addr16[0]) == net_htons(0xFEC0);
1136 }
1137 
1138 
1139 /**
1140  * @brief Check if the given IPv6 address is a unique local address.
1141  *
1142  * @param addr A valid pointer on an IPv6 address
1143  *
1144  * @return True if it is, false otherwise.
1145  */
net_ipv6_is_ula_addr(const struct net_in6_addr * addr)1146 static inline bool net_ipv6_is_ula_addr(const struct net_in6_addr *addr)
1147 {
1148 	return addr->s6_addr[0] == 0xFD;
1149 }
1150 
1151 /**
1152  * @brief Check if the given IPv6 address is a global address.
1153  *
1154  * @param addr A valid pointer on an IPv6 address
1155  *
1156  * @return True if it is, false otherwise.
1157  */
net_ipv6_is_global_addr(const struct net_in6_addr * addr)1158 static inline bool net_ipv6_is_global_addr(const struct net_in6_addr *addr)
1159 {
1160 	return (addr->s6_addr[0] & 0xE0) == 0x20;
1161 }
1162 
1163 /**
1164  * @brief Check if the given IPv6 address is from a private/local address range.
1165  *
1166  * See https://en.wikipedia.org/wiki/Reserved_IP_addresses for details.
1167  *
1168  * @param addr A valid pointer on an IPv6 address
1169  *
1170  * @return True if it is, false otherwise.
1171  */
net_ipv6_is_private_addr(const struct net_in6_addr * addr)1172 static inline bool net_ipv6_is_private_addr(const struct net_in6_addr *addr)
1173 {
1174 	uint32_t masked_32, masked_7;
1175 
1176 	masked_32 = net_ntohl(UNALIGNED_GET(&addr->s6_addr32[0]));
1177 	masked_7 = masked_32 & 0xfc000000;
1178 
1179 	return masked_32 == 0x20010db8 || /* 2001:db8::/32 */
1180 	       masked_7  == 0xfc000000;   /* fc00::/7      */
1181 }
1182 
1183 /**
1184  * @brief Return pointer to any (all bits zeros) IPv6 address.
1185  *
1186  * @return Any IPv6 address.
1187  */
1188 const struct net_in6_addr *net_ipv6_unspecified_address(void);
1189 
1190 /**
1191  * @brief Return pointer to any (all bits zeros) IPv4 address.
1192  *
1193  * @return Any IPv4 address.
1194  */
1195 const struct net_in_addr *net_ipv4_unspecified_address(void);
1196 
1197 /**
1198  * @brief Return pointer to broadcast (all bits ones) IPv4 address.
1199  *
1200  * @return Broadcast IPv4 address.
1201  */
1202 const struct net_in_addr *net_ipv4_broadcast_address(void);
1203 
1204 struct net_if;
1205 extern bool net_if_ipv4_addr_mask_cmp(struct net_if *iface,
1206 				      const struct net_in_addr *addr);
1207 
1208 /**
1209  * @brief Check if the given address belongs to same subnet that
1210  * has been configured for the interface.
1211  *
1212  * @param iface A valid pointer on an interface
1213  * @param addr IPv4 address
1214  *
1215  * @return True if address is in same subnet, false otherwise.
1216  */
net_ipv4_addr_mask_cmp(struct net_if * iface,const struct net_in_addr * addr)1217 static inline bool net_ipv4_addr_mask_cmp(struct net_if *iface,
1218 					  const struct net_in_addr *addr)
1219 {
1220 	return net_if_ipv4_addr_mask_cmp(iface, addr);
1221 }
1222 
1223 /** @cond INTERNAL_HIDDEN */
1224 extern bool net_if_ipv4_is_addr_bcast_raw(struct net_if *iface,
1225 					  const uint8_t *addr);
1226 
1227 #if defined(CONFIG_NET_NATIVE_IPV4)
net_ipv4_is_addr_bcast_raw(struct net_if * iface,const uint8_t * addr)1228 static inline bool net_ipv4_is_addr_bcast_raw(struct net_if *iface,
1229 					      const uint8_t *addr)
1230 {
1231 	if (net_ipv4_addr_cmp_raw(addr, net_ipv4_broadcast_address()->s4_addr)) {
1232 		return true;
1233 	}
1234 
1235 	return net_if_ipv4_is_addr_bcast_raw(iface, addr);
1236 }
1237 #else
net_ipv4_is_addr_bcast_raw(struct net_if * iface,const uint8_t * addr)1238 static inline bool net_ipv4_is_addr_bcast_raw(struct net_if *iface,
1239 					      const uint8_t *addr)
1240 {
1241 	ARG_UNUSED(iface);
1242 	ARG_UNUSED(addr);
1243 
1244 	return false;
1245 }
1246 #endif
1247 /** @endcond */
1248 
1249 extern bool net_if_ipv4_is_addr_bcast(struct net_if *iface,
1250 				      const struct net_in_addr *addr);
1251 
1252 /**
1253  * @brief Check if the given IPv4 address is a broadcast address.
1254  *
1255  * @param iface Interface to use. Must be a valid pointer to an interface.
1256  * @param addr IPv4 address
1257  *
1258  * @return True if address is a broadcast address, false otherwise.
1259  */
1260 #if defined(CONFIG_NET_NATIVE_IPV4)
net_ipv4_is_addr_bcast(struct net_if * iface,const struct net_in_addr * addr)1261 static inline bool net_ipv4_is_addr_bcast(struct net_if *iface,
1262 					  const struct net_in_addr *addr)
1263 {
1264 	if (net_ipv4_addr_cmp(addr, net_ipv4_broadcast_address())) {
1265 		return true;
1266 	}
1267 
1268 	return net_if_ipv4_is_addr_bcast(iface, addr);
1269 }
1270 #else
net_ipv4_is_addr_bcast(struct net_if * iface,const struct net_in_addr * addr)1271 static inline bool net_ipv4_is_addr_bcast(struct net_if *iface,
1272 					  const struct net_in_addr *addr)
1273 {
1274 	ARG_UNUSED(iface);
1275 	ARG_UNUSED(addr);
1276 
1277 	return false;
1278 }
1279 #endif
1280 
1281 /** @cond INTERNAL_HIDDEN */
1282 extern struct net_if_addr *net_if_ipv4_addr_lookup_raw(const uint8_t *addr,
1283 						       struct net_if **ret);
1284 
net_ipv4_is_my_addr_raw(const uint8_t * addr)1285 static inline bool net_ipv4_is_my_addr_raw(const uint8_t *addr)
1286 {
1287 	bool ret;
1288 
1289 	ret = net_if_ipv4_addr_lookup_raw(addr, NULL) != NULL;
1290 	if (!ret) {
1291 		ret = net_ipv4_is_addr_bcast_raw(NULL, addr);
1292 	}
1293 
1294 	return ret;
1295 }
1296 /** @endcond */
1297 
1298 extern struct net_if_addr *net_if_ipv4_addr_lookup(const struct net_in_addr *addr,
1299 						   struct net_if **iface);
1300 
1301 /**
1302  * @brief Check if the IPv4 address is assigned to any network interface
1303  * in the system.
1304  *
1305  * @param addr A valid pointer on an IPv4 address
1306  *
1307  * @return True if IPv4 address is found in one of the network interfaces,
1308  * False otherwise.
1309  */
net_ipv4_is_my_addr(const struct net_in_addr * addr)1310 static inline bool net_ipv4_is_my_addr(const struct net_in_addr *addr)
1311 {
1312 	bool ret;
1313 
1314 	ret = net_if_ipv4_addr_lookup(addr, NULL) != NULL;
1315 	if (!ret) {
1316 		ret = net_ipv4_is_addr_bcast(NULL, addr);
1317 	}
1318 
1319 	return ret;
1320 }
1321 
1322 /** @cond INTERNAL_HIDDEN */
net_ipv6_is_addr_unspecified_raw(const uint8_t * addr)1323 static inline bool net_ipv6_is_addr_unspecified_raw(const uint8_t *addr)
1324 {
1325 	return UNALIGNED_GET((uint32_t *)addr) == 0 &&
1326 	       UNALIGNED_GET((uint32_t *)addr + 1) == 0 &&
1327 	       UNALIGNED_GET((uint32_t *)addr + 2) == 0 &&
1328 	       UNALIGNED_GET((uint32_t *)addr + 3) == 0;
1329 }
1330 /** @endcond */
1331 
1332 /**
1333  *  @brief Check if the IPv6 address is unspecified (all bits zero)
1334  *
1335  *  @param addr IPv6 address.
1336  *
1337  *  @return True if the address is unspecified, false otherwise.
1338  */
net_ipv6_is_addr_unspecified(const struct net_in6_addr * addr)1339 static inline bool net_ipv6_is_addr_unspecified(const struct net_in6_addr *addr)
1340 {
1341 	return net_ipv6_is_addr_unspecified_raw(addr->s6_addr);
1342 }
1343 
1344 /** @cond INTERNAL_HIDDEN */
net_ipv6_is_addr_solicited_node_raw(const uint8_t * addr)1345 static inline bool net_ipv6_is_addr_solicited_node_raw(const uint8_t *addr)
1346 {
1347 	return UNALIGNED_GET((uint32_t *)addr) == net_htonl(0xff020000) &&
1348 	       UNALIGNED_GET((uint32_t *)addr + 1) == 0x00000000 &&
1349 	       UNALIGNED_GET((uint32_t *)addr + 2) == net_htonl(0x00000001) &&
1350 	       ((UNALIGNED_GET((uint32_t *)addr + 3) & net_htonl(0xff000000)) ==
1351 		net_htonl(0xff000000));
1352 }
1353 /** @endcond */
1354 
1355 /**
1356  *  @brief Check if the IPv6 address is solicited node multicast address
1357  *  FF02:0:0:0:0:1:FFXX:XXXX defined in RFC 3513
1358  *
1359  *  @param addr IPv6 address.
1360  *
1361  *  @return True if the address is solicited node address, false otherwise.
1362  */
net_ipv6_is_addr_solicited_node(const struct net_in6_addr * addr)1363 static inline bool net_ipv6_is_addr_solicited_node(const struct net_in6_addr *addr)
1364 {
1365 	return net_ipv6_is_addr_solicited_node_raw(addr->s6_addr);
1366 }
1367 
1368 /** @cond INTERNAL_HIDDEN */
net_ipv6_is_addr_mcast_scope_raw(const uint8_t * addr,int scope)1369 static inline bool net_ipv6_is_addr_mcast_scope_raw(const uint8_t *addr,
1370 						    int scope)
1371 {
1372 	return (addr[0] == 0xff) && ((addr[1] & 0xF) == scope);
1373 }
1374 /** @endcond */
1375 
1376 /** @cond INTERNAL_HIDDEN */
net_ipv6_get_addr_mcast_scope_raw(const uint8_t * addr)1377 static inline int net_ipv6_get_addr_mcast_scope_raw(const uint8_t *addr)
1378 {
1379 	if (addr[0] == 0xff) {
1380 		return (addr[1] & 0xF);
1381 	}
1382 
1383 	return -1;
1384 }
1385 /** @endcond */
1386 
1387 /**
1388  * @brief Check if the IPv6 address is a given scope multicast
1389  * address (FFyx::).
1390  *
1391  * @param addr IPv6 address
1392  * @param scope Scope to check
1393  *
1394  * @return True if the address is in given scope multicast address,
1395  * false otherwise.
1396  */
net_ipv6_is_addr_mcast_scope(const struct net_in6_addr * addr,int scope)1397 static inline bool net_ipv6_is_addr_mcast_scope(const struct net_in6_addr *addr,
1398 						int scope)
1399 {
1400 	return net_ipv6_is_addr_mcast_scope_raw(addr->s6_addr, scope);
1401 }
1402 
1403 /**
1404  * @brief Check if the IPv6 addresses have the same multicast scope (FFyx::).
1405  *
1406  * @param addr_1 IPv6 address 1
1407  * @param addr_2 IPv6 address 2
1408  *
1409  * @return True if both addresses have same multicast scope,
1410  * false otherwise.
1411  */
net_ipv6_is_same_mcast_scope(const struct net_in6_addr * addr_1,const struct net_in6_addr * addr_2)1412 static inline bool net_ipv6_is_same_mcast_scope(const struct net_in6_addr *addr_1,
1413 						const struct net_in6_addr *addr_2)
1414 {
1415 	return (addr_1->s6_addr[0] == 0xff) && (addr_2->s6_addr[0] == 0xff) &&
1416 		(addr_1->s6_addr[1] == addr_2->s6_addr[1]);
1417 }
1418 
1419 /**
1420  * @brief Returns the scope of the given IPv6 address.
1421  *
1422  * @param addr IPv6 address
1423  *
1424  * @return Scope of the address, -1 if address is not multicast.
1425  */
net_ipv6_get_addr_mcast_scope(const struct net_in6_addr * addr)1426 static inline int net_ipv6_get_addr_mcast_scope(const struct net_in6_addr *addr)
1427 {
1428 	return net_ipv6_get_addr_mcast_scope_raw(addr->s6_addr);
1429 }
1430 
1431 /** @cond INTERNAL_HIDDEN */
net_ipv6_is_addr_mcast_iface_raw(const uint8_t * addr)1432 static inline bool net_ipv6_is_addr_mcast_iface_raw(const uint8_t *addr)
1433 {
1434 	return net_ipv6_is_addr_mcast_scope_raw(addr, 0x01);
1435 }
1436 
net_ipv6_is_addr_mcast_link_raw(const uint8_t * addr)1437 static inline bool net_ipv6_is_addr_mcast_link_raw(const uint8_t *addr)
1438 {
1439 	return net_ipv6_is_addr_mcast_scope_raw(addr, 0x02);
1440 }
1441 
net_ipv6_is_addr_mcast_mesh_raw(const uint8_t * addr)1442 static inline bool net_ipv6_is_addr_mcast_mesh_raw(const uint8_t *addr)
1443 {
1444 	return net_ipv6_is_addr_mcast_scope_raw(addr, 0x03);
1445 }
1446 
net_ipv6_is_addr_mcast_site_raw(const uint8_t * addr)1447 static inline bool net_ipv6_is_addr_mcast_site_raw(const uint8_t *addr)
1448 {
1449 	return net_ipv6_is_addr_mcast_scope_raw(addr, 0x05);
1450 }
1451 
net_ipv6_is_addr_mcast_org_raw(const uint8_t * addr)1452 static inline bool net_ipv6_is_addr_mcast_org_raw(const uint8_t *addr)
1453 {
1454 	return net_ipv6_is_addr_mcast_scope_raw(addr, 0x08);
1455 }
1456 /** @endcond */
1457 
1458 /**
1459  * @brief Check if the IPv6 address is a global multicast address (FFxE::/16).
1460  *
1461  * @param addr IPv6 address.
1462  *
1463  * @return True if the address is global multicast address, false otherwise.
1464  */
net_ipv6_is_addr_mcast_global(const struct net_in6_addr * addr)1465 static inline bool net_ipv6_is_addr_mcast_global(const struct net_in6_addr *addr)
1466 {
1467 	return net_ipv6_is_addr_mcast_scope(addr, 0x0e);
1468 }
1469 
1470 /**
1471  * @brief Check if the IPv6 address is a interface scope multicast
1472  * address (FFx1::).
1473  *
1474  * @param addr IPv6 address.
1475  *
1476  * @return True if the address is a interface scope multicast address,
1477  * false otherwise.
1478  */
net_ipv6_is_addr_mcast_iface(const struct net_in6_addr * addr)1479 static inline bool net_ipv6_is_addr_mcast_iface(const struct net_in6_addr *addr)
1480 {
1481 	return net_ipv6_is_addr_mcast_scope(addr, 0x01);
1482 }
1483 
1484 /**
1485  * @brief Check if the IPv6 address is a link local scope multicast
1486  * address (FFx2::).
1487  *
1488  * @param addr IPv6 address.
1489  *
1490  * @return True if the address is a link local scope multicast address,
1491  * false otherwise.
1492  */
net_ipv6_is_addr_mcast_link(const struct net_in6_addr * addr)1493 static inline bool net_ipv6_is_addr_mcast_link(const struct net_in6_addr *addr)
1494 {
1495 	return net_ipv6_is_addr_mcast_scope(addr, 0x02);
1496 }
1497 
1498 /**
1499  * @brief Check if the IPv6 address is a mesh-local scope multicast
1500  * address (FFx3::).
1501  *
1502  * @param addr IPv6 address.
1503  *
1504  * @return True if the address is a mesh-local scope multicast address,
1505  * false otherwise.
1506  */
net_ipv6_is_addr_mcast_mesh(const struct net_in6_addr * addr)1507 static inline bool net_ipv6_is_addr_mcast_mesh(const struct net_in6_addr *addr)
1508 {
1509 	return net_ipv6_is_addr_mcast_scope(addr, 0x03);
1510 }
1511 
1512 /**
1513  * @brief Check if the IPv6 address is a site scope multicast
1514  * address (FFx5::).
1515  *
1516  * @param addr IPv6 address.
1517  *
1518  * @return True if the address is a site scope multicast address,
1519  * false otherwise.
1520  */
net_ipv6_is_addr_mcast_site(const struct net_in6_addr * addr)1521 static inline bool net_ipv6_is_addr_mcast_site(const struct net_in6_addr *addr)
1522 {
1523 	return net_ipv6_is_addr_mcast_scope(addr, 0x05);
1524 }
1525 
1526 /**
1527  * @brief Check if the IPv6 address is an organization scope multicast
1528  * address (FFx8::).
1529  *
1530  * @param addr IPv6 address.
1531  *
1532  * @return True if the address is an organization scope multicast address,
1533  * false otherwise.
1534  */
net_ipv6_is_addr_mcast_org(const struct net_in6_addr * addr)1535 static inline bool net_ipv6_is_addr_mcast_org(const struct net_in6_addr *addr)
1536 {
1537 	return net_ipv6_is_addr_mcast_scope(addr, 0x08);
1538 }
1539 
1540 /** @cond INTERNAL_HIDDEN */
net_ipv6_is_addr_mcast_group_raw(const uint8_t * addr,const uint8_t * group)1541 static inline bool net_ipv6_is_addr_mcast_group_raw(const uint8_t *addr,
1542 						    const uint8_t *group)
1543 {
1544 	return UNALIGNED_GET((uint16_t *)addr + 1) == UNALIGNED_GET((uint16_t *)group + 1) &&
1545 	       UNALIGNED_GET((uint32_t *)addr + 1) == UNALIGNED_GET((uint32_t *)group + 1) &&
1546 	       UNALIGNED_GET((uint32_t *)addr + 2) == UNALIGNED_GET((uint32_t *)group + 2) &&
1547 	       UNALIGNED_GET((uint32_t *)addr + 3) == UNALIGNED_GET((uint32_t *)group + 3);
1548 }
1549 /** @endcond */
1550 
1551 /**
1552  * @brief Check if the IPv6 address belongs to certain multicast group
1553  *
1554  * @param addr IPv6 address.
1555  * @param group Group id IPv6 address, the values must be in network
1556  * byte order
1557  *
1558  * @return True if the IPv6 multicast address belongs to given multicast
1559  * group, false otherwise.
1560  */
net_ipv6_is_addr_mcast_group(const struct net_in6_addr * addr,const struct net_in6_addr * group)1561 static inline bool net_ipv6_is_addr_mcast_group(const struct net_in6_addr *addr,
1562 						const struct net_in6_addr *group)
1563 {
1564 	return net_ipv6_is_addr_mcast_group_raw(addr->s6_addr, group->s6_addr);
1565 }
1566 
1567 /** @cond INTERNAL_HIDDEN */
net_ipv6_is_addr_mcast_all_nodes_group_raw(const uint8_t * addr)1568 static inline bool net_ipv6_is_addr_mcast_all_nodes_group_raw(const uint8_t *addr)
1569 {
1570 	static const uint8_t all_nodes_mcast_group[NET_IPV6_ADDR_SIZE] = {
1571 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1572 		0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1573 	};
1574 
1575 	return net_ipv6_is_addr_mcast_group_raw(addr, all_nodes_mcast_group);
1576 }
1577 /** @endcond */
1578 
1579 /**
1580  * @brief Check if the IPv6 address belongs to the all nodes multicast group
1581  *
1582  * @param addr IPv6 address
1583  *
1584  * @return True if the IPv6 multicast address belongs to the all nodes multicast
1585  * group, false otherwise
1586  */
1587 static inline bool
net_ipv6_is_addr_mcast_all_nodes_group(const struct net_in6_addr * addr)1588 net_ipv6_is_addr_mcast_all_nodes_group(const struct net_in6_addr *addr)
1589 {
1590 	return net_ipv6_is_addr_mcast_all_nodes_group_raw(addr->s6_addr);
1591 }
1592 
1593 /**
1594  * @brief Check if the IPv6 address is a interface scope all nodes multicast
1595  * address (FF01::1).
1596  *
1597  * @param addr IPv6 address.
1598  *
1599  * @return True if the address is a interface scope all nodes multicast address,
1600  * false otherwise.
1601  */
1602 static inline bool
net_ipv6_is_addr_mcast_iface_all_nodes(const struct net_in6_addr * addr)1603 net_ipv6_is_addr_mcast_iface_all_nodes(const struct net_in6_addr *addr)
1604 {
1605 	return net_ipv6_is_addr_mcast_iface(addr) &&
1606 	       net_ipv6_is_addr_mcast_all_nodes_group(addr);
1607 }
1608 
1609 /** @cond INTERNAL_HIDDEN */
net_ipv6_is_addr_mcast_link_all_nodes_raw(const uint8_t * addr)1610 static inline bool net_ipv6_is_addr_mcast_link_all_nodes_raw(const uint8_t *addr)
1611 {
1612 	return net_ipv6_is_addr_mcast_link_raw(addr) &&
1613 	       net_ipv6_is_addr_mcast_all_nodes_group_raw(addr);
1614 }
1615 /** @endcond */
1616 
1617 /**
1618  * @brief Check if the IPv6 address is a link local scope all nodes multicast
1619  * address (FF02::1).
1620  *
1621  * @param addr IPv6 address.
1622  *
1623  * @return True if the address is a link local scope all nodes multicast
1624  * address, false otherwise.
1625  */
1626 static inline bool
net_ipv6_is_addr_mcast_link_all_nodes(const struct net_in6_addr * addr)1627 net_ipv6_is_addr_mcast_link_all_nodes(const struct net_in6_addr *addr)
1628 {
1629 	return net_ipv6_is_addr_mcast_link(addr) &&
1630 	       net_ipv6_is_addr_mcast_all_nodes_group(addr);
1631 }
1632 
1633 /**
1634  *  @brief Create solicited node IPv6 multicast address
1635  *  FF02:0:0:0:0:1:FFXX:XXXX defined in RFC 3513
1636  *
1637  *  @param src IPv6 address.
1638  *  @param dst IPv6 address.
1639  */
1640 static inline
net_ipv6_addr_create_solicited_node(const struct net_in6_addr * src,struct net_in6_addr * dst)1641 void net_ipv6_addr_create_solicited_node(const struct net_in6_addr *src,
1642 					 struct net_in6_addr *dst)
1643 {
1644 	dst->s6_addr[0]   = 0xFF;
1645 	dst->s6_addr[1]   = 0x02;
1646 	UNALIGNED_PUT(0, &dst->s6_addr16[1]);
1647 	UNALIGNED_PUT(0, &dst->s6_addr16[2]);
1648 	UNALIGNED_PUT(0, &dst->s6_addr16[3]);
1649 	UNALIGNED_PUT(0, &dst->s6_addr16[4]);
1650 	dst->s6_addr[10]  = 0U;
1651 	dst->s6_addr[11]  = 0x01;
1652 	dst->s6_addr[12]  = 0xFF;
1653 	dst->s6_addr[13]  = src->s6_addr[13];
1654 	UNALIGNED_PUT(UNALIGNED_GET(&src->s6_addr16[7]), &dst->s6_addr16[7]);
1655 }
1656 
1657 /** @brief Construct an IPv6 address from eight 16-bit words.
1658  *
1659  *  @param addr IPv6 address
1660  *  @param addr0 16-bit word which is part of the address
1661  *  @param addr1 16-bit word which is part of the address
1662  *  @param addr2 16-bit word which is part of the address
1663  *  @param addr3 16-bit word which is part of the address
1664  *  @param addr4 16-bit word which is part of the address
1665  *  @param addr5 16-bit word which is part of the address
1666  *  @param addr6 16-bit word which is part of the address
1667  *  @param addr7 16-bit word which is part of the address
1668  */
net_ipv6_addr_create(struct net_in6_addr * addr,uint16_t addr0,uint16_t addr1,uint16_t addr2,uint16_t addr3,uint16_t addr4,uint16_t addr5,uint16_t addr6,uint16_t addr7)1669 static inline void net_ipv6_addr_create(struct net_in6_addr *addr,
1670 					uint16_t addr0, uint16_t addr1,
1671 					uint16_t addr2, uint16_t addr3,
1672 					uint16_t addr4, uint16_t addr5,
1673 					uint16_t addr6, uint16_t addr7)
1674 {
1675 	UNALIGNED_PUT(net_htons(addr0), &addr->s6_addr16[0]);
1676 	UNALIGNED_PUT(net_htons(addr1), &addr->s6_addr16[1]);
1677 	UNALIGNED_PUT(net_htons(addr2), &addr->s6_addr16[2]);
1678 	UNALIGNED_PUT(net_htons(addr3), &addr->s6_addr16[3]);
1679 	UNALIGNED_PUT(net_htons(addr4), &addr->s6_addr16[4]);
1680 	UNALIGNED_PUT(net_htons(addr5), &addr->s6_addr16[5]);
1681 	UNALIGNED_PUT(net_htons(addr6), &addr->s6_addr16[6]);
1682 	UNALIGNED_PUT(net_htons(addr7), &addr->s6_addr16[7]);
1683 }
1684 
1685 /**
1686  *  @brief Create link local allnodes multicast IPv6 address
1687  *
1688  *  @param addr IPv6 address
1689  */
net_ipv6_addr_create_ll_allnodes_mcast(struct net_in6_addr * addr)1690 static inline void net_ipv6_addr_create_ll_allnodes_mcast(struct net_in6_addr *addr)
1691 {
1692 	net_ipv6_addr_create(addr, 0xff02, 0, 0, 0, 0, 0, 0, 0x0001);
1693 }
1694 
1695 /**
1696  *  @brief Create link local allrouters multicast IPv6 address
1697  *
1698  *  @param addr IPv6 address
1699  */
net_ipv6_addr_create_ll_allrouters_mcast(struct net_in6_addr * addr)1700 static inline void net_ipv6_addr_create_ll_allrouters_mcast(struct net_in6_addr *addr)
1701 {
1702 	net_ipv6_addr_create(addr, 0xff02, 0, 0, 0, 0, 0, 0, 0x0002);
1703 }
1704 
1705 /**
1706  *  @brief Create IPv4 mapped IPv6 address
1707  *
1708  *  @param addr4 IPv4 address
1709  *  @param addr6 IPv6 address to be created
1710  */
net_ipv6_addr_create_v4_mapped(const struct net_in_addr * addr4,struct net_in6_addr * addr6)1711 static inline void net_ipv6_addr_create_v4_mapped(const struct net_in_addr *addr4,
1712 						  struct net_in6_addr *addr6)
1713 {
1714 	net_ipv6_addr_create(addr6, 0, 0, 0, 0, 0, 0xffff,
1715 			     net_ntohs(addr4->s4_addr16[0]),
1716 			     net_ntohs(addr4->s4_addr16[1]));
1717 }
1718 
1719 /**
1720  *  @brief Is the IPv6 address an IPv4 mapped one. The v4 mapped addresses
1721  *         look like \::ffff:a.b.c.d
1722  *
1723  *  @param addr IPv6 address
1724  *
1725  *  @return True if IPv6 address is a IPv4 mapped address, False otherwise.
1726  */
net_ipv6_addr_is_v4_mapped(const struct net_in6_addr * addr)1727 static inline bool net_ipv6_addr_is_v4_mapped(const struct net_in6_addr *addr)
1728 {
1729 	if (UNALIGNED_GET(&addr->s6_addr32[0]) == 0 &&
1730 	    UNALIGNED_GET(&addr->s6_addr32[1]) == 0 &&
1731 	    UNALIGNED_GET(&addr->s6_addr16[5]) == 0xffff) {
1732 		return true;
1733 	}
1734 
1735 	return false;
1736 }
1737 
1738 /**
1739  *  @brief Generate IPv6 address using a prefix and interface identifier.
1740  *         Interface identifier is either generated from EUI-64 (MAC) defined
1741  *         in RFC 4291 or from randomized value defined in RFC 7217.
1742  *
1743  *  @param iface Network interface
1744  *  @param prefix IPv6 prefix, can be left out in which case fe80::/64 is used
1745  *  @param network_id Network identifier (for example SSID in WLAN), this is
1746  *         optional can be set to NULL
1747  *  @param network_id_len Network identifier length, if set to 0 then the
1748  *         network id is ignored.
1749  *  @param dad_counter Duplicate Address Detection counter value, can be set to 0
1750  *         if it is not known.
1751  *  @param addr IPv6 address
1752  *  @param lladdr Link local address
1753  *
1754  *  @return 0 if ok, < 0 if error
1755  */
1756 int net_ipv6_addr_generate_iid(struct net_if *iface,
1757 			       const struct net_in6_addr *prefix,
1758 			       uint8_t *network_id, size_t network_id_len,
1759 			       uint8_t dad_counter,
1760 			       struct net_in6_addr *addr,
1761 			       struct net_linkaddr *lladdr);
1762 
1763 /**
1764  *  @brief Create IPv6 address interface identifier.
1765  *
1766  *  @param addr IPv6 address
1767  *  @param lladdr Link local address
1768  */
net_ipv6_addr_create_iid(struct net_in6_addr * addr,struct net_linkaddr * lladdr)1769 static inline void net_ipv6_addr_create_iid(struct net_in6_addr *addr,
1770 					    struct net_linkaddr *lladdr)
1771 {
1772 	(void)net_ipv6_addr_generate_iid(NULL, NULL, NULL, 0, 0, addr, lladdr);
1773 }
1774 
1775 /** @cond INTERNAL_HIDDEN */
net_ipv6_addr_based_on_ll_raw(const uint8_t * addr,const struct net_linkaddr * lladdr)1776 static inline bool net_ipv6_addr_based_on_ll_raw(const uint8_t *addr,
1777 						 const struct net_linkaddr *lladdr)
1778 {
1779 	if (addr == NULL || lladdr == NULL) {
1780 		return false;
1781 	}
1782 
1783 	switch (lladdr->len) {
1784 	case 2:
1785 		if (!memcmp(&addr[14], lladdr->addr, lladdr->len) &&
1786 		    addr[8]  == 0U &&
1787 		    addr[9]  == 0U &&
1788 		    addr[10] == 0U &&
1789 		    addr[11] == 0xff &&
1790 		    addr[12] == 0xfe) {
1791 			return true;
1792 		}
1793 
1794 		break;
1795 	case 6:
1796 		if (lladdr->type == NET_LINK_ETHERNET) {
1797 			if (!memcmp(&addr[9], &lladdr->addr[1], 2) &&
1798 			    !memcmp(&addr[13], &lladdr->addr[3], 3) &&
1799 			    addr[11] == 0xff &&
1800 			    addr[12] == 0xfe &&
1801 			    (addr[8] ^ 0x02) == lladdr->addr[0]) {
1802 				return true;
1803 			}
1804 		}
1805 
1806 		break;
1807 	case 8:
1808 		if (sizeof(lladdr->addr) < 8) {
1809 			return false;
1810 		}
1811 
1812 		if (!memcmp(&addr[9], &lladdr->addr[1],
1813 			    lladdr->len - 1) &&
1814 		    (addr[8] ^ 0x02) == lladdr->addr[0]) {
1815 			return true;
1816 		}
1817 
1818 		break;
1819 	default:
1820 		return false;
1821 	}
1822 
1823 	return false;
1824 }
1825 /** @endcond */
1826 
1827 /**
1828  *  @brief Check if given address is based on link layer address
1829  *
1830  *  @return True if it is, False otherwise
1831  */
net_ipv6_addr_based_on_ll(const struct net_in6_addr * addr,const struct net_linkaddr * lladdr)1832 static inline bool net_ipv6_addr_based_on_ll(const struct net_in6_addr *addr,
1833 					     const struct net_linkaddr *lladdr)
1834 {
1835 	if (addr == NULL || lladdr == NULL) {
1836 		return false;
1837 	}
1838 
1839 	return net_ipv6_addr_based_on_ll_raw(addr->s6_addr, lladdr);
1840 }
1841 
1842 /**
1843  * @brief Get net_sockaddr from net_sockaddr_storage. This is a helper so that
1844  * the code calling this function can be made shorter.
1845  *
1846  * @param addr Socket storage address
1847  *
1848  * @return Pointer to socket address (struct sockaddr)
1849  */
net_sad(const struct net_sockaddr_storage * addr)1850 static inline struct net_sockaddr *net_sad(const struct net_sockaddr_storage *addr)
1851 {
1852 	return (struct net_sockaddr *)addr;
1853 }
1854 
1855 /**
1856  * @brief Get net_sockaddr_in6 from net_sockaddr. This is a helper so that
1857  * the code calling this function can be made shorter.
1858  *
1859  * @param addr Socket address
1860  *
1861  * @return Pointer to IPv6 socket address
1862  */
net_sin6(const struct net_sockaddr * addr)1863 static inline struct net_sockaddr_in6 *net_sin6(const struct net_sockaddr *addr)
1864 {
1865 	return (struct net_sockaddr_in6 *)addr;
1866 }
1867 
1868 /**
1869  * @brief Get net_sockaddr_in from net_sockaddr. This is a helper so that
1870  * the code calling this function can be made shorter.
1871  *
1872  * @param addr Socket address
1873  *
1874  * @return Pointer to IPv4 socket address
1875  */
net_sin(const struct net_sockaddr * addr)1876 static inline struct net_sockaddr_in *net_sin(const struct net_sockaddr *addr)
1877 {
1878 	return (struct net_sockaddr_in *)addr;
1879 }
1880 
1881 /**
1882  * @brief Get net_sockaddr_in6_ptr from net_sockaddr_ptr. This is a helper so that
1883  * the code calling this function can be made shorter.
1884  *
1885  * @param addr Socket address
1886  *
1887  * @return Pointer to IPv6 socket address
1888  */
1889 static inline
net_sin6_ptr(const struct net_sockaddr_ptr * addr)1890 struct net_sockaddr_in6_ptr *net_sin6_ptr(const struct net_sockaddr_ptr *addr)
1891 {
1892 	return (struct net_sockaddr_in6_ptr *)addr;
1893 }
1894 
1895 /**
1896  * @brief Get net_sockaddr_in_ptr from sockaddr_ptr. This is a helper so that
1897  * the code calling this function can be made shorter.
1898  *
1899  * @param addr Socket address
1900  *
1901  * @return Pointer to IPv4 socket address
1902  */
1903 static inline
net_sin_ptr(const struct net_sockaddr_ptr * addr)1904 struct net_sockaddr_in_ptr *net_sin_ptr(const struct net_sockaddr_ptr *addr)
1905 {
1906 	return (struct net_sockaddr_in_ptr *)addr;
1907 }
1908 
1909 /**
1910  * @brief Get net_sockaddr_ll_ptr from sockaddr_ptr. This is a helper so that
1911  * the code calling this function can be made shorter.
1912  *
1913  * @param addr Socket address
1914  *
1915  * @return Pointer to linklayer socket address
1916  */
1917 static inline
net_sll_ptr(const struct net_sockaddr_ptr * addr)1918 struct net_sockaddr_ll_ptr *net_sll_ptr(const struct net_sockaddr_ptr *addr)
1919 {
1920 	return (struct net_sockaddr_ll_ptr *)addr;
1921 }
1922 
1923 /**
1924  * @brief Get net_sockaddr_can_ptr from net_sockaddr_ptr. This is a helper so that
1925  * the code needing this functionality can be made shorter.
1926  *
1927  * @param addr Socket address
1928  *
1929  * @return Pointer to CAN socket address
1930  */
1931 static inline
net_can_ptr(const struct net_sockaddr_ptr * addr)1932 struct net_sockaddr_can_ptr *net_can_ptr(const struct net_sockaddr_ptr *addr)
1933 {
1934 	return (struct net_sockaddr_can_ptr *)addr;
1935 }
1936 
1937 /**
1938  * @brief Convert a string to IP address.
1939  *
1940  * @param family IP address family (NET_AF_INET or NET_AF_INET6)
1941  * @param src IP address in a null terminated string
1942  * @param dst Pointer to struct net_in_addr if family is NET_AF_INET or
1943  * pointer to struct net_in6_addr if family is NET_AF_INET6
1944  *
1945  * @note This function doesn't do precise error checking,
1946  * do not use for untrusted strings.
1947  *
1948  * @return 0 if ok, < 0 if error
1949  */
1950 __syscall int net_addr_pton(net_sa_family_t family, const char *src, void *dst);
1951 
1952 /**
1953  * @brief Convert IP address to string form.
1954  *
1955  * @param family IP address family (NET_AF_INET or NET_AF_INET6)
1956  * @param src Pointer to struct net_in_addr if family is NET_AF_INET or
1957  *        pointer to struct net_in6_addr if family is NET_AF_INET6
1958  * @param dst Buffer for IP address as a null terminated string
1959  * @param size Number of bytes available in the buffer
1960  *
1961  * @return dst pointer if ok, NULL if error
1962  */
1963 __syscall char *net_addr_ntop(net_sa_family_t family, const void *src,
1964 			      char *dst, size_t size);
1965 
1966 /**
1967  * @brief Create netmask from mask length.
1968  *
1969  * @param family IP address family (NET_AF_INET or NET_AF_INET6)
1970  * @param mask_len Netmask length (in IPv4) or prefix length (in IPv6)
1971  * @param mask Pointer to struct sockaddr_in if family is NET_AF_INET or
1972  * pointer to struct sockaddr_in6 if family is NET_AF_INET6
1973  *
1974  * @return 0 if ok, < 0 if error
1975  */
1976 int net_mask_len_to_netmask(net_sa_family_t family, uint8_t mask_len,
1977 			    struct net_sockaddr *mask);
1978 
1979 /**
1980  * @brief Create mask length from netmask.
1981  *
1982  * @param family IP address family (NET_AF_INET or NET_AF_INET6)
1983  * @param mask Pointer to struct sockaddr_in if family is NET_AF_INET or
1984  * pointer to struct sockaddr_in6 if family is NET_AF_INET6
1985  * @param mask_len Netmask length (in IPv4) or prefix length (in IPv6)
1986  *
1987  * @return 0 if ok, < 0 if error
1988  */
1989 int net_netmask_to_mask_len(net_sa_family_t family, struct net_sockaddr *mask,
1990 			    uint8_t *mask_len);
1991 
1992 /**
1993  * @brief Parse a string that contains either IPv4 or IPv6 address
1994  * and optional port, and store the information in user supplied
1995  * sockaddr struct.
1996  *
1997  * @details Syntax of the IP address string:
1998  *   192.0.2.1:80
1999  *   192.0.2.42
2000  *   [2001:db8::1]:8080
2001  *   [2001:db8::2]
2002  *   2001:db::42
2003  * Note that the str_len parameter is used to restrict the amount of
2004  * characters that are checked. If the string does not contain port
2005  * number, then the port number in sockaddr is not modified.
2006  *
2007  * @param str String that contains the IP address.
2008  * @param str_len Length of the string to be parsed.
2009  * @param addr Pointer to user supplied struct sockaddr.
2010  *
2011  * @return True if parsing could be done, false otherwise.
2012  */
2013 bool net_ipaddr_parse(const char *str, size_t str_len,
2014 		      struct net_sockaddr *addr);
2015 
2016 /**
2017  * @brief Parse a string that contains either IPv4 or IPv6 address
2018  * and optional mask len, and store the information in user supplied
2019  * sockaddr struct. There can be multiple IP addresses separated by
2020  * comma or space. The function returns the pointer to the next IP address
2021  * in the string.
2022  *
2023  * @details Syntax of the IP address string:
2024  *   192.0.2.1/24
2025  *   192.0.2.42
2026  *   2001:db8::1/64
2027  *   2001:db8::2
2028  *   2001:db::42/128
2029  *   2001:db8::1/64,192.0.2.1,2001:db8::2,192.0.2.2/24
2030  *   2001:db8::1/64 192.0.2.1 2001:db8::2 192.0.2.2/24
2031  * Note that the str_len parameter is used to restrict the amount of
2032  * characters that are checked.
2033  *
2034  * @param str String that contains the IP address.
2035  * @param str_len Length of the string to be parsed.
2036  * @param addr Pointer to user supplied struct sockaddr.
2037  * @param mask_len Pointer to mask_len which is returned to the caller.
2038  *
2039  * @return NULL if there was an error while parsing.
2040  *         "" if we could parse the IP address and there is nothing more to parse.
2041  *         All other values point to next character after the "," or " " in the string.
2042  */
2043 const char *net_ipaddr_parse_mask(const char *str, size_t str_len,
2044 				  struct net_sockaddr *addr, uint8_t *mask_len);
2045 
2046 /**
2047  * @brief Set the default port in the sockaddr structure.
2048  * If the port is already set, then do nothing.
2049  *
2050  * @param addr Pointer to user supplied struct sockaddr.
2051  * @param default_port Default port number to set.
2052  *
2053  * @return 0 if ok, <0 if error
2054  */
2055 int net_port_set_default(struct net_sockaddr *addr, uint16_t default_port);
2056 
2057 /**
2058  * @brief Compare TCP sequence numbers.
2059  *
2060  * @details This function compares TCP sequence numbers,
2061  *          accounting for wraparound effects.
2062  *
2063  * @param seq1 First sequence number
2064  * @param seq2 Seconds sequence number
2065  *
2066  * @return < 0 if seq1 < seq2, 0 if seq1 == seq2, > 0 if seq > seq2
2067  */
net_tcp_seq_cmp(uint32_t seq1,uint32_t seq2)2068 static inline int32_t net_tcp_seq_cmp(uint32_t seq1, uint32_t seq2)
2069 {
2070 	return (int32_t)(seq1 - seq2);
2071 }
2072 
2073 /**
2074  * @brief Check that one TCP sequence number is greater.
2075  *
2076  * @details This is convenience function on top of net_tcp_seq_cmp().
2077  *
2078  * @param seq1 First sequence number
2079  * @param seq2 Seconds sequence number
2080  *
2081  * @return True if seq > seq2
2082  */
net_tcp_seq_greater(uint32_t seq1,uint32_t seq2)2083 static inline bool net_tcp_seq_greater(uint32_t seq1, uint32_t seq2)
2084 {
2085 	return net_tcp_seq_cmp(seq1, seq2) > 0;
2086 }
2087 
2088 /**
2089  * @brief Convert a string of hex values to array of bytes.
2090  *
2091  * @details The syntax of the string is "ab:02:98:fa:42:01"
2092  *
2093  * @param buf Pointer to memory where the bytes are written.
2094  * @param buf_len Length of the memory area.
2095  * @param src String of bytes.
2096  *
2097  * @return 0 if ok, <0 if error
2098  */
2099 int net_bytes_from_str(uint8_t *buf, int buf_len, const char *src);
2100 
2101 /**
2102  * @brief Convert Tx network packet priority to traffic class so we can place
2103  * the packet into correct Tx queue.
2104  *
2105  * @param prio Network priority
2106  *
2107  * @return Tx traffic class that handles that priority network traffic.
2108  */
2109 int net_tx_priority2tc(enum net_priority prio);
2110 
2111 /**
2112  * @brief Convert Rx network packet priority to traffic class so we can place
2113  * the packet into correct Rx queue.
2114  *
2115  * @param prio Network priority
2116  *
2117  * @return Rx traffic class that handles that priority network traffic.
2118  */
2119 int net_rx_priority2tc(enum net_priority prio);
2120 
2121 /**
2122  * @brief Convert network packet VLAN priority to network packet priority so we
2123  * can place the packet into correct queue.
2124  *
2125  * @param priority VLAN priority
2126  *
2127  * @return Network priority
2128  */
net_vlan2priority(uint8_t priority)2129 static inline enum net_priority net_vlan2priority(uint8_t priority)
2130 {
2131 	/* Map according to IEEE 802.1Q */
2132 	static const uint8_t vlan2priority[] = {
2133 		NET_PRIORITY_BE,
2134 		NET_PRIORITY_BK,
2135 		NET_PRIORITY_EE,
2136 		NET_PRIORITY_CA,
2137 		NET_PRIORITY_VI,
2138 		NET_PRIORITY_VO,
2139 		NET_PRIORITY_IC,
2140 		NET_PRIORITY_NC
2141 	};
2142 
2143 	if (priority >= ARRAY_SIZE(vlan2priority)) {
2144 		/* Use Best Effort as the default priority */
2145 		return NET_PRIORITY_BE;
2146 	}
2147 
2148 	return (enum net_priority)vlan2priority[priority];
2149 }
2150 
2151 /**
2152  * @brief Convert network packet priority to network packet VLAN priority.
2153  *
2154  * @param priority Packet priority
2155  *
2156  * @return VLAN priority (PCP)
2157  */
net_priority2vlan(enum net_priority priority)2158 static inline uint8_t net_priority2vlan(enum net_priority priority)
2159 {
2160 	/* The conversion works both ways */
2161 	return (uint8_t)net_vlan2priority(priority);
2162 }
2163 
2164 /**
2165  * @brief Return network address family value as a string. This is only usable
2166  * for debugging.
2167  *
2168  * @param family Network address family code
2169  *
2170  * @return Network address family as a string, or NULL if family is unknown.
2171  */
2172 const char *net_family2str(net_sa_family_t family);
2173 
2174 /**
2175  * @brief Add IPv6 prefix as a privacy extension filter.
2176  *
2177  * @details Note that the filters can either allow or deny listing.
2178  *
2179  * @param addr IPv6 prefix
2180  * @param is_denylist Tells if this filter is for allowing or denying listing.
2181  *
2182  * @return 0 if ok, <0 if error
2183  */
2184 #if defined(CONFIG_NET_IPV6_PE)
2185 int net_ipv6_pe_add_filter(struct net_in6_addr *addr, bool is_denylist);
2186 #else
net_ipv6_pe_add_filter(struct net_in6_addr * addr,bool is_denylist)2187 static inline int net_ipv6_pe_add_filter(struct net_in6_addr *addr,
2188 					 bool is_denylist)
2189 {
2190 	ARG_UNUSED(addr);
2191 	ARG_UNUSED(is_denylist);
2192 
2193 	return -ENOTSUP;
2194 }
2195 #endif /* CONFIG_NET_IPV6_PE */
2196 
2197 /**
2198  * @brief Delete IPv6 prefix from privacy extension filter list.
2199  *
2200  * @param addr IPv6 prefix
2201  *
2202  * @return 0 if ok, <0 if error
2203  */
2204 #if defined(CONFIG_NET_IPV6_PE)
2205 int net_ipv6_pe_del_filter(struct net_in6_addr *addr);
2206 #else
net_ipv6_pe_del_filter(struct net_in6_addr * addr)2207 static inline int net_ipv6_pe_del_filter(struct net_in6_addr *addr)
2208 {
2209 	ARG_UNUSED(addr);
2210 
2211 	return -ENOTSUP;
2212 }
2213 #endif /* CONFIG_NET_IPV6_PE */
2214 
2215 #ifdef __cplusplus
2216 }
2217 #endif
2218 
2219 #include <zephyr/syscalls/net_ip.h>
2220 
2221 #if defined(CONFIG_NET_NAMESPACE_COMPAT_MODE)
2222 #define ZEPHYR_INCLUDE_NET_COMPAT_MODE_SYMBOLS
2223 #include <zephyr/net/net_compat.h>
2224 #undef ZEPHYR_INCLUDE_NET_COMPAT_MODE_SYMBOLS
2225 #endif /* CONFIG_NET_NAMESPACE_COMPAT_MODE */
2226 
2227 /**
2228  * @}
2229  */
2230 
2231 #endif /* ZEPHYR_INCLUDE_NET_NET_IP_H_ */
2232