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