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