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