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