LCOV - code coverage report
Current view: top level - zephyr/net - net_ip.h Coverage Total Hit
Test: new.info Lines: 95.6 % 182 174
Test Date: 2025-09-05 22:20:39

            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_ */
        

Generated by: LCOV version 2.0-1