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 : /**
1300 : * @brief Check if the IPv6 address is a given scope multicast
1301 : * address (FFyx::).
1302 : *
1303 : * @param addr IPv6 address
1304 : * @param scope Scope to check
1305 : *
1306 : * @return True if the address is in given scope multicast address,
1307 : * false otherwise.
1308 : */
1309 1 : static inline bool net_ipv6_is_addr_mcast_scope(const struct in6_addr *addr,
1310 : int scope)
1311 : {
1312 : return net_ipv6_is_addr_mcast_scope_raw(addr->s6_addr, scope);
1313 : }
1314 :
1315 : /**
1316 : * @brief Check if the IPv6 addresses have the same multicast scope (FFyx::).
1317 : *
1318 : * @param addr_1 IPv6 address 1
1319 : * @param addr_2 IPv6 address 2
1320 : *
1321 : * @return True if both addresses have same multicast scope,
1322 : * false otherwise.
1323 : */
1324 1 : static inline bool net_ipv6_is_same_mcast_scope(const struct in6_addr *addr_1,
1325 : const struct in6_addr *addr_2)
1326 : {
1327 : return (addr_1->s6_addr[0] == 0xff) && (addr_2->s6_addr[0] == 0xff) &&
1328 : (addr_1->s6_addr[1] == addr_2->s6_addr[1]);
1329 : }
1330 :
1331 : /** @cond INTERNAL_HIDDEN */
1332 : static inline bool net_ipv6_is_addr_mcast_iface_raw(const uint8_t *addr)
1333 : {
1334 : return net_ipv6_is_addr_mcast_scope_raw(addr, 0x01);
1335 : }
1336 :
1337 : static inline bool net_ipv6_is_addr_mcast_link_raw(const uint8_t *addr)
1338 : {
1339 : return net_ipv6_is_addr_mcast_scope_raw(addr, 0x02);
1340 : }
1341 :
1342 : static inline bool net_ipv6_is_addr_mcast_mesh_raw(const uint8_t *addr)
1343 : {
1344 : return net_ipv6_is_addr_mcast_scope_raw(addr, 0x03);
1345 : }
1346 :
1347 : static inline bool net_ipv6_is_addr_mcast_site_raw(const uint8_t *addr)
1348 : {
1349 : return net_ipv6_is_addr_mcast_scope_raw(addr, 0x05);
1350 : }
1351 :
1352 : static inline bool net_ipv6_is_addr_mcast_org_raw(const uint8_t *addr)
1353 : {
1354 : return net_ipv6_is_addr_mcast_scope_raw(addr, 0x08);
1355 : }
1356 : /** @endcond */
1357 :
1358 : /**
1359 : * @brief Check if the IPv6 address is a global multicast address (FFxE::/16).
1360 : *
1361 : * @param addr IPv6 address.
1362 : *
1363 : * @return True if the address is global multicast address, false otherwise.
1364 : */
1365 1 : static inline bool net_ipv6_is_addr_mcast_global(const struct in6_addr *addr)
1366 : {
1367 : return net_ipv6_is_addr_mcast_scope(addr, 0x0e);
1368 : }
1369 :
1370 : /**
1371 : * @brief Check if the IPv6 address is a interface scope multicast
1372 : * address (FFx1::).
1373 : *
1374 : * @param addr IPv6 address.
1375 : *
1376 : * @return True if the address is a interface scope multicast address,
1377 : * false otherwise.
1378 : */
1379 1 : static inline bool net_ipv6_is_addr_mcast_iface(const struct in6_addr *addr)
1380 : {
1381 : return net_ipv6_is_addr_mcast_scope(addr, 0x01);
1382 : }
1383 :
1384 : /**
1385 : * @brief Check if the IPv6 address is a link local scope multicast
1386 : * address (FFx2::).
1387 : *
1388 : * @param addr IPv6 address.
1389 : *
1390 : * @return True if the address is a link local scope multicast address,
1391 : * false otherwise.
1392 : */
1393 1 : static inline bool net_ipv6_is_addr_mcast_link(const struct in6_addr *addr)
1394 : {
1395 : return net_ipv6_is_addr_mcast_scope(addr, 0x02);
1396 : }
1397 :
1398 : /**
1399 : * @brief Check if the IPv6 address is a mesh-local scope multicast
1400 : * address (FFx3::).
1401 : *
1402 : * @param addr IPv6 address.
1403 : *
1404 : * @return True if the address is a mesh-local scope multicast address,
1405 : * false otherwise.
1406 : */
1407 1 : static inline bool net_ipv6_is_addr_mcast_mesh(const struct in6_addr *addr)
1408 : {
1409 : return net_ipv6_is_addr_mcast_scope(addr, 0x03);
1410 : }
1411 :
1412 : /**
1413 : * @brief Check if the IPv6 address is a site scope multicast
1414 : * address (FFx5::).
1415 : *
1416 : * @param addr IPv6 address.
1417 : *
1418 : * @return True if the address is a site scope multicast address,
1419 : * false otherwise.
1420 : */
1421 1 : static inline bool net_ipv6_is_addr_mcast_site(const struct in6_addr *addr)
1422 : {
1423 : return net_ipv6_is_addr_mcast_scope(addr, 0x05);
1424 : }
1425 :
1426 : /**
1427 : * @brief Check if the IPv6 address is an organization scope multicast
1428 : * address (FFx8::).
1429 : *
1430 : * @param addr IPv6 address.
1431 : *
1432 : * @return True if the address is an organization scope multicast address,
1433 : * false otherwise.
1434 : */
1435 1 : static inline bool net_ipv6_is_addr_mcast_org(const struct in6_addr *addr)
1436 : {
1437 : return net_ipv6_is_addr_mcast_scope(addr, 0x08);
1438 : }
1439 :
1440 : /** @cond INTERNAL_HIDDEN */
1441 : static inline bool net_ipv6_is_addr_mcast_group_raw(const uint8_t *addr,
1442 : const uint8_t *group)
1443 : {
1444 : return UNALIGNED_GET((uint16_t *)addr + 1) == UNALIGNED_GET((uint16_t *)group + 1) &&
1445 : UNALIGNED_GET((uint32_t *)addr + 1) == UNALIGNED_GET((uint32_t *)group + 1) &&
1446 : UNALIGNED_GET((uint32_t *)addr + 2) == UNALIGNED_GET((uint32_t *)group + 2) &&
1447 : UNALIGNED_GET((uint32_t *)addr + 3) == UNALIGNED_GET((uint32_t *)group + 3);
1448 : }
1449 : /** @endcond */
1450 :
1451 : /**
1452 : * @brief Check if the IPv6 address belongs to certain multicast group
1453 : *
1454 : * @param addr IPv6 address.
1455 : * @param group Group id IPv6 address, the values must be in network
1456 : * byte order
1457 : *
1458 : * @return True if the IPv6 multicast address belongs to given multicast
1459 : * group, false otherwise.
1460 : */
1461 1 : static inline bool net_ipv6_is_addr_mcast_group(const struct in6_addr *addr,
1462 : const struct in6_addr *group)
1463 : {
1464 : return net_ipv6_is_addr_mcast_group_raw(addr->s6_addr, group->s6_addr);
1465 : }
1466 :
1467 : /** @cond INTERNAL_HIDDEN */
1468 : static inline bool net_ipv6_is_addr_mcast_all_nodes_group_raw(const uint8_t *addr)
1469 : {
1470 : static const uint8_t all_nodes_mcast_group[NET_IPV6_ADDR_SIZE] = {
1471 : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1472 : 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1473 : };
1474 :
1475 : return net_ipv6_is_addr_mcast_group_raw(addr, all_nodes_mcast_group);
1476 : }
1477 : /** @endcond */
1478 :
1479 : /**
1480 : * @brief Check if the IPv6 address belongs to the all nodes multicast group
1481 : *
1482 : * @param addr IPv6 address
1483 : *
1484 : * @return True if the IPv6 multicast address belongs to the all nodes multicast
1485 : * group, false otherwise
1486 : */
1487 : static inline bool
1488 1 : net_ipv6_is_addr_mcast_all_nodes_group(const struct in6_addr *addr)
1489 : {
1490 : return net_ipv6_is_addr_mcast_all_nodes_group_raw(addr->s6_addr);
1491 : }
1492 :
1493 : /**
1494 : * @brief Check if the IPv6 address is a interface scope all nodes multicast
1495 : * address (FF01::1).
1496 : *
1497 : * @param addr IPv6 address.
1498 : *
1499 : * @return True if the address is a interface scope all nodes multicast address,
1500 : * false otherwise.
1501 : */
1502 : static inline bool
1503 1 : net_ipv6_is_addr_mcast_iface_all_nodes(const struct in6_addr *addr)
1504 : {
1505 : return net_ipv6_is_addr_mcast_iface(addr) &&
1506 : net_ipv6_is_addr_mcast_all_nodes_group(addr);
1507 : }
1508 :
1509 : /** @cond INTERNAL_HIDDEN */
1510 : static inline bool net_ipv6_is_addr_mcast_link_all_nodes_raw(const uint8_t *addr)
1511 : {
1512 : return net_ipv6_is_addr_mcast_link_raw(addr) &&
1513 : net_ipv6_is_addr_mcast_all_nodes_group_raw(addr);
1514 : }
1515 : /** @endcond */
1516 :
1517 : /**
1518 : * @brief Check if the IPv6 address is a link local scope all nodes multicast
1519 : * address (FF02::1).
1520 : *
1521 : * @param addr IPv6 address.
1522 : *
1523 : * @return True if the address is a link local scope all nodes multicast
1524 : * address, false otherwise.
1525 : */
1526 : static inline bool
1527 1 : net_ipv6_is_addr_mcast_link_all_nodes(const struct in6_addr *addr)
1528 : {
1529 : return net_ipv6_is_addr_mcast_link(addr) &&
1530 : net_ipv6_is_addr_mcast_all_nodes_group(addr);
1531 : }
1532 :
1533 : /**
1534 : * @brief Create solicited node IPv6 multicast address
1535 : * FF02:0:0:0:0:1:FFXX:XXXX defined in RFC 3513
1536 : *
1537 : * @param src IPv6 address.
1538 : * @param dst IPv6 address.
1539 : */
1540 : static inline
1541 1 : void net_ipv6_addr_create_solicited_node(const struct in6_addr *src,
1542 : struct in6_addr *dst)
1543 : {
1544 : dst->s6_addr[0] = 0xFF;
1545 : dst->s6_addr[1] = 0x02;
1546 : UNALIGNED_PUT(0, &dst->s6_addr16[1]);
1547 : UNALIGNED_PUT(0, &dst->s6_addr16[2]);
1548 : UNALIGNED_PUT(0, &dst->s6_addr16[3]);
1549 : UNALIGNED_PUT(0, &dst->s6_addr16[4]);
1550 : dst->s6_addr[10] = 0U;
1551 : dst->s6_addr[11] = 0x01;
1552 : dst->s6_addr[12] = 0xFF;
1553 : dst->s6_addr[13] = src->s6_addr[13];
1554 : UNALIGNED_PUT(UNALIGNED_GET(&src->s6_addr16[7]), &dst->s6_addr16[7]);
1555 : }
1556 :
1557 : /** @brief Construct an IPv6 address from eight 16-bit words.
1558 : *
1559 : * @param addr IPv6 address
1560 : * @param addr0 16-bit word which is part of the address
1561 : * @param addr1 16-bit word which is part of the address
1562 : * @param addr2 16-bit word which is part of the address
1563 : * @param addr3 16-bit word which is part of the address
1564 : * @param addr4 16-bit word which is part of the address
1565 : * @param addr5 16-bit word which is part of the address
1566 : * @param addr6 16-bit word which is part of the address
1567 : * @param addr7 16-bit word which is part of the address
1568 : */
1569 1 : static inline void net_ipv6_addr_create(struct in6_addr *addr,
1570 : uint16_t addr0, uint16_t addr1,
1571 : uint16_t addr2, uint16_t addr3,
1572 : uint16_t addr4, uint16_t addr5,
1573 : uint16_t addr6, uint16_t addr7)
1574 : {
1575 : UNALIGNED_PUT(htons(addr0), &addr->s6_addr16[0]);
1576 : UNALIGNED_PUT(htons(addr1), &addr->s6_addr16[1]);
1577 : UNALIGNED_PUT(htons(addr2), &addr->s6_addr16[2]);
1578 : UNALIGNED_PUT(htons(addr3), &addr->s6_addr16[3]);
1579 : UNALIGNED_PUT(htons(addr4), &addr->s6_addr16[4]);
1580 : UNALIGNED_PUT(htons(addr5), &addr->s6_addr16[5]);
1581 : UNALIGNED_PUT(htons(addr6), &addr->s6_addr16[6]);
1582 : UNALIGNED_PUT(htons(addr7), &addr->s6_addr16[7]);
1583 : }
1584 :
1585 : /**
1586 : * @brief Create link local allnodes multicast IPv6 address
1587 : *
1588 : * @param addr IPv6 address
1589 : */
1590 1 : static inline void net_ipv6_addr_create_ll_allnodes_mcast(struct in6_addr *addr)
1591 : {
1592 : net_ipv6_addr_create(addr, 0xff02, 0, 0, 0, 0, 0, 0, 0x0001);
1593 : }
1594 :
1595 : /**
1596 : * @brief Create link local allrouters multicast IPv6 address
1597 : *
1598 : * @param addr IPv6 address
1599 : */
1600 1 : static inline void net_ipv6_addr_create_ll_allrouters_mcast(struct in6_addr *addr)
1601 : {
1602 : net_ipv6_addr_create(addr, 0xff02, 0, 0, 0, 0, 0, 0, 0x0002);
1603 : }
1604 :
1605 : /**
1606 : * @brief Create IPv4 mapped IPv6 address
1607 : *
1608 : * @param addr4 IPv4 address
1609 : * @param addr6 IPv6 address to be created
1610 : */
1611 1 : static inline void net_ipv6_addr_create_v4_mapped(const struct in_addr *addr4,
1612 : struct in6_addr *addr6)
1613 : {
1614 : net_ipv6_addr_create(addr6, 0, 0, 0, 0, 0, 0xffff,
1615 : ntohs(addr4->s4_addr16[0]),
1616 : ntohs(addr4->s4_addr16[1]));
1617 : }
1618 :
1619 : /**
1620 : * @brief Is the IPv6 address an IPv4 mapped one. The v4 mapped addresses
1621 : * look like \::ffff:a.b.c.d
1622 : *
1623 : * @param addr IPv6 address
1624 : *
1625 : * @return True if IPv6 address is a IPv4 mapped address, False otherwise.
1626 : */
1627 1 : static inline bool net_ipv6_addr_is_v4_mapped(const struct in6_addr *addr)
1628 : {
1629 : if (UNALIGNED_GET(&addr->s6_addr32[0]) == 0 &&
1630 : UNALIGNED_GET(&addr->s6_addr32[1]) == 0 &&
1631 : UNALIGNED_GET(&addr->s6_addr16[5]) == 0xffff) {
1632 : return true;
1633 : }
1634 :
1635 : return false;
1636 : }
1637 :
1638 : /**
1639 : * @brief Generate IPv6 address using a prefix and interface identifier.
1640 : * Interface identifier is either generated from EUI-64 (MAC) defined
1641 : * in RFC 4291 or from randomized value defined in RFC 7217.
1642 : *
1643 : * @param iface Network interface
1644 : * @param prefix IPv6 prefix, can be left out in which case fe80::/64 is used
1645 : * @param network_id Network identifier (for example SSID in WLAN), this is
1646 : * optional can be set to NULL
1647 : * @param network_id_len Network identifier length, if set to 0 then the
1648 : * network id is ignored.
1649 : * @param dad_counter Duplicate Address Detection counter value, can be set to 0
1650 : * if it is not known.
1651 : * @param addr IPv6 address
1652 : * @param lladdr Link local address
1653 : *
1654 : * @return 0 if ok, < 0 if error
1655 : */
1656 1 : int net_ipv6_addr_generate_iid(struct net_if *iface,
1657 : const struct in6_addr *prefix,
1658 : uint8_t *network_id, size_t network_id_len,
1659 : uint8_t dad_counter,
1660 : struct in6_addr *addr,
1661 : struct net_linkaddr *lladdr);
1662 :
1663 : /**
1664 : * @brief Create IPv6 address interface identifier.
1665 : *
1666 : * @param addr IPv6 address
1667 : * @param lladdr Link local address
1668 : */
1669 1 : static inline void net_ipv6_addr_create_iid(struct in6_addr *addr,
1670 : struct net_linkaddr *lladdr)
1671 : {
1672 : (void)net_ipv6_addr_generate_iid(NULL, NULL, NULL, 0, 0, addr, lladdr);
1673 : }
1674 :
1675 : /** @cond INTERNAL_HIDDEN */
1676 : static inline bool net_ipv6_addr_based_on_ll_raw(const uint8_t *addr,
1677 : const struct net_linkaddr *lladdr)
1678 : {
1679 : if (addr == NULL || lladdr == NULL) {
1680 : return false;
1681 : }
1682 :
1683 : switch (lladdr->len) {
1684 : case 2:
1685 : if (!memcmp(&addr[14], lladdr->addr, lladdr->len) &&
1686 : addr[8] == 0U &&
1687 : addr[9] == 0U &&
1688 : addr[10] == 0U &&
1689 : addr[11] == 0xff &&
1690 : addr[12] == 0xfe) {
1691 : return true;
1692 : }
1693 :
1694 : break;
1695 : case 6:
1696 : if (lladdr->type == NET_LINK_ETHERNET) {
1697 : if (!memcmp(&addr[9], &lladdr->addr[1], 2) &&
1698 : !memcmp(&addr[13], &lladdr->addr[3], 3) &&
1699 : addr[11] == 0xff &&
1700 : addr[12] == 0xfe &&
1701 : (addr[8] ^ 0x02) == lladdr->addr[0]) {
1702 : return true;
1703 : }
1704 : }
1705 :
1706 : break;
1707 : case 8:
1708 : if (sizeof(lladdr->addr) < 8) {
1709 : return false;
1710 : }
1711 :
1712 : if (!memcmp(&addr[9], &lladdr->addr[1],
1713 : lladdr->len - 1) &&
1714 : (addr[8] ^ 0x02) == lladdr->addr[0]) {
1715 : return true;
1716 : }
1717 :
1718 : break;
1719 : default:
1720 : return false;
1721 : }
1722 :
1723 : return false;
1724 : }
1725 : /** @endcond */
1726 :
1727 : /**
1728 : * @brief Check if given address is based on link layer address
1729 : *
1730 : * @return True if it is, False otherwise
1731 : */
1732 1 : static inline bool net_ipv6_addr_based_on_ll(const struct in6_addr *addr,
1733 : const struct net_linkaddr *lladdr)
1734 : {
1735 : if (addr == NULL || lladdr == NULL) {
1736 : return false;
1737 : }
1738 :
1739 : return net_ipv6_addr_based_on_ll_raw(addr->s6_addr, lladdr);
1740 : }
1741 :
1742 : /**
1743 : * @brief Get sockaddr from sockaddr_storage. This is a helper so that
1744 : * the code calling this function can be made shorter.
1745 : *
1746 : * @param addr Socket storage address
1747 : *
1748 : * @return Pointer to socket address (struct sockaddr)
1749 : */
1750 1 : static inline struct sockaddr *net_sad(const struct sockaddr_storage *addr)
1751 : {
1752 : return (struct sockaddr *)addr;
1753 : }
1754 :
1755 : /**
1756 : * @brief Get sockaddr_in6 from sockaddr. This is a helper so that
1757 : * the code calling this function can be made shorter.
1758 : *
1759 : * @param addr Socket address
1760 : *
1761 : * @return Pointer to IPv6 socket address
1762 : */
1763 1 : static inline struct sockaddr_in6 *net_sin6(const struct sockaddr *addr)
1764 : {
1765 : return (struct sockaddr_in6 *)addr;
1766 : }
1767 :
1768 : /**
1769 : * @brief Get sockaddr_in from sockaddr. This is a helper so that
1770 : * the code calling this function can be made shorter.
1771 : *
1772 : * @param addr Socket address
1773 : *
1774 : * @return Pointer to IPv4 socket address
1775 : */
1776 1 : static inline struct sockaddr_in *net_sin(const struct sockaddr *addr)
1777 : {
1778 : return (struct sockaddr_in *)addr;
1779 : }
1780 :
1781 : /**
1782 : * @brief Get sockaddr_in6_ptr from sockaddr_ptr. This is a helper so that
1783 : * the code calling this function can be made shorter.
1784 : *
1785 : * @param addr Socket address
1786 : *
1787 : * @return Pointer to IPv6 socket address
1788 : */
1789 : static inline
1790 1 : struct sockaddr_in6_ptr *net_sin6_ptr(const struct sockaddr_ptr *addr)
1791 : {
1792 : return (struct sockaddr_in6_ptr *)addr;
1793 : }
1794 :
1795 : /**
1796 : * @brief Get sockaddr_in_ptr from sockaddr_ptr. This is a helper so that
1797 : * the code calling this function can be made shorter.
1798 : *
1799 : * @param addr Socket address
1800 : *
1801 : * @return Pointer to IPv4 socket address
1802 : */
1803 : static inline
1804 1 : struct sockaddr_in_ptr *net_sin_ptr(const struct sockaddr_ptr *addr)
1805 : {
1806 : return (struct sockaddr_in_ptr *)addr;
1807 : }
1808 :
1809 : /**
1810 : * @brief Get sockaddr_ll_ptr from sockaddr_ptr. This is a helper so that
1811 : * the code calling this function can be made shorter.
1812 : *
1813 : * @param addr Socket address
1814 : *
1815 : * @return Pointer to linklayer socket address
1816 : */
1817 : static inline
1818 1 : struct sockaddr_ll_ptr *net_sll_ptr(const struct sockaddr_ptr *addr)
1819 : {
1820 : return (struct sockaddr_ll_ptr *)addr;
1821 : }
1822 :
1823 : /**
1824 : * @brief Get sockaddr_can_ptr from sockaddr_ptr. This is a helper so that
1825 : * the code needing this functionality can be made shorter.
1826 : *
1827 : * @param addr Socket address
1828 : *
1829 : * @return Pointer to CAN socket address
1830 : */
1831 : static inline
1832 1 : struct sockaddr_can_ptr *net_can_ptr(const struct sockaddr_ptr *addr)
1833 : {
1834 : return (struct sockaddr_can_ptr *)addr;
1835 : }
1836 :
1837 : /**
1838 : * @brief Convert a string to IP address.
1839 : *
1840 : * @param family IP address family (AF_INET or AF_INET6)
1841 : * @param src IP address in a null terminated string
1842 : * @param dst Pointer to struct in_addr if family is AF_INET or
1843 : * pointer to struct in6_addr if family is AF_INET6
1844 : *
1845 : * @note This function doesn't do precise error checking,
1846 : * do not use for untrusted strings.
1847 : *
1848 : * @return 0 if ok, < 0 if error
1849 : */
1850 1 : __syscall int net_addr_pton(sa_family_t family, const char *src, void *dst);
1851 :
1852 : /**
1853 : * @brief Convert IP address to string form.
1854 : *
1855 : * @param family IP address family (AF_INET or AF_INET6)
1856 : * @param src Pointer to struct in_addr if family is AF_INET or
1857 : * pointer to struct in6_addr if family is AF_INET6
1858 : * @param dst Buffer for IP address as a null terminated string
1859 : * @param size Number of bytes available in the buffer
1860 : *
1861 : * @return dst pointer if ok, NULL if error
1862 : */
1863 1 : __syscall char *net_addr_ntop(sa_family_t family, const void *src,
1864 : char *dst, size_t size);
1865 :
1866 : /**
1867 : * @brief Create netmask from mask length.
1868 : *
1869 : * @param family IP address family (AF_INET or AF_INET6)
1870 : * @param mask_len Netmask length (in IPv4) or prefix length (in IPv6)
1871 : * @param mask Pointer to struct sockaddr_in if family is AF_INET or
1872 : * pointer to struct sockaddr_in6 if family is AF_INET6
1873 : *
1874 : * @return 0 if ok, < 0 if error
1875 : */
1876 1 : int net_mask_len_to_netmask(sa_family_t family, uint8_t mask_len,
1877 : struct sockaddr *mask);
1878 :
1879 : /**
1880 : * @brief Create mask length from netmask.
1881 : *
1882 : * @param family IP address family (AF_INET or AF_INET6)
1883 : * @param mask Pointer to struct sockaddr_in if family is AF_INET or
1884 : * pointer to struct sockaddr_in6 if family is AF_INET6
1885 : * @param mask_len Netmask length (in IPv4) or prefix length (in IPv6)
1886 : *
1887 : * @return 0 if ok, < 0 if error
1888 : */
1889 1 : int net_netmask_to_mask_len(sa_family_t family, struct sockaddr *mask,
1890 : uint8_t *mask_len);
1891 :
1892 : /**
1893 : * @brief Parse a string that contains either IPv4 or IPv6 address
1894 : * and optional port, and store the information in user supplied
1895 : * sockaddr struct.
1896 : *
1897 : * @details Syntax of the IP address string:
1898 : * 192.0.2.1:80
1899 : * 192.0.2.42
1900 : * [2001:db8::1]:8080
1901 : * [2001:db8::2]
1902 : * 2001:db::42
1903 : * Note that the str_len parameter is used to restrict the amount of
1904 : * characters that are checked. If the string does not contain port
1905 : * number, then the port number in sockaddr is not modified.
1906 : *
1907 : * @param str String that contains the IP address.
1908 : * @param str_len Length of the string to be parsed.
1909 : * @param addr Pointer to user supplied struct sockaddr.
1910 : *
1911 : * @return True if parsing could be done, false otherwise.
1912 : */
1913 1 : bool net_ipaddr_parse(const char *str, size_t str_len,
1914 : struct sockaddr *addr);
1915 :
1916 : /**
1917 : * @brief Parse a string that contains either IPv4 or IPv6 address
1918 : * and optional mask len, and store the information in user supplied
1919 : * sockaddr struct. There can be multiple IP addresses separated by
1920 : * comma or space. The function returns the pointer to the next IP address
1921 : * in the string.
1922 : *
1923 : * @details Syntax of the IP address string:
1924 : * 192.0.2.1/24
1925 : * 192.0.2.42
1926 : * 2001:db8::1/64
1927 : * 2001:db8::2
1928 : * 2001:db::42/128
1929 : * 2001:db8::1/64,192.0.2.1,2001:db8::2,192.0.2.2/24
1930 : * 2001:db8::1/64 192.0.2.1 2001:db8::2 192.0.2.2/24
1931 : * Note that the str_len parameter is used to restrict the amount of
1932 : * characters that are checked.
1933 : *
1934 : * @param str String that contains the IP address.
1935 : * @param str_len Length of the string to be parsed.
1936 : * @param addr Pointer to user supplied struct sockaddr.
1937 : * @param mask_len Pointer to mask_len which is returned to the caller.
1938 : *
1939 : * @return NULL if there was an error while parsing.
1940 : * "" if we could parse the IP address and there is nothing more to parse.
1941 : * All other values point to next character after the "," or " " in the string.
1942 : */
1943 1 : const char *net_ipaddr_parse_mask(const char *str, size_t str_len,
1944 : struct sockaddr *addr, uint8_t *mask_len);
1945 :
1946 : /**
1947 : * @brief Set the default port in the sockaddr structure.
1948 : * If the port is already set, then do nothing.
1949 : *
1950 : * @param addr Pointer to user supplied struct sockaddr.
1951 : * @param default_port Default port number to set.
1952 : *
1953 : * @return 0 if ok, <0 if error
1954 : */
1955 1 : int net_port_set_default(struct sockaddr *addr, uint16_t default_port);
1956 :
1957 : /**
1958 : * @brief Compare TCP sequence numbers.
1959 : *
1960 : * @details This function compares TCP sequence numbers,
1961 : * accounting for wraparound effects.
1962 : *
1963 : * @param seq1 First sequence number
1964 : * @param seq2 Seconds sequence number
1965 : *
1966 : * @return < 0 if seq1 < seq2, 0 if seq1 == seq2, > 0 if seq > seq2
1967 : */
1968 1 : static inline int32_t net_tcp_seq_cmp(uint32_t seq1, uint32_t seq2)
1969 : {
1970 : return (int32_t)(seq1 - seq2);
1971 : }
1972 :
1973 : /**
1974 : * @brief Check that one TCP sequence number is greater.
1975 : *
1976 : * @details This is convenience function on top of net_tcp_seq_cmp().
1977 : *
1978 : * @param seq1 First sequence number
1979 : * @param seq2 Seconds sequence number
1980 : *
1981 : * @return True if seq > seq2
1982 : */
1983 1 : static inline bool net_tcp_seq_greater(uint32_t seq1, uint32_t seq2)
1984 : {
1985 : return net_tcp_seq_cmp(seq1, seq2) > 0;
1986 : }
1987 :
1988 : /**
1989 : * @brief Convert a string of hex values to array of bytes.
1990 : *
1991 : * @details The syntax of the string is "ab:02:98:fa:42:01"
1992 : *
1993 : * @param buf Pointer to memory where the bytes are written.
1994 : * @param buf_len Length of the memory area.
1995 : * @param src String of bytes.
1996 : *
1997 : * @return 0 if ok, <0 if error
1998 : */
1999 1 : int net_bytes_from_str(uint8_t *buf, int buf_len, const char *src);
2000 :
2001 : /**
2002 : * @brief Convert Tx network packet priority to traffic class so we can place
2003 : * the packet into correct Tx queue.
2004 : *
2005 : * @param prio Network priority
2006 : *
2007 : * @return Tx traffic class that handles that priority network traffic.
2008 : */
2009 1 : int net_tx_priority2tc(enum net_priority prio);
2010 :
2011 : /**
2012 : * @brief Convert Rx network packet priority to traffic class so we can place
2013 : * the packet into correct Rx queue.
2014 : *
2015 : * @param prio Network priority
2016 : *
2017 : * @return Rx traffic class that handles that priority network traffic.
2018 : */
2019 1 : int net_rx_priority2tc(enum net_priority prio);
2020 :
2021 : /**
2022 : * @brief Convert network packet VLAN priority to network packet priority so we
2023 : * can place the packet into correct queue.
2024 : *
2025 : * @param priority VLAN priority
2026 : *
2027 : * @return Network priority
2028 : */
2029 1 : static inline enum net_priority net_vlan2priority(uint8_t priority)
2030 : {
2031 : /* Map according to IEEE 802.1Q */
2032 : static const uint8_t vlan2priority[] = {
2033 : NET_PRIORITY_BE,
2034 : NET_PRIORITY_BK,
2035 : NET_PRIORITY_EE,
2036 : NET_PRIORITY_CA,
2037 : NET_PRIORITY_VI,
2038 : NET_PRIORITY_VO,
2039 : NET_PRIORITY_IC,
2040 : NET_PRIORITY_NC
2041 : };
2042 :
2043 : if (priority >= ARRAY_SIZE(vlan2priority)) {
2044 : /* Use Best Effort as the default priority */
2045 : return NET_PRIORITY_BE;
2046 : }
2047 :
2048 : return (enum net_priority)vlan2priority[priority];
2049 : }
2050 :
2051 : /**
2052 : * @brief Convert network packet priority to network packet VLAN priority.
2053 : *
2054 : * @param priority Packet priority
2055 : *
2056 : * @return VLAN priority (PCP)
2057 : */
2058 1 : static inline uint8_t net_priority2vlan(enum net_priority priority)
2059 : {
2060 : /* The conversion works both ways */
2061 : return (uint8_t)net_vlan2priority(priority);
2062 : }
2063 :
2064 : /**
2065 : * @brief Return network address family value as a string. This is only usable
2066 : * for debugging.
2067 : *
2068 : * @param family Network address family code
2069 : *
2070 : * @return Network address family as a string, or NULL if family is unknown.
2071 : */
2072 1 : const char *net_family2str(sa_family_t family);
2073 :
2074 : /**
2075 : * @brief Add IPv6 prefix as a privacy extension filter.
2076 : *
2077 : * @details Note that the filters can either allow or deny listing.
2078 : *
2079 : * @param addr IPv6 prefix
2080 : * @param is_denylist Tells if this filter is for allowing or denying listing.
2081 : *
2082 : * @return 0 if ok, <0 if error
2083 : */
2084 : #if defined(CONFIG_NET_IPV6_PE)
2085 : int net_ipv6_pe_add_filter(struct in6_addr *addr, bool is_denylist);
2086 : #else
2087 1 : static inline int net_ipv6_pe_add_filter(struct in6_addr *addr,
2088 : bool is_denylist)
2089 : {
2090 : ARG_UNUSED(addr);
2091 : ARG_UNUSED(is_denylist);
2092 :
2093 : return -ENOTSUP;
2094 : }
2095 : #endif /* CONFIG_NET_IPV6_PE */
2096 :
2097 : /**
2098 : * @brief Delete IPv6 prefix from privacy extension filter list.
2099 : *
2100 : * @param addr IPv6 prefix
2101 : *
2102 : * @return 0 if ok, <0 if error
2103 : */
2104 : #if defined(CONFIG_NET_IPV6_PE)
2105 : int net_ipv6_pe_del_filter(struct in6_addr *addr);
2106 : #else
2107 1 : static inline int net_ipv6_pe_del_filter(struct in6_addr *addr)
2108 : {
2109 : ARG_UNUSED(addr);
2110 :
2111 : return -ENOTSUP;
2112 : }
2113 : #endif /* CONFIG_NET_IPV6_PE */
2114 :
2115 : #ifdef __cplusplus
2116 : }
2117 : #endif
2118 :
2119 : #include <zephyr/syscalls/net_ip.h>
2120 :
2121 : /**
2122 : * @}
2123 : */
2124 :
2125 :
2126 : #endif /* ZEPHYR_INCLUDE_NET_NET_IP_H_ */
|