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