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 NET_PF_UNSPEC 0 /**< Unspecified protocol family. */
45 #define NET_PF_INET 1 /**< IP protocol family version 4. */
46 #define NET_PF_INET6 2 /**< IP protocol family version 6. */
47 #define NET_PF_PACKET 3 /**< Packet family. */
48 #define NET_PF_CAN 4 /**< Controller Area Network. */
49 #define NET_PF_NET_MGMT 5 /**< Network management info. */
50 #define NET_PF_LOCAL 6 /**< Inter-process communication */
51 #define NET_PF_UNIX NET_PF_LOCAL /**< Inter-process communication */
52
53 /* Address families. */
54 #define NET_AF_UNSPEC NET_PF_UNSPEC /**< Unspecified address family. */
55 #define NET_AF_INET NET_PF_INET /**< IP protocol family version 4. */
56 #define NET_AF_INET6 NET_PF_INET6 /**< IP protocol family version 6. */
57 #define NET_AF_PACKET NET_PF_PACKET /**< Packet family. */
58 #define NET_AF_CAN NET_PF_CAN /**< Controller Area Network. */
59 #define NET_AF_NET_MGMT NET_PF_NET_MGMT /**< Network management info. */
60 #define NET_AF_LOCAL NET_PF_LOCAL /**< Inter-process communication */
61 #define NET_AF_UNIX NET_PF_UNIX /**< Inter-process communication */
62
63 /** Protocol numbers from IANA/BSD */
64 enum net_ip_protocol {
65 NET_IPPROTO_IP = 0, /**< IP protocol (pseudo-val for setsockopt() */
66 NET_IPPROTO_ICMP = 1, /**< ICMP protocol */
67 NET_IPPROTO_IGMP = 2, /**< IGMP protocol */
68 NET_IPPROTO_ETH_P_ALL = 3, /**< Every packet. from linux if_ether.h */
69 NET_IPPROTO_IPIP = 4, /**< IPIP tunnels */
70 NET_IPPROTO_TCP = 6, /**< TCP protocol */
71 NET_IPPROTO_UDP = 17, /**< UDP protocol */
72 NET_IPPROTO_IPV6 = 41, /**< IPv6 protocol */
73 NET_IPPROTO_ICMPV6 = 58, /**< ICMPv6 protocol */
74 NET_IPPROTO_RAW = 255, /**< RAW IP packets */
75 };
76
77 /** Protocol numbers for TLS protocols */
78 enum net_ip_protocol_secure {
79 NET_IPPROTO_TLS_1_0 = 256, /**< TLS 1.0 protocol */
80 NET_IPPROTO_TLS_1_1 = 257, /**< TLS 1.1 protocol */
81 NET_IPPROTO_TLS_1_2 = 258, /**< TLS 1.2 protocol */
82 NET_IPPROTO_TLS_1_3 = 259, /**< TLS 1.3 protocol */
83 NET_IPPROTO_DTLS_1_0 = 272, /**< DTLS 1.0 protocol */
84 NET_IPPROTO_DTLS_1_2 = 273, /**< DTLS 1.2 protocol */
85 };
86
87 /** Socket type */
88 enum net_sock_type {
89 NET_SOCK_STREAM = 1, /**< Stream socket type */
90 NET_SOCK_DGRAM, /**< Datagram socket type */
91 NET_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 net_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 net_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 net_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 net_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 net_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 net_htonll(x) sys_cpu_to_be64(x)
141
142 /** IPv6 address struct */
143 struct net_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 net_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 net_sa_family_t;
169
170 /** Length of a socket address */
171 typedef uint32_t net_socklen_t;
172
173 /*
174 * Note that the sin_port and sin6_port are in network byte order
175 * in various net_sockaddr* structs.
176 */
177
178 /** Socket address struct for IPv6. */
179 struct net_sockaddr_in6 {
180 net_sa_family_t sin6_family; /**< NET_AF_INET6 */
181 uint16_t sin6_port; /**< Port number */
182 struct net_in6_addr sin6_addr; /**< IPv6 address */
183 uint8_t sin6_scope_id; /**< Interfaces for a scope */
184 };
185
186 /** Socket address struct for IPv4. */
187 struct net_sockaddr_in {
188 net_sa_family_t sin_family; /**< NET_AF_INET */
189 uint16_t sin_port; /**< Port number */
190 struct net_in_addr sin_addr; /**< IPv4 address */
191 };
192
193 /** Socket address struct for packet socket. */
194 struct net_sockaddr_ll {
195 net_sa_family_t sll_family; /**< Always NET_AF_PACKET */
196 uint16_t sll_protocol; /**< Physical-layer protocol */
197 int sll_ifindex; /**< Interface number */
198 uint16_t sll_hatype; /**< ARP hardware type */
199 uint8_t sll_pkttype; /**< Packet type */
200 uint8_t sll_halen; /**< Length of address */
201 uint8_t sll_addr[8]; /**< Physical-layer address, big endian */
202 };
203
204 /** @cond INTERNAL_HIDDEN */
205
206 /** Socket address struct for IPv6 where address is a pointer */
207 struct net_sockaddr_in6_ptr {
208 net_sa_family_t sin6_family; /**< NET_AF_INET6 */
209 uint16_t sin6_port; /**< Port number */
210 struct net_in6_addr *sin6_addr; /**< IPv6 address */
211 uint8_t sin6_scope_id; /**< interfaces for a scope */
212 };
213
214 /** Socket address struct for IPv4 where address is a pointer */
215 struct net_sockaddr_in_ptr {
216 net_sa_family_t sin_family; /**< NET_AF_INET */
217 uint16_t sin_port; /**< Port number */
218 struct net_in_addr *sin_addr; /**< IPv4 address */
219 };
220
221 /** Socket address struct for packet socket where address is a pointer */
222 struct net_sockaddr_ll_ptr {
223 net_sa_family_t sll_family; /**< Always NET_AF_PACKET */
224 uint16_t sll_protocol; /**< Physical-layer protocol */
225 int sll_ifindex; /**< Interface number */
226 uint16_t sll_hatype; /**< ARP hardware type */
227 uint8_t sll_pkttype; /**< Packet type */
228 uint8_t sll_halen; /**< Length of address */
229 uint8_t *sll_addr; /**< Physical-layer address, big endian */
230 };
231
232 /** Socket address struct for unix socket where address is a pointer */
233 struct net_sockaddr_un_ptr {
234 net_sa_family_t sun_family; /**< Always NET_AF_UNIX */
235 char *sun_path; /**< Pathname */
236 };
237
238 struct net_sockaddr_can_ptr {
239 net_sa_family_t can_family;
240 int can_ifindex;
241 };
242
243 /** @endcond */
244
245 #if !defined(HAVE_IOVEC)
246 /** IO vector array element */
247 struct net_iovec {
248 void *iov_base; /**< Pointer to data */
249 size_t iov_len; /**< Length of the data */
250 };
251 #endif
252
253 /** Message struct */
254 struct net_msghdr {
255 void *msg_name; /**< Optional socket address, big endian */
256 net_socklen_t msg_namelen; /**< Size of socket address */
257 struct net_iovec *msg_iov; /**< Scatter/gather array */
258 size_t msg_iovlen; /**< Number of elements in msg_iov */
259 void *msg_control; /**< Ancillary data */
260 size_t msg_controllen; /**< Ancillary data buffer len */
261 int msg_flags; /**< Flags on received message */
262 };
263
264 /** Control message ancillary data */
265 struct net_cmsghdr {
266 net_socklen_t cmsg_len; /**< Number of bytes, including header */
267 int cmsg_level; /**< Originating protocol */
268 int cmsg_type; /**< Protocol-specific type */
269 z_max_align_t cmsg_data[]; /**< Flexible array member to force alignment of net_cmsghdr */
270 };
271
272 /** @cond INTERNAL_HIDDEN */
273
274 /* Alignment for headers and data. These are arch specific but define
275 * them here atm if not found already.
276 */
277 #if !defined(NET_ALIGN_H)
278 #define NET_ALIGN_H(x) ROUND_UP(x, __alignof__(struct net_cmsghdr))
279 #endif
280 #if !defined(NET_ALIGN_D)
281 #define NET_ALIGN_D(x) ROUND_UP(x, __alignof__(z_max_align_t))
282 #endif
283
284 /** @endcond */
285
286 #if !defined(NET_CMSG_FIRSTHDR)
287 /**
288 * Returns a pointer to the first cmsghdr in the ancillary data buffer
289 * associated with the passed msghdr. It returns NULL if there isn't
290 * enough space for a cmsghdr in the buffer.
291 */
292 #define NET_CMSG_FIRSTHDR(msghdr) \
293 ((msghdr)->msg_controllen >= sizeof(struct net_cmsghdr) ? \
294 (struct net_cmsghdr *)((msghdr)->msg_control) : NULL)
295 #endif
296
297 #if !defined(NET_CMSG_NXTHDR)
298 /**
299 * Returns the next valid cmsghdr after the passed cmsghdr. It returns NULL
300 * when there isn't enough space left in the buffer.
301 */
302 #define NET_CMSG_NXTHDR(msghdr, cmsg) \
303 (((cmsg) == NULL) ? NET_CMSG_FIRSTHDR(msghdr) : \
304 (((uint8_t *)(cmsg) + NET_ALIGN_H((cmsg)->cmsg_len) + \
305 NET_ALIGN_D(sizeof(struct net_cmsghdr)) > \
306 (uint8_t *)((msghdr)->msg_control) + (msghdr)->msg_controllen) ? \
307 NULL : \
308 (struct net_cmsghdr *)((uint8_t *)(cmsg) + \
309 NET_ALIGN_H((cmsg)->cmsg_len))))
310 #endif
311
312 #if !defined(NET_CMSG_DATA)
313 /**
314 * Returns a pointer to the data portion of a cmsghdr. The pointer returned
315 * cannot be assumed to be suitably aligned for accessing arbitrary payload
316 * data types. Applications should not cast it to a pointer type matching
317 * the payload, but should instead use memcpy(3) to copy data to or from a
318 * suitably declared object.
319 */
320 #define NET_CMSG_DATA(cmsg) ((uint8_t *)(cmsg) + NET_ALIGN_D(sizeof(struct net_cmsghdr)))
321 #endif
322
323 #if !defined(NET_CMSG_SPACE)
324 /**
325 * Returns the number of bytes an ancillary element with payload of the passed
326 * data length occupies.
327 */
328 #define NET_CMSG_SPACE(length) (NET_ALIGN_D(sizeof(struct net_cmsghdr)) + NET_ALIGN_H(length))
329 #endif
330
331 #if !defined(NET_CMSG_LEN)
332 /**
333 * Returns the value to store in the cmsg_len member of the net_cmsghdr structure,
334 * taking into account any necessary alignment.
335 * It takes the data length as an argument.
336 */
337 #define NET_CMSG_LEN(length) (NET_ALIGN_D(sizeof(struct net_cmsghdr)) + length)
338 #endif
339
340 /** @cond INTERNAL_HIDDEN */
341
342 /* Packet types. */
343 #define NET_PACKET_HOST 0 /* To us */
344 #define NET_PACKET_BROADCAST 1 /* To all */
345 #define NET_PACKET_MULTICAST 2 /* To group */
346 #define NET_PACKET_OTHERHOST 3 /* To someone else */
347 #define NET_PACKET_OUTGOING 4 /* Originated by us */
348 #define NET_PACKET_LOOPBACK 5
349 #define NET_PACKET_FASTROUTE 6
350
351 /* ARP protocol HARDWARE identifiers. */
352 #define NET_ARPHRD_ETHER 1
353 #define NET_ARPHRD_PPP 512
354
355 /* Note: These macros are defined in a specific order.
356 * The largest sockaddr size is the last one.
357 */
358 #if defined(CONFIG_NET_IPV4)
359 #undef NET_SOCKADDR_MAX_SIZE
360 #undef NET_SOCKADDR_PTR_MAX_SIZE
361 #define NET_SOCKADDR_MAX_SIZE (sizeof(struct net_sockaddr_in))
362 #define NET_SOCKADDR_PTR_MAX_SIZE (sizeof(struct net_sockaddr_in_ptr))
363 #endif
364
365 #if defined(CONFIG_NET_SOCKETS_PACKET)
366 #undef NET_SOCKADDR_MAX_SIZE
367 #undef NET_SOCKADDR_PTR_MAX_SIZE
368 #define NET_SOCKADDR_MAX_SIZE (sizeof(struct net_sockaddr_ll))
369 #define NET_SOCKADDR_PTR_MAX_SIZE (sizeof(struct net_sockaddr_ll_ptr))
370 #endif
371
372 #if defined(CONFIG_NET_IPV6)
373 #undef NET_SOCKADDR_MAX_SIZE
374 #define NET_SOCKADDR_MAX_SIZE (sizeof(struct net_sockaddr_in6))
375 #if !defined(CONFIG_NET_SOCKETS_PACKET)
376 #undef NET_SOCKADDR_PTR_MAX_SIZE
377 #define NET_SOCKADDR_PTR_MAX_SIZE (sizeof(struct net_sockaddr_in6_ptr))
378 #endif
379 #endif
380
381 #if defined(CONFIG_NET_NATIVE_OFFLOADED_SOCKETS)
382 #define UNIX_PATH_MAX 108
383 #undef NET_SOCKADDR_MAX_SIZE
384 /* Define NET_SOCKADDR_MAX_SIZE to be struct of net_sa_family_t + char[UNIX_PATH_MAX] */
385 #define NET_SOCKADDR_MAX_SIZE (UNIX_PATH_MAX+sizeof(net_sa_family_t))
386 #if !defined(CONFIG_NET_SOCKETS_PACKET)
387 #undef NET_SOCKADDR_PTR_MAX_SIZE
388 #define NET_SOCKADDR_PTR_MAX_SIZE (sizeof(struct net_sockaddr_un_ptr))
389 #endif
390 #endif
391
392 #if !defined(CONFIG_NET_IPV4)
393 #if !defined(CONFIG_NET_IPV6)
394 #if !defined(CONFIG_NET_SOCKETS_PACKET)
395 #if !defined(CONFIG_NET_NATIVE_OFFLOADED_SOCKETS)
396 #define NET_SOCKADDR_MAX_SIZE (sizeof(struct net_sockaddr_in6))
397 #define NET_SOCKADDR_PTR_MAX_SIZE (sizeof(struct net_sockaddr_in6_ptr))
398 #endif
399 #endif
400 #endif
401 #endif
402
403 /** @endcond */
404
405 #define SOCKADDR_ALIGN (4)
406
407 /** Generic sockaddr struct. Must be cast to proper type. */
408 struct net_sockaddr {
409 net_sa_family_t sa_family; /**< Address family */
410 /** @cond INTERNAL_HIDDEN */
411 char data[NET_SOCKADDR_MAX_SIZE - sizeof(net_sa_family_t)];
412 /** @endcond */
413 } __aligned(SOCKADDR_ALIGN);
414
415 /** @cond INTERNAL_HIDDEN */
416
417 struct net_sockaddr_ptr {
418 net_sa_family_t family;
419 char data[NET_SOCKADDR_PTR_MAX_SIZE - sizeof(net_sa_family_t)];
420 } __aligned(SOCKADDR_ALIGN);
421
422 /* Same as sockaddr in our case */
423 struct net_sockaddr_storage {
424 net_sa_family_t ss_family;
425 char data[NET_SOCKADDR_MAX_SIZE - sizeof(net_sa_family_t)];
426 } __aligned(SOCKADDR_ALIGN);
427
428 /* Socket address struct for UNIX domain sockets */
429 struct net_sockaddr_un {
430 net_sa_family_t sun_family; /* NET_AF_UNIX */
431 char sun_path[NET_SOCKADDR_MAX_SIZE - sizeof(net_sa_family_t)];
432 };
433
434 struct net_addr {
435 net_sa_family_t family;
436 union {
437 #if defined(CONFIG_NET_NAMESPACE_COMPAT_MODE)
438 struct net_in6_addr net_in6_addr;
439 struct net_in_addr net_in_addr;
440 #else
441 struct net_in6_addr in6_addr;
442 struct net_in_addr in_addr;
443 #endif
444 };
445 };
446
447 /** A pointer to IPv6 any address (all values zero) */
448 extern const struct net_in6_addr net_in6addr_any;
449
450 /** A pointer to IPv6 loopback address (::1) */
451 extern const struct net_in6_addr net_in6addr_loopback;
452
453 /** @endcond */
454
455 /** IPv6 address initializer */
456 #define NET_IN6ADDR_ANY_INIT { { { 0, 0, 0, 0, 0, 0, 0, 0, \
457 0, 0, 0, 0, 0, 0, 0, 0 } } }
458
459 /** IPv6 loopback address initializer */
460 #define NET_IN6ADDR_LOOPBACK_INIT { { { 0, 0, 0, 0, 0, 0, 0, 0, \
461 0, 0, 0, 0, 0, 0, 0, 1 } } }
462
463 /** IPv4 any address */
464 #define NET_INADDR_ANY 0
465
466 /** IPv4 broadcast address */
467 #define NET_INADDR_BROADCAST 0xffffffff
468
469 /** IPv4 address initializer */
470 #define NET_INADDR_ANY_INIT { { { NET_INADDR_ANY } } }
471
472 /** IPv6 loopback address initializer */
473 #define NET_INADDR_LOOPBACK_INIT { { { 127, 0, 0, 1 } } }
474
475 /** Max length of the IPv4 address as a string. Defined by POSIX. */
476 #define NET_INET_ADDRSTRLEN 16
477
478 /** Max length of the IPv6 address as a string. Takes into account possible
479 * mapped IPv4 addresses.
480 */
481 #define NET_INET6_ADDRSTRLEN 46
482
483 /** @cond INTERNAL_HIDDEN */
484
485 /* These are for internal usage of the stack */
486 #define NET_IPV6_ADDR_LEN sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxx.xxx.xxx.xxx")
487 #define NET_IPV4_ADDR_LEN sizeof("xxx.xxx.xxx.xxx")
488
489 /** @endcond */
490
491 /** @brief IP Maximum Transfer Unit */
492 enum net_ip_mtu {
493 /** IPv6 MTU length. We must be able to receive this size IPv6 packet
494 * without fragmentation.
495 */
496 #if defined(CONFIG_NET_NATIVE_IPV6)
497 NET_IPV6_MTU = CONFIG_NET_IPV6_MTU,
498 #else
499 NET_IPV6_MTU = 1280,
500 #endif
501
502 /** IPv4 MTU length. We must be able to receive this size IPv4 packet
503 * without fragmentation.
504 */
505 #if defined(CONFIG_NET_NATIVE_IPV4)
506 NET_IPV4_MTU = CONFIG_NET_IPV4_MTU,
507 #else
508 NET_IPV4_MTU = 576,
509 #endif
510 };
511
512 /** @brief Network packet priority settings described in IEEE 802.1Q Annex I.1 */
513 enum net_priority {
514 NET_PRIORITY_BK = 1, /**< Background (lowest) */
515 NET_PRIORITY_BE = 0, /**< Best effort (default) */
516 NET_PRIORITY_EE = 2, /**< Excellent effort */
517 NET_PRIORITY_CA = 3, /**< Critical applications */
518 NET_PRIORITY_VI = 4, /**< Video, < 100 ms latency and jitter */
519 NET_PRIORITY_VO = 5, /**< Voice, < 10 ms latency and jitter */
520 NET_PRIORITY_IC = 6, /**< Internetwork control */
521 NET_PRIORITY_NC = 7 /**< Network control (highest) */
522 } __packed;
523
524 #define NET_MAX_PRIORITIES 8 /**< How many priority values there are */
525
526 /** @brief IPv6/IPv4 network connection tuple */
527 struct net_tuple {
528 struct net_addr *remote_addr; /**< IPv6/IPv4 remote address */
529 struct net_addr *local_addr; /**< IPv6/IPv4 local address */
530 uint16_t remote_port; /**< UDP/TCP remote port */
531 uint16_t local_port; /**< UDP/TCP local port */
532 enum net_ip_protocol ip_proto; /**< IP protocol */
533 };
534
535 /** @brief What is the current state of the network address */
536 enum net_addr_state {
537 NET_ADDR_ANY_STATE = -1, /**< Default (invalid) address type */
538 NET_ADDR_TENTATIVE = 0, /**< Tentative address */
539 NET_ADDR_PREFERRED, /**< Preferred address */
540 NET_ADDR_DEPRECATED, /**< Deprecated address */
541 } __packed;
542
543 /** @brief How the network address is assigned to network interface */
544 enum net_addr_type {
545 /** Default value. This is not a valid value. */
546 NET_ADDR_ANY = 0,
547 /** Auto configured address */
548 NET_ADDR_AUTOCONF,
549 /** Address is from DHCP */
550 NET_ADDR_DHCP,
551 /** Manually set address */
552 NET_ADDR_MANUAL,
553 /** Manually set address which is overridable by DHCP */
554 NET_ADDR_OVERRIDABLE,
555 } __packed;
556
557 /** @cond INTERNAL_HIDDEN */
558
559 struct net_ipv6_hdr {
560 uint8_t vtc;
561 uint8_t tcflow;
562 uint16_t flow;
563 uint16_t len;
564 uint8_t nexthdr;
565 uint8_t hop_limit;
566 uint8_t src[NET_IPV6_ADDR_SIZE];
567 uint8_t dst[NET_IPV6_ADDR_SIZE];
568 } __packed;
569
570 struct net_ipv6_frag_hdr {
571 uint8_t nexthdr;
572 uint8_t reserved;
573 uint16_t offset;
574 uint32_t id;
575 } __packed;
576
577 struct net_ipv4_hdr {
578 uint8_t vhl;
579 uint8_t tos;
580 uint16_t len;
581 uint8_t id[2];
582 uint8_t offset[2];
583 uint8_t ttl;
584 uint8_t proto;
585 uint16_t chksum;
586 uint8_t src[NET_IPV4_ADDR_SIZE];
587 uint8_t dst[NET_IPV4_ADDR_SIZE];
588 } __packed;
589
590 struct net_icmp_hdr {
591 uint8_t type;
592 uint8_t code;
593 uint16_t chksum;
594 } __packed;
595
596 struct net_udp_hdr {
597 uint16_t src_port;
598 uint16_t dst_port;
599 uint16_t len;
600 uint16_t chksum;
601 } __packed;
602
603 struct net_tcp_hdr {
604 uint16_t src_port;
605 uint16_t dst_port;
606 uint8_t seq[4];
607 uint8_t ack[4];
608 uint8_t offset;
609 uint8_t flags;
610 uint8_t wnd[2];
611 uint16_t chksum;
612 uint8_t urg[2];
613 uint8_t optdata[0];
614 } __packed;
615
net_addr_type2str(enum net_addr_type type)616 static inline const char *net_addr_type2str(enum net_addr_type type)
617 {
618 switch (type) {
619 case NET_ADDR_AUTOCONF:
620 return "AUTO";
621 case NET_ADDR_DHCP:
622 return "DHCP";
623 case NET_ADDR_MANUAL:
624 return "MANUAL";
625 case NET_ADDR_OVERRIDABLE:
626 return "OVERRIDE";
627 case NET_ADDR_ANY:
628 default:
629 break;
630 }
631
632 return "<unknown>";
633 }
634
635 /* IPv6 extension headers types */
636 #define NET_IPV6_NEXTHDR_HBHO 0
637 #define NET_IPV6_NEXTHDR_DESTO 60
638 #define NET_IPV6_NEXTHDR_ROUTING 43
639 #define NET_IPV6_NEXTHDR_FRAG 44
640 #define NET_IPV6_NEXTHDR_NONE 59
641
642 /**
643 * This 2 unions are here temporarily, as long as net_context.h will
644 * be still public and not part of the core only.
645 */
646 union net_ip_header {
647 struct net_ipv4_hdr *ipv4;
648 struct net_ipv6_hdr *ipv6;
649 };
650
651 union net_proto_header {
652 struct net_udp_hdr *udp;
653 struct net_tcp_hdr *tcp;
654 };
655
656 #define NET_UDPH_LEN 8 /* Size of UDP header */
657 #define NET_TCPH_LEN 20 /* Size of TCP header */
658 #define NET_ICMPH_LEN 4 /* Size of ICMP header */
659
660 #define NET_IPV6H_LEN 40 /* Size of IPv6 header */
661 #define NET_ICMPV6H_LEN NET_ICMPH_LEN /* Size of ICMPv6 header */
662 #define NET_IPV6UDPH_LEN (NET_UDPH_LEN + NET_IPV6H_LEN) /* IPv6 + UDP */
663 #define NET_IPV6TCPH_LEN (NET_TCPH_LEN + NET_IPV6H_LEN) /* IPv6 + TCP */
664 #define NET_IPV6ICMPH_LEN (NET_IPV6H_LEN + NET_ICMPH_LEN) /* ICMPv6 + IPv6 */
665 #define NET_IPV6_FRAGH_LEN 8
666
667 #define NET_IPV4H_LEN 20 /* Size of IPv4 header */
668 #define NET_ICMPV4H_LEN NET_ICMPH_LEN /* Size of ICMPv4 header */
669 #define NET_IPV4UDPH_LEN (NET_UDPH_LEN + NET_IPV4H_LEN) /* IPv4 + UDP */
670 #define NET_IPV4TCPH_LEN (NET_TCPH_LEN + NET_IPV4H_LEN) /* IPv4 + TCP */
671 #define NET_IPV4ICMPH_LEN (NET_IPV4H_LEN + NET_ICMPH_LEN) /* ICMPv4 + IPv4 */
672
673 #define NET_IPV6H_LENGTH_OFFSET 0x04 /* Offset of the Length field in the IPv6 header */
674
675 #define NET_IPV6_FRAGH_OFFSET_MASK 0xfff8 /* Mask for the 13-bit Fragment Offset field */
676 #define NET_IPV4_FRAGH_OFFSET_MASK 0x1fff /* Mask for the 13-bit Fragment Offset field */
677 #define NET_IPV4_MORE_FRAG_MASK 0x2000 /* Mask for the 1-bit More Fragments field */
678 #define NET_IPV4_DO_NOT_FRAG_MASK 0x4000 /* Mask for the 1-bit Do Not Fragment field */
679
680 /** Network interface name length */
681 #if defined(CONFIG_NET_INTERFACE_NAME)
682 #define NET_IFNAMSIZ CONFIG_NET_INTERFACE_NAME_LEN
683 #else
684 #if defined(Z_DEVICE_MAX_NAME_LEN)
685 #define NET_IFNAMSIZ Z_DEVICE_MAX_NAME_LEN
686 #else
687 #define NET_IFNAMSIZ 1
688 #endif /* Z_DEVICE_MAX_NAME_LEN */
689 #endif /* CONFIG_NET_INTERFACE_NAME */
690
691 /** @endcond */
692
693 /**
694 * @name Network interface name description
695 * @{
696 */
697
698 /** Interface description structure */
699 struct net_ifreq {
700 char ifr_name[NET_IFNAMSIZ]; /**< Network interface name */
701 };
702 /** @} */
703
704 /**
705 * @brief Incoming IPv4 packet information.
706 *
707 * Used as ancillary data when calling recvmsg() and IP_PKTINFO socket
708 * option is set.
709 */
710 struct net_in_pktinfo {
711 unsigned int ipi_ifindex; /**< Network interface index */
712 struct net_in_addr ipi_spec_dst; /**< Local address */
713 struct net_in_addr ipi_addr; /**< Header Destination address */
714 };
715
716 /**
717 * @brief Struct used when joining or leaving a IPv4 multicast group.
718 */
719 struct net_ip_mreqn {
720 struct net_in_addr imr_multiaddr; /**< IP multicast group address */
721 struct net_in_addr imr_address; /**< IP address of local interface */
722 int imr_ifindex; /**< Network interface index */
723 };
724
725 /**
726 * @brief Struct used when setting a IPv4 multicast network interface.
727 */
728 struct net_ip_mreq {
729 struct net_in_addr imr_multiaddr; /**< IP multicast group address */
730 struct net_in_addr imr_interface; /**< IP address of local interface */
731 };
732
733 /**
734 * @brief Struct used when joining or leaving a IPv6 multicast group.
735 */
736 struct net_ipv6_mreq {
737 /** IPv6 multicast address of group */
738 struct net_in6_addr ipv6mr_multiaddr;
739
740 /** Network interface index of the local IPv6 address */
741 int ipv6mr_ifindex;
742 };
743
744 /**
745 * @brief Incoming IPv6 packet information.
746 *
747 * Used as ancillary data when calling recvmsg() and IPV6_RECVPKTINFO socket
748 * option is set.
749 */
750 struct net_in6_pktinfo {
751 struct net_in6_addr ipi6_addr; /**< Destination IPv6 address */
752 unsigned int ipi6_ifindex; /**< Receive interface index */
753 };
754
755 /** @cond INTERNAL_HIDDEN */
net_ipv6_is_addr_loopback_raw(const uint8_t * addr)756 static inline bool net_ipv6_is_addr_loopback_raw(const uint8_t *addr)
757 {
758 return UNALIGNED_GET((uint32_t *)addr) == 0 &&
759 UNALIGNED_GET((uint32_t *)addr + 1) == 0 &&
760 UNALIGNED_GET((uint32_t *)addr + 2) == 0 &&
761 net_ntohl(UNALIGNED_GET((uint32_t *)addr + 3)) == 1;
762 }
763 /** @endcond */
764
765 /**
766 * @brief Check if the IPv6 address is a loopback address (::1).
767 *
768 * @param addr IPv6 address
769 *
770 * @return True if address is a loopback address, False otherwise.
771 */
net_ipv6_is_addr_loopback(const struct net_in6_addr * addr)772 static inline bool net_ipv6_is_addr_loopback(const struct net_in6_addr *addr)
773 {
774 return net_ipv6_is_addr_loopback_raw(addr->s6_addr);
775 }
776
777 /** @cond INTERNAL_HIDDEN */
net_ipv6_is_addr_mcast_raw(const uint8_t * addr)778 static inline bool net_ipv6_is_addr_mcast_raw(const uint8_t *addr)
779 {
780 return addr[0] == 0xff;
781 }
782 /** @endcond */
783
784 /**
785 * @brief Check if the IPv6 address is a multicast address.
786 *
787 * @param addr IPv6 address
788 *
789 * @return True if address is multicast address, False otherwise.
790 */
net_ipv6_is_addr_mcast(const struct net_in6_addr * addr)791 static inline bool net_ipv6_is_addr_mcast(const struct net_in6_addr *addr)
792 {
793 return net_ipv6_is_addr_mcast_raw(addr->s6_addr);
794 }
795
796 struct net_if;
797 struct net_if_config;
798
799 /** @cond INTERNAL_HIDDEN */
800 extern struct net_if_addr *net_if_ipv6_addr_lookup_raw(const uint8_t *addr,
801 struct net_if **ret);
802
net_ipv6_is_my_addr_raw(const uint8_t * addr)803 static inline bool net_ipv6_is_my_addr_raw(const uint8_t *addr)
804 {
805 return net_if_ipv6_addr_lookup_raw(addr, NULL) != NULL;
806 }
807 /** @endcond */
808
809 extern struct net_if_addr *net_if_ipv6_addr_lookup(const struct net_in6_addr *addr,
810 struct net_if **iface);
811
812 /**
813 * @brief Check if IPv6 address is found in one of the network interfaces.
814 *
815 * @param addr IPv6 address
816 *
817 * @return True if address was found, False otherwise.
818 */
net_ipv6_is_my_addr(struct net_in6_addr * addr)819 static inline bool net_ipv6_is_my_addr(struct net_in6_addr *addr)
820 {
821 return net_if_ipv6_addr_lookup(addr, NULL) != NULL;
822 }
823
824 extern struct net_if_mcast_addr *net_if_ipv6_maddr_lookup(
825 const struct net_in6_addr *addr, struct net_if **iface);
826
827 /**
828 * @brief Check if IPv6 multicast address is found in one of the
829 * network interfaces.
830 *
831 * @param maddr Multicast IPv6 address
832 *
833 * @return True if address was found, False otherwise.
834 */
net_ipv6_is_my_maddr(struct net_in6_addr * maddr)835 static inline bool net_ipv6_is_my_maddr(struct net_in6_addr *maddr)
836 {
837 return net_if_ipv6_maddr_lookup(maddr, NULL) != NULL;
838 }
839
840 /**
841 * @brief Check if two IPv6 addresses are same when compared after prefix mask.
842 *
843 * @param addr1 First IPv6 address.
844 * @param addr2 Second IPv6 address.
845 * @param length Prefix length (max length is 128).
846 *
847 * @return True if IPv6 prefixes are the same, False otherwise.
848 */
net_ipv6_is_prefix(const uint8_t * addr1,const uint8_t * addr2,uint8_t length)849 static inline bool net_ipv6_is_prefix(const uint8_t *addr1,
850 const uint8_t *addr2,
851 uint8_t length)
852 {
853 uint8_t bits = 128 - length;
854 uint8_t bytes = length / 8U;
855 uint8_t remain = bits % 8;
856 uint8_t mask;
857
858 if (length > 128) {
859 return false;
860 }
861
862 if (memcmp(addr1, addr2, bytes)) {
863 return false;
864 }
865
866 if (!remain) {
867 /* No remaining bits, the prefixes are the same as first
868 * bytes are the same.
869 */
870 return true;
871 }
872
873 /* Create a mask that has remaining most significant bits set */
874 mask = (uint8_t)((0xff << (8 - remain)) ^ 0xff) << remain;
875
876 return (addr1[bytes] & mask) == (addr2[bytes] & mask);
877 }
878
879
880 /**
881 * @brief Get the IPv6 network address via the unicast address and the prefix mask.
882 *
883 * @param inaddr Unicast IPv6 address.
884 * @param outaddr Prefix masked IPv6 address (network address).
885 * @param prefix_len Prefix length (max length is 128).
886 */
net_ipv6_addr_prefix_mask(const uint8_t * inaddr,uint8_t * outaddr,uint8_t prefix_len)887 static inline void net_ipv6_addr_prefix_mask(const uint8_t *inaddr,
888 uint8_t *outaddr,
889 uint8_t prefix_len)
890 {
891 uint8_t bits = 128 - prefix_len;
892 uint8_t bytes = prefix_len / 8U;
893 uint8_t remain = bits % 8;
894 uint8_t mask;
895
896 memset(outaddr, 0, 16U);
897 memcpy(outaddr, inaddr, bytes);
898
899 if (!remain) {
900 /* No remaining bits, the prefixes are the same as first
901 * bytes are the same.
902 */
903 return;
904 }
905
906 /* Create a mask that has remaining most significant bits set */
907 mask = (uint8_t)((0xff << (8 - remain)) ^ 0xff) << remain;
908 outaddr[bytes] = inaddr[bytes] & mask;
909 }
910
911 /** @cond INTERNAL_HIDDEN */
net_ipv4_is_addr_loopback_raw(const uint8_t * addr)912 static inline bool net_ipv4_is_addr_loopback_raw(const uint8_t *addr)
913 {
914 return addr[0] == 127U;
915 }
916 /** @endcond */
917
918 /**
919 * @brief Check if the IPv4 address is a loopback address (127.0.0.0/8).
920 *
921 * @param addr IPv4 address
922 *
923 * @return True if address is a loopback address, False otherwise.
924 */
net_ipv4_is_addr_loopback(const struct net_in_addr * addr)925 static inline bool net_ipv4_is_addr_loopback(const struct net_in_addr *addr)
926 {
927 return net_ipv4_is_addr_loopback_raw(addr->s4_addr);
928 }
929
930 /** @cond INTERNAL_HIDDEN */
net_ipv4_is_addr_unspecified_raw(const uint8_t * addr)931 static inline bool net_ipv4_is_addr_unspecified_raw(const uint8_t *addr)
932 {
933 return UNALIGNED_GET((uint32_t *)addr) == 0;
934 }
935 /** @endcond */
936
937 /**
938 * @brief Check if the IPv4 address is unspecified (all bits zero)
939 *
940 * @param addr IPv4 address.
941 *
942 * @return True if the address is unspecified, false otherwise.
943 */
net_ipv4_is_addr_unspecified(const struct net_in_addr * addr)944 static inline bool net_ipv4_is_addr_unspecified(const struct net_in_addr *addr)
945 {
946 return net_ipv4_is_addr_unspecified_raw(addr->s4_addr);
947 }
948
949 /** @cond INTERNAL_HIDDEN */
net_ipv4_is_addr_mcast_raw(const uint8_t * addr)950 static inline bool net_ipv4_is_addr_mcast_raw(const uint8_t *addr)
951 {
952 return (net_ntohl(UNALIGNED_GET((uint32_t *)addr)) & 0xF0000000) == 0xE0000000;
953 }
954 /** @endcond */
955
956 /**
957 * @brief Check if the IPv4 address is a multicast address.
958 *
959 * @param addr IPv4 address
960 *
961 * @return True if address is multicast address, False otherwise.
962 */
net_ipv4_is_addr_mcast(const struct net_in_addr * addr)963 static inline bool net_ipv4_is_addr_mcast(const struct net_in_addr *addr)
964 {
965 return net_ipv4_is_addr_mcast_raw(addr->s4_addr);
966 }
967
968 /** @cond INTERNAL_HIDDEN */
net_ipv4_is_ll_addr_raw(const uint8_t * addr)969 static inline bool net_ipv4_is_ll_addr_raw(const uint8_t *addr)
970 {
971 return (net_ntohl(UNALIGNED_GET((uint32_t *)addr)) & 0xFFFF0000) == 0xA9FE0000;
972 }
973 /** @endcond */
974
975 /**
976 * @brief Check if the given IPv4 address is a link local address.
977 *
978 * @param addr A valid pointer on an IPv4 address
979 *
980 * @return True if it is, false otherwise.
981 */
net_ipv4_is_ll_addr(const struct net_in_addr * addr)982 static inline bool net_ipv4_is_ll_addr(const struct net_in_addr *addr)
983 {
984 return net_ipv4_is_ll_addr_raw(addr->s4_addr);
985 }
986
987 /**
988 * @brief Check if the given IPv4 address is from a private address range.
989 *
990 * See https://en.wikipedia.org/wiki/Reserved_IP_addresses for details.
991 *
992 * @param addr A valid pointer on an IPv4 address
993 *
994 * @return True if it is, false otherwise.
995 */
net_ipv4_is_private_addr(const struct net_in_addr * addr)996 static inline bool net_ipv4_is_private_addr(const struct net_in_addr *addr)
997 {
998 uint32_t masked_24, masked_16, masked_12, masked_10, masked_8;
999
1000 masked_24 = net_ntohl(UNALIGNED_GET(&addr->s_addr)) & 0xFFFFFF00;
1001 masked_16 = masked_24 & 0xFFFF0000;
1002 masked_12 = masked_24 & 0xFFF00000;
1003 masked_10 = masked_24 & 0xFFC00000;
1004 masked_8 = masked_24 & 0xFF000000;
1005
1006 return masked_8 == 0x0A000000 || /* 10.0.0.0/8 */
1007 masked_10 == 0x64400000 || /* 100.64.0.0/10 */
1008 masked_12 == 0xAC100000 || /* 172.16.0.0/12 */
1009 masked_16 == 0xC0A80000 || /* 192.168.0.0/16 */
1010 masked_24 == 0xC0000200 || /* 192.0.2.0/24 */
1011 masked_24 == 0xC0336400 || /* 192.51.100.0/24 */
1012 masked_24 == 0xCB007100; /* 203.0.113.0/24 */
1013 }
1014
1015 /**
1016 * @brief Copy an IPv4 or IPv6 address
1017 *
1018 * @param dest Destination IP address.
1019 * @param src Source IP address.
1020 *
1021 * @return Destination address.
1022 */
1023 #define net_ipaddr_copy(dest, src) \
1024 UNALIGNED_PUT(UNALIGNED_GET(src), dest)
1025
1026 /**
1027 * @brief Copy an IPv4 address raw buffer
1028 *
1029 * @param dest Destination IP address.
1030 * @param src Source IP address.
1031 */
net_ipv4_addr_copy_raw(uint8_t * dest,const uint8_t * src)1032 static inline void net_ipv4_addr_copy_raw(uint8_t *dest,
1033 const uint8_t *src)
1034 {
1035 net_ipaddr_copy((struct net_in_addr *)dest, (const struct net_in_addr *)src);
1036 }
1037
1038 /**
1039 * @brief Copy an IPv6 address raw buffer
1040 *
1041 * @param dest Destination IP address.
1042 * @param src Source IP address.
1043 */
net_ipv6_addr_copy_raw(uint8_t * dest,const uint8_t * src)1044 static inline void net_ipv6_addr_copy_raw(uint8_t *dest,
1045 const uint8_t *src)
1046 {
1047 memcpy(dest, src, sizeof(struct net_in6_addr));
1048 }
1049
1050 /**
1051 * @brief Compare two raw IPv4 address buffers
1052 *
1053 * @param addr1 Pointer to IPv4 address buffer.
1054 * @param addr2 Pointer to IPv4 address buffer.
1055 *
1056 * @return True if the addresses are the same, false otherwise.
1057 */
net_ipv4_addr_cmp_raw(const uint8_t * addr1,const uint8_t * addr2)1058 static inline bool net_ipv4_addr_cmp_raw(const uint8_t *addr1,
1059 const uint8_t *addr2)
1060 {
1061 return UNALIGNED_GET((uint32_t *)addr1) == UNALIGNED_GET((uint32_t *)addr2);
1062 }
1063
1064 /**
1065 * @brief Compare two IPv4 addresses
1066 *
1067 * @param addr1 Pointer to IPv4 address.
1068 * @param addr2 Pointer to IPv4 address.
1069 *
1070 * @return True if the addresses are the same, false otherwise.
1071 */
net_ipv4_addr_cmp(const struct net_in_addr * addr1,const struct net_in_addr * addr2)1072 static inline bool net_ipv4_addr_cmp(const struct net_in_addr *addr1,
1073 const struct net_in_addr *addr2)
1074 {
1075 return net_ipv4_addr_cmp_raw(addr1->s4_addr, addr2->s4_addr);
1076 }
1077
1078 /**
1079 * @brief Compare two IPv6 addresses
1080 *
1081 * @param addr1 Pointer to IPv6 address.
1082 * @param addr2 Pointer to IPv6 address.
1083 *
1084 * @return True if the addresses are the same, false otherwise.
1085 */
net_ipv6_addr_cmp(const struct net_in6_addr * addr1,const struct net_in6_addr * addr2)1086 static inline bool net_ipv6_addr_cmp(const struct net_in6_addr *addr1,
1087 const struct net_in6_addr *addr2)
1088 {
1089 return !memcmp(addr1, addr2, sizeof(struct net_in6_addr));
1090 }
1091
1092 /**
1093 * @brief Compare two raw IPv6 address buffers
1094 *
1095 * @param addr1 Pointer to IPv6 address buffer.
1096 * @param addr2 Pointer to IPv6 address buffer.
1097 *
1098 * @return True if the addresses are the same, false otherwise.
1099 */
net_ipv6_addr_cmp_raw(const uint8_t * addr1,const uint8_t * addr2)1100 static inline bool net_ipv6_addr_cmp_raw(const uint8_t *addr1,
1101 const uint8_t *addr2)
1102 {
1103 return net_ipv6_addr_cmp((const struct net_in6_addr *)addr1,
1104 (const struct net_in6_addr *)addr2);
1105 }
1106
1107 /** @cond INTERNAL_HIDDEN */
net_ipv6_is_ll_addr_raw(const uint8_t * addr)1108 static inline bool net_ipv6_is_ll_addr_raw(const uint8_t *addr)
1109 {
1110 return UNALIGNED_GET((uint16_t *)addr) == net_htons(0xFE80);
1111 }
1112 /** @endcond */
1113
1114 /**
1115 * @brief Check if the given IPv6 address is a link local address.
1116 *
1117 * @param addr A valid pointer on an IPv6 address
1118 *
1119 * @return True if it is, false otherwise.
1120 */
net_ipv6_is_ll_addr(const struct net_in6_addr * addr)1121 static inline bool net_ipv6_is_ll_addr(const struct net_in6_addr *addr)
1122 {
1123 return net_ipv6_is_ll_addr_raw(addr->s6_addr);
1124 }
1125
1126 /**
1127 * @brief Check if the given IPv6 address is a site local address.
1128 *
1129 * @param addr A valid pointer on an IPv6 address
1130 *
1131 * @return True if it is, false otherwise.
1132 */
net_ipv6_is_sl_addr(const struct net_in6_addr * addr)1133 static inline bool net_ipv6_is_sl_addr(const struct net_in6_addr *addr)
1134 {
1135 return UNALIGNED_GET(&addr->s6_addr16[0]) == net_htons(0xFEC0);
1136 }
1137
1138
1139 /**
1140 * @brief Check if the given IPv6 address is a unique local address.
1141 *
1142 * @param addr A valid pointer on an IPv6 address
1143 *
1144 * @return True if it is, false otherwise.
1145 */
net_ipv6_is_ula_addr(const struct net_in6_addr * addr)1146 static inline bool net_ipv6_is_ula_addr(const struct net_in6_addr *addr)
1147 {
1148 return addr->s6_addr[0] == 0xFD;
1149 }
1150
1151 /**
1152 * @brief Check if the given IPv6 address is a global address.
1153 *
1154 * @param addr A valid pointer on an IPv6 address
1155 *
1156 * @return True if it is, false otherwise.
1157 */
net_ipv6_is_global_addr(const struct net_in6_addr * addr)1158 static inline bool net_ipv6_is_global_addr(const struct net_in6_addr *addr)
1159 {
1160 return (addr->s6_addr[0] & 0xE0) == 0x20;
1161 }
1162
1163 /**
1164 * @brief Check if the given IPv6 address is from a private/local address range.
1165 *
1166 * See https://en.wikipedia.org/wiki/Reserved_IP_addresses for details.
1167 *
1168 * @param addr A valid pointer on an IPv6 address
1169 *
1170 * @return True if it is, false otherwise.
1171 */
net_ipv6_is_private_addr(const struct net_in6_addr * addr)1172 static inline bool net_ipv6_is_private_addr(const struct net_in6_addr *addr)
1173 {
1174 uint32_t masked_32, masked_7;
1175
1176 masked_32 = net_ntohl(UNALIGNED_GET(&addr->s6_addr32[0]));
1177 masked_7 = masked_32 & 0xfc000000;
1178
1179 return masked_32 == 0x20010db8 || /* 2001:db8::/32 */
1180 masked_7 == 0xfc000000; /* fc00::/7 */
1181 }
1182
1183 /**
1184 * @brief Return pointer to any (all bits zeros) IPv6 address.
1185 *
1186 * @return Any IPv6 address.
1187 */
1188 const struct net_in6_addr *net_ipv6_unspecified_address(void);
1189
1190 /**
1191 * @brief Return pointer to any (all bits zeros) IPv4 address.
1192 *
1193 * @return Any IPv4 address.
1194 */
1195 const struct net_in_addr *net_ipv4_unspecified_address(void);
1196
1197 /**
1198 * @brief Return pointer to broadcast (all bits ones) IPv4 address.
1199 *
1200 * @return Broadcast IPv4 address.
1201 */
1202 const struct net_in_addr *net_ipv4_broadcast_address(void);
1203
1204 struct net_if;
1205 extern bool net_if_ipv4_addr_mask_cmp(struct net_if *iface,
1206 const struct net_in_addr *addr);
1207
1208 /**
1209 * @brief Check if the given address belongs to same subnet that
1210 * has been configured for the interface.
1211 *
1212 * @param iface A valid pointer on an interface
1213 * @param addr IPv4 address
1214 *
1215 * @return True if address is in same subnet, false otherwise.
1216 */
net_ipv4_addr_mask_cmp(struct net_if * iface,const struct net_in_addr * addr)1217 static inline bool net_ipv4_addr_mask_cmp(struct net_if *iface,
1218 const struct net_in_addr *addr)
1219 {
1220 return net_if_ipv4_addr_mask_cmp(iface, addr);
1221 }
1222
1223 /** @cond INTERNAL_HIDDEN */
1224 extern bool net_if_ipv4_is_addr_bcast_raw(struct net_if *iface,
1225 const uint8_t *addr);
1226
1227 #if defined(CONFIG_NET_NATIVE_IPV4)
net_ipv4_is_addr_bcast_raw(struct net_if * iface,const uint8_t * addr)1228 static inline bool net_ipv4_is_addr_bcast_raw(struct net_if *iface,
1229 const uint8_t *addr)
1230 {
1231 if (net_ipv4_addr_cmp_raw(addr, net_ipv4_broadcast_address()->s4_addr)) {
1232 return true;
1233 }
1234
1235 return net_if_ipv4_is_addr_bcast_raw(iface, addr);
1236 }
1237 #else
net_ipv4_is_addr_bcast_raw(struct net_if * iface,const uint8_t * addr)1238 static inline bool net_ipv4_is_addr_bcast_raw(struct net_if *iface,
1239 const uint8_t *addr)
1240 {
1241 ARG_UNUSED(iface);
1242 ARG_UNUSED(addr);
1243
1244 return false;
1245 }
1246 #endif
1247 /** @endcond */
1248
1249 extern bool net_if_ipv4_is_addr_bcast(struct net_if *iface,
1250 const struct net_in_addr *addr);
1251
1252 /**
1253 * @brief Check if the given IPv4 address is a broadcast address.
1254 *
1255 * @param iface Interface to use. Must be a valid pointer to an interface.
1256 * @param addr IPv4 address
1257 *
1258 * @return True if address is a broadcast address, false otherwise.
1259 */
1260 #if defined(CONFIG_NET_NATIVE_IPV4)
net_ipv4_is_addr_bcast(struct net_if * iface,const struct net_in_addr * addr)1261 static inline bool net_ipv4_is_addr_bcast(struct net_if *iface,
1262 const struct net_in_addr *addr)
1263 {
1264 if (net_ipv4_addr_cmp(addr, net_ipv4_broadcast_address())) {
1265 return true;
1266 }
1267
1268 return net_if_ipv4_is_addr_bcast(iface, addr);
1269 }
1270 #else
net_ipv4_is_addr_bcast(struct net_if * iface,const struct net_in_addr * addr)1271 static inline bool net_ipv4_is_addr_bcast(struct net_if *iface,
1272 const struct net_in_addr *addr)
1273 {
1274 ARG_UNUSED(iface);
1275 ARG_UNUSED(addr);
1276
1277 return false;
1278 }
1279 #endif
1280
1281 /** @cond INTERNAL_HIDDEN */
1282 extern struct net_if_addr *net_if_ipv4_addr_lookup_raw(const uint8_t *addr,
1283 struct net_if **ret);
1284
net_ipv4_is_my_addr_raw(const uint8_t * addr)1285 static inline bool net_ipv4_is_my_addr_raw(const uint8_t *addr)
1286 {
1287 bool ret;
1288
1289 ret = net_if_ipv4_addr_lookup_raw(addr, NULL) != NULL;
1290 if (!ret) {
1291 ret = net_ipv4_is_addr_bcast_raw(NULL, addr);
1292 }
1293
1294 return ret;
1295 }
1296 /** @endcond */
1297
1298 extern struct net_if_addr *net_if_ipv4_addr_lookup(const struct net_in_addr *addr,
1299 struct net_if **iface);
1300
1301 /**
1302 * @brief Check if the IPv4 address is assigned to any network interface
1303 * in the system.
1304 *
1305 * @param addr A valid pointer on an IPv4 address
1306 *
1307 * @return True if IPv4 address is found in one of the network interfaces,
1308 * False otherwise.
1309 */
net_ipv4_is_my_addr(const struct net_in_addr * addr)1310 static inline bool net_ipv4_is_my_addr(const struct net_in_addr *addr)
1311 {
1312 bool ret;
1313
1314 ret = net_if_ipv4_addr_lookup(addr, NULL) != NULL;
1315 if (!ret) {
1316 ret = net_ipv4_is_addr_bcast(NULL, addr);
1317 }
1318
1319 return ret;
1320 }
1321
1322 /** @cond INTERNAL_HIDDEN */
net_ipv6_is_addr_unspecified_raw(const uint8_t * addr)1323 static inline bool net_ipv6_is_addr_unspecified_raw(const uint8_t *addr)
1324 {
1325 return UNALIGNED_GET((uint32_t *)addr) == 0 &&
1326 UNALIGNED_GET((uint32_t *)addr + 1) == 0 &&
1327 UNALIGNED_GET((uint32_t *)addr + 2) == 0 &&
1328 UNALIGNED_GET((uint32_t *)addr + 3) == 0;
1329 }
1330 /** @endcond */
1331
1332 /**
1333 * @brief Check if the IPv6 address is unspecified (all bits zero)
1334 *
1335 * @param addr IPv6 address.
1336 *
1337 * @return True if the address is unspecified, false otherwise.
1338 */
net_ipv6_is_addr_unspecified(const struct net_in6_addr * addr)1339 static inline bool net_ipv6_is_addr_unspecified(const struct net_in6_addr *addr)
1340 {
1341 return net_ipv6_is_addr_unspecified_raw(addr->s6_addr);
1342 }
1343
1344 /** @cond INTERNAL_HIDDEN */
net_ipv6_is_addr_solicited_node_raw(const uint8_t * addr)1345 static inline bool net_ipv6_is_addr_solicited_node_raw(const uint8_t *addr)
1346 {
1347 return UNALIGNED_GET((uint32_t *)addr) == net_htonl(0xff020000) &&
1348 UNALIGNED_GET((uint32_t *)addr + 1) == 0x00000000 &&
1349 UNALIGNED_GET((uint32_t *)addr + 2) == net_htonl(0x00000001) &&
1350 ((UNALIGNED_GET((uint32_t *)addr + 3) & net_htonl(0xff000000)) ==
1351 net_htonl(0xff000000));
1352 }
1353 /** @endcond */
1354
1355 /**
1356 * @brief Check if the IPv6 address is solicited node multicast address
1357 * FF02:0:0:0:0:1:FFXX:XXXX defined in RFC 3513
1358 *
1359 * @param addr IPv6 address.
1360 *
1361 * @return True if the address is solicited node address, false otherwise.
1362 */
net_ipv6_is_addr_solicited_node(const struct net_in6_addr * addr)1363 static inline bool net_ipv6_is_addr_solicited_node(const struct net_in6_addr *addr)
1364 {
1365 return net_ipv6_is_addr_solicited_node_raw(addr->s6_addr);
1366 }
1367
1368 /** @cond INTERNAL_HIDDEN */
net_ipv6_is_addr_mcast_scope_raw(const uint8_t * addr,int scope)1369 static inline bool net_ipv6_is_addr_mcast_scope_raw(const uint8_t *addr,
1370 int scope)
1371 {
1372 return (addr[0] == 0xff) && ((addr[1] & 0xF) == scope);
1373 }
1374 /** @endcond */
1375
1376 /** @cond INTERNAL_HIDDEN */
net_ipv6_get_addr_mcast_scope_raw(const uint8_t * addr)1377 static inline int net_ipv6_get_addr_mcast_scope_raw(const uint8_t *addr)
1378 {
1379 if (addr[0] == 0xff) {
1380 return (addr[1] & 0xF);
1381 }
1382
1383 return -1;
1384 }
1385 /** @endcond */
1386
1387 /**
1388 * @brief Check if the IPv6 address is a given scope multicast
1389 * address (FFyx::).
1390 *
1391 * @param addr IPv6 address
1392 * @param scope Scope to check
1393 *
1394 * @return True if the address is in given scope multicast address,
1395 * false otherwise.
1396 */
net_ipv6_is_addr_mcast_scope(const struct net_in6_addr * addr,int scope)1397 static inline bool net_ipv6_is_addr_mcast_scope(const struct net_in6_addr *addr,
1398 int scope)
1399 {
1400 return net_ipv6_is_addr_mcast_scope_raw(addr->s6_addr, scope);
1401 }
1402
1403 /**
1404 * @brief Check if the IPv6 addresses have the same multicast scope (FFyx::).
1405 *
1406 * @param addr_1 IPv6 address 1
1407 * @param addr_2 IPv6 address 2
1408 *
1409 * @return True if both addresses have same multicast scope,
1410 * false otherwise.
1411 */
net_ipv6_is_same_mcast_scope(const struct net_in6_addr * addr_1,const struct net_in6_addr * addr_2)1412 static inline bool net_ipv6_is_same_mcast_scope(const struct net_in6_addr *addr_1,
1413 const struct net_in6_addr *addr_2)
1414 {
1415 return (addr_1->s6_addr[0] == 0xff) && (addr_2->s6_addr[0] == 0xff) &&
1416 (addr_1->s6_addr[1] == addr_2->s6_addr[1]);
1417 }
1418
1419 /**
1420 * @brief Returns the scope of the given IPv6 address.
1421 *
1422 * @param addr IPv6 address
1423 *
1424 * @return Scope of the address, -1 if address is not multicast.
1425 */
net_ipv6_get_addr_mcast_scope(const struct net_in6_addr * addr)1426 static inline int net_ipv6_get_addr_mcast_scope(const struct net_in6_addr *addr)
1427 {
1428 return net_ipv6_get_addr_mcast_scope_raw(addr->s6_addr);
1429 }
1430
1431 /** @cond INTERNAL_HIDDEN */
net_ipv6_is_addr_mcast_iface_raw(const uint8_t * addr)1432 static inline bool net_ipv6_is_addr_mcast_iface_raw(const uint8_t *addr)
1433 {
1434 return net_ipv6_is_addr_mcast_scope_raw(addr, 0x01);
1435 }
1436
net_ipv6_is_addr_mcast_link_raw(const uint8_t * addr)1437 static inline bool net_ipv6_is_addr_mcast_link_raw(const uint8_t *addr)
1438 {
1439 return net_ipv6_is_addr_mcast_scope_raw(addr, 0x02);
1440 }
1441
net_ipv6_is_addr_mcast_mesh_raw(const uint8_t * addr)1442 static inline bool net_ipv6_is_addr_mcast_mesh_raw(const uint8_t *addr)
1443 {
1444 return net_ipv6_is_addr_mcast_scope_raw(addr, 0x03);
1445 }
1446
net_ipv6_is_addr_mcast_site_raw(const uint8_t * addr)1447 static inline bool net_ipv6_is_addr_mcast_site_raw(const uint8_t *addr)
1448 {
1449 return net_ipv6_is_addr_mcast_scope_raw(addr, 0x05);
1450 }
1451
net_ipv6_is_addr_mcast_org_raw(const uint8_t * addr)1452 static inline bool net_ipv6_is_addr_mcast_org_raw(const uint8_t *addr)
1453 {
1454 return net_ipv6_is_addr_mcast_scope_raw(addr, 0x08);
1455 }
1456 /** @endcond */
1457
1458 /**
1459 * @brief Check if the IPv6 address is a global multicast address (FFxE::/16).
1460 *
1461 * @param addr IPv6 address.
1462 *
1463 * @return True if the address is global multicast address, false otherwise.
1464 */
net_ipv6_is_addr_mcast_global(const struct net_in6_addr * addr)1465 static inline bool net_ipv6_is_addr_mcast_global(const struct net_in6_addr *addr)
1466 {
1467 return net_ipv6_is_addr_mcast_scope(addr, 0x0e);
1468 }
1469
1470 /**
1471 * @brief Check if the IPv6 address is a interface scope multicast
1472 * address (FFx1::).
1473 *
1474 * @param addr IPv6 address.
1475 *
1476 * @return True if the address is a interface scope multicast address,
1477 * false otherwise.
1478 */
net_ipv6_is_addr_mcast_iface(const struct net_in6_addr * addr)1479 static inline bool net_ipv6_is_addr_mcast_iface(const struct net_in6_addr *addr)
1480 {
1481 return net_ipv6_is_addr_mcast_scope(addr, 0x01);
1482 }
1483
1484 /**
1485 * @brief Check if the IPv6 address is a link local scope multicast
1486 * address (FFx2::).
1487 *
1488 * @param addr IPv6 address.
1489 *
1490 * @return True if the address is a link local scope multicast address,
1491 * false otherwise.
1492 */
net_ipv6_is_addr_mcast_link(const struct net_in6_addr * addr)1493 static inline bool net_ipv6_is_addr_mcast_link(const struct net_in6_addr *addr)
1494 {
1495 return net_ipv6_is_addr_mcast_scope(addr, 0x02);
1496 }
1497
1498 /**
1499 * @brief Check if the IPv6 address is a mesh-local scope multicast
1500 * address (FFx3::).
1501 *
1502 * @param addr IPv6 address.
1503 *
1504 * @return True if the address is a mesh-local scope multicast address,
1505 * false otherwise.
1506 */
net_ipv6_is_addr_mcast_mesh(const struct net_in6_addr * addr)1507 static inline bool net_ipv6_is_addr_mcast_mesh(const struct net_in6_addr *addr)
1508 {
1509 return net_ipv6_is_addr_mcast_scope(addr, 0x03);
1510 }
1511
1512 /**
1513 * @brief Check if the IPv6 address is a site scope multicast
1514 * address (FFx5::).
1515 *
1516 * @param addr IPv6 address.
1517 *
1518 * @return True if the address is a site scope multicast address,
1519 * false otherwise.
1520 */
net_ipv6_is_addr_mcast_site(const struct net_in6_addr * addr)1521 static inline bool net_ipv6_is_addr_mcast_site(const struct net_in6_addr *addr)
1522 {
1523 return net_ipv6_is_addr_mcast_scope(addr, 0x05);
1524 }
1525
1526 /**
1527 * @brief Check if the IPv6 address is an organization scope multicast
1528 * address (FFx8::).
1529 *
1530 * @param addr IPv6 address.
1531 *
1532 * @return True if the address is an organization scope multicast address,
1533 * false otherwise.
1534 */
net_ipv6_is_addr_mcast_org(const struct net_in6_addr * addr)1535 static inline bool net_ipv6_is_addr_mcast_org(const struct net_in6_addr *addr)
1536 {
1537 return net_ipv6_is_addr_mcast_scope(addr, 0x08);
1538 }
1539
1540 /** @cond INTERNAL_HIDDEN */
net_ipv6_is_addr_mcast_group_raw(const uint8_t * addr,const uint8_t * group)1541 static inline bool net_ipv6_is_addr_mcast_group_raw(const uint8_t *addr,
1542 const uint8_t *group)
1543 {
1544 return UNALIGNED_GET((uint16_t *)addr + 1) == UNALIGNED_GET((uint16_t *)group + 1) &&
1545 UNALIGNED_GET((uint32_t *)addr + 1) == UNALIGNED_GET((uint32_t *)group + 1) &&
1546 UNALIGNED_GET((uint32_t *)addr + 2) == UNALIGNED_GET((uint32_t *)group + 2) &&
1547 UNALIGNED_GET((uint32_t *)addr + 3) == UNALIGNED_GET((uint32_t *)group + 3);
1548 }
1549 /** @endcond */
1550
1551 /**
1552 * @brief Check if the IPv6 address belongs to certain multicast group
1553 *
1554 * @param addr IPv6 address.
1555 * @param group Group id IPv6 address, the values must be in network
1556 * byte order
1557 *
1558 * @return True if the IPv6 multicast address belongs to given multicast
1559 * group, false otherwise.
1560 */
net_ipv6_is_addr_mcast_group(const struct net_in6_addr * addr,const struct net_in6_addr * group)1561 static inline bool net_ipv6_is_addr_mcast_group(const struct net_in6_addr *addr,
1562 const struct net_in6_addr *group)
1563 {
1564 return net_ipv6_is_addr_mcast_group_raw(addr->s6_addr, group->s6_addr);
1565 }
1566
1567 /** @cond INTERNAL_HIDDEN */
net_ipv6_is_addr_mcast_all_nodes_group_raw(const uint8_t * addr)1568 static inline bool net_ipv6_is_addr_mcast_all_nodes_group_raw(const uint8_t *addr)
1569 {
1570 static const uint8_t all_nodes_mcast_group[NET_IPV6_ADDR_SIZE] = {
1571 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1572 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1573 };
1574
1575 return net_ipv6_is_addr_mcast_group_raw(addr, all_nodes_mcast_group);
1576 }
1577 /** @endcond */
1578
1579 /**
1580 * @brief Check if the IPv6 address belongs to the all nodes multicast group
1581 *
1582 * @param addr IPv6 address
1583 *
1584 * @return True if the IPv6 multicast address belongs to the all nodes multicast
1585 * group, false otherwise
1586 */
1587 static inline bool
net_ipv6_is_addr_mcast_all_nodes_group(const struct net_in6_addr * addr)1588 net_ipv6_is_addr_mcast_all_nodes_group(const struct net_in6_addr *addr)
1589 {
1590 return net_ipv6_is_addr_mcast_all_nodes_group_raw(addr->s6_addr);
1591 }
1592
1593 /**
1594 * @brief Check if the IPv6 address is a interface scope all nodes multicast
1595 * address (FF01::1).
1596 *
1597 * @param addr IPv6 address.
1598 *
1599 * @return True if the address is a interface scope all nodes multicast address,
1600 * false otherwise.
1601 */
1602 static inline bool
net_ipv6_is_addr_mcast_iface_all_nodes(const struct net_in6_addr * addr)1603 net_ipv6_is_addr_mcast_iface_all_nodes(const struct net_in6_addr *addr)
1604 {
1605 return net_ipv6_is_addr_mcast_iface(addr) &&
1606 net_ipv6_is_addr_mcast_all_nodes_group(addr);
1607 }
1608
1609 /** @cond INTERNAL_HIDDEN */
net_ipv6_is_addr_mcast_link_all_nodes_raw(const uint8_t * addr)1610 static inline bool net_ipv6_is_addr_mcast_link_all_nodes_raw(const uint8_t *addr)
1611 {
1612 return net_ipv6_is_addr_mcast_link_raw(addr) &&
1613 net_ipv6_is_addr_mcast_all_nodes_group_raw(addr);
1614 }
1615 /** @endcond */
1616
1617 /**
1618 * @brief Check if the IPv6 address is a link local scope all nodes multicast
1619 * address (FF02::1).
1620 *
1621 * @param addr IPv6 address.
1622 *
1623 * @return True if the address is a link local scope all nodes multicast
1624 * address, false otherwise.
1625 */
1626 static inline bool
net_ipv6_is_addr_mcast_link_all_nodes(const struct net_in6_addr * addr)1627 net_ipv6_is_addr_mcast_link_all_nodes(const struct net_in6_addr *addr)
1628 {
1629 return net_ipv6_is_addr_mcast_link(addr) &&
1630 net_ipv6_is_addr_mcast_all_nodes_group(addr);
1631 }
1632
1633 /**
1634 * @brief Create solicited node IPv6 multicast address
1635 * FF02:0:0:0:0:1:FFXX:XXXX defined in RFC 3513
1636 *
1637 * @param src IPv6 address.
1638 * @param dst IPv6 address.
1639 */
1640 static inline
net_ipv6_addr_create_solicited_node(const struct net_in6_addr * src,struct net_in6_addr * dst)1641 void net_ipv6_addr_create_solicited_node(const struct net_in6_addr *src,
1642 struct net_in6_addr *dst)
1643 {
1644 dst->s6_addr[0] = 0xFF;
1645 dst->s6_addr[1] = 0x02;
1646 UNALIGNED_PUT(0, &dst->s6_addr16[1]);
1647 UNALIGNED_PUT(0, &dst->s6_addr16[2]);
1648 UNALIGNED_PUT(0, &dst->s6_addr16[3]);
1649 UNALIGNED_PUT(0, &dst->s6_addr16[4]);
1650 dst->s6_addr[10] = 0U;
1651 dst->s6_addr[11] = 0x01;
1652 dst->s6_addr[12] = 0xFF;
1653 dst->s6_addr[13] = src->s6_addr[13];
1654 UNALIGNED_PUT(UNALIGNED_GET(&src->s6_addr16[7]), &dst->s6_addr16[7]);
1655 }
1656
1657 /** @brief Construct an IPv6 address from eight 16-bit words.
1658 *
1659 * @param addr IPv6 address
1660 * @param addr0 16-bit word which is part of the address
1661 * @param addr1 16-bit word which is part of the address
1662 * @param addr2 16-bit word which is part of the address
1663 * @param addr3 16-bit word which is part of the address
1664 * @param addr4 16-bit word which is part of the address
1665 * @param addr5 16-bit word which is part of the address
1666 * @param addr6 16-bit word which is part of the address
1667 * @param addr7 16-bit word which is part of the address
1668 */
net_ipv6_addr_create(struct net_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)1669 static inline void net_ipv6_addr_create(struct net_in6_addr *addr,
1670 uint16_t addr0, uint16_t addr1,
1671 uint16_t addr2, uint16_t addr3,
1672 uint16_t addr4, uint16_t addr5,
1673 uint16_t addr6, uint16_t addr7)
1674 {
1675 UNALIGNED_PUT(net_htons(addr0), &addr->s6_addr16[0]);
1676 UNALIGNED_PUT(net_htons(addr1), &addr->s6_addr16[1]);
1677 UNALIGNED_PUT(net_htons(addr2), &addr->s6_addr16[2]);
1678 UNALIGNED_PUT(net_htons(addr3), &addr->s6_addr16[3]);
1679 UNALIGNED_PUT(net_htons(addr4), &addr->s6_addr16[4]);
1680 UNALIGNED_PUT(net_htons(addr5), &addr->s6_addr16[5]);
1681 UNALIGNED_PUT(net_htons(addr6), &addr->s6_addr16[6]);
1682 UNALIGNED_PUT(net_htons(addr7), &addr->s6_addr16[7]);
1683 }
1684
1685 /**
1686 * @brief Create link local allnodes multicast IPv6 address
1687 *
1688 * @param addr IPv6 address
1689 */
net_ipv6_addr_create_ll_allnodes_mcast(struct net_in6_addr * addr)1690 static inline void net_ipv6_addr_create_ll_allnodes_mcast(struct net_in6_addr *addr)
1691 {
1692 net_ipv6_addr_create(addr, 0xff02, 0, 0, 0, 0, 0, 0, 0x0001);
1693 }
1694
1695 /**
1696 * @brief Create link local allrouters multicast IPv6 address
1697 *
1698 * @param addr IPv6 address
1699 */
net_ipv6_addr_create_ll_allrouters_mcast(struct net_in6_addr * addr)1700 static inline void net_ipv6_addr_create_ll_allrouters_mcast(struct net_in6_addr *addr)
1701 {
1702 net_ipv6_addr_create(addr, 0xff02, 0, 0, 0, 0, 0, 0, 0x0002);
1703 }
1704
1705 /**
1706 * @brief Create IPv4 mapped IPv6 address
1707 *
1708 * @param addr4 IPv4 address
1709 * @param addr6 IPv6 address to be created
1710 */
net_ipv6_addr_create_v4_mapped(const struct net_in_addr * addr4,struct net_in6_addr * addr6)1711 static inline void net_ipv6_addr_create_v4_mapped(const struct net_in_addr *addr4,
1712 struct net_in6_addr *addr6)
1713 {
1714 net_ipv6_addr_create(addr6, 0, 0, 0, 0, 0, 0xffff,
1715 net_ntohs(addr4->s4_addr16[0]),
1716 net_ntohs(addr4->s4_addr16[1]));
1717 }
1718
1719 /**
1720 * @brief Is the IPv6 address an IPv4 mapped one. The v4 mapped addresses
1721 * look like \::ffff:a.b.c.d
1722 *
1723 * @param addr IPv6 address
1724 *
1725 * @return True if IPv6 address is a IPv4 mapped address, False otherwise.
1726 */
net_ipv6_addr_is_v4_mapped(const struct net_in6_addr * addr)1727 static inline bool net_ipv6_addr_is_v4_mapped(const struct net_in6_addr *addr)
1728 {
1729 if (UNALIGNED_GET(&addr->s6_addr32[0]) == 0 &&
1730 UNALIGNED_GET(&addr->s6_addr32[1]) == 0 &&
1731 UNALIGNED_GET(&addr->s6_addr16[5]) == 0xffff) {
1732 return true;
1733 }
1734
1735 return false;
1736 }
1737
1738 /**
1739 * @brief Generate IPv6 address using a prefix and interface identifier.
1740 * Interface identifier is either generated from EUI-64 (MAC) defined
1741 * in RFC 4291 or from randomized value defined in RFC 7217.
1742 *
1743 * @param iface Network interface
1744 * @param prefix IPv6 prefix, can be left out in which case fe80::/64 is used
1745 * @param network_id Network identifier (for example SSID in WLAN), this is
1746 * optional can be set to NULL
1747 * @param network_id_len Network identifier length, if set to 0 then the
1748 * network id is ignored.
1749 * @param dad_counter Duplicate Address Detection counter value, can be set to 0
1750 * if it is not known.
1751 * @param addr IPv6 address
1752 * @param lladdr Link local address
1753 *
1754 * @return 0 if ok, < 0 if error
1755 */
1756 int net_ipv6_addr_generate_iid(struct net_if *iface,
1757 const struct net_in6_addr *prefix,
1758 uint8_t *network_id, size_t network_id_len,
1759 uint8_t dad_counter,
1760 struct net_in6_addr *addr,
1761 struct net_linkaddr *lladdr);
1762
1763 /**
1764 * @brief Create IPv6 address interface identifier.
1765 *
1766 * @param addr IPv6 address
1767 * @param lladdr Link local address
1768 */
net_ipv6_addr_create_iid(struct net_in6_addr * addr,struct net_linkaddr * lladdr)1769 static inline void net_ipv6_addr_create_iid(struct net_in6_addr *addr,
1770 struct net_linkaddr *lladdr)
1771 {
1772 (void)net_ipv6_addr_generate_iid(NULL, NULL, NULL, 0, 0, addr, lladdr);
1773 }
1774
1775 /** @cond INTERNAL_HIDDEN */
net_ipv6_addr_based_on_ll_raw(const uint8_t * addr,const struct net_linkaddr * lladdr)1776 static inline bool net_ipv6_addr_based_on_ll_raw(const uint8_t *addr,
1777 const struct net_linkaddr *lladdr)
1778 {
1779 if (addr == NULL || lladdr == NULL) {
1780 return false;
1781 }
1782
1783 switch (lladdr->len) {
1784 case 2:
1785 if (!memcmp(&addr[14], lladdr->addr, lladdr->len) &&
1786 addr[8] == 0U &&
1787 addr[9] == 0U &&
1788 addr[10] == 0U &&
1789 addr[11] == 0xff &&
1790 addr[12] == 0xfe) {
1791 return true;
1792 }
1793
1794 break;
1795 case 6:
1796 if (lladdr->type == NET_LINK_ETHERNET) {
1797 if (!memcmp(&addr[9], &lladdr->addr[1], 2) &&
1798 !memcmp(&addr[13], &lladdr->addr[3], 3) &&
1799 addr[11] == 0xff &&
1800 addr[12] == 0xfe &&
1801 (addr[8] ^ 0x02) == lladdr->addr[0]) {
1802 return true;
1803 }
1804 }
1805
1806 break;
1807 case 8:
1808 if (sizeof(lladdr->addr) < 8) {
1809 return false;
1810 }
1811
1812 if (!memcmp(&addr[9], &lladdr->addr[1],
1813 lladdr->len - 1) &&
1814 (addr[8] ^ 0x02) == lladdr->addr[0]) {
1815 return true;
1816 }
1817
1818 break;
1819 default:
1820 return false;
1821 }
1822
1823 return false;
1824 }
1825 /** @endcond */
1826
1827 /**
1828 * @brief Check if given address is based on link layer address
1829 *
1830 * @return True if it is, False otherwise
1831 */
net_ipv6_addr_based_on_ll(const struct net_in6_addr * addr,const struct net_linkaddr * lladdr)1832 static inline bool net_ipv6_addr_based_on_ll(const struct net_in6_addr *addr,
1833 const struct net_linkaddr *lladdr)
1834 {
1835 if (addr == NULL || lladdr == NULL) {
1836 return false;
1837 }
1838
1839 return net_ipv6_addr_based_on_ll_raw(addr->s6_addr, lladdr);
1840 }
1841
1842 /**
1843 * @brief Get net_sockaddr from net_sockaddr_storage. This is a helper so that
1844 * the code calling this function can be made shorter.
1845 *
1846 * @param addr Socket storage address
1847 *
1848 * @return Pointer to socket address (struct sockaddr)
1849 */
net_sad(const struct net_sockaddr_storage * addr)1850 static inline struct net_sockaddr *net_sad(const struct net_sockaddr_storage *addr)
1851 {
1852 return (struct net_sockaddr *)addr;
1853 }
1854
1855 /**
1856 * @brief Get net_sockaddr_in6 from net_sockaddr. This is a helper so that
1857 * the code calling this function can be made shorter.
1858 *
1859 * @param addr Socket address
1860 *
1861 * @return Pointer to IPv6 socket address
1862 */
net_sin6(const struct net_sockaddr * addr)1863 static inline struct net_sockaddr_in6 *net_sin6(const struct net_sockaddr *addr)
1864 {
1865 return (struct net_sockaddr_in6 *)addr;
1866 }
1867
1868 /**
1869 * @brief Get net_sockaddr_in from net_sockaddr. This is a helper so that
1870 * the code calling this function can be made shorter.
1871 *
1872 * @param addr Socket address
1873 *
1874 * @return Pointer to IPv4 socket address
1875 */
net_sin(const struct net_sockaddr * addr)1876 static inline struct net_sockaddr_in *net_sin(const struct net_sockaddr *addr)
1877 {
1878 return (struct net_sockaddr_in *)addr;
1879 }
1880
1881 /**
1882 * @brief Get net_sockaddr_in6_ptr from net_sockaddr_ptr. This is a helper so that
1883 * the code calling this function can be made shorter.
1884 *
1885 * @param addr Socket address
1886 *
1887 * @return Pointer to IPv6 socket address
1888 */
1889 static inline
net_sin6_ptr(const struct net_sockaddr_ptr * addr)1890 struct net_sockaddr_in6_ptr *net_sin6_ptr(const struct net_sockaddr_ptr *addr)
1891 {
1892 return (struct net_sockaddr_in6_ptr *)addr;
1893 }
1894
1895 /**
1896 * @brief Get net_sockaddr_in_ptr from sockaddr_ptr. This is a helper so that
1897 * the code calling this function can be made shorter.
1898 *
1899 * @param addr Socket address
1900 *
1901 * @return Pointer to IPv4 socket address
1902 */
1903 static inline
net_sin_ptr(const struct net_sockaddr_ptr * addr)1904 struct net_sockaddr_in_ptr *net_sin_ptr(const struct net_sockaddr_ptr *addr)
1905 {
1906 return (struct net_sockaddr_in_ptr *)addr;
1907 }
1908
1909 /**
1910 * @brief Get net_sockaddr_ll_ptr from sockaddr_ptr. This is a helper so that
1911 * the code calling this function can be made shorter.
1912 *
1913 * @param addr Socket address
1914 *
1915 * @return Pointer to linklayer socket address
1916 */
1917 static inline
net_sll_ptr(const struct net_sockaddr_ptr * addr)1918 struct net_sockaddr_ll_ptr *net_sll_ptr(const struct net_sockaddr_ptr *addr)
1919 {
1920 return (struct net_sockaddr_ll_ptr *)addr;
1921 }
1922
1923 /**
1924 * @brief Get net_sockaddr_can_ptr from net_sockaddr_ptr. This is a helper so that
1925 * the code needing this functionality can be made shorter.
1926 *
1927 * @param addr Socket address
1928 *
1929 * @return Pointer to CAN socket address
1930 */
1931 static inline
net_can_ptr(const struct net_sockaddr_ptr * addr)1932 struct net_sockaddr_can_ptr *net_can_ptr(const struct net_sockaddr_ptr *addr)
1933 {
1934 return (struct net_sockaddr_can_ptr *)addr;
1935 }
1936
1937 /**
1938 * @brief Convert a string to IP address.
1939 *
1940 * @param family IP address family (NET_AF_INET or NET_AF_INET6)
1941 * @param src IP address in a null terminated string
1942 * @param dst Pointer to struct net_in_addr if family is NET_AF_INET or
1943 * pointer to struct net_in6_addr if family is NET_AF_INET6
1944 *
1945 * @note This function doesn't do precise error checking,
1946 * do not use for untrusted strings.
1947 *
1948 * @return 0 if ok, < 0 if error
1949 */
1950 __syscall int net_addr_pton(net_sa_family_t family, const char *src, void *dst);
1951
1952 /**
1953 * @brief Convert IP address to string form.
1954 *
1955 * @param family IP address family (NET_AF_INET or NET_AF_INET6)
1956 * @param src Pointer to struct net_in_addr if family is NET_AF_INET or
1957 * pointer to struct net_in6_addr if family is NET_AF_INET6
1958 * @param dst Buffer for IP address as a null terminated string
1959 * @param size Number of bytes available in the buffer
1960 *
1961 * @return dst pointer if ok, NULL if error
1962 */
1963 __syscall char *net_addr_ntop(net_sa_family_t family, const void *src,
1964 char *dst, size_t size);
1965
1966 /**
1967 * @brief Create netmask from mask length.
1968 *
1969 * @param family IP address family (NET_AF_INET or NET_AF_INET6)
1970 * @param mask_len Netmask length (in IPv4) or prefix length (in IPv6)
1971 * @param mask Pointer to struct sockaddr_in if family is NET_AF_INET or
1972 * pointer to struct sockaddr_in6 if family is NET_AF_INET6
1973 *
1974 * @return 0 if ok, < 0 if error
1975 */
1976 int net_mask_len_to_netmask(net_sa_family_t family, uint8_t mask_len,
1977 struct net_sockaddr *mask);
1978
1979 /**
1980 * @brief Create mask length from netmask.
1981 *
1982 * @param family IP address family (NET_AF_INET or NET_AF_INET6)
1983 * @param mask Pointer to struct sockaddr_in if family is NET_AF_INET or
1984 * pointer to struct sockaddr_in6 if family is NET_AF_INET6
1985 * @param mask_len Netmask length (in IPv4) or prefix length (in IPv6)
1986 *
1987 * @return 0 if ok, < 0 if error
1988 */
1989 int net_netmask_to_mask_len(net_sa_family_t family, struct net_sockaddr *mask,
1990 uint8_t *mask_len);
1991
1992 /**
1993 * @brief Parse a string that contains either IPv4 or IPv6 address
1994 * and optional port, and store the information in user supplied
1995 * sockaddr struct.
1996 *
1997 * @details Syntax of the IP address string:
1998 * 192.0.2.1:80
1999 * 192.0.2.42
2000 * [2001:db8::1]:8080
2001 * [2001:db8::2]
2002 * 2001:db::42
2003 * Note that the str_len parameter is used to restrict the amount of
2004 * characters that are checked. If the string does not contain port
2005 * number, then the port number in sockaddr is not modified.
2006 *
2007 * @param str String that contains the IP address.
2008 * @param str_len Length of the string to be parsed.
2009 * @param addr Pointer to user supplied struct sockaddr.
2010 *
2011 * @return True if parsing could be done, false otherwise.
2012 */
2013 bool net_ipaddr_parse(const char *str, size_t str_len,
2014 struct net_sockaddr *addr);
2015
2016 /**
2017 * @brief Parse a string that contains either IPv4 or IPv6 address
2018 * and optional mask len, and store the information in user supplied
2019 * sockaddr struct. There can be multiple IP addresses separated by
2020 * comma or space. The function returns the pointer to the next IP address
2021 * in the string.
2022 *
2023 * @details Syntax of the IP address string:
2024 * 192.0.2.1/24
2025 * 192.0.2.42
2026 * 2001:db8::1/64
2027 * 2001:db8::2
2028 * 2001:db::42/128
2029 * 2001:db8::1/64,192.0.2.1,2001:db8::2,192.0.2.2/24
2030 * 2001:db8::1/64 192.0.2.1 2001:db8::2 192.0.2.2/24
2031 * Note that the str_len parameter is used to restrict the amount of
2032 * characters that are checked.
2033 *
2034 * @param str String that contains the IP address.
2035 * @param str_len Length of the string to be parsed.
2036 * @param addr Pointer to user supplied struct sockaddr.
2037 * @param mask_len Pointer to mask_len which is returned to the caller.
2038 *
2039 * @return NULL if there was an error while parsing.
2040 * "" if we could parse the IP address and there is nothing more to parse.
2041 * All other values point to next character after the "," or " " in the string.
2042 */
2043 const char *net_ipaddr_parse_mask(const char *str, size_t str_len,
2044 struct net_sockaddr *addr, uint8_t *mask_len);
2045
2046 /**
2047 * @brief Set the default port in the sockaddr structure.
2048 * If the port is already set, then do nothing.
2049 *
2050 * @param addr Pointer to user supplied struct sockaddr.
2051 * @param default_port Default port number to set.
2052 *
2053 * @return 0 if ok, <0 if error
2054 */
2055 int net_port_set_default(struct net_sockaddr *addr, uint16_t default_port);
2056
2057 /**
2058 * @brief Compare TCP sequence numbers.
2059 *
2060 * @details This function compares TCP sequence numbers,
2061 * accounting for wraparound effects.
2062 *
2063 * @param seq1 First sequence number
2064 * @param seq2 Seconds sequence number
2065 *
2066 * @return < 0 if seq1 < seq2, 0 if seq1 == seq2, > 0 if seq > seq2
2067 */
net_tcp_seq_cmp(uint32_t seq1,uint32_t seq2)2068 static inline int32_t net_tcp_seq_cmp(uint32_t seq1, uint32_t seq2)
2069 {
2070 return (int32_t)(seq1 - seq2);
2071 }
2072
2073 /**
2074 * @brief Check that one TCP sequence number is greater.
2075 *
2076 * @details This is convenience function on top of net_tcp_seq_cmp().
2077 *
2078 * @param seq1 First sequence number
2079 * @param seq2 Seconds sequence number
2080 *
2081 * @return True if seq > seq2
2082 */
net_tcp_seq_greater(uint32_t seq1,uint32_t seq2)2083 static inline bool net_tcp_seq_greater(uint32_t seq1, uint32_t seq2)
2084 {
2085 return net_tcp_seq_cmp(seq1, seq2) > 0;
2086 }
2087
2088 /**
2089 * @brief Convert a string of hex values to array of bytes.
2090 *
2091 * @details The syntax of the string is "ab:02:98:fa:42:01"
2092 *
2093 * @param buf Pointer to memory where the bytes are written.
2094 * @param buf_len Length of the memory area.
2095 * @param src String of bytes.
2096 *
2097 * @return 0 if ok, <0 if error
2098 */
2099 int net_bytes_from_str(uint8_t *buf, int buf_len, const char *src);
2100
2101 /**
2102 * @brief Convert Tx network packet priority to traffic class so we can place
2103 * the packet into correct Tx queue.
2104 *
2105 * @param prio Network priority
2106 *
2107 * @return Tx traffic class that handles that priority network traffic.
2108 */
2109 int net_tx_priority2tc(enum net_priority prio);
2110
2111 /**
2112 * @brief Convert Rx network packet priority to traffic class so we can place
2113 * the packet into correct Rx queue.
2114 *
2115 * @param prio Network priority
2116 *
2117 * @return Rx traffic class that handles that priority network traffic.
2118 */
2119 int net_rx_priority2tc(enum net_priority prio);
2120
2121 /**
2122 * @brief Convert network packet VLAN priority to network packet priority so we
2123 * can place the packet into correct queue.
2124 *
2125 * @param priority VLAN priority
2126 *
2127 * @return Network priority
2128 */
net_vlan2priority(uint8_t priority)2129 static inline enum net_priority net_vlan2priority(uint8_t priority)
2130 {
2131 /* Map according to IEEE 802.1Q */
2132 static const uint8_t vlan2priority[] = {
2133 NET_PRIORITY_BE,
2134 NET_PRIORITY_BK,
2135 NET_PRIORITY_EE,
2136 NET_PRIORITY_CA,
2137 NET_PRIORITY_VI,
2138 NET_PRIORITY_VO,
2139 NET_PRIORITY_IC,
2140 NET_PRIORITY_NC
2141 };
2142
2143 if (priority >= ARRAY_SIZE(vlan2priority)) {
2144 /* Use Best Effort as the default priority */
2145 return NET_PRIORITY_BE;
2146 }
2147
2148 return (enum net_priority)vlan2priority[priority];
2149 }
2150
2151 /**
2152 * @brief Convert network packet priority to network packet VLAN priority.
2153 *
2154 * @param priority Packet priority
2155 *
2156 * @return VLAN priority (PCP)
2157 */
net_priority2vlan(enum net_priority priority)2158 static inline uint8_t net_priority2vlan(enum net_priority priority)
2159 {
2160 /* The conversion works both ways */
2161 return (uint8_t)net_vlan2priority(priority);
2162 }
2163
2164 /**
2165 * @brief Return network address family value as a string. This is only usable
2166 * for debugging.
2167 *
2168 * @param family Network address family code
2169 *
2170 * @return Network address family as a string, or NULL if family is unknown.
2171 */
2172 const char *net_family2str(net_sa_family_t family);
2173
2174 /**
2175 * @brief Add IPv6 prefix as a privacy extension filter.
2176 *
2177 * @details Note that the filters can either allow or deny listing.
2178 *
2179 * @param addr IPv6 prefix
2180 * @param is_denylist Tells if this filter is for allowing or denying listing.
2181 *
2182 * @return 0 if ok, <0 if error
2183 */
2184 #if defined(CONFIG_NET_IPV6_PE)
2185 int net_ipv6_pe_add_filter(struct net_in6_addr *addr, bool is_denylist);
2186 #else
net_ipv6_pe_add_filter(struct net_in6_addr * addr,bool is_denylist)2187 static inline int net_ipv6_pe_add_filter(struct net_in6_addr *addr,
2188 bool is_denylist)
2189 {
2190 ARG_UNUSED(addr);
2191 ARG_UNUSED(is_denylist);
2192
2193 return -ENOTSUP;
2194 }
2195 #endif /* CONFIG_NET_IPV6_PE */
2196
2197 /**
2198 * @brief Delete IPv6 prefix from privacy extension filter list.
2199 *
2200 * @param addr IPv6 prefix
2201 *
2202 * @return 0 if ok, <0 if error
2203 */
2204 #if defined(CONFIG_NET_IPV6_PE)
2205 int net_ipv6_pe_del_filter(struct net_in6_addr *addr);
2206 #else
net_ipv6_pe_del_filter(struct net_in6_addr * addr)2207 static inline int net_ipv6_pe_del_filter(struct net_in6_addr *addr)
2208 {
2209 ARG_UNUSED(addr);
2210
2211 return -ENOTSUP;
2212 }
2213 #endif /* CONFIG_NET_IPV6_PE */
2214
2215 #ifdef __cplusplus
2216 }
2217 #endif
2218
2219 #include <zephyr/syscalls/net_ip.h>
2220
2221 #if defined(CONFIG_NET_NAMESPACE_COMPAT_MODE)
2222 #define ZEPHYR_INCLUDE_NET_COMPAT_MODE_SYMBOLS
2223 #include <zephyr/net/net_compat.h>
2224 #undef ZEPHYR_INCLUDE_NET_COMPAT_MODE_SYMBOLS
2225 #endif /* CONFIG_NET_NAMESPACE_COMPAT_MODE */
2226
2227 /**
2228 * @}
2229 */
2230
2231 #endif /* ZEPHYR_INCLUDE_NET_NET_IP_H_ */
2232