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 PF_UNSPEC       0          /**< Unspecified protocol family.  */
45 #define PF_INET         1          /**< IP protocol family version 4. */
46 #define PF_INET6        2          /**< IP protocol family version 6. */
47 #define PF_PACKET       3          /**< Packet family.                */
48 #define PF_CAN          4          /**< Controller Area Network.      */
49 #define PF_NET_MGMT     5          /**< Network management info.      */
50 #define PF_LOCAL        6          /**< Inter-process communication   */
51 #define PF_UNIX         PF_LOCAL   /**< Inter-process communication   */
52 
53 /* Address families. */
54 #define AF_UNSPEC      PF_UNSPEC   /**< Unspecified address family.   */
55 #define AF_INET        PF_INET     /**< IP protocol family version 4. */
56 #define AF_INET6       PF_INET6    /**< IP protocol family version 6. */
57 #define AF_PACKET      PF_PACKET   /**< Packet family.                */
58 #define AF_CAN         PF_CAN      /**< Controller Area Network.      */
59 #define AF_NET_MGMT    PF_NET_MGMT /**< Network management info.      */
60 #define AF_LOCAL       PF_LOCAL    /**< Inter-process communication   */
61 #define AF_UNIX        PF_UNIX     /**< Inter-process communication   */
62 
63 /** Protocol numbers from IANA/BSD */
64 enum net_ip_protocol {
65 	IPPROTO_IP = 0,            /**< IP protocol (pseudo-val for setsockopt() */
66 	IPPROTO_ICMP = 1,          /**< ICMP protocol   */
67 	IPPROTO_IGMP = 2,          /**< IGMP protocol   */
68 	IPPROTO_IPIP = 4,          /**< IPIP tunnels    */
69 	IPPROTO_TCP = 6,           /**< TCP protocol    */
70 	IPPROTO_UDP = 17,          /**< UDP protocol    */
71 	IPPROTO_IPV6 = 41,         /**< IPv6 protocol   */
72 	IPPROTO_ICMPV6 = 58,       /**< ICMPv6 protocol */
73 	IPPROTO_RAW = 255,         /**< RAW IP packets  */
74 };
75 
76 /** Protocol numbers for TLS protocols */
77 enum net_ip_protocol_secure {
78 	IPPROTO_TLS_1_0 = 256,     /**< TLS 1.0 protocol */
79 	IPPROTO_TLS_1_1 = 257,     /**< TLS 1.1 protocol */
80 	IPPROTO_TLS_1_2 = 258,     /**< TLS 1.2 protocol */
81 	IPPROTO_DTLS_1_0 = 272,    /**< DTLS 1.0 protocol */
82 	IPPROTO_DTLS_1_2 = 273,    /**< DTLS 1.2 protocol */
83 };
84 
85 /** Socket type */
86 enum net_sock_type {
87 	SOCK_STREAM = 1,           /**< Stream socket type   */
88 	SOCK_DGRAM,                /**< Datagram socket type */
89 	SOCK_RAW                   /**< RAW socket type      */
90 };
91 
92 /** @brief Convert 16-bit value from network to host byte order.
93  *
94  * @param x The network byte order value to convert.
95  *
96  * @return Host byte order value.
97  */
98 #define ntohs(x) sys_be16_to_cpu(x)
99 
100 /** @brief Convert 32-bit value from network to host byte order.
101  *
102  * @param x The network byte order value to convert.
103  *
104  * @return Host byte order value.
105  */
106 #define ntohl(x) sys_be32_to_cpu(x)
107 
108 /** @brief Convert 64-bit value from network to host byte order.
109  *
110  * @param x The network byte order value to convert.
111  *
112  * @return Host byte order value.
113  */
114 #define ntohll(x) sys_be64_to_cpu(x)
115 
116 /** @brief Convert 16-bit value from host to network byte order.
117  *
118  * @param x The host byte order value to convert.
119  *
120  * @return Network byte order value.
121  */
122 #define htons(x) sys_cpu_to_be16(x)
123 
124 /** @brief Convert 32-bit value from host to network byte order.
125  *
126  * @param x The host byte order value to convert.
127  *
128  * @return Network byte order value.
129  */
130 #define htonl(x) sys_cpu_to_be32(x)
131 
132 /** @brief Convert 64-bit value from host to network byte order.
133  *
134  * @param x The host byte order value to convert.
135  *
136  * @return Network byte order value.
137  */
138 #define htonll(x) sys_cpu_to_be64(x)
139 
140 /** IPv6 address struct */
141 struct in6_addr {
142 	union {
143 		uint8_t s6_addr[16];   /**< IPv6 address buffer */
144 		uint16_t s6_addr16[8]; /**< In big endian */
145 		uint32_t s6_addr32[4]; /**< In big endian */
146 	};
147 };
148 
149 /** Binary size of the IPv6 address */
150 #define NET_IPV6_ADDR_SIZE 16
151 
152 /** IPv4 address struct */
153 struct in_addr {
154 	union {
155 		uint8_t s4_addr[4];    /**< IPv4 address buffer */
156 		uint16_t s4_addr16[2]; /**< In big endian */
157 		uint32_t s4_addr32[1]; /**< In big endian */
158 		uint32_t s_addr; /**< In big endian, for POSIX compatibility. */
159 	};
160 };
161 
162 /** Binary size of the IPv4 address */
163 #define NET_IPV4_ADDR_SIZE 4
164 
165 /** Socket address family type */
166 typedef unsigned short int sa_family_t;
167 
168 /** Length of a socket address */
169 #ifndef __socklen_t_defined
170 typedef size_t socklen_t;
171 #define __socklen_t_defined
172 #endif
173 
174 /*
175  * Note that the sin_port and sin6_port are in network byte order
176  * in various sockaddr* structs.
177  */
178 
179 /** Socket address struct for IPv6. */
180 struct sockaddr_in6 {
181 	sa_family_t		sin6_family;   /**< AF_INET6               */
182 	uint16_t		sin6_port;     /**< Port number            */
183 	struct in6_addr		sin6_addr;     /**< IPv6 address           */
184 	uint8_t			sin6_scope_id; /**< Interfaces for a scope */
185 };
186 
187 /** Socket address struct for IPv4. */
188 struct sockaddr_in {
189 	sa_family_t		sin_family;    /**< AF_INET      */
190 	uint16_t		sin_port;      /**< Port number  */
191 	struct in_addr		sin_addr;      /**< IPv4 address */
192 };
193 
194 /** Socket address struct for packet socket. */
195 struct sockaddr_ll {
196 	sa_family_t sll_family;   /**< Always AF_PACKET                   */
197 	uint16_t    sll_protocol; /**< Physical-layer protocol            */
198 	int         sll_ifindex;  /**< Interface number                   */
199 	uint16_t    sll_hatype;   /**< ARP hardware type                  */
200 	uint8_t     sll_pkttype;  /**< Packet type                        */
201 	uint8_t     sll_halen;    /**< Length of address                  */
202 	uint8_t     sll_addr[8];  /**< Physical-layer address, big endian */
203 };
204 
205 /** @cond INTERNAL_HIDDEN */
206 
207 /** Socket address struct for IPv6 where address is a pointer */
208 struct sockaddr_in6_ptr {
209 	sa_family_t		sin6_family;   /**< AF_INET6               */
210 	uint16_t		sin6_port;     /**< Port number            */
211 	struct in6_addr		*sin6_addr;    /**< IPv6 address           */
212 	uint8_t			sin6_scope_id; /**< interfaces for a scope */
213 };
214 
215 /** Socket address struct for IPv4 where address is a pointer */
216 struct sockaddr_in_ptr {
217 	sa_family_t		sin_family;    /**< AF_INET      */
218 	uint16_t		sin_port;      /**< Port number  */
219 	struct in_addr		*sin_addr;     /**< IPv4 address */
220 };
221 
222 /** Socket address struct for packet socket where address is a pointer */
223 struct sockaddr_ll_ptr {
224 	sa_family_t sll_family;   /**< Always AF_PACKET                   */
225 	uint16_t    sll_protocol; /**< Physical-layer protocol            */
226 	int         sll_ifindex;  /**< Interface number                   */
227 	uint16_t    sll_hatype;   /**< ARP hardware type                  */
228 	uint8_t     sll_pkttype;  /**< Packet type                        */
229 	uint8_t     sll_halen;    /**< Length of address                  */
230 	uint8_t     *sll_addr;    /**< Physical-layer address, big endian */
231 };
232 
233 struct sockaddr_can_ptr {
234 	sa_family_t can_family;
235 	int         can_ifindex;
236 };
237 
238 /** @endcond */
239 
240 #if !defined(HAVE_IOVEC)
241 /** IO vector array element */
242 struct iovec {
243 	void  *iov_base; /**< Pointer to data */
244 	size_t iov_len;  /**< Length of the data */
245 };
246 #endif
247 
248 /** Message struct */
249 struct msghdr {
250 	void         *msg_name;       /**< Optional socket address, big endian */
251 	socklen_t     msg_namelen;    /**< Size of socket address */
252 	struct iovec *msg_iov;        /**< Scatter/gather array */
253 	size_t        msg_iovlen;     /**< Number of elements in msg_iov */
254 	void         *msg_control;    /**< Ancillary data */
255 	size_t        msg_controllen; /**< Ancillary data buffer len */
256 	int           msg_flags;      /**< Flags on received message */
257 };
258 
259 /** Control message ancillary data */
260 struct cmsghdr {
261 	socklen_t cmsg_len;    /**< Number of bytes, including header */
262 	int       cmsg_level;  /**< Originating protocol */
263 	int       cmsg_type;   /**< Protocol-specific type */
264 	z_max_align_t cmsg_data[]; /**< Flexible array member to force alignment of cmsghdr */
265 };
266 
267 /** @cond INTERNAL_HIDDEN */
268 
269 /* Alignment for headers and data. These are arch specific but define
270  * them here atm if not found already.
271  */
272 #if !defined(ALIGN_H)
273 #define ALIGN_H(x) ROUND_UP(x, __alignof__(struct cmsghdr))
274 #endif
275 #if !defined(ALIGN_D)
276 #define ALIGN_D(x) ROUND_UP(x, __alignof__(z_max_align_t))
277 #endif
278 
279 /** @endcond */
280 
281 #if !defined(CMSG_FIRSTHDR)
282 /**
283  * Returns a pointer to the first cmsghdr in the ancillary data buffer
284  * associated with the passed msghdr.  It returns NULL if there isn't
285  * enough space for a cmsghdr in the buffer.
286  */
287 #define CMSG_FIRSTHDR(msghdr)					\
288 	((msghdr)->msg_controllen >= sizeof(struct cmsghdr) ?	\
289 	 (struct cmsghdr *)((msghdr)->msg_control) : NULL)
290 #endif
291 
292 #if !defined(CMSG_NXTHDR)
293 /**
294  * Returns the next valid cmsghdr after the passed cmsghdr. It returns NULL
295  * when there isn't enough space left in the buffer.
296  */
297 #define CMSG_NXTHDR(msghdr, cmsg)					 \
298 	(((cmsg) == NULL) ? CMSG_FIRSTHDR(msghdr) :			 \
299 	 (((uint8_t *)(cmsg) + ALIGN_H((cmsg)->cmsg_len) +		 \
300 	   ALIGN_D(sizeof(struct cmsghdr)) >				 \
301 	   (uint8_t *)((msghdr)->msg_control) + (msghdr)->msg_controllen) ? \
302 	  NULL :							 \
303 	  (struct cmsghdr *)((uint8_t *)(cmsg) +			 \
304 			     ALIGN_H((cmsg)->cmsg_len))))
305 #endif
306 
307 #if !defined(CMSG_DATA)
308 /**
309  * Returns a pointer to the data portion of a cmsghdr.  The pointer returned
310  * cannot be assumed to be suitably aligned for accessing arbitrary payload
311  * data types. Applications should not cast it to a pointer type matching
312  * the payload, but should instead use memcpy(3) to copy data to or from a
313  * suitably declared object.
314  */
315 #define CMSG_DATA(cmsg) ((uint8_t *)(cmsg) + ALIGN_D(sizeof(struct cmsghdr)))
316 #endif
317 
318 #if !defined(CMSG_SPACE)
319 /**
320  * Returns the number of bytes an ancillary element with payload of the passed
321  * data length occupies.
322  */
323 #define CMSG_SPACE(length) (ALIGN_D(sizeof(struct cmsghdr)) + ALIGN_H(length))
324 #endif
325 
326 #if !defined(CMSG_LEN)
327 /**
328  * Returns the value to store in the cmsg_len member of the cmsghdr structure,
329  * taking into account any necessary alignment.
330  * It takes the data length as an argument.
331  */
332 #define CMSG_LEN(length) (ALIGN_D(sizeof(struct cmsghdr)) + length)
333 #endif
334 
335 /** @cond INTERNAL_HIDDEN */
336 
337 /* Packet types.  */
338 #define PACKET_HOST         0     /* To us            */
339 #define PACKET_BROADCAST    1     /* To all           */
340 #define PACKET_MULTICAST    2     /* To group         */
341 #define PACKET_OTHERHOST    3     /* To someone else  */
342 #define PACKET_OUTGOING     4     /* Originated by us */
343 #define PACKET_LOOPBACK     5
344 #define PACKET_FASTROUTE    6
345 
346 /* ARP protocol HARDWARE identifiers. */
347 #define ARPHRD_ETHER 1
348 
349 /* Note: These macros are defined in a specific order.
350  * The largest sockaddr size is the last one.
351  */
352 #if defined(CONFIG_NET_IPV4)
353 #undef NET_SOCKADDR_MAX_SIZE
354 #undef NET_SOCKADDR_PTR_MAX_SIZE
355 #define NET_SOCKADDR_MAX_SIZE (sizeof(struct sockaddr_in))
356 #define NET_SOCKADDR_PTR_MAX_SIZE (sizeof(struct sockaddr_in_ptr))
357 #endif
358 
359 #if defined(CONFIG_NET_SOCKETS_PACKET)
360 #undef NET_SOCKADDR_MAX_SIZE
361 #undef NET_SOCKADDR_PTR_MAX_SIZE
362 #define NET_SOCKADDR_MAX_SIZE (sizeof(struct sockaddr_ll))
363 #define NET_SOCKADDR_PTR_MAX_SIZE (sizeof(struct sockaddr_ll_ptr))
364 #endif
365 
366 #if defined(CONFIG_NET_IPV6)
367 #undef NET_SOCKADDR_MAX_SIZE
368 #define NET_SOCKADDR_MAX_SIZE (sizeof(struct sockaddr_in6))
369 #if !defined(CONFIG_NET_SOCKETS_PACKET)
370 #undef NET_SOCKADDR_PTR_MAX_SIZE
371 #define NET_SOCKADDR_PTR_MAX_SIZE (sizeof(struct sockaddr_in6_ptr))
372 #endif
373 #endif
374 
375 #if !defined(CONFIG_NET_IPV4)
376 #if !defined(CONFIG_NET_IPV6)
377 #if !defined(CONFIG_NET_SOCKETS_PACKET)
378 #define NET_SOCKADDR_MAX_SIZE (sizeof(struct sockaddr_in6))
379 #define NET_SOCKADDR_PTR_MAX_SIZE (sizeof(struct sockaddr_in6_ptr))
380 #endif
381 #endif
382 #endif
383 
384 /** @endcond */
385 
386 /** Generic sockaddr struct. Must be cast to proper type. */
387 struct sockaddr {
388 	sa_family_t sa_family; /**< Address family */
389 /** @cond INTERNAL_HIDDEN */
390 	char data[NET_SOCKADDR_MAX_SIZE - sizeof(sa_family_t)];
391 /** @endcond */
392 };
393 
394 /** @cond INTERNAL_HIDDEN */
395 
396 struct sockaddr_ptr {
397 	sa_family_t family;
398 	char data[NET_SOCKADDR_PTR_MAX_SIZE - sizeof(sa_family_t)];
399 };
400 
401 /* Same as sockaddr in our case */
402 struct sockaddr_storage {
403 	sa_family_t ss_family;
404 	char data[NET_SOCKADDR_MAX_SIZE - sizeof(sa_family_t)];
405 };
406 
407 /* Socket address struct for UNIX domain sockets */
408 struct sockaddr_un {
409 	sa_family_t sun_family;    /* AF_UNIX */
410 	char        sun_path[NET_SOCKADDR_MAX_SIZE - sizeof(sa_family_t)];
411 };
412 
413 struct net_addr {
414 	sa_family_t family;
415 	union {
416 		struct in6_addr in6_addr;
417 		struct in_addr in_addr;
418 	};
419 };
420 
421 /** A pointer to IPv6 any address (all values zero) */
422 extern const struct in6_addr in6addr_any;
423 
424 /** A pointer to IPv6 loopback address (::1) */
425 extern const struct in6_addr in6addr_loopback;
426 
427 /** @endcond */
428 
429 /** IPv6 address initializer */
430 #define IN6ADDR_ANY_INIT { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, \
431 				0, 0, 0, 0, 0, 0, 0 } } }
432 
433 /** IPv6 loopback address initializer */
434 #define IN6ADDR_LOOPBACK_INIT { { { 0, 0, 0, 0, 0, 0, 0, \
435 				0, 0, 0, 0, 0, 0, 0, 0, 1 } } }
436 
437 /** IPv4 any address */
438 #define INADDR_ANY 0
439 
440 /** IPv4 address initializer */
441 #define INADDR_ANY_INIT { { { INADDR_ANY } } }
442 
443 /** IPv6 loopback address initializer */
444 #define INADDR_LOOPBACK_INIT  { { { 127, 0, 0, 1 } } }
445 
446 /** Max length of the IPv4 address as a string. Defined by POSIX. */
447 #define INET_ADDRSTRLEN 16
448 /** Max length of the IPv6 address as a string. Takes into account possible
449  * mapped IPv4 addresses.
450  */
451 #define INET6_ADDRSTRLEN 46
452 
453 /** @cond INTERNAL_HIDDEN */
454 
455 /* These are for internal usage of the stack */
456 #define NET_IPV6_ADDR_LEN sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")
457 #define NET_IPV4_ADDR_LEN sizeof("xxx.xxx.xxx.xxx")
458 
459 /** @endcond */
460 
461 /** @brief IP Maximum Transfer Unit */
462 enum net_ip_mtu {
463 	/** IPv6 MTU length. We must be able to receive this size IPv6 packet
464 	 * without fragmentation.
465 	 */
466 #if defined(CONFIG_NET_NATIVE_IPV6)
467 	NET_IPV6_MTU = CONFIG_NET_IPV6_MTU,
468 #else
469 	NET_IPV6_MTU = 1280,
470 #endif
471 
472 	/** IPv4 MTU length. We must be able to receive this size IPv4 packet
473 	 * without fragmentation.
474 	 */
475 	NET_IPV4_MTU = 576,
476 };
477 
478 /** @brief Network packet priority settings described in IEEE 802.1Q Annex I.1 */
479 enum net_priority {
480 	NET_PRIORITY_BK = 1, /**< Background (lowest)                */
481 	NET_PRIORITY_BE = 0, /**< Best effort (default)              */
482 	NET_PRIORITY_EE = 2, /**< Excellent effort                   */
483 	NET_PRIORITY_CA = 3, /**< Critical applications              */
484 	NET_PRIORITY_VI = 4, /**< Video, < 100 ms latency and jitter */
485 	NET_PRIORITY_VO = 5, /**< Voice, < 10 ms latency and jitter  */
486 	NET_PRIORITY_IC = 6, /**< Internetwork control               */
487 	NET_PRIORITY_NC = 7  /**< Network control (highest)          */
488 } __packed;
489 
490 #define NET_MAX_PRIORITIES 8 /**< How many priority values there are */
491 
492 /** @brief IPv6/IPv4 network connection tuple */
493 struct net_tuple {
494 	struct net_addr *remote_addr;  /**< IPv6/IPv4 remote address */
495 	struct net_addr *local_addr;   /**< IPv6/IPv4 local address  */
496 	uint16_t remote_port;          /**< UDP/TCP remote port      */
497 	uint16_t local_port;           /**< UDP/TCP local port       */
498 	enum net_ip_protocol ip_proto; /**< IP protocol              */
499 };
500 
501 /** @brief What is the current state of the network address */
502 enum net_addr_state {
503 	NET_ADDR_ANY_STATE = -1, /**< Default (invalid) address type */
504 	NET_ADDR_TENTATIVE = 0,  /**< Tentative address              */
505 	NET_ADDR_PREFERRED,      /**< Preferred address              */
506 	NET_ADDR_DEPRECATED,     /**< Deprecated address             */
507 } __packed;
508 
509 /** @brief How the network address is assigned to network interface */
510 enum net_addr_type {
511 	/** Default value. This is not a valid value. */
512 	NET_ADDR_ANY = 0,
513 	/** Auto configured address */
514 	NET_ADDR_AUTOCONF,
515 	/** Address is from DHCP */
516 	NET_ADDR_DHCP,
517 	/** Manually set address */
518 	NET_ADDR_MANUAL,
519 	/** Manually set address which is overridable by DHCP */
520 	NET_ADDR_OVERRIDABLE,
521 } __packed;
522 
523 /** @cond INTERNAL_HIDDEN */
524 
525 struct net_ipv6_hdr {
526 	uint8_t vtc;
527 	uint8_t tcflow;
528 	uint16_t flow;
529 	uint16_t len;
530 	uint8_t nexthdr;
531 	uint8_t hop_limit;
532 	uint8_t src[NET_IPV6_ADDR_SIZE];
533 	uint8_t dst[NET_IPV6_ADDR_SIZE];
534 } __packed;
535 
536 struct net_ipv6_frag_hdr {
537 	uint8_t nexthdr;
538 	uint8_t reserved;
539 	uint16_t offset;
540 	uint32_t id;
541 } __packed;
542 
543 struct net_ipv4_hdr {
544 	uint8_t vhl;
545 	uint8_t tos;
546 	uint16_t len;
547 	uint8_t id[2];
548 	uint8_t offset[2];
549 	uint8_t ttl;
550 	uint8_t proto;
551 	uint16_t chksum;
552 	uint8_t src[NET_IPV4_ADDR_SIZE];
553 	uint8_t dst[NET_IPV4_ADDR_SIZE];
554 } __packed;
555 
556 struct net_icmp_hdr {
557 	uint8_t type;
558 	uint8_t code;
559 	uint16_t chksum;
560 } __packed;
561 
562 struct net_udp_hdr {
563 	uint16_t src_port;
564 	uint16_t dst_port;
565 	uint16_t len;
566 	uint16_t chksum;
567 } __packed;
568 
569 struct net_tcp_hdr {
570 	uint16_t src_port;
571 	uint16_t dst_port;
572 	uint8_t seq[4];
573 	uint8_t ack[4];
574 	uint8_t offset;
575 	uint8_t flags;
576 	uint8_t wnd[2];
577 	uint16_t chksum;
578 	uint8_t urg[2];
579 	uint8_t optdata[0];
580 } __packed;
581 
net_addr_type2str(enum net_addr_type type)582 static inline const char *net_addr_type2str(enum net_addr_type type)
583 {
584 	switch (type) {
585 	case NET_ADDR_AUTOCONF:
586 		return "AUTO";
587 	case NET_ADDR_DHCP:
588 		return "DHCP";
589 	case NET_ADDR_MANUAL:
590 		return "MANUAL";
591 	case NET_ADDR_OVERRIDABLE:
592 		return "OVERRIDE";
593 	case NET_ADDR_ANY:
594 	default:
595 		break;
596 	}
597 
598 	return "<unknown>";
599 }
600 
601 /* IPv6 extension headers types */
602 #define NET_IPV6_NEXTHDR_HBHO        0
603 #define NET_IPV6_NEXTHDR_DESTO       60
604 #define NET_IPV6_NEXTHDR_ROUTING     43
605 #define NET_IPV6_NEXTHDR_FRAG        44
606 #define NET_IPV6_NEXTHDR_NONE        59
607 
608 /**
609  * This 2 unions are here temporarily, as long as net_context.h will
610  * be still public and not part of the core only.
611  */
612 union net_ip_header {
613 	struct net_ipv4_hdr *ipv4;
614 	struct net_ipv6_hdr *ipv6;
615 };
616 
617 union net_proto_header {
618 	struct net_udp_hdr *udp;
619 	struct net_tcp_hdr *tcp;
620 };
621 
622 #define NET_UDPH_LEN	8			/* Size of UDP header */
623 #define NET_TCPH_LEN	20			/* Size of TCP header */
624 #define NET_ICMPH_LEN	4			/* Size of ICMP header */
625 
626 #define NET_IPV6H_LEN	   40			/* Size of IPv6 header */
627 #define NET_ICMPV6H_LEN	   NET_ICMPH_LEN	/* Size of ICMPv6 header */
628 #define NET_IPV6UDPH_LEN   (NET_UDPH_LEN + NET_IPV6H_LEN) /* IPv6 + UDP */
629 #define NET_IPV6TCPH_LEN   (NET_TCPH_LEN + NET_IPV6H_LEN) /* IPv6 + TCP */
630 #define NET_IPV6ICMPH_LEN  (NET_IPV6H_LEN + NET_ICMPH_LEN) /* ICMPv6 + IPv6 */
631 #define NET_IPV6_FRAGH_LEN 8
632 
633 #define NET_IPV4H_LEN	   20			/* Size of IPv4 header */
634 #define NET_ICMPV4H_LEN	   NET_ICMPH_LEN	/* Size of ICMPv4 header */
635 #define NET_IPV4UDPH_LEN   (NET_UDPH_LEN + NET_IPV4H_LEN) /* IPv4 + UDP */
636 #define NET_IPV4TCPH_LEN   (NET_TCPH_LEN + NET_IPV4H_LEN) /* IPv4 + TCP */
637 #define NET_IPV4ICMPH_LEN  (NET_IPV4H_LEN + NET_ICMPH_LEN) /* ICMPv4 + IPv4 */
638 
639 #define NET_IPV6H_LENGTH_OFFSET		0x04	/* Offset of the Length field in the IPv6 header */
640 
641 #define NET_IPV6_FRAGH_OFFSET_MASK	0xfff8	/* Mask for the 13-bit Fragment Offset field */
642 #define NET_IPV4_FRAGH_OFFSET_MASK	0x1fff	/* Mask for the 13-bit Fragment Offset field */
643 #define NET_IPV4_MORE_FRAG_MASK		0x2000	/* Mask for the 1-bit More Fragments field */
644 #define NET_IPV4_DO_NOT_FRAG_MASK	0x4000	/* Mask for the 1-bit Do Not Fragment field */
645 
646 /** @endcond */
647 
648 /**
649  * @brief Check if the IPv6 address is a loopback address (::1).
650  *
651  * @param addr IPv6 address
652  *
653  * @return True if address is a loopback address, False otherwise.
654  */
net_ipv6_is_addr_loopback(struct in6_addr * addr)655 static inline bool net_ipv6_is_addr_loopback(struct in6_addr *addr)
656 {
657 	return UNALIGNED_GET(&addr->s6_addr32[0]) == 0 &&
658 		UNALIGNED_GET(&addr->s6_addr32[1]) == 0 &&
659 		UNALIGNED_GET(&addr->s6_addr32[2]) == 0 &&
660 		ntohl(UNALIGNED_GET(&addr->s6_addr32[3])) == 1;
661 }
662 
663 /**
664  * @brief Check if the IPv6 address is a multicast address.
665  *
666  * @param addr IPv6 address
667  *
668  * @return True if address is multicast address, False otherwise.
669  */
net_ipv6_is_addr_mcast(const struct in6_addr * addr)670 static inline bool net_ipv6_is_addr_mcast(const struct in6_addr *addr)
671 {
672 	return addr->s6_addr[0] == 0xFF;
673 }
674 
675 struct net_if;
676 struct net_if_config;
677 
678 extern struct net_if_addr *net_if_ipv6_addr_lookup(const struct in6_addr *addr,
679 						   struct net_if **iface);
680 
681 /**
682  * @brief Check if IPv6 address is found in one of the network interfaces.
683  *
684  * @param addr IPv6 address
685  *
686  * @return True if address was found, False otherwise.
687  */
net_ipv6_is_my_addr(struct in6_addr * addr)688 static inline bool net_ipv6_is_my_addr(struct in6_addr *addr)
689 {
690 	return net_if_ipv6_addr_lookup(addr, NULL) != NULL;
691 }
692 
693 extern struct net_if_mcast_addr *net_if_ipv6_maddr_lookup(
694 	const struct in6_addr *addr, struct net_if **iface);
695 
696 /**
697  * @brief Check if IPv6 multicast address is found in one of the
698  * network interfaces.
699  *
700  * @param maddr Multicast IPv6 address
701  *
702  * @return True if address was found, False otherwise.
703  */
net_ipv6_is_my_maddr(struct in6_addr * maddr)704 static inline bool net_ipv6_is_my_maddr(struct in6_addr *maddr)
705 {
706 	return net_if_ipv6_maddr_lookup(maddr, NULL) != NULL;
707 }
708 
709 /**
710  * @brief Check if two IPv6 addresses are same when compared after prefix mask.
711  *
712  * @param addr1 First IPv6 address.
713  * @param addr2 Second IPv6 address.
714  * @param length Prefix length (max length is 128).
715  *
716  * @return True if IPv6 prefixes are the same, False otherwise.
717  */
net_ipv6_is_prefix(const uint8_t * addr1,const uint8_t * addr2,uint8_t length)718 static inline bool net_ipv6_is_prefix(const uint8_t *addr1,
719 				      const uint8_t *addr2,
720 				      uint8_t length)
721 {
722 	uint8_t bits = 128 - length;
723 	uint8_t bytes = length / 8U;
724 	uint8_t remain = bits % 8;
725 	uint8_t mask;
726 
727 	if (length > 128) {
728 		return false;
729 	}
730 
731 	if (memcmp(addr1, addr2, bytes)) {
732 		return false;
733 	}
734 
735 	if (!remain) {
736 		/* No remaining bits, the prefixes are the same as first
737 		 * bytes are the same.
738 		 */
739 		return true;
740 	}
741 
742 	/* Create a mask that has remaining most significant bits set */
743 	mask = (uint8_t)((0xff << (8 - remain)) ^ 0xff) << remain;
744 
745 	return (addr1[bytes] & mask) == (addr2[bytes] & mask);
746 }
747 
748 /**
749  * @brief Check if the IPv4 address is a loopback address (127.0.0.0/8).
750  *
751  * @param addr IPv4 address
752  *
753  * @return True if address is a loopback address, False otherwise.
754  */
net_ipv4_is_addr_loopback(struct in_addr * addr)755 static inline bool net_ipv4_is_addr_loopback(struct in_addr *addr)
756 {
757 	return addr->s4_addr[0] == 127U;
758 }
759 
760 /**
761  *  @brief Check if the IPv4 address is unspecified (all bits zero)
762  *
763  *  @param addr IPv4 address.
764  *
765  *  @return True if the address is unspecified, false otherwise.
766  */
net_ipv4_is_addr_unspecified(const struct in_addr * addr)767 static inline bool net_ipv4_is_addr_unspecified(const struct in_addr *addr)
768 {
769 	return UNALIGNED_GET(&addr->s_addr) == 0;
770 }
771 
772 /**
773  * @brief Check if the IPv4 address is a multicast address.
774  *
775  * @param addr IPv4 address
776  *
777  * @return True if address is multicast address, False otherwise.
778  */
net_ipv4_is_addr_mcast(const struct in_addr * addr)779 static inline bool net_ipv4_is_addr_mcast(const struct in_addr *addr)
780 {
781 	return (ntohl(UNALIGNED_GET(&addr->s_addr)) & 0xF0000000) == 0xE0000000;
782 }
783 
784 /**
785  * @brief Check if the given IPv4 address is a link local address.
786  *
787  * @param addr A valid pointer on an IPv4 address
788  *
789  * @return True if it is, false otherwise.
790  */
net_ipv4_is_ll_addr(const struct in_addr * addr)791 static inline bool net_ipv4_is_ll_addr(const struct in_addr *addr)
792 {
793 	return (ntohl(UNALIGNED_GET(&addr->s_addr)) & 0xFFFF0000) == 0xA9FE0000;
794 }
795 
796 /**
797  * @brief Check if the given IPv4 address is from a private address range.
798  *
799  * See https://en.wikipedia.org/wiki/Reserved_IP_addresses for details.
800  *
801  * @param addr A valid pointer on an IPv4 address
802  *
803  * @return True if it is, false otherwise.
804  */
net_ipv4_is_private_addr(const struct in_addr * addr)805 static inline bool net_ipv4_is_private_addr(const struct in_addr *addr)
806 {
807 	uint32_t masked_24, masked_16, masked_12, masked_10, masked_8;
808 
809 	masked_24 = ntohl(UNALIGNED_GET(&addr->s_addr)) & 0xFFFFFF00;
810 	masked_16 = masked_24 & 0xFFFF0000;
811 	masked_12 = masked_24 & 0xFFF00000;
812 	masked_10 = masked_24 & 0xFFC00000;
813 	masked_8 = masked_24 & 0xFF000000;
814 
815 	return masked_8  == 0x0A000000 || /* 10.0.0.0/8      */
816 	       masked_10 == 0x64400000 || /* 100.64.0.0/10   */
817 	       masked_12 == 0xAC100000 || /* 172.16.0.0/12   */
818 	       masked_16 == 0xC0A80000 || /* 192.168.0.0/16  */
819 	       masked_24 == 0xC0000200 || /* 192.0.2.0/24    */
820 	       masked_24 == 0xC0336400 || /* 192.51.100.0/24 */
821 	       masked_24 == 0xCB007100;   /* 203.0.113.0/24  */
822 }
823 
824 /**
825  *  @brief Copy an IPv4 or IPv6 address
826  *
827  *  @param dest Destination IP address.
828  *  @param src Source IP address.
829  *
830  *  @return Destination address.
831  */
832 #define net_ipaddr_copy(dest, src) \
833 	UNALIGNED_PUT(UNALIGNED_GET(src), dest)
834 
835 /**
836  *  @brief Copy an IPv4 address raw buffer
837  *
838  *  @param dest Destination IP address.
839  *  @param src Source IP address.
840  */
net_ipv4_addr_copy_raw(uint8_t * dest,const uint8_t * src)841 static inline void net_ipv4_addr_copy_raw(uint8_t *dest,
842 					  const uint8_t *src)
843 {
844 	net_ipaddr_copy((struct in_addr *)dest, (const struct in_addr *)src);
845 }
846 
847 /**
848  *  @brief Copy an IPv6 address raw buffer
849  *
850  *  @param dest Destination IP address.
851  *  @param src Source IP address.
852  */
net_ipv6_addr_copy_raw(uint8_t * dest,const uint8_t * src)853 static inline void net_ipv6_addr_copy_raw(uint8_t *dest,
854 					  const uint8_t *src)
855 {
856 	memcpy(dest, src, sizeof(struct in6_addr));
857 }
858 
859 /**
860  *  @brief Compare two IPv4 addresses
861  *
862  *  @param addr1 Pointer to IPv4 address.
863  *  @param addr2 Pointer to IPv4 address.
864  *
865  *  @return True if the addresses are the same, false otherwise.
866  */
net_ipv4_addr_cmp(const struct in_addr * addr1,const struct in_addr * addr2)867 static inline bool net_ipv4_addr_cmp(const struct in_addr *addr1,
868 				     const struct in_addr *addr2)
869 {
870 	return UNALIGNED_GET(&addr1->s_addr) == UNALIGNED_GET(&addr2->s_addr);
871 }
872 
873 /**
874  *  @brief Compare two raw IPv4 address buffers
875  *
876  *  @param addr1 Pointer to IPv4 address buffer.
877  *  @param addr2 Pointer to IPv4 address buffer.
878  *
879  *  @return True if the addresses are the same, false otherwise.
880  */
net_ipv4_addr_cmp_raw(const uint8_t * addr1,const uint8_t * addr2)881 static inline bool net_ipv4_addr_cmp_raw(const uint8_t *addr1,
882 					 const uint8_t *addr2)
883 {
884 	return net_ipv4_addr_cmp((const struct in_addr *)addr1,
885 				 (const struct in_addr *)addr2);
886 }
887 
888 /**
889  *  @brief Compare two IPv6 addresses
890  *
891  *  @param addr1 Pointer to IPv6 address.
892  *  @param addr2 Pointer to IPv6 address.
893  *
894  *  @return True if the addresses are the same, false otherwise.
895  */
net_ipv6_addr_cmp(const struct in6_addr * addr1,const struct in6_addr * addr2)896 static inline bool net_ipv6_addr_cmp(const struct in6_addr *addr1,
897 				     const struct in6_addr *addr2)
898 {
899 	return !memcmp(addr1, addr2, sizeof(struct in6_addr));
900 }
901 
902 /**
903  *  @brief Compare two raw IPv6 address buffers
904  *
905  *  @param addr1 Pointer to IPv6 address buffer.
906  *  @param addr2 Pointer to IPv6 address buffer.
907  *
908  *  @return True if the addresses are the same, false otherwise.
909  */
net_ipv6_addr_cmp_raw(const uint8_t * addr1,const uint8_t * addr2)910 static inline bool net_ipv6_addr_cmp_raw(const uint8_t *addr1,
911 					 const uint8_t *addr2)
912 {
913 	return net_ipv6_addr_cmp((const struct in6_addr *)addr1,
914 				 (const struct in6_addr *)addr2);
915 }
916 
917 /**
918  * @brief Check if the given IPv6 address is a link local address.
919  *
920  * @param addr A valid pointer on an IPv6 address
921  *
922  * @return True if it is, false otherwise.
923  */
net_ipv6_is_ll_addr(const struct in6_addr * addr)924 static inline bool net_ipv6_is_ll_addr(const struct in6_addr *addr)
925 {
926 	return UNALIGNED_GET(&addr->s6_addr16[0]) == htons(0xFE80);
927 }
928 
929 /**
930  * @brief Check if the given IPv6 address is a site local address.
931  *
932  * @param addr A valid pointer on an IPv6 address
933  *
934  * @return True if it is, false otherwise.
935  */
net_ipv6_is_sl_addr(const struct in6_addr * addr)936 static inline bool net_ipv6_is_sl_addr(const struct in6_addr *addr)
937 {
938 	return UNALIGNED_GET(&addr->s6_addr16[0]) == htons(0xFEC0);
939 }
940 
941 
942 /**
943  * @brief Check if the given IPv6 address is a unique local address.
944  *
945  * @param addr A valid pointer on an IPv6 address
946  *
947  * @return True if it is, false otherwise.
948  */
net_ipv6_is_ula_addr(const struct in6_addr * addr)949 static inline bool net_ipv6_is_ula_addr(const struct in6_addr *addr)
950 {
951 	return addr->s6_addr[0] == 0xFD;
952 }
953 
954 /**
955  * @brief Check if the given IPv6 address is a global address.
956  *
957  * @param addr A valid pointer on an IPv6 address
958  *
959  * @return True if it is, false otherwise.
960  */
net_ipv6_is_global_addr(const struct in6_addr * addr)961 static inline bool net_ipv6_is_global_addr(const struct in6_addr *addr)
962 {
963 	return (addr->s6_addr[0] & 0xE0) == 0x20;
964 }
965 
966 /**
967  * @brief Check if the given IPv6 address is from a private/local address range.
968  *
969  * See https://en.wikipedia.org/wiki/Reserved_IP_addresses for details.
970  *
971  * @param addr A valid pointer on an IPv6 address
972  *
973  * @return True if it is, false otherwise.
974  */
net_ipv6_is_private_addr(const struct in6_addr * addr)975 static inline bool net_ipv6_is_private_addr(const struct in6_addr *addr)
976 {
977 	uint32_t masked_32, masked_7;
978 
979 	masked_32 = ntohl(UNALIGNED_GET(&addr->s6_addr32[0]));
980 	masked_7 = masked_32 & 0xfc000000;
981 
982 	return masked_32 == 0x20010db8 || /* 2001:db8::/32 */
983 	       masked_7  == 0xfc000000;   /* fc00::/7      */
984 }
985 
986 /**
987  * @brief Return pointer to any (all bits zeros) IPv6 address.
988  *
989  * @return Any IPv6 address.
990  */
991 const struct in6_addr *net_ipv6_unspecified_address(void);
992 
993 /**
994  * @brief Return pointer to any (all bits zeros) IPv4 address.
995  *
996  * @return Any IPv4 address.
997  */
998 const struct in_addr *net_ipv4_unspecified_address(void);
999 
1000 /**
1001  * @brief Return pointer to broadcast (all bits ones) IPv4 address.
1002  *
1003  * @return Broadcast IPv4 address.
1004  */
1005 const struct in_addr *net_ipv4_broadcast_address(void);
1006 
1007 struct net_if;
1008 extern bool net_if_ipv4_addr_mask_cmp(struct net_if *iface,
1009 				      const struct in_addr *addr);
1010 
1011 /**
1012  * @brief Check if the given address belongs to same subnet that
1013  * has been configured for the interface.
1014  *
1015  * @param iface A valid pointer on an interface
1016  * @param addr IPv4 address
1017  *
1018  * @return True if address is in same subnet, false otherwise.
1019  */
net_ipv4_addr_mask_cmp(struct net_if * iface,const struct in_addr * addr)1020 static inline bool net_ipv4_addr_mask_cmp(struct net_if *iface,
1021 					  const struct in_addr *addr)
1022 {
1023 	return net_if_ipv4_addr_mask_cmp(iface, addr);
1024 }
1025 
1026 extern bool net_if_ipv4_is_addr_bcast(struct net_if *iface,
1027 				      const struct in_addr *addr);
1028 
1029 /**
1030  * @brief Check if the given IPv4 address is a broadcast address.
1031  *
1032  * @param iface Interface to use. Must be a valid pointer to an interface.
1033  * @param addr IPv4 address
1034  *
1035  * @return True if address is a broadcast address, false otherwise.
1036  */
1037 #if defined(CONFIG_NET_NATIVE_IPV4)
net_ipv4_is_addr_bcast(struct net_if * iface,const struct in_addr * addr)1038 static inline bool net_ipv4_is_addr_bcast(struct net_if *iface,
1039 					  const struct in_addr *addr)
1040 {
1041 	if (net_ipv4_addr_cmp(addr, net_ipv4_broadcast_address())) {
1042 		return true;
1043 	}
1044 
1045 	return net_if_ipv4_is_addr_bcast(iface, addr);
1046 }
1047 #else
net_ipv4_is_addr_bcast(struct net_if * iface,const struct in_addr * addr)1048 static inline bool net_ipv4_is_addr_bcast(struct net_if *iface,
1049 					  const struct in_addr *addr)
1050 {
1051 	ARG_UNUSED(iface);
1052 	ARG_UNUSED(addr);
1053 
1054 	return false;
1055 }
1056 #endif
1057 
1058 extern struct net_if_addr *net_if_ipv4_addr_lookup(const struct in_addr *addr,
1059 						   struct net_if **iface);
1060 
1061 /**
1062  * @brief Check if the IPv4 address is assigned to any network interface
1063  * in the system.
1064  *
1065  * @param addr A valid pointer on an IPv4 address
1066  *
1067  * @return True if IPv4 address is found in one of the network interfaces,
1068  * False otherwise.
1069  */
net_ipv4_is_my_addr(const struct in_addr * addr)1070 static inline bool net_ipv4_is_my_addr(const struct in_addr *addr)
1071 {
1072 	bool ret;
1073 
1074 	ret = net_if_ipv4_addr_lookup(addr, NULL) != NULL;
1075 	if (!ret) {
1076 		ret = net_ipv4_is_addr_bcast(NULL, addr);
1077 	}
1078 
1079 	return ret;
1080 }
1081 
1082 /**
1083  *  @brief Check if the IPv6 address is unspecified (all bits zero)
1084  *
1085  *  @param addr IPv6 address.
1086  *
1087  *  @return True if the address is unspecified, false otherwise.
1088  */
net_ipv6_is_addr_unspecified(const struct in6_addr * addr)1089 static inline bool net_ipv6_is_addr_unspecified(const struct in6_addr *addr)
1090 {
1091 	return UNALIGNED_GET(&addr->s6_addr32[0]) == 0 &&
1092 		UNALIGNED_GET(&addr->s6_addr32[1]) == 0 &&
1093 		UNALIGNED_GET(&addr->s6_addr32[2]) == 0 &&
1094 		UNALIGNED_GET(&addr->s6_addr32[3]) == 0;
1095 }
1096 
1097 /**
1098  *  @brief Check if the IPv6 address is solicited node multicast address
1099  *  FF02:0:0:0:0:1:FFXX:XXXX defined in RFC 3513
1100  *
1101  *  @param addr IPv6 address.
1102  *
1103  *  @return True if the address is solicited node address, false otherwise.
1104  */
net_ipv6_is_addr_solicited_node(const struct in6_addr * addr)1105 static inline bool net_ipv6_is_addr_solicited_node(const struct in6_addr *addr)
1106 {
1107 	return UNALIGNED_GET(&addr->s6_addr32[0]) == htonl(0xff020000) &&
1108 		UNALIGNED_GET(&addr->s6_addr32[1]) == 0x00000000 &&
1109 		UNALIGNED_GET(&addr->s6_addr32[2]) == htonl(0x00000001) &&
1110 		((UNALIGNED_GET(&addr->s6_addr32[3]) & htonl(0xff000000)) ==
1111 		 htonl(0xff000000));
1112 }
1113 
1114 /**
1115  * @brief Check if the IPv6 address is a given scope multicast
1116  * address (FFyx::).
1117  *
1118  * @param addr IPv6 address
1119  * @param scope Scope to check
1120  *
1121  * @return True if the address is in given scope multicast address,
1122  * false otherwise.
1123  */
net_ipv6_is_addr_mcast_scope(const struct in6_addr * addr,int scope)1124 static inline bool net_ipv6_is_addr_mcast_scope(const struct in6_addr *addr,
1125 						int scope)
1126 {
1127 	return (addr->s6_addr[0] == 0xff) && ((addr->s6_addr[1] & 0xF) == scope);
1128 }
1129 
1130 /**
1131  * @brief Check if the IPv6 addresses have the same multicast scope (FFyx::).
1132  *
1133  * @param addr_1 IPv6 address 1
1134  * @param addr_2 IPv6 address 2
1135  *
1136  * @return True if both addresses have same multicast scope,
1137  * false otherwise.
1138  */
net_ipv6_is_same_mcast_scope(const struct in6_addr * addr_1,const struct in6_addr * addr_2)1139 static inline bool net_ipv6_is_same_mcast_scope(const struct in6_addr *addr_1,
1140 						const struct in6_addr *addr_2)
1141 {
1142 	return (addr_1->s6_addr[0] == 0xff) && (addr_2->s6_addr[0] == 0xff) &&
1143 			(addr_1->s6_addr[1] == addr_2->s6_addr[1]);
1144 }
1145 
1146 /**
1147  * @brief Check if the IPv6 address is a global multicast address (FFxE::/16).
1148  *
1149  * @param addr IPv6 address.
1150  *
1151  * @return True if the address is global multicast address, false otherwise.
1152  */
net_ipv6_is_addr_mcast_global(const struct in6_addr * addr)1153 static inline bool net_ipv6_is_addr_mcast_global(const struct in6_addr *addr)
1154 {
1155 	return net_ipv6_is_addr_mcast_scope(addr, 0x0e);
1156 }
1157 
1158 /**
1159  * @brief Check if the IPv6 address is a interface scope multicast
1160  * address (FFx1::).
1161  *
1162  * @param addr IPv6 address.
1163  *
1164  * @return True if the address is a interface scope multicast address,
1165  * false otherwise.
1166  */
net_ipv6_is_addr_mcast_iface(const struct in6_addr * addr)1167 static inline bool net_ipv6_is_addr_mcast_iface(const struct in6_addr *addr)
1168 {
1169 	return net_ipv6_is_addr_mcast_scope(addr, 0x01);
1170 }
1171 
1172 /**
1173  * @brief Check if the IPv6 address is a link local scope multicast
1174  * address (FFx2::).
1175  *
1176  * @param addr IPv6 address.
1177  *
1178  * @return True if the address is a link local scope multicast address,
1179  * false otherwise.
1180  */
net_ipv6_is_addr_mcast_link(const struct in6_addr * addr)1181 static inline bool net_ipv6_is_addr_mcast_link(const struct in6_addr *addr)
1182 {
1183 	return net_ipv6_is_addr_mcast_scope(addr, 0x02);
1184 }
1185 
1186 /**
1187  * @brief Check if the IPv6 address is a mesh-local scope multicast
1188  * address (FFx3::).
1189  *
1190  * @param addr IPv6 address.
1191  *
1192  * @return True if the address is a mesh-local scope multicast address,
1193  * false otherwise.
1194  */
net_ipv6_is_addr_mcast_mesh(const struct in6_addr * addr)1195 static inline bool net_ipv6_is_addr_mcast_mesh(const struct in6_addr *addr)
1196 {
1197 	return net_ipv6_is_addr_mcast_scope(addr, 0x03);
1198 }
1199 
1200 /**
1201  * @brief Check if the IPv6 address is a site scope multicast
1202  * address (FFx5::).
1203  *
1204  * @param addr IPv6 address.
1205  *
1206  * @return True if the address is a site scope multicast address,
1207  * false otherwise.
1208  */
net_ipv6_is_addr_mcast_site(const struct in6_addr * addr)1209 static inline bool net_ipv6_is_addr_mcast_site(const struct in6_addr *addr)
1210 {
1211 	return net_ipv6_is_addr_mcast_scope(addr, 0x05);
1212 }
1213 
1214 /**
1215  * @brief Check if the IPv6 address is an organization scope multicast
1216  * address (FFx8::).
1217  *
1218  * @param addr IPv6 address.
1219  *
1220  * @return True if the address is an organization scope multicast address,
1221  * false otherwise.
1222  */
net_ipv6_is_addr_mcast_org(const struct in6_addr * addr)1223 static inline bool net_ipv6_is_addr_mcast_org(const struct in6_addr *addr)
1224 {
1225 	return net_ipv6_is_addr_mcast_scope(addr, 0x08);
1226 }
1227 
1228 /**
1229  * @brief Check if the IPv6 address belongs to certain multicast group
1230  *
1231  * @param addr IPv6 address.
1232  * @param group Group id IPv6 address, the values must be in network
1233  * byte order
1234  *
1235  * @return True if the IPv6 multicast address belongs to given multicast
1236  * group, false otherwise.
1237  */
net_ipv6_is_addr_mcast_group(const struct in6_addr * addr,const struct in6_addr * group)1238 static inline bool net_ipv6_is_addr_mcast_group(const struct in6_addr *addr,
1239 						const struct in6_addr *group)
1240 {
1241 	return UNALIGNED_GET(&addr->s6_addr16[1]) == group->s6_addr16[1] &&
1242 		UNALIGNED_GET(&addr->s6_addr16[2]) == group->s6_addr16[2] &&
1243 		UNALIGNED_GET(&addr->s6_addr16[3]) == group->s6_addr16[3] &&
1244 		UNALIGNED_GET(&addr->s6_addr32[1]) == group->s6_addr32[1] &&
1245 		UNALIGNED_GET(&addr->s6_addr32[2]) == group->s6_addr32[1] &&
1246 		UNALIGNED_GET(&addr->s6_addr32[3]) == group->s6_addr32[3];
1247 }
1248 
1249 /**
1250  * @brief Check if the IPv6 address belongs to the all nodes multicast group
1251  *
1252  * @param addr IPv6 address
1253  *
1254  * @return True if the IPv6 multicast address belongs to the all nodes multicast
1255  * group, false otherwise
1256  */
1257 static inline bool
net_ipv6_is_addr_mcast_all_nodes_group(const struct in6_addr * addr)1258 net_ipv6_is_addr_mcast_all_nodes_group(const struct in6_addr *addr)
1259 {
1260 	static const struct in6_addr all_nodes_mcast_group = {
1261 		{ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1262 		    0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1263 	};
1264 
1265 	return net_ipv6_is_addr_mcast_group(addr, &all_nodes_mcast_group);
1266 }
1267 
1268 /**
1269  * @brief Check if the IPv6 address is a interface scope all nodes multicast
1270  * address (FF01::1).
1271  *
1272  * @param addr IPv6 address.
1273  *
1274  * @return True if the address is a interface scope all nodes multicast address,
1275  * false otherwise.
1276  */
1277 static inline bool
net_ipv6_is_addr_mcast_iface_all_nodes(const struct in6_addr * addr)1278 net_ipv6_is_addr_mcast_iface_all_nodes(const struct in6_addr *addr)
1279 {
1280 	return net_ipv6_is_addr_mcast_iface(addr) &&
1281 	       net_ipv6_is_addr_mcast_all_nodes_group(addr);
1282 }
1283 
1284 /**
1285  * @brief Check if the IPv6 address is a link local scope all nodes multicast
1286  * address (FF02::1).
1287  *
1288  * @param addr IPv6 address.
1289  *
1290  * @return True if the address is a link local scope all nodes multicast
1291  * address, false otherwise.
1292  */
1293 static inline bool
net_ipv6_is_addr_mcast_link_all_nodes(const struct in6_addr * addr)1294 net_ipv6_is_addr_mcast_link_all_nodes(const struct in6_addr *addr)
1295 {
1296 	return net_ipv6_is_addr_mcast_link(addr) &&
1297 	       net_ipv6_is_addr_mcast_all_nodes_group(addr);
1298 }
1299 
1300 /**
1301  *  @brief Create solicited node IPv6 multicast address
1302  *  FF02:0:0:0:0:1:FFXX:XXXX defined in RFC 3513
1303  *
1304  *  @param src IPv6 address.
1305  *  @param dst IPv6 address.
1306  */
1307 static inline
net_ipv6_addr_create_solicited_node(const struct in6_addr * src,struct in6_addr * dst)1308 void net_ipv6_addr_create_solicited_node(const struct in6_addr *src,
1309 					 struct in6_addr *dst)
1310 {
1311 	dst->s6_addr[0]   = 0xFF;
1312 	dst->s6_addr[1]   = 0x02;
1313 	UNALIGNED_PUT(0, &dst->s6_addr16[1]);
1314 	UNALIGNED_PUT(0, &dst->s6_addr16[2]);
1315 	UNALIGNED_PUT(0, &dst->s6_addr16[3]);
1316 	UNALIGNED_PUT(0, &dst->s6_addr16[4]);
1317 	dst->s6_addr[10]  = 0U;
1318 	dst->s6_addr[11]  = 0x01;
1319 	dst->s6_addr[12]  = 0xFF;
1320 	dst->s6_addr[13]  = src->s6_addr[13];
1321 	UNALIGNED_PUT(UNALIGNED_GET(&src->s6_addr16[7]), &dst->s6_addr16[7]);
1322 }
1323 
1324 /** @brief Construct an IPv6 address from eight 16-bit words.
1325  *
1326  *  @param addr IPv6 address
1327  *  @param addr0 16-bit word which is part of the address
1328  *  @param addr1 16-bit word which is part of the address
1329  *  @param addr2 16-bit word which is part of the address
1330  *  @param addr3 16-bit word which is part of the address
1331  *  @param addr4 16-bit word which is part of the address
1332  *  @param addr5 16-bit word which is part of the address
1333  *  @param addr6 16-bit word which is part of the address
1334  *  @param addr7 16-bit word which is part of the address
1335  */
net_ipv6_addr_create(struct 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)1336 static inline void net_ipv6_addr_create(struct in6_addr *addr,
1337 					uint16_t addr0, uint16_t addr1,
1338 					uint16_t addr2, uint16_t addr3,
1339 					uint16_t addr4, uint16_t addr5,
1340 					uint16_t addr6, uint16_t addr7)
1341 {
1342 	UNALIGNED_PUT(htons(addr0), &addr->s6_addr16[0]);
1343 	UNALIGNED_PUT(htons(addr1), &addr->s6_addr16[1]);
1344 	UNALIGNED_PUT(htons(addr2), &addr->s6_addr16[2]);
1345 	UNALIGNED_PUT(htons(addr3), &addr->s6_addr16[3]);
1346 	UNALIGNED_PUT(htons(addr4), &addr->s6_addr16[4]);
1347 	UNALIGNED_PUT(htons(addr5), &addr->s6_addr16[5]);
1348 	UNALIGNED_PUT(htons(addr6), &addr->s6_addr16[6]);
1349 	UNALIGNED_PUT(htons(addr7), &addr->s6_addr16[7]);
1350 }
1351 
1352 /**
1353  *  @brief Create link local allnodes multicast IPv6 address
1354  *
1355  *  @param addr IPv6 address
1356  */
net_ipv6_addr_create_ll_allnodes_mcast(struct in6_addr * addr)1357 static inline void net_ipv6_addr_create_ll_allnodes_mcast(struct in6_addr *addr)
1358 {
1359 	net_ipv6_addr_create(addr, 0xff02, 0, 0, 0, 0, 0, 0, 0x0001);
1360 }
1361 
1362 /**
1363  *  @brief Create link local allrouters multicast IPv6 address
1364  *
1365  *  @param addr IPv6 address
1366  */
net_ipv6_addr_create_ll_allrouters_mcast(struct in6_addr * addr)1367 static inline void net_ipv6_addr_create_ll_allrouters_mcast(struct in6_addr *addr)
1368 {
1369 	net_ipv6_addr_create(addr, 0xff02, 0, 0, 0, 0, 0, 0, 0x0002);
1370 }
1371 
1372 /**
1373  *  @brief Create IPv4 mapped IPv6 address
1374  *
1375  *  @param addr4 IPv4 address
1376  *  @param addr6 IPv6 address to be created
1377  */
net_ipv6_addr_create_v4_mapped(const struct in_addr * addr4,struct in6_addr * addr6)1378 static inline void net_ipv6_addr_create_v4_mapped(const struct in_addr *addr4,
1379 						  struct in6_addr *addr6)
1380 {
1381 	net_ipv6_addr_create(addr6, 0, 0, 0, 0, 0, 0xffff,
1382 			     ntohs(addr4->s4_addr16[0]),
1383 			     ntohs(addr4->s4_addr16[1]));
1384 }
1385 
1386 /**
1387  *  @brief Is the IPv6 address an IPv4 mapped one. The v4 mapped addresses
1388  *         look like \::ffff:a.b.c.d
1389  *
1390  *  @param addr IPv6 address
1391  *
1392  *  @return True if IPv6 address is a IPv4 mapped address, False otherwise.
1393  */
net_ipv6_addr_is_v4_mapped(const struct in6_addr * addr)1394 static inline bool net_ipv6_addr_is_v4_mapped(const struct in6_addr *addr)
1395 {
1396 	if (UNALIGNED_GET(&addr->s6_addr32[0]) == 0 &&
1397 	    UNALIGNED_GET(&addr->s6_addr32[1]) == 0 &&
1398 	    UNALIGNED_GET(&addr->s6_addr16[5]) == 0xffff) {
1399 		return true;
1400 	}
1401 
1402 	return false;
1403 }
1404 
1405 /**
1406  *  @brief Create IPv6 address interface identifier
1407  *
1408  *  @param addr IPv6 address
1409  *  @param lladdr Link local address
1410  */
net_ipv6_addr_create_iid(struct in6_addr * addr,struct net_linkaddr * lladdr)1411 static inline void net_ipv6_addr_create_iid(struct in6_addr *addr,
1412 					    struct net_linkaddr *lladdr)
1413 {
1414 	UNALIGNED_PUT(htonl(0xfe800000), &addr->s6_addr32[0]);
1415 	UNALIGNED_PUT(0, &addr->s6_addr32[1]);
1416 
1417 	switch (lladdr->len) {
1418 	case 2:
1419 		/* The generated IPv6 shall not toggle the
1420 		 * Universal/Local bit. RFC 6282 ch 3.2.2
1421 		 */
1422 		if (lladdr->type == NET_LINK_IEEE802154) {
1423 			UNALIGNED_PUT(0, &addr->s6_addr32[2]);
1424 			addr->s6_addr[11] = 0xff;
1425 			addr->s6_addr[12] = 0xfe;
1426 			addr->s6_addr[13] = 0U;
1427 			addr->s6_addr[14] = lladdr->addr[0];
1428 			addr->s6_addr[15] = lladdr->addr[1];
1429 		}
1430 
1431 		break;
1432 	case 6:
1433 		/* We do not toggle the Universal/Local bit
1434 		 * in Bluetooth. See RFC 7668 ch 3.2.2
1435 		 */
1436 		memcpy(&addr->s6_addr[8], lladdr->addr, 3);
1437 		addr->s6_addr[11] = 0xff;
1438 		addr->s6_addr[12] = 0xfe;
1439 		memcpy(&addr->s6_addr[13], lladdr->addr + 3, 3);
1440 
1441 		if (lladdr->type == NET_LINK_ETHERNET) {
1442 			addr->s6_addr[8] ^= 0x02;
1443 		}
1444 
1445 		break;
1446 	case 8:
1447 		memcpy(&addr->s6_addr[8], lladdr->addr, lladdr->len);
1448 		addr->s6_addr[8] ^= 0x02;
1449 		break;
1450 	}
1451 }
1452 
1453 /**
1454  *  @brief Check if given address is based on link layer address
1455  *
1456  *  @return True if it is, False otherwise
1457  */
net_ipv6_addr_based_on_ll(const struct in6_addr * addr,const struct net_linkaddr * lladdr)1458 static inline bool net_ipv6_addr_based_on_ll(const struct in6_addr *addr,
1459 					     const struct net_linkaddr *lladdr)
1460 {
1461 	if (!addr || !lladdr) {
1462 		return false;
1463 	}
1464 
1465 	switch (lladdr->len) {
1466 	case 2:
1467 		if (!memcmp(&addr->s6_addr[14], lladdr->addr, lladdr->len) &&
1468 		    addr->s6_addr[8]  == 0U &&
1469 		    addr->s6_addr[9]  == 0U &&
1470 		    addr->s6_addr[10] == 0U &&
1471 		    addr->s6_addr[11] == 0xff &&
1472 		    addr->s6_addr[12] == 0xfe) {
1473 			return true;
1474 		}
1475 
1476 		break;
1477 	case 6:
1478 		if (lladdr->type == NET_LINK_ETHERNET) {
1479 			if (!memcmp(&addr->s6_addr[9], &lladdr->addr[1], 2) &&
1480 			    !memcmp(&addr->s6_addr[13], &lladdr->addr[3], 3) &&
1481 			    addr->s6_addr[11] == 0xff &&
1482 			    addr->s6_addr[12] == 0xfe &&
1483 			    (addr->s6_addr[8] ^ 0x02) == lladdr->addr[0]) {
1484 				return true;
1485 			}
1486 		}
1487 
1488 		break;
1489 	case 8:
1490 		if (!memcmp(&addr->s6_addr[9], &lladdr->addr[1],
1491 			    lladdr->len - 1) &&
1492 		    (addr->s6_addr[8] ^ 0x02) == lladdr->addr[0]) {
1493 			return true;
1494 		}
1495 
1496 		break;
1497 	}
1498 
1499 	return false;
1500 }
1501 
1502 /**
1503  * @brief Get sockaddr_in6 from sockaddr. This is a helper so that
1504  * the code calling this function can be made shorter.
1505  *
1506  * @param addr Socket address
1507  *
1508  * @return Pointer to IPv6 socket address
1509  */
net_sin6(const struct sockaddr * addr)1510 static inline struct sockaddr_in6 *net_sin6(const struct sockaddr *addr)
1511 {
1512 	return (struct sockaddr_in6 *)addr;
1513 }
1514 
1515 /**
1516  * @brief Get sockaddr_in from sockaddr. This is a helper so that
1517  * the code calling this function can be made shorter.
1518  *
1519  * @param addr Socket address
1520  *
1521  * @return Pointer to IPv4 socket address
1522  */
net_sin(const struct sockaddr * addr)1523 static inline struct sockaddr_in *net_sin(const struct sockaddr *addr)
1524 {
1525 	return (struct sockaddr_in *)addr;
1526 }
1527 
1528 /**
1529  * @brief Get sockaddr_in6_ptr from sockaddr_ptr. This is a helper so that
1530  * the code calling this function can be made shorter.
1531  *
1532  * @param addr Socket address
1533  *
1534  * @return Pointer to IPv6 socket address
1535  */
1536 static inline
net_sin6_ptr(const struct sockaddr_ptr * addr)1537 struct sockaddr_in6_ptr *net_sin6_ptr(const struct sockaddr_ptr *addr)
1538 {
1539 	return (struct sockaddr_in6_ptr *)addr;
1540 }
1541 
1542 /**
1543  * @brief Get sockaddr_in_ptr from sockaddr_ptr. This is a helper so that
1544  * the code calling this function can be made shorter.
1545  *
1546  * @param addr Socket address
1547  *
1548  * @return Pointer to IPv4 socket address
1549  */
1550 static inline
net_sin_ptr(const struct sockaddr_ptr * addr)1551 struct sockaddr_in_ptr *net_sin_ptr(const struct sockaddr_ptr *addr)
1552 {
1553 	return (struct sockaddr_in_ptr *)addr;
1554 }
1555 
1556 /**
1557  * @brief Get sockaddr_ll_ptr from sockaddr_ptr. This is a helper so that
1558  * the code calling this function can be made shorter.
1559  *
1560  * @param addr Socket address
1561  *
1562  * @return Pointer to linklayer socket address
1563  */
1564 static inline
net_sll_ptr(const struct sockaddr_ptr * addr)1565 struct sockaddr_ll_ptr *net_sll_ptr(const struct sockaddr_ptr *addr)
1566 {
1567 	return (struct sockaddr_ll_ptr *)addr;
1568 }
1569 
1570 /**
1571  * @brief Get sockaddr_can_ptr from sockaddr_ptr. This is a helper so that
1572  * the code needing this functionality can be made shorter.
1573  *
1574  * @param addr Socket address
1575  *
1576  * @return Pointer to CAN socket address
1577  */
1578 static inline
net_can_ptr(const struct sockaddr_ptr * addr)1579 struct sockaddr_can_ptr *net_can_ptr(const struct sockaddr_ptr *addr)
1580 {
1581 	return (struct sockaddr_can_ptr *)addr;
1582 }
1583 
1584 /**
1585  * @brief Convert a string to IP address.
1586  *
1587  * @param family IP address family (AF_INET or AF_INET6)
1588  * @param src IP address in a null terminated string
1589  * @param dst Pointer to struct in_addr if family is AF_INET or
1590  * pointer to struct in6_addr if family is AF_INET6
1591  *
1592  * @note This function doesn't do precise error checking,
1593  * do not use for untrusted strings.
1594  *
1595  * @return 0 if ok, < 0 if error
1596  */
1597 __syscall int net_addr_pton(sa_family_t family, const char *src, void *dst);
1598 
1599 /**
1600  * @brief Convert IP address to string form.
1601  *
1602  * @param family IP address family (AF_INET or AF_INET6)
1603  * @param src Pointer to struct in_addr if family is AF_INET or
1604  *        pointer to struct in6_addr if family is AF_INET6
1605  * @param dst Buffer for IP address as a null terminated string
1606  * @param size Number of bytes available in the buffer
1607  *
1608  * @return dst pointer if ok, NULL if error
1609  */
1610 __syscall char *net_addr_ntop(sa_family_t family, const void *src,
1611 			      char *dst, size_t size);
1612 
1613 /**
1614  * @brief Parse a string that contains either IPv4 or IPv6 address
1615  * and optional port, and store the information in user supplied
1616  * sockaddr struct.
1617  *
1618  * @details Syntax of the IP address string:
1619  *   192.0.2.1:80
1620  *   192.0.2.42
1621  *   [2001:db8::1]:8080
1622  *   [2001:db8::2]
1623  *   2001:db::42
1624  * Note that the str_len parameter is used to restrict the amount of
1625  * characters that are checked. If the string does not contain port
1626  * number, then the port number in sockaddr is not modified.
1627  *
1628  * @param str String that contains the IP address.
1629  * @param str_len Length of the string to be parsed.
1630  * @param addr Pointer to user supplied struct sockaddr.
1631  *
1632  * @return True if parsing could be done, false otherwise.
1633  */
1634 bool net_ipaddr_parse(const char *str, size_t str_len,
1635 		      struct sockaddr *addr);
1636 
1637 /**
1638  * @brief Set the default port in the sockaddr structure.
1639  * If the port is already set, then do nothing.
1640  *
1641  * @param addr Pointer to user supplied struct sockaddr.
1642  * @param default_port Default port number to set.
1643  *
1644  * @return 0 if ok, <0 if error
1645  */
1646 int net_port_set_default(struct sockaddr *addr, uint16_t default_port);
1647 
1648 /**
1649  * @brief Compare TCP sequence numbers.
1650  *
1651  * @details This function compares TCP sequence numbers,
1652  *          accounting for wraparound effects.
1653  *
1654  * @param seq1 First sequence number
1655  * @param seq2 Seconds sequence number
1656  *
1657  * @return < 0 if seq1 < seq2, 0 if seq1 == seq2, > 0 if seq > seq2
1658  */
net_tcp_seq_cmp(uint32_t seq1,uint32_t seq2)1659 static inline int32_t net_tcp_seq_cmp(uint32_t seq1, uint32_t seq2)
1660 {
1661 	return (int32_t)(seq1 - seq2);
1662 }
1663 
1664 /**
1665  * @brief Check that one TCP sequence number is greater.
1666  *
1667  * @details This is convenience function on top of net_tcp_seq_cmp().
1668  *
1669  * @param seq1 First sequence number
1670  * @param seq2 Seconds sequence number
1671  *
1672  * @return True if seq > seq2
1673  */
net_tcp_seq_greater(uint32_t seq1,uint32_t seq2)1674 static inline bool net_tcp_seq_greater(uint32_t seq1, uint32_t seq2)
1675 {
1676 	return net_tcp_seq_cmp(seq1, seq2) > 0;
1677 }
1678 
1679 /**
1680  * @brief Convert a string of hex values to array of bytes.
1681  *
1682  * @details The syntax of the string is "ab:02:98:fa:42:01"
1683  *
1684  * @param buf Pointer to memory where the bytes are written.
1685  * @param buf_len Length of the memory area.
1686  * @param src String of bytes.
1687  *
1688  * @return 0 if ok, <0 if error
1689  */
1690 int net_bytes_from_str(uint8_t *buf, int buf_len, const char *src);
1691 
1692 /**
1693  * @brief Convert Tx network packet priority to traffic class so we can place
1694  * the packet into correct Tx queue.
1695  *
1696  * @param prio Network priority
1697  *
1698  * @return Tx traffic class that handles that priority network traffic.
1699  */
1700 int net_tx_priority2tc(enum net_priority prio);
1701 
1702 /**
1703  * @brief Convert Rx network packet priority to traffic class so we can place
1704  * the packet into correct Rx queue.
1705  *
1706  * @param prio Network priority
1707  *
1708  * @return Rx traffic class that handles that priority network traffic.
1709  */
1710 int net_rx_priority2tc(enum net_priority prio);
1711 
1712 /**
1713  * @brief Convert network packet VLAN priority to network packet priority so we
1714  * can place the packet into correct queue.
1715  *
1716  * @param priority VLAN priority
1717  *
1718  * @return Network priority
1719  */
net_vlan2priority(uint8_t priority)1720 static inline enum net_priority net_vlan2priority(uint8_t priority)
1721 {
1722 	/* Map according to IEEE 802.1Q */
1723 	static const uint8_t vlan2priority[] = {
1724 		NET_PRIORITY_BE,
1725 		NET_PRIORITY_BK,
1726 		NET_PRIORITY_EE,
1727 		NET_PRIORITY_CA,
1728 		NET_PRIORITY_VI,
1729 		NET_PRIORITY_VO,
1730 		NET_PRIORITY_IC,
1731 		NET_PRIORITY_NC
1732 	};
1733 
1734 	if (priority >= ARRAY_SIZE(vlan2priority)) {
1735 		/* Use Best Effort as the default priority */
1736 		return NET_PRIORITY_BE;
1737 	}
1738 
1739 	return (enum net_priority)vlan2priority[priority];
1740 }
1741 
1742 /**
1743  * @brief Convert network packet priority to network packet VLAN priority.
1744  *
1745  * @param priority Packet priority
1746  *
1747  * @return VLAN priority (PCP)
1748  */
net_priority2vlan(enum net_priority priority)1749 static inline uint8_t net_priority2vlan(enum net_priority priority)
1750 {
1751 	/* The conversion works both ways */
1752 	return (uint8_t)net_vlan2priority(priority);
1753 }
1754 
1755 /**
1756  * @brief Return network address family value as a string. This is only usable
1757  * for debugging.
1758  *
1759  * @param family Network address family code
1760  *
1761  * @return Network address family as a string, or NULL if family is unknown.
1762  */
1763 const char *net_family2str(sa_family_t family);
1764 
1765 /**
1766  * @brief Add IPv6 prefix as a privacy extension filter.
1767  *
1768  * @details Note that the filters can either allow or deny listing.
1769  *
1770  * @param addr IPv6 prefix
1771  * @param is_denylist Tells if this filter is for allowing or denying listing.
1772  *
1773  * @return 0 if ok, <0 if error
1774  */
1775 #if defined(CONFIG_NET_IPV6_PE)
1776 int net_ipv6_pe_add_filter(struct in6_addr *addr, bool is_denylist);
1777 #else
net_ipv6_pe_add_filter(struct in6_addr * addr,bool is_denylist)1778 static inline int net_ipv6_pe_add_filter(struct in6_addr *addr,
1779 					 bool is_denylist)
1780 {
1781 	ARG_UNUSED(addr);
1782 	ARG_UNUSED(is_denylist);
1783 
1784 	return -ENOTSUP;
1785 }
1786 #endif /* CONFIG_NET_IPV6_PE */
1787 
1788 /**
1789  * @brief Delete IPv6 prefix from privacy extension filter list.
1790  *
1791  * @param addr IPv6 prefix
1792  *
1793  * @return 0 if ok, <0 if error
1794  */
1795 #if defined(CONFIG_NET_IPV6_PE)
1796 int net_ipv6_pe_del_filter(struct in6_addr *addr);
1797 #else
net_ipv6_pe_del_filter(struct in6_addr * addr)1798 static inline int net_ipv6_pe_del_filter(struct in6_addr *addr)
1799 {
1800 	ARG_UNUSED(addr);
1801 
1802 	return -ENOTSUP;
1803 }
1804 #endif /* CONFIG_NET_IPV6_PE */
1805 
1806 #ifdef __cplusplus
1807 }
1808 #endif
1809 
1810 #include <zephyr/syscalls/net_ip.h>
1811 
1812 /**
1813  * @}
1814  */
1815 
1816 
1817 #endif /* ZEPHYR_INCLUDE_NET_NET_IP_H_ */
1818