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 (highest)    */
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                    */
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 unique 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_ula_addr(const struct in6_addr * addr)851 static inline bool net_ipv6_is_ula_addr(const struct in6_addr *addr)
852 {
853 	return addr->s6_addr[0] == 0xFD;
854 }
855 
856 /**
857  * @brief Return pointer to any (all bits zeros) IPv6 address.
858  *
859  * @return Any IPv6 address.
860  */
861 const struct in6_addr *net_ipv6_unspecified_address(void);
862 
863 /**
864  * @brief Return pointer to any (all bits zeros) IPv4 address.
865  *
866  * @return Any IPv4 address.
867  */
868 const struct in_addr *net_ipv4_unspecified_address(void);
869 
870 /**
871  * @brief Return pointer to broadcast (all bits ones) IPv4 address.
872  *
873  * @return Broadcast IPv4 address.
874  */
875 const struct in_addr *net_ipv4_broadcast_address(void);
876 
877 struct net_if;
878 extern bool net_if_ipv4_addr_mask_cmp(struct net_if *iface,
879 				      const struct in_addr *addr);
880 
881 /**
882  * @brief Check if the given address belongs to same subnet that
883  * has been configured for the interface.
884  *
885  * @param iface A valid pointer on an interface
886  * @param addr IPv4 address
887  *
888  * @return True if address is in same subnet, false otherwise.
889  */
net_ipv4_addr_mask_cmp(struct net_if * iface,const struct in_addr * addr)890 static inline bool net_ipv4_addr_mask_cmp(struct net_if *iface,
891 					  const struct in_addr *addr)
892 {
893 	return net_if_ipv4_addr_mask_cmp(iface, addr);
894 }
895 
896 extern bool net_if_ipv4_is_addr_bcast(struct net_if *iface,
897 				      const struct in_addr *addr);
898 
899 /**
900  * @brief Check if the given IPv4 address is a broadcast address.
901  *
902  * @param iface Interface to use. Must be a valid pointer to an interface.
903  * @param addr IPv4 address
904  *
905  * @return True if address is a broadcast address, false otherwise.
906  */
907 #if defined(CONFIG_NET_NATIVE_IPV4)
net_ipv4_is_addr_bcast(struct net_if * iface,const struct in_addr * addr)908 static inline bool net_ipv4_is_addr_bcast(struct net_if *iface,
909 					  const struct in_addr *addr)
910 {
911 	if (net_ipv4_addr_cmp(addr, net_ipv4_broadcast_address())) {
912 		return true;
913 	}
914 
915 	return net_if_ipv4_is_addr_bcast(iface, addr);
916 }
917 #else
net_ipv4_is_addr_bcast(struct net_if * iface,const struct in_addr * addr)918 static inline bool net_ipv4_is_addr_bcast(struct net_if *iface,
919 					  const struct in_addr *addr)
920 {
921 	ARG_UNUSED(iface);
922 	ARG_UNUSED(addr);
923 
924 	return false;
925 }
926 #endif
927 
928 extern struct net_if_addr *net_if_ipv4_addr_lookup(const struct in_addr *addr,
929 						   struct net_if **iface);
930 
931 /**
932  * @brief Check if the IPv4 address is assigned to any network interface
933  * in the system.
934  *
935  * @param addr A valid pointer on an IPv4 address
936  *
937  * @return True if IPv4 address is found in one of the network interfaces,
938  * False otherwise.
939  */
net_ipv4_is_my_addr(const struct in_addr * addr)940 static inline bool net_ipv4_is_my_addr(const struct in_addr *addr)
941 {
942 	bool ret;
943 
944 	ret = net_if_ipv4_addr_lookup(addr, NULL) != NULL;
945 	if (!ret) {
946 		ret = net_ipv4_is_addr_bcast(NULL, addr);
947 	}
948 
949 	return ret;
950 }
951 
952 /**
953  *  @brief Check if the IPv6 address is unspecified (all bits zero)
954  *
955  *  @param addr IPv6 address.
956  *
957  *  @return True if the address is unspecified, false otherwise.
958  */
net_ipv6_is_addr_unspecified(const struct in6_addr * addr)959 static inline bool net_ipv6_is_addr_unspecified(const struct in6_addr *addr)
960 {
961 	return UNALIGNED_GET(&addr->s6_addr32[0]) == 0 &&
962 		UNALIGNED_GET(&addr->s6_addr32[1]) == 0 &&
963 		UNALIGNED_GET(&addr->s6_addr32[2]) == 0 &&
964 		UNALIGNED_GET(&addr->s6_addr32[3]) == 0;
965 }
966 
967 /**
968  *  @brief Check if the IPv6 address is solicited node multicast address
969  *  FF02:0:0:0:0:1:FFXX:XXXX defined in RFC 3513
970  *
971  *  @param addr IPv6 address.
972  *
973  *  @return True if the address is solicited node address, false otherwise.
974  */
net_ipv6_is_addr_solicited_node(const struct in6_addr * addr)975 static inline bool net_ipv6_is_addr_solicited_node(const struct in6_addr *addr)
976 {
977 	return UNALIGNED_GET(&addr->s6_addr32[0]) == htonl(0xff020000) &&
978 		UNALIGNED_GET(&addr->s6_addr32[1]) == 0x00000000 &&
979 		UNALIGNED_GET(&addr->s6_addr32[2]) == htonl(0x00000001) &&
980 		((UNALIGNED_GET(&addr->s6_addr32[3]) & htonl(0xff000000)) ==
981 		 htonl(0xff000000));
982 }
983 
984 /**
985  * @brief Check if the IPv6 address is a given scope multicast
986  * address (FFyx::).
987  *
988  * @param addr IPv6 address
989  * @param scope Scope to check
990  *
991  * @return True if the address is in given scope multicast address,
992  * false otherwise.
993  */
net_ipv6_is_addr_mcast_scope(const struct in6_addr * addr,int scope)994 static inline bool net_ipv6_is_addr_mcast_scope(const struct in6_addr *addr,
995 						int scope)
996 {
997 	return (addr->s6_addr[0] == 0xff) && (addr->s6_addr[1] == scope);
998 }
999 
1000 /**
1001  * @brief Check if the IPv6 addresses have the same multicast scope (FFyx::).
1002  *
1003  * @param addr_1 IPv6 address 1
1004  * @param addr_2 IPv6 address 2
1005  *
1006  * @return True if both addresses have same multicast scope,
1007  * false otherwise.
1008  */
net_ipv6_is_same_mcast_scope(const struct in6_addr * addr_1,const struct in6_addr * addr_2)1009 static inline bool net_ipv6_is_same_mcast_scope(const struct in6_addr *addr_1,
1010 						const struct in6_addr *addr_2)
1011 {
1012 	return (addr_1->s6_addr[0] == 0xff) && (addr_2->s6_addr[0] == 0xff) &&
1013 			(addr_1->s6_addr[1] == addr_2->s6_addr[1]);
1014 }
1015 
1016 /**
1017  * @brief Check if the IPv6 address is a global multicast address (FFxE::/16).
1018  *
1019  * @param addr IPv6 address.
1020  *
1021  * @return True if the address is global multicast address, false otherwise.
1022  */
net_ipv6_is_addr_mcast_global(const struct in6_addr * addr)1023 static inline bool net_ipv6_is_addr_mcast_global(const struct in6_addr *addr)
1024 {
1025 	return net_ipv6_is_addr_mcast_scope(addr, 0x0e);
1026 }
1027 
1028 /**
1029  * @brief Check if the IPv6 address is a interface scope multicast
1030  * address (FFx1::).
1031  *
1032  * @param addr IPv6 address.
1033  *
1034  * @return True if the address is a interface scope multicast address,
1035  * false otherwise.
1036  */
net_ipv6_is_addr_mcast_iface(const struct in6_addr * addr)1037 static inline bool net_ipv6_is_addr_mcast_iface(const struct in6_addr *addr)
1038 {
1039 	return net_ipv6_is_addr_mcast_scope(addr, 0x01);
1040 }
1041 
1042 /**
1043  * @brief Check if the IPv6 address is a link local scope multicast
1044  * address (FFx2::).
1045  *
1046  * @param addr IPv6 address.
1047  *
1048  * @return True if the address is a link local scope multicast address,
1049  * false otherwise.
1050  */
net_ipv6_is_addr_mcast_link(const struct in6_addr * addr)1051 static inline bool net_ipv6_is_addr_mcast_link(const struct in6_addr *addr)
1052 {
1053 	return net_ipv6_is_addr_mcast_scope(addr, 0x02);
1054 }
1055 
1056 /**
1057  * @brief Check if the IPv6 address is a mesh-local scope multicast
1058  * address (FFx3::).
1059  *
1060  * @param addr IPv6 address.
1061  *
1062  * @return True if the address is a mesh-local scope multicast address,
1063  * false otherwise.
1064  */
net_ipv6_is_addr_mcast_mesh(const struct in6_addr * addr)1065 static inline bool net_ipv6_is_addr_mcast_mesh(const struct in6_addr *addr)
1066 {
1067 	return net_ipv6_is_addr_mcast_scope(addr, 0x03);
1068 }
1069 
1070 /**
1071  * @brief Check if the IPv6 address is a site scope multicast
1072  * address (FFx5::).
1073  *
1074  * @param addr IPv6 address.
1075  *
1076  * @return True if the address is a site scope multicast address,
1077  * false otherwise.
1078  */
net_ipv6_is_addr_mcast_site(const struct in6_addr * addr)1079 static inline bool net_ipv6_is_addr_mcast_site(const struct in6_addr *addr)
1080 {
1081 	return net_ipv6_is_addr_mcast_scope(addr, 0x05);
1082 }
1083 
1084 /**
1085  * @brief Check if the IPv6 address is an organization scope multicast
1086  * address (FFx8::).
1087  *
1088  * @param addr IPv6 address.
1089  *
1090  * @return True if the address is an organization scope multicast address,
1091  * false otherwise.
1092  */
net_ipv6_is_addr_mcast_org(const struct in6_addr * addr)1093 static inline bool net_ipv6_is_addr_mcast_org(const struct in6_addr *addr)
1094 {
1095 	return net_ipv6_is_addr_mcast_scope(addr, 0x08);
1096 }
1097 
1098 /**
1099  * @brief Check if the IPv6 address belongs to certain multicast group
1100  *
1101  * @param addr IPv6 address.
1102  * @param group Group id IPv6 address, the values must be in network
1103  * byte order
1104  *
1105  * @return True if the IPv6 multicast address belongs to given multicast
1106  * group, false otherwise.
1107  */
net_ipv6_is_addr_mcast_group(const struct in6_addr * addr,const struct in6_addr * group)1108 static inline bool net_ipv6_is_addr_mcast_group(const struct in6_addr *addr,
1109 						const struct in6_addr *group)
1110 {
1111 	return UNALIGNED_GET(&addr->s6_addr16[1]) == group->s6_addr16[1] &&
1112 		UNALIGNED_GET(&addr->s6_addr16[2]) == group->s6_addr16[2] &&
1113 		UNALIGNED_GET(&addr->s6_addr16[3]) == group->s6_addr16[3] &&
1114 		UNALIGNED_GET(&addr->s6_addr32[1]) == group->s6_addr32[1] &&
1115 		UNALIGNED_GET(&addr->s6_addr32[2]) == group->s6_addr32[1] &&
1116 		UNALIGNED_GET(&addr->s6_addr32[3]) == group->s6_addr32[3];
1117 }
1118 
1119 /**
1120  * @brief Check if the IPv6 address belongs to the all nodes multicast group
1121  *
1122  * @param addr IPv6 address
1123  *
1124  * @return True if the IPv6 multicast address belongs to the all nodes multicast
1125  * group, false otherwise
1126  */
1127 static inline bool
net_ipv6_is_addr_mcast_all_nodes_group(const struct in6_addr * addr)1128 net_ipv6_is_addr_mcast_all_nodes_group(const struct in6_addr *addr)
1129 {
1130 	static const struct in6_addr all_nodes_mcast_group = {
1131 		{ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1132 		    0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1133 	};
1134 
1135 	return net_ipv6_is_addr_mcast_group(addr, &all_nodes_mcast_group);
1136 }
1137 
1138 /**
1139  * @brief Check if the IPv6 address is a interface scope all nodes multicast
1140  * address (FF01::1).
1141  *
1142  * @param addr IPv6 address.
1143  *
1144  * @return True if the address is a interface scope all nodes multicast address,
1145  * false otherwise.
1146  */
1147 static inline bool
net_ipv6_is_addr_mcast_iface_all_nodes(const struct in6_addr * addr)1148 net_ipv6_is_addr_mcast_iface_all_nodes(const struct in6_addr *addr)
1149 {
1150 	return net_ipv6_is_addr_mcast_iface(addr) &&
1151 	       net_ipv6_is_addr_mcast_all_nodes_group(addr);
1152 }
1153 
1154 /**
1155  * @brief Check if the IPv6 address is a link local scope all nodes multicast
1156  * address (FF02::1).
1157  *
1158  * @param addr IPv6 address.
1159  *
1160  * @return True if the address is a link local scope all nodes multicast
1161  * address, false otherwise.
1162  */
1163 static inline bool
net_ipv6_is_addr_mcast_link_all_nodes(const struct in6_addr * addr)1164 net_ipv6_is_addr_mcast_link_all_nodes(const struct in6_addr *addr)
1165 {
1166 	return net_ipv6_is_addr_mcast_link(addr) &&
1167 	       net_ipv6_is_addr_mcast_all_nodes_group(addr);
1168 }
1169 
1170 /**
1171  *  @brief Create solicited node IPv6 multicast address
1172  *  FF02:0:0:0:0:1:FFXX:XXXX defined in RFC 3513
1173  *
1174  *  @param src IPv6 address.
1175  *  @param dst IPv6 address.
1176  */
1177 static inline
net_ipv6_addr_create_solicited_node(const struct in6_addr * src,struct in6_addr * dst)1178 void net_ipv6_addr_create_solicited_node(const struct in6_addr *src,
1179 					 struct in6_addr *dst)
1180 {
1181 	dst->s6_addr[0]   = 0xFF;
1182 	dst->s6_addr[1]   = 0x02;
1183 	UNALIGNED_PUT(0, &dst->s6_addr16[1]);
1184 	UNALIGNED_PUT(0, &dst->s6_addr16[2]);
1185 	UNALIGNED_PUT(0, &dst->s6_addr16[3]);
1186 	UNALIGNED_PUT(0, &dst->s6_addr16[4]);
1187 	dst->s6_addr[10]  = 0U;
1188 	dst->s6_addr[11]  = 0x01;
1189 	dst->s6_addr[12]  = 0xFF;
1190 	dst->s6_addr[13]  = src->s6_addr[13];
1191 	UNALIGNED_PUT(UNALIGNED_GET(&src->s6_addr16[7]), &dst->s6_addr16[7]);
1192 }
1193 
1194 /** @brief Construct an IPv6 address from eight 16-bit words.
1195  *
1196  *  @param addr IPv6 address
1197  *  @param addr0 16-bit word which is part of the address
1198  *  @param addr1 16-bit word which is part of the address
1199  *  @param addr2 16-bit word which is part of the address
1200  *  @param addr3 16-bit word which is part of the address
1201  *  @param addr4 16-bit word which is part of the address
1202  *  @param addr5 16-bit word which is part of the address
1203  *  @param addr6 16-bit word which is part of the address
1204  *  @param addr7 16-bit word which is part of the address
1205  */
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)1206 static inline void net_ipv6_addr_create(struct in6_addr *addr,
1207 					uint16_t addr0, uint16_t addr1,
1208 					uint16_t addr2, uint16_t addr3,
1209 					uint16_t addr4, uint16_t addr5,
1210 					uint16_t addr6, uint16_t addr7)
1211 {
1212 	UNALIGNED_PUT(htons(addr0), &addr->s6_addr16[0]);
1213 	UNALIGNED_PUT(htons(addr1), &addr->s6_addr16[1]);
1214 	UNALIGNED_PUT(htons(addr2), &addr->s6_addr16[2]);
1215 	UNALIGNED_PUT(htons(addr3), &addr->s6_addr16[3]);
1216 	UNALIGNED_PUT(htons(addr4), &addr->s6_addr16[4]);
1217 	UNALIGNED_PUT(htons(addr5), &addr->s6_addr16[5]);
1218 	UNALIGNED_PUT(htons(addr6), &addr->s6_addr16[6]);
1219 	UNALIGNED_PUT(htons(addr7), &addr->s6_addr16[7]);
1220 }
1221 
1222 /**
1223  *  @brief Create link local allnodes multicast IPv6 address
1224  *
1225  *  @param addr IPv6 address
1226  */
net_ipv6_addr_create_ll_allnodes_mcast(struct in6_addr * addr)1227 static inline void net_ipv6_addr_create_ll_allnodes_mcast(struct in6_addr *addr)
1228 {
1229 	net_ipv6_addr_create(addr, 0xff02, 0, 0, 0, 0, 0, 0, 0x0001);
1230 }
1231 
1232 /**
1233  *  @brief Create link local allrouters multicast IPv6 address
1234  *
1235  *  @param addr IPv6 address
1236  */
net_ipv6_addr_create_ll_allrouters_mcast(struct in6_addr * addr)1237 static inline void net_ipv6_addr_create_ll_allrouters_mcast(struct in6_addr *addr)
1238 {
1239 	net_ipv6_addr_create(addr, 0xff02, 0, 0, 0, 0, 0, 0, 0x0002);
1240 }
1241 
1242 /**
1243  *  @brief Create IPv6 address interface identifier
1244  *
1245  *  @param addr IPv6 address
1246  *  @param lladdr Link local address
1247  */
net_ipv6_addr_create_iid(struct in6_addr * addr,struct net_linkaddr * lladdr)1248 static inline void net_ipv6_addr_create_iid(struct in6_addr *addr,
1249 					    struct net_linkaddr *lladdr)
1250 {
1251 	UNALIGNED_PUT(htonl(0xfe800000), &addr->s6_addr32[0]);
1252 	UNALIGNED_PUT(0, &addr->s6_addr32[1]);
1253 
1254 	switch (lladdr->len) {
1255 	case 2:
1256 		/* The generated IPv6 shall not toggle the
1257 		 * Universal/Local bit. RFC 6282 ch 3.2.2
1258 		 */
1259 		if (lladdr->type == NET_LINK_IEEE802154) {
1260 			UNALIGNED_PUT(0, &addr->s6_addr32[2]);
1261 			addr->s6_addr[11] = 0xff;
1262 			addr->s6_addr[12] = 0xfe;
1263 			addr->s6_addr[13] = 0U;
1264 			addr->s6_addr[14] = lladdr->addr[0];
1265 			addr->s6_addr[15] = lladdr->addr[1];
1266 		}
1267 
1268 		break;
1269 	case 6:
1270 		/* We do not toggle the Universal/Local bit
1271 		 * in Bluetooth. See RFC 7668 ch 3.2.2
1272 		 */
1273 		memcpy(&addr->s6_addr[8], lladdr->addr, 3);
1274 		addr->s6_addr[11] = 0xff;
1275 		addr->s6_addr[12] = 0xfe;
1276 		memcpy(&addr->s6_addr[13], lladdr->addr + 3, 3);
1277 
1278 #if defined(CONFIG_NET_L2_BT_ZEP1656)
1279 		/* Workaround against older Linux kernel BT IPSP code.
1280 		 * This will be removed eventually.
1281 		 */
1282 		if (lladdr->type == NET_LINK_BLUETOOTH) {
1283 			addr->s6_addr[8] ^= 0x02;
1284 		}
1285 #endif
1286 
1287 		if (lladdr->type == NET_LINK_ETHERNET) {
1288 			addr->s6_addr[8] ^= 0x02;
1289 		}
1290 
1291 		break;
1292 	case 8:
1293 		memcpy(&addr->s6_addr[8], lladdr->addr, lladdr->len);
1294 		addr->s6_addr[8] ^= 0x02;
1295 		break;
1296 	}
1297 }
1298 
1299 /**
1300  *  @brief Check if given address is based on link layer address
1301  *
1302  *  @return True if it is, False otherwise
1303  */
net_ipv6_addr_based_on_ll(const struct in6_addr * addr,const struct net_linkaddr * lladdr)1304 static inline bool net_ipv6_addr_based_on_ll(const struct in6_addr *addr,
1305 					     const struct net_linkaddr *lladdr)
1306 {
1307 	if (!addr || !lladdr) {
1308 		return false;
1309 	}
1310 
1311 	switch (lladdr->len) {
1312 	case 2:
1313 		if (!memcmp(&addr->s6_addr[14], lladdr->addr, lladdr->len) &&
1314 		    addr->s6_addr[8]  == 0U &&
1315 		    addr->s6_addr[9]  == 0U &&
1316 		    addr->s6_addr[10] == 0U &&
1317 		    addr->s6_addr[11] == 0xff &&
1318 		    addr->s6_addr[12] == 0xfe) {
1319 			return true;
1320 		}
1321 
1322 		break;
1323 	case 6:
1324 		if (lladdr->type == NET_LINK_ETHERNET) {
1325 			if (!memcmp(&addr->s6_addr[9], &lladdr->addr[1], 2) &&
1326 			    !memcmp(&addr->s6_addr[13], &lladdr->addr[3], 3) &&
1327 			    addr->s6_addr[11] == 0xff &&
1328 			    addr->s6_addr[12] == 0xfe &&
1329 			    (addr->s6_addr[8] ^ 0x02) == lladdr->addr[0]) {
1330 				return true;
1331 			}
1332 		} else if (lladdr->type == NET_LINK_BLUETOOTH) {
1333 			if (!memcmp(&addr->s6_addr[9], &lladdr->addr[1], 2) &&
1334 			    !memcmp(&addr->s6_addr[13], &lladdr->addr[3], 3) &&
1335 			    addr->s6_addr[11] == 0xff &&
1336 			    addr->s6_addr[12] == 0xfe
1337 #if defined(CONFIG_NET_L2_BT_ZEP1656)
1338 			    /* Workaround against older Linux kernel BT IPSP
1339 			     * code. This will be removed eventually.
1340 			     */
1341 			    && (addr->s6_addr[8] ^ 0x02) == lladdr->addr[0]
1342 #endif
1343 			    ) {
1344 				return true;
1345 			}
1346 		}
1347 
1348 		break;
1349 	case 8:
1350 		if (!memcmp(&addr->s6_addr[9], &lladdr->addr[1],
1351 			    lladdr->len - 1) &&
1352 		    (addr->s6_addr[8] ^ 0x02) == lladdr->addr[0]) {
1353 			return true;
1354 		}
1355 
1356 		break;
1357 	}
1358 
1359 	return false;
1360 }
1361 
1362 /**
1363  * @brief Get sockaddr_in6 from sockaddr. This is a helper so that
1364  * the code calling this function can be made shorter.
1365  *
1366  * @param addr Socket address
1367  *
1368  * @return Pointer to IPv6 socket address
1369  */
net_sin6(const struct sockaddr * addr)1370 static inline struct sockaddr_in6 *net_sin6(const struct sockaddr *addr)
1371 {
1372 	return (struct sockaddr_in6 *)addr;
1373 }
1374 
1375 /**
1376  * @brief Get sockaddr_in from sockaddr. This is a helper so that
1377  * the code calling this function can be made shorter.
1378  *
1379  * @param addr Socket address
1380  *
1381  * @return Pointer to IPv4 socket address
1382  */
net_sin(const struct sockaddr * addr)1383 static inline struct sockaddr_in *net_sin(const struct sockaddr *addr)
1384 {
1385 	return (struct sockaddr_in *)addr;
1386 }
1387 
1388 /**
1389  * @brief Get sockaddr_in6_ptr from sockaddr_ptr. This is a helper so that
1390  * the code calling this function can be made shorter.
1391  *
1392  * @param addr Socket address
1393  *
1394  * @return Pointer to IPv6 socket address
1395  */
1396 static inline
net_sin6_ptr(const struct sockaddr_ptr * addr)1397 struct sockaddr_in6_ptr *net_sin6_ptr(const struct sockaddr_ptr *addr)
1398 {
1399 	return (struct sockaddr_in6_ptr *)addr;
1400 }
1401 
1402 /**
1403  * @brief Get sockaddr_in_ptr from sockaddr_ptr. This is a helper so that
1404  * the code calling this function can be made shorter.
1405  *
1406  * @param addr Socket address
1407  *
1408  * @return Pointer to IPv4 socket address
1409  */
1410 static inline
net_sin_ptr(const struct sockaddr_ptr * addr)1411 struct sockaddr_in_ptr *net_sin_ptr(const struct sockaddr_ptr *addr)
1412 {
1413 	return (struct sockaddr_in_ptr *)addr;
1414 }
1415 
1416 /**
1417  * @brief Get sockaddr_ll_ptr from sockaddr_ptr. This is a helper so that
1418  * the code calling this function can be made shorter.
1419  *
1420  * @param addr Socket address
1421  *
1422  * @return Pointer to linklayer socket address
1423  */
1424 static inline
net_sll_ptr(const struct sockaddr_ptr * addr)1425 struct sockaddr_ll_ptr *net_sll_ptr(const struct sockaddr_ptr *addr)
1426 {
1427 	return (struct sockaddr_ll_ptr *)addr;
1428 }
1429 
1430 /**
1431  * @brief Get sockaddr_can_ptr from sockaddr_ptr. This is a helper so that
1432  * the code needing this functionality can be made shorter.
1433  *
1434  * @param addr Socket address
1435  *
1436  * @return Pointer to CAN socket address
1437  */
1438 static inline
net_can_ptr(const struct sockaddr_ptr * addr)1439 struct sockaddr_can_ptr *net_can_ptr(const struct sockaddr_ptr *addr)
1440 {
1441 	return (struct sockaddr_can_ptr *)addr;
1442 }
1443 
1444 /**
1445  * @brief Convert a string to IP address.
1446  *
1447  * @param family IP address family (AF_INET or AF_INET6)
1448  * @param src IP address in a null terminated string
1449  * @param dst Pointer to struct in_addr if family is AF_INET or
1450  * pointer to struct in6_addr if family is AF_INET6
1451  *
1452  * @note This function doesn't do precise error checking,
1453  * do not use for untrusted strings.
1454  *
1455  * @return 0 if ok, < 0 if error
1456  */
1457 __syscall int net_addr_pton(sa_family_t family, const char *src, void *dst);
1458 
1459 /**
1460  * @brief Convert IP address to string form.
1461  *
1462  * @param family IP address family (AF_INET or AF_INET6)
1463  * @param src Pointer to struct in_addr if family is AF_INET or
1464  *        pointer to struct in6_addr if family is AF_INET6
1465  * @param dst Buffer for IP address as a null terminated string
1466  * @param size Number of bytes available in the buffer
1467  *
1468  * @return dst pointer if ok, NULL if error
1469  */
1470 __syscall char *net_addr_ntop(sa_family_t family, const void *src,
1471 			      char *dst, size_t size);
1472 
1473 /**
1474  * @brief Parse a string that contains either IPv4 or IPv6 address
1475  * and optional port, and store the information in user supplied
1476  * sockaddr struct.
1477  *
1478  * @details Syntax of the IP address string:
1479  *   192.0.2.1:80
1480  *   192.0.2.42
1481  *   [2001:db8::1]:8080
1482  *   [2001:db8::2]
1483  *   2001:db::42
1484  * Note that the str_len parameter is used to restrict the amount of
1485  * characters that are checked. If the string does not contain port
1486  * number, then the port number in sockaddr is not modified.
1487  *
1488  * @param str String that contains the IP address.
1489  * @param str_len Length of the string to be parsed.
1490  * @param addr Pointer to user supplied struct sockaddr.
1491  *
1492  * @return True if parsing could be done, false otherwise.
1493  */
1494 bool net_ipaddr_parse(const char *str, size_t str_len,
1495 		      struct sockaddr *addr);
1496 
1497 /**
1498  * @brief Compare TCP sequence numbers.
1499  *
1500  * @details This function compares TCP sequence numbers,
1501  *          accounting for wraparound effects.
1502  *
1503  * @param seq1 First sequence number
1504  * @param seq2 Seconds sequence number
1505  *
1506  * @return < 0 if seq1 < seq2, 0 if seq1 == seq2, > 0 if seq > seq2
1507  */
net_tcp_seq_cmp(uint32_t seq1,uint32_t seq2)1508 static inline int32_t net_tcp_seq_cmp(uint32_t seq1, uint32_t seq2)
1509 {
1510 	return (int32_t)(seq1 - seq2);
1511 }
1512 
1513 /**
1514  * @brief Check that one TCP sequence number is greater.
1515  *
1516  * @details This is convenience function on top of net_tcp_seq_cmp().
1517  *
1518  * @param seq1 First sequence number
1519  * @param seq2 Seconds sequence number
1520  *
1521  * @return True if seq > seq2
1522  */
net_tcp_seq_greater(uint32_t seq1,uint32_t seq2)1523 static inline bool net_tcp_seq_greater(uint32_t seq1, uint32_t seq2)
1524 {
1525 	return net_tcp_seq_cmp(seq1, seq2) > 0;
1526 }
1527 
1528 /**
1529  * @brief Convert a string of hex values to array of bytes.
1530  *
1531  * @details The syntax of the string is "ab:02:98:fa:42:01"
1532  *
1533  * @param buf Pointer to memory where the bytes are written.
1534  * @param buf_len Length of the memory area.
1535  * @param src String of bytes.
1536  *
1537  * @return 0 if ok, <0 if error
1538  */
1539 int net_bytes_from_str(uint8_t *buf, int buf_len, const char *src);
1540 
1541 /**
1542  * @brief Convert Tx network packet priority to traffic class so we can place
1543  * the packet into correct Tx queue.
1544  *
1545  * @param prio Network priority
1546  *
1547  * @return Tx traffic class that handles that priority network traffic.
1548  */
1549 int net_tx_priority2tc(enum net_priority prio);
1550 
1551 /**
1552  * @brief Convert Rx network packet priority to traffic class so we can place
1553  * the packet into correct Rx queue.
1554  *
1555  * @param prio Network priority
1556  *
1557  * @return Rx traffic class that handles that priority network traffic.
1558  */
1559 int net_rx_priority2tc(enum net_priority prio);
1560 
1561 /**
1562  * @brief Convert network packet VLAN priority to network packet priority so we
1563  * can place the packet into correct queue.
1564  *
1565  * @param priority VLAN priority
1566  *
1567  * @return Network priority
1568  */
net_vlan2priority(uint8_t priority)1569 static inline enum net_priority net_vlan2priority(uint8_t priority)
1570 {
1571 	/* Map according to IEEE 802.1Q */
1572 	static const uint8_t vlan2priority[] = {
1573 		NET_PRIORITY_BE,
1574 		NET_PRIORITY_BK,
1575 		NET_PRIORITY_EE,
1576 		NET_PRIORITY_CA,
1577 		NET_PRIORITY_VI,
1578 		NET_PRIORITY_VO,
1579 		NET_PRIORITY_IC,
1580 		NET_PRIORITY_NC
1581 	};
1582 
1583 	if (priority >= ARRAY_SIZE(vlan2priority)) {
1584 		/* Use Best Effort as the default priority */
1585 		return NET_PRIORITY_BE;
1586 	}
1587 
1588 	return (enum net_priority)vlan2priority[priority];
1589 }
1590 
1591 /**
1592  * @brief Convert network packet priority to network packet VLAN priority.
1593  *
1594  * @param priority Packet priority
1595  *
1596  * @return VLAN priority (PCP)
1597  */
net_priority2vlan(enum net_priority priority)1598 static inline uint8_t net_priority2vlan(enum net_priority priority)
1599 {
1600 	/* The conversion works both ways */
1601 	return (uint8_t)net_vlan2priority(priority);
1602 }
1603 
1604 /**
1605  * @brief Return network address family value as a string. This is only usable
1606  * for debugging.
1607  *
1608  * @param family Network address family code
1609  *
1610  * @return Network address family as a string, or NULL if family is unknown.
1611  */
1612 const char *net_family2str(sa_family_t family);
1613 
1614 #ifdef __cplusplus
1615 }
1616 #endif
1617 
1618 #include <syscalls/net_ip.h>
1619 
1620 /**
1621  * @}
1622  */
1623 
1624 
1625 #endif /* ZEPHYR_INCLUDE_NET_NET_IP_H_ */
1626