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