LCOV - code coverage report
Current view: top level - zephyr/net - net_ip.h Hit Total Coverage
Test: new.info Lines: 170 177 96.0 %
Date: 2024-12-22 00:14:23

          Line data    Source code
       1           1 : /** @file
       2             :  * @brief IPv6 and IPv4 definitions
       3             :  *
       4             :  * Generic IPv6 and IPv4 address definitions.
       5             :  */
       6             : 
       7             : /*
       8             :  * Copyright (c) 2016 Intel Corporation
       9             :  *
      10             :  * SPDX-License-Identifier: Apache-2.0
      11             :  */
      12             : 
      13             : #ifndef ZEPHYR_INCLUDE_NET_NET_IP_H_
      14             : #define ZEPHYR_INCLUDE_NET_NET_IP_H_
      15             : 
      16             : /**
      17             :  * @brief IPv4/IPv6 primitives and helpers
      18             :  * @defgroup ip_4_6 IPv4/IPv6 primitives and helpers
      19             :  * @since 1.0
      20             :  * @version 1.0.0
      21             :  * @ingroup networking
      22             :  * @{
      23             :  */
      24             : 
      25             : #include <string.h>
      26             : #include <zephyr/types.h>
      27             : #include <stdbool.h>
      28             : #include <zephyr/sys/util.h>
      29             : #include <zephyr/sys/byteorder.h>
      30             : #include <zephyr/toolchain.h>
      31             : 
      32             : #include <zephyr/net/net_linkaddr.h>
      33             : 
      34             : #ifdef __cplusplus
      35             : extern "C" {
      36             : #endif
      37             : 
      38             : /** @cond INTERNAL_HIDDEN */
      39             : /* Specifying VLAN tag here in order to avoid circular dependencies */
      40             : #define NET_VLAN_TAG_UNSPEC 0x0fff
      41             : /** @endcond */
      42             : 
      43             : /* Protocol families. */
      44           1 : #define PF_UNSPEC       0          /**< Unspecified protocol family.  */
      45           1 : #define PF_INET         1          /**< IP protocol family version 4. */
      46           1 : #define PF_INET6        2          /**< IP protocol family version 6. */
      47           1 : #define PF_PACKET       3          /**< Packet family.                */
      48           1 : #define PF_CAN          4          /**< Controller Area Network.      */
      49           1 : #define PF_NET_MGMT     5          /**< Network management info.      */
      50           1 : #define PF_LOCAL        6          /**< Inter-process communication   */
      51           1 : #define PF_UNIX         PF_LOCAL   /**< Inter-process communication   */
      52             : 
      53             : /* Address families. */
      54           1 : #define AF_UNSPEC      PF_UNSPEC   /**< Unspecified address family.   */
      55           1 : #define AF_INET        PF_INET     /**< IP protocol family version 4. */
      56           1 : #define AF_INET6       PF_INET6    /**< IP protocol family version 6. */
      57           1 : #define AF_PACKET      PF_PACKET   /**< Packet family.                */
      58           1 : #define AF_CAN         PF_CAN      /**< Controller Area Network.      */
      59           1 : #define AF_NET_MGMT    PF_NET_MGMT /**< Network management info.      */
      60           1 : #define AF_LOCAL       PF_LOCAL    /**< Inter-process communication   */
      61           1 : #define AF_UNIX        PF_UNIX     /**< Inter-process communication   */
      62             : 
      63             : /** Protocol numbers from IANA/BSD */
      64           1 : enum net_ip_protocol {
      65             :         IPPROTO_IP = 0,            /**< IP protocol (pseudo-val for setsockopt() */
      66             :         IPPROTO_ICMP = 1,          /**< ICMP protocol   */
      67             :         IPPROTO_IGMP = 2,          /**< IGMP protocol   */
      68             :         IPPROTO_ETH_P_ALL = 3,     /**< Every packet. from linux if_ether.h   */
      69             :         IPPROTO_IPIP = 4,          /**< IPIP tunnels    */
      70             :         IPPROTO_TCP = 6,           /**< TCP protocol    */
      71             :         IPPROTO_UDP = 17,          /**< UDP protocol    */
      72             :         IPPROTO_IPV6 = 41,         /**< IPv6 protocol   */
      73             :         IPPROTO_ICMPV6 = 58,       /**< ICMPv6 protocol */
      74             :         IPPROTO_RAW = 255,         /**< RAW IP packets  */
      75             : };
      76             : 
      77             : /** Protocol numbers for TLS protocols */
      78           1 : enum net_ip_protocol_secure {
      79             :         IPPROTO_TLS_1_0 = 256,     /**< TLS 1.0 protocol */
      80             :         IPPROTO_TLS_1_1 = 257,     /**< TLS 1.1 protocol */
      81             :         IPPROTO_TLS_1_2 = 258,     /**< TLS 1.2 protocol */
      82             :         IPPROTO_TLS_1_3 = 259,     /**< TLS 1.3 protocol */
      83             :         IPPROTO_DTLS_1_0 = 272,    /**< DTLS 1.0 protocol */
      84             :         IPPROTO_DTLS_1_2 = 273,    /**< DTLS 1.2 protocol */
      85             : };
      86             : 
      87             : /** Socket type */
      88           1 : enum net_sock_type {
      89             :         SOCK_STREAM = 1,           /**< Stream socket type   */
      90             :         SOCK_DGRAM,                /**< Datagram socket type */
      91             :         SOCK_RAW                   /**< RAW socket type      */
      92             : };
      93             : 
      94             : /** @brief Convert 16-bit value from network to host byte order.
      95             :  *
      96             :  * @param x The network byte order value to convert.
      97             :  *
      98             :  * @return Host byte order value.
      99             :  */
     100           1 : #define ntohs(x) sys_be16_to_cpu(x)
     101             : 
     102             : /** @brief Convert 32-bit value from network to host byte order.
     103             :  *
     104             :  * @param x The network byte order value to convert.
     105             :  *
     106             :  * @return Host byte order value.
     107             :  */
     108           1 : #define ntohl(x) sys_be32_to_cpu(x)
     109             : 
     110             : /** @brief Convert 64-bit value from network to host byte order.
     111             :  *
     112             :  * @param x The network byte order value to convert.
     113             :  *
     114             :  * @return Host byte order value.
     115             :  */
     116           1 : #define ntohll(x) sys_be64_to_cpu(x)
     117             : 
     118             : /** @brief Convert 16-bit value from host to network byte order.
     119             :  *
     120             :  * @param x The host byte order value to convert.
     121             :  *
     122             :  * @return Network byte order value.
     123             :  */
     124           1 : #define htons(x) sys_cpu_to_be16(x)
     125             : 
     126             : /** @brief Convert 32-bit value from host to network byte order.
     127             :  *
     128             :  * @param x The host byte order value to convert.
     129             :  *
     130             :  * @return Network byte order value.
     131             :  */
     132           1 : #define htonl(x) sys_cpu_to_be32(x)
     133             : 
     134             : /** @brief Convert 64-bit value from host to network byte order.
     135             :  *
     136             :  * @param x The host byte order value to convert.
     137             :  *
     138             :  * @return Network byte order value.
     139             :  */
     140           1 : #define htonll(x) sys_cpu_to_be64(x)
     141             : 
     142             : /** IPv6 address struct */
     143           1 : struct in6_addr {
     144             :         union {
     145           1 :                 uint8_t s6_addr[16];   /**< IPv6 address buffer */
     146           1 :                 uint16_t s6_addr16[8]; /**< In big endian */
     147           1 :                 uint32_t s6_addr32[4]; /**< In big endian */
     148           0 :         };
     149             : };
     150             : 
     151             : /** Binary size of the IPv6 address */
     152           1 : #define NET_IPV6_ADDR_SIZE 16
     153             : 
     154             : /** IPv4 address struct */
     155           1 : struct in_addr {
     156             :         union {
     157           1 :                 uint8_t s4_addr[4];    /**< IPv4 address buffer */
     158           1 :                 uint16_t s4_addr16[2]; /**< In big endian */
     159           1 :                 uint32_t s4_addr32[1]; /**< In big endian */
     160           1 :                 uint32_t s_addr; /**< In big endian, for POSIX compatibility. */
     161           0 :         };
     162             : };
     163             : 
     164             : /** Binary size of the IPv4 address */
     165           1 : #define NET_IPV4_ADDR_SIZE 4
     166             : 
     167             : /** Socket address family type */
     168           1 : typedef unsigned short int sa_family_t;
     169             : 
     170             : /** Length of a socket address */
     171             : #ifndef __socklen_t_defined
     172           1 : typedef size_t socklen_t;
     173             : #define __socklen_t_defined
     174             : #endif
     175             : 
     176             : /*
     177             :  * Note that the sin_port and sin6_port are in network byte order
     178             :  * in various sockaddr* structs.
     179             :  */
     180             : 
     181             : /** Socket address struct for IPv6. */
     182           1 : struct sockaddr_in6 {
     183           1 :         sa_family_t             sin6_family;   /**< AF_INET6               */
     184           1 :         uint16_t                sin6_port;     /**< Port number            */
     185           1 :         struct in6_addr         sin6_addr;     /**< IPv6 address           */
     186           1 :         uint8_t                 sin6_scope_id; /**< Interfaces for a scope */
     187             : };
     188             : 
     189             : /** Socket address struct for IPv4. */
     190           1 : struct sockaddr_in {
     191           1 :         sa_family_t             sin_family;    /**< AF_INET      */
     192           1 :         uint16_t                sin_port;      /**< Port number  */
     193           1 :         struct in_addr          sin_addr;      /**< IPv4 address */
     194             : };
     195             : 
     196             : /** Socket address struct for packet socket. */
     197           1 : struct sockaddr_ll {
     198           1 :         sa_family_t sll_family;   /**< Always AF_PACKET                   */
     199           1 :         uint16_t    sll_protocol; /**< Physical-layer protocol            */
     200           1 :         int         sll_ifindex;  /**< Interface number                   */
     201           1 :         uint16_t    sll_hatype;   /**< ARP hardware type                  */
     202           1 :         uint8_t     sll_pkttype;  /**< Packet type                        */
     203           1 :         uint8_t     sll_halen;    /**< Length of address                  */
     204           1 :         uint8_t     sll_addr[8];  /**< Physical-layer address, big endian */
     205             : };
     206             : 
     207             : /** @cond INTERNAL_HIDDEN */
     208             : 
     209             : /** Socket address struct for IPv6 where address is a pointer */
     210             : struct sockaddr_in6_ptr {
     211             :         sa_family_t             sin6_family;   /**< AF_INET6               */
     212             :         uint16_t                sin6_port;     /**< Port number            */
     213             :         struct in6_addr         *sin6_addr;    /**< IPv6 address           */
     214             :         uint8_t                 sin6_scope_id; /**< interfaces for a scope */
     215             : };
     216             : 
     217             : /** Socket address struct for IPv4 where address is a pointer */
     218             : struct sockaddr_in_ptr {
     219             :         sa_family_t             sin_family;    /**< AF_INET      */
     220             :         uint16_t                sin_port;      /**< Port number  */
     221             :         struct in_addr          *sin_addr;     /**< IPv4 address */
     222             : };
     223             : 
     224             : /** Socket address struct for packet socket where address is a pointer */
     225             : struct sockaddr_ll_ptr {
     226             :         sa_family_t sll_family;   /**< Always AF_PACKET                   */
     227             :         uint16_t    sll_protocol; /**< Physical-layer protocol            */
     228             :         int         sll_ifindex;  /**< Interface number                   */
     229             :         uint16_t    sll_hatype;   /**< ARP hardware type                  */
     230             :         uint8_t     sll_pkttype;  /**< Packet type                        */
     231             :         uint8_t     sll_halen;    /**< Length of address                  */
     232             :         uint8_t     *sll_addr;    /**< Physical-layer address, big endian */
     233             : };
     234             : 
     235             : /** Socket address struct for unix socket where address is a pointer */
     236             : struct sockaddr_un_ptr {
     237             :         sa_family_t sun_family;    /**< Always AF_UNIX */
     238             :         char        *sun_path;     /**< pathname */
     239             : };
     240             : 
     241             : struct sockaddr_can_ptr {
     242             :         sa_family_t can_family;
     243             :         int         can_ifindex;
     244             : };
     245             : 
     246             : /** @endcond */
     247             : 
     248             : #if !defined(HAVE_IOVEC)
     249             : /** IO vector array element */
     250           1 : struct iovec {
     251           1 :         void  *iov_base; /**< Pointer to data */
     252           1 :         size_t iov_len;  /**< Length of the data */
     253             : };
     254             : #endif
     255             : 
     256             : /** Message struct */
     257           1 : struct msghdr {
     258           1 :         void         *msg_name;       /**< Optional socket address, big endian */
     259           1 :         socklen_t     msg_namelen;    /**< Size of socket address */
     260           1 :         struct iovec *msg_iov;        /**< Scatter/gather array */
     261           1 :         size_t        msg_iovlen;     /**< Number of elements in msg_iov */
     262           1 :         void         *msg_control;    /**< Ancillary data */
     263           1 :         size_t        msg_controllen; /**< Ancillary data buffer len */
     264           1 :         int           msg_flags;      /**< Flags on received message */
     265             : };
     266             : 
     267             : /** Control message ancillary data */
     268           1 : struct cmsghdr {
     269           1 :         socklen_t cmsg_len;    /**< Number of bytes, including header */
     270           1 :         int       cmsg_level;  /**< Originating protocol */
     271           1 :         int       cmsg_type;   /**< Protocol-specific type */
     272           1 :         z_max_align_t cmsg_data[]; /**< Flexible array member to force alignment of cmsghdr */
     273             : };
     274             : 
     275             : /** @cond INTERNAL_HIDDEN */
     276             : 
     277             : /* Alignment for headers and data. These are arch specific but define
     278             :  * them here atm if not found already.
     279             :  */
     280             : #if !defined(ALIGN_H)
     281             : #define ALIGN_H(x) ROUND_UP(x, __alignof__(struct cmsghdr))
     282             : #endif
     283             : #if !defined(ALIGN_D)
     284             : #define ALIGN_D(x) ROUND_UP(x, __alignof__(z_max_align_t))
     285             : #endif
     286             : 
     287             : /** @endcond */
     288             : 
     289             : #if !defined(CMSG_FIRSTHDR)
     290             : /**
     291             :  * Returns a pointer to the first cmsghdr in the ancillary data buffer
     292             :  * associated with the passed msghdr.  It returns NULL if there isn't
     293             :  * enough space for a cmsghdr in the buffer.
     294             :  */
     295           1 : #define CMSG_FIRSTHDR(msghdr)                                   \
     296             :         ((msghdr)->msg_controllen >= sizeof(struct cmsghdr) ?     \
     297             :          (struct cmsghdr *)((msghdr)->msg_control) : NULL)
     298             : #endif
     299             : 
     300             : #if !defined(CMSG_NXTHDR)
     301             : /**
     302             :  * Returns the next valid cmsghdr after the passed cmsghdr. It returns NULL
     303             :  * when there isn't enough space left in the buffer.
     304             :  */
     305           1 : #define CMSG_NXTHDR(msghdr, cmsg)                                        \
     306             :         (((cmsg) == NULL) ? CMSG_FIRSTHDR(msghdr) :                      \
     307             :          (((uint8_t *)(cmsg) + ALIGN_H((cmsg)->cmsg_len) +            \
     308             :            ALIGN_D(sizeof(struct cmsghdr)) >                          \
     309             :            (uint8_t *)((msghdr)->msg_control) + (msghdr)->msg_controllen) ? \
     310             :           NULL :                                                         \
     311             :           (struct cmsghdr *)((uint8_t *)(cmsg) +                         \
     312             :                              ALIGN_H((cmsg)->cmsg_len))))
     313             : #endif
     314             : 
     315             : #if !defined(CMSG_DATA)
     316             : /**
     317             :  * Returns a pointer to the data portion of a cmsghdr.  The pointer returned
     318             :  * cannot be assumed to be suitably aligned for accessing arbitrary payload
     319             :  * data types. Applications should not cast it to a pointer type matching
     320             :  * the payload, but should instead use memcpy(3) to copy data to or from a
     321             :  * suitably declared object.
     322             :  */
     323           1 : #define CMSG_DATA(cmsg) ((uint8_t *)(cmsg) + ALIGN_D(sizeof(struct cmsghdr)))
     324             : #endif
     325             : 
     326             : #if !defined(CMSG_SPACE)
     327             : /**
     328             :  * Returns the number of bytes an ancillary element with payload of the passed
     329             :  * data length occupies.
     330             :  */
     331           1 : #define CMSG_SPACE(length) (ALIGN_D(sizeof(struct cmsghdr)) + ALIGN_H(length))
     332             : #endif
     333             : 
     334             : #if !defined(CMSG_LEN)
     335             : /**
     336             :  * Returns the value to store in the cmsg_len member of the cmsghdr structure,
     337             :  * taking into account any necessary alignment.
     338             :  * It takes the data length as an argument.
     339             :  */
     340           1 : #define CMSG_LEN(length) (ALIGN_D(sizeof(struct cmsghdr)) + length)
     341             : #endif
     342             : 
     343             : /** @cond INTERNAL_HIDDEN */
     344             : 
     345             : /* Packet types.  */
     346             : #define PACKET_HOST         0     /* To us            */
     347             : #define PACKET_BROADCAST    1     /* To all           */
     348             : #define PACKET_MULTICAST    2     /* To group         */
     349             : #define PACKET_OTHERHOST    3     /* To someone else  */
     350             : #define PACKET_OUTGOING     4     /* Originated by us */
     351             : #define PACKET_LOOPBACK     5
     352             : #define PACKET_FASTROUTE    6
     353             : 
     354             : /* ARP protocol HARDWARE identifiers. */
     355             : #define ARPHRD_ETHER 1
     356             : 
     357             : /* Note: These macros are defined in a specific order.
     358             :  * The largest sockaddr size is the last one.
     359             :  */
     360             : #if defined(CONFIG_NET_IPV4)
     361             : #undef NET_SOCKADDR_MAX_SIZE
     362             : #undef NET_SOCKADDR_PTR_MAX_SIZE
     363             : #define NET_SOCKADDR_MAX_SIZE (sizeof(struct sockaddr_in))
     364             : #define NET_SOCKADDR_PTR_MAX_SIZE (sizeof(struct sockaddr_in_ptr))
     365             : #endif
     366             : 
     367             : #if defined(CONFIG_NET_SOCKETS_PACKET)
     368             : #undef NET_SOCKADDR_MAX_SIZE
     369             : #undef NET_SOCKADDR_PTR_MAX_SIZE
     370             : #define NET_SOCKADDR_MAX_SIZE (sizeof(struct sockaddr_ll))
     371             : #define NET_SOCKADDR_PTR_MAX_SIZE (sizeof(struct sockaddr_ll_ptr))
     372             : #endif
     373             : 
     374             : #if defined(CONFIG_NET_IPV6)
     375             : #undef NET_SOCKADDR_MAX_SIZE
     376             : #define NET_SOCKADDR_MAX_SIZE (sizeof(struct sockaddr_in6))
     377             : #if !defined(CONFIG_NET_SOCKETS_PACKET)
     378             : #undef NET_SOCKADDR_PTR_MAX_SIZE
     379             : #define NET_SOCKADDR_PTR_MAX_SIZE (sizeof(struct sockaddr_in6_ptr))
     380             : #endif
     381             : #endif
     382             : 
     383             : #if defined(CONFIG_NET_NATIVE_OFFLOADED_SOCKETS)
     384             : #define UNIX_PATH_MAX 108
     385             : #undef NET_SOCKADDR_MAX_SIZE
     386             : /* Define NET_SOCKADDR_MAX_SIZE to be struct of sa_family_t + char[UNIX_PATH_MAX] */
     387             : #define NET_SOCKADDR_MAX_SIZE (UNIX_PATH_MAX+sizeof(sa_family_t))
     388             : #if !defined(CONFIG_NET_SOCKETS_PACKET)
     389             : #undef NET_SOCKADDR_PTR_MAX_SIZE
     390             : #define NET_SOCKADDR_PTR_MAX_SIZE (sizeof(struct sockaddr_un_ptr))
     391             : #endif
     392             : #endif
     393             : 
     394             : #if !defined(CONFIG_NET_IPV4)
     395             : #if !defined(CONFIG_NET_IPV6)
     396             : #if !defined(CONFIG_NET_SOCKETS_PACKET)
     397             : #if !defined(CONFIG_NET_NATIVE_OFFLOADED_SOCKETS)
     398             : #define NET_SOCKADDR_MAX_SIZE (sizeof(struct sockaddr_in6))
     399             : #define NET_SOCKADDR_PTR_MAX_SIZE (sizeof(struct sockaddr_in6_ptr))
     400             : #endif
     401             : #endif
     402             : #endif
     403             : #endif
     404             : 
     405             : /** @endcond */
     406             : 
     407             : /** Generic sockaddr struct. Must be cast to proper type. */
     408           1 : struct sockaddr {
     409           1 :         sa_family_t sa_family; /**< Address family */
     410             : /** @cond INTERNAL_HIDDEN */
     411             :         char data[NET_SOCKADDR_MAX_SIZE - sizeof(sa_family_t)];
     412             : /** @endcond */
     413             : };
     414             : 
     415             : /** @cond INTERNAL_HIDDEN */
     416             : 
     417             : struct sockaddr_ptr {
     418             :         sa_family_t family;
     419             :         char data[NET_SOCKADDR_PTR_MAX_SIZE - sizeof(sa_family_t)];
     420             : };
     421             : 
     422             : /* Same as sockaddr in our case */
     423             : struct sockaddr_storage {
     424             :         sa_family_t ss_family;
     425             :         char data[NET_SOCKADDR_MAX_SIZE - sizeof(sa_family_t)];
     426             : };
     427             : 
     428             : /* Socket address struct for UNIX domain sockets */
     429             : struct sockaddr_un {
     430             :         sa_family_t sun_family;    /* AF_UNIX */
     431             :         char        sun_path[NET_SOCKADDR_MAX_SIZE - sizeof(sa_family_t)];
     432             : };
     433             : 
     434             : struct net_addr {
     435             :         sa_family_t family;
     436             :         union {
     437             :                 struct in6_addr in6_addr;
     438             :                 struct in_addr in_addr;
     439             :         };
     440             : };
     441             : 
     442             : /** A pointer to IPv6 any address (all values zero) */
     443             : extern const struct in6_addr in6addr_any;
     444             : 
     445             : /** A pointer to IPv6 loopback address (::1) */
     446             : extern const struct in6_addr in6addr_loopback;
     447             : 
     448             : /** @endcond */
     449             : 
     450             : /** IPv6 address initializer */
     451           1 : #define IN6ADDR_ANY_INIT { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     452             :                                 0, 0, 0, 0, 0, 0, 0 } } }
     453             : 
     454             : /** IPv6 loopback address initializer */
     455           1 : #define IN6ADDR_LOOPBACK_INIT { { { 0, 0, 0, 0, 0, 0, 0, \
     456             :                                 0, 0, 0, 0, 0, 0, 0, 0, 1 } } }
     457             : 
     458             : /** IPv4 any address */
     459           1 : #define INADDR_ANY 0
     460             : 
     461             : /** IPv4 broadcast address */
     462           1 : #define INADDR_BROADCAST 0xffffffff
     463             : 
     464             : /** IPv4 address initializer */
     465           1 : #define INADDR_ANY_INIT { { { INADDR_ANY } } }
     466             : 
     467             : /** IPv6 loopback address initializer */
     468           1 : #define INADDR_LOOPBACK_INIT  { { { 127, 0, 0, 1 } } }
     469             : 
     470             : /** Max length of the IPv4 address as a string. Defined by POSIX. */
     471           1 : #define INET_ADDRSTRLEN 16
     472             : /** Max length of the IPv6 address as a string. Takes into account possible
     473             :  * mapped IPv4 addresses.
     474             :  */
     475           1 : #define INET6_ADDRSTRLEN 46
     476             : 
     477             : /** @cond INTERNAL_HIDDEN */
     478             : 
     479             : /* These are for internal usage of the stack */
     480             : #define NET_IPV6_ADDR_LEN sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")
     481             : #define NET_IPV4_ADDR_LEN sizeof("xxx.xxx.xxx.xxx")
     482             : 
     483             : /** @endcond */
     484             : 
     485             : /** @brief IP Maximum Transfer Unit */
     486           1 : enum net_ip_mtu {
     487             :         /** IPv6 MTU length. We must be able to receive this size IPv6 packet
     488             :          * without fragmentation.
     489             :          */
     490             : #if defined(CONFIG_NET_NATIVE_IPV6)
     491             :         NET_IPV6_MTU = CONFIG_NET_IPV6_MTU,
     492             : #else
     493             :         NET_IPV6_MTU = 1280,
     494             : #endif
     495             : 
     496             :         /** IPv4 MTU length. We must be able to receive this size IPv4 packet
     497             :          * without fragmentation.
     498             :          */
     499             :         NET_IPV4_MTU = 576,
     500             : };
     501             : 
     502             : /** @brief Network packet priority settings described in IEEE 802.1Q Annex I.1 */
     503           1 : enum net_priority {
     504             :         NET_PRIORITY_BK = 1, /**< Background (lowest)                */
     505             :         NET_PRIORITY_BE = 0, /**< Best effort (default)              */
     506             :         NET_PRIORITY_EE = 2, /**< Excellent effort                   */
     507             :         NET_PRIORITY_CA = 3, /**< Critical applications              */
     508             :         NET_PRIORITY_VI = 4, /**< Video, < 100 ms latency and jitter */
     509             :         NET_PRIORITY_VO = 5, /**< Voice, < 10 ms latency and jitter  */
     510             :         NET_PRIORITY_IC = 6, /**< Internetwork control               */
     511             :         NET_PRIORITY_NC = 7  /**< Network control (highest)          */
     512             : } __packed;
     513             : 
     514           1 : #define NET_MAX_PRIORITIES 8 /**< How many priority values there are */
     515             : 
     516             : /** @brief IPv6/IPv4 network connection tuple */
     517           1 : struct net_tuple {
     518           1 :         struct net_addr *remote_addr;  /**< IPv6/IPv4 remote address */
     519           1 :         struct net_addr *local_addr;   /**< IPv6/IPv4 local address  */
     520           1 :         uint16_t remote_port;          /**< UDP/TCP remote port      */
     521           1 :         uint16_t local_port;           /**< UDP/TCP local port       */
     522           1 :         enum net_ip_protocol ip_proto; /**< IP protocol              */
     523             : };
     524             : 
     525             : /** @brief What is the current state of the network address */
     526           1 : enum net_addr_state {
     527             :         NET_ADDR_ANY_STATE = -1, /**< Default (invalid) address type */
     528             :         NET_ADDR_TENTATIVE = 0,  /**< Tentative address              */
     529             :         NET_ADDR_PREFERRED,      /**< Preferred address              */
     530             :         NET_ADDR_DEPRECATED,     /**< Deprecated address             */
     531             : } __packed;
     532             : 
     533             : /** @brief How the network address is assigned to network interface */
     534           1 : enum net_addr_type {
     535             :         /** Default value. This is not a valid value. */
     536             :         NET_ADDR_ANY = 0,
     537             :         /** Auto configured address */
     538             :         NET_ADDR_AUTOCONF,
     539             :         /** Address is from DHCP */
     540             :         NET_ADDR_DHCP,
     541             :         /** Manually set address */
     542             :         NET_ADDR_MANUAL,
     543             :         /** Manually set address which is overridable by DHCP */
     544             :         NET_ADDR_OVERRIDABLE,
     545             : } __packed;
     546             : 
     547             : /** @cond INTERNAL_HIDDEN */
     548             : 
     549             : struct net_ipv6_hdr {
     550             :         uint8_t vtc;
     551             :         uint8_t tcflow;
     552             :         uint16_t flow;
     553             :         uint16_t len;
     554             :         uint8_t nexthdr;
     555             :         uint8_t hop_limit;
     556             :         uint8_t src[NET_IPV6_ADDR_SIZE];
     557             :         uint8_t dst[NET_IPV6_ADDR_SIZE];
     558             : } __packed;
     559             : 
     560             : struct net_ipv6_frag_hdr {
     561             :         uint8_t nexthdr;
     562             :         uint8_t reserved;
     563             :         uint16_t offset;
     564             :         uint32_t id;
     565             : } __packed;
     566             : 
     567             : struct net_ipv4_hdr {
     568             :         uint8_t vhl;
     569             :         uint8_t tos;
     570             :         uint16_t len;
     571             :         uint8_t id[2];
     572             :         uint8_t offset[2];
     573             :         uint8_t ttl;
     574             :         uint8_t proto;
     575             :         uint16_t chksum;
     576             :         uint8_t src[NET_IPV4_ADDR_SIZE];
     577             :         uint8_t dst[NET_IPV4_ADDR_SIZE];
     578             : } __packed;
     579             : 
     580             : struct net_icmp_hdr {
     581             :         uint8_t type;
     582             :         uint8_t code;
     583             :         uint16_t chksum;
     584             : } __packed;
     585             : 
     586             : struct net_udp_hdr {
     587             :         uint16_t src_port;
     588             :         uint16_t dst_port;
     589             :         uint16_t len;
     590             :         uint16_t chksum;
     591             : } __packed;
     592             : 
     593             : struct net_tcp_hdr {
     594             :         uint16_t src_port;
     595             :         uint16_t dst_port;
     596             :         uint8_t seq[4];
     597             :         uint8_t ack[4];
     598             :         uint8_t offset;
     599             :         uint8_t flags;
     600             :         uint8_t wnd[2];
     601             :         uint16_t chksum;
     602             :         uint8_t urg[2];
     603             :         uint8_t optdata[0];
     604             : } __packed;
     605             : 
     606             : static inline const char *net_addr_type2str(enum net_addr_type type)
     607             : {
     608             :         switch (type) {
     609             :         case NET_ADDR_AUTOCONF:
     610             :                 return "AUTO";
     611             :         case NET_ADDR_DHCP:
     612             :                 return "DHCP";
     613             :         case NET_ADDR_MANUAL:
     614             :                 return "MANUAL";
     615             :         case NET_ADDR_OVERRIDABLE:
     616             :                 return "OVERRIDE";
     617             :         case NET_ADDR_ANY:
     618             :         default:
     619             :                 break;
     620             :         }
     621             : 
     622             :         return "<unknown>";
     623             : }
     624             : 
     625             : /* IPv6 extension headers types */
     626             : #define NET_IPV6_NEXTHDR_HBHO        0
     627             : #define NET_IPV6_NEXTHDR_DESTO       60
     628             : #define NET_IPV6_NEXTHDR_ROUTING     43
     629             : #define NET_IPV6_NEXTHDR_FRAG        44
     630             : #define NET_IPV6_NEXTHDR_NONE        59
     631             : 
     632             : /**
     633             :  * This 2 unions are here temporarily, as long as net_context.h will
     634             :  * be still public and not part of the core only.
     635             :  */
     636             : union net_ip_header {
     637             :         struct net_ipv4_hdr *ipv4;
     638             :         struct net_ipv6_hdr *ipv6;
     639             : };
     640             : 
     641             : union net_proto_header {
     642             :         struct net_udp_hdr *udp;
     643             :         struct net_tcp_hdr *tcp;
     644             : };
     645             : 
     646             : #define NET_UDPH_LEN    8                       /* Size of UDP header */
     647             : #define NET_TCPH_LEN    20                      /* Size of TCP header */
     648             : #define NET_ICMPH_LEN   4                       /* Size of ICMP header */
     649             : 
     650             : #define NET_IPV6H_LEN      40                   /* Size of IPv6 header */
     651             : #define NET_ICMPV6H_LEN    NET_ICMPH_LEN        /* Size of ICMPv6 header */
     652             : #define NET_IPV6UDPH_LEN   (NET_UDPH_LEN + NET_IPV6H_LEN) /* IPv6 + UDP */
     653             : #define NET_IPV6TCPH_LEN   (NET_TCPH_LEN + NET_IPV6H_LEN) /* IPv6 + TCP */
     654             : #define NET_IPV6ICMPH_LEN  (NET_IPV6H_LEN + NET_ICMPH_LEN) /* ICMPv6 + IPv6 */
     655             : #define NET_IPV6_FRAGH_LEN 8
     656             : 
     657             : #define NET_IPV4H_LEN      20                   /* Size of IPv4 header */
     658             : #define NET_ICMPV4H_LEN    NET_ICMPH_LEN        /* Size of ICMPv4 header */
     659             : #define NET_IPV4UDPH_LEN   (NET_UDPH_LEN + NET_IPV4H_LEN) /* IPv4 + UDP */
     660             : #define NET_IPV4TCPH_LEN   (NET_TCPH_LEN + NET_IPV4H_LEN) /* IPv4 + TCP */
     661             : #define NET_IPV4ICMPH_LEN  (NET_IPV4H_LEN + NET_ICMPH_LEN) /* ICMPv4 + IPv4 */
     662             : 
     663             : #define NET_IPV6H_LENGTH_OFFSET         0x04    /* Offset of the Length field in the IPv6 header */
     664             : 
     665             : #define NET_IPV6_FRAGH_OFFSET_MASK      0xfff8  /* Mask for the 13-bit Fragment Offset field */
     666             : #define NET_IPV4_FRAGH_OFFSET_MASK      0x1fff  /* Mask for the 13-bit Fragment Offset field */
     667             : #define NET_IPV4_MORE_FRAG_MASK         0x2000  /* Mask for the 1-bit More Fragments field */
     668             : #define NET_IPV4_DO_NOT_FRAG_MASK       0x4000  /* Mask for the 1-bit Do Not Fragment field */
     669             : 
     670             : /** @endcond */
     671             : 
     672             : /**
     673             :  * @brief Check if the IPv6 address is a loopback address (::1).
     674             :  *
     675             :  * @param addr IPv6 address
     676             :  *
     677             :  * @return True if address is a loopback address, False otherwise.
     678             :  */
     679           1 : static inline bool net_ipv6_is_addr_loopback(struct in6_addr *addr)
     680             : {
     681             :         return UNALIGNED_GET(&addr->s6_addr32[0]) == 0 &&
     682             :                 UNALIGNED_GET(&addr->s6_addr32[1]) == 0 &&
     683             :                 UNALIGNED_GET(&addr->s6_addr32[2]) == 0 &&
     684             :                 ntohl(UNALIGNED_GET(&addr->s6_addr32[3])) == 1;
     685             : }
     686             : 
     687             : /**
     688             :  * @brief Check if the IPv6 address is a multicast address.
     689             :  *
     690             :  * @param addr IPv6 address
     691             :  *
     692             :  * @return True if address is multicast address, False otherwise.
     693             :  */
     694           1 : static inline bool net_ipv6_is_addr_mcast(const struct in6_addr *addr)
     695             : {
     696             :         return addr->s6_addr[0] == 0xFF;
     697             : }
     698             : 
     699             : struct net_if;
     700             : struct net_if_config;
     701             : 
     702           0 : extern struct net_if_addr *net_if_ipv6_addr_lookup(const struct in6_addr *addr,
     703             :                                                    struct net_if **iface);
     704             : 
     705             : /**
     706             :  * @brief Check if IPv6 address is found in one of the network interfaces.
     707             :  *
     708             :  * @param addr IPv6 address
     709             :  *
     710             :  * @return True if address was found, False otherwise.
     711             :  */
     712           1 : static inline bool net_ipv6_is_my_addr(struct in6_addr *addr)
     713             : {
     714             :         return net_if_ipv6_addr_lookup(addr, NULL) != NULL;
     715             : }
     716             : 
     717           0 : extern struct net_if_mcast_addr *net_if_ipv6_maddr_lookup(
     718             :         const struct in6_addr *addr, struct net_if **iface);
     719             : 
     720             : /**
     721             :  * @brief Check if IPv6 multicast address is found in one of the
     722             :  * network interfaces.
     723             :  *
     724             :  * @param maddr Multicast IPv6 address
     725             :  *
     726             :  * @return True if address was found, False otherwise.
     727             :  */
     728           1 : static inline bool net_ipv6_is_my_maddr(struct in6_addr *maddr)
     729             : {
     730             :         return net_if_ipv6_maddr_lookup(maddr, NULL) != NULL;
     731             : }
     732             : 
     733             : /**
     734             :  * @brief Check if two IPv6 addresses are same when compared after prefix mask.
     735             :  *
     736             :  * @param addr1 First IPv6 address.
     737             :  * @param addr2 Second IPv6 address.
     738             :  * @param length Prefix length (max length is 128).
     739             :  *
     740             :  * @return True if IPv6 prefixes are the same, False otherwise.
     741             :  */
     742           1 : static inline bool net_ipv6_is_prefix(const uint8_t *addr1,
     743             :                                       const uint8_t *addr2,
     744             :                                       uint8_t length)
     745             : {
     746             :         uint8_t bits = 128 - length;
     747             :         uint8_t bytes = length / 8U;
     748             :         uint8_t remain = bits % 8;
     749             :         uint8_t mask;
     750             : 
     751             :         if (length > 128) {
     752             :                 return false;
     753             :         }
     754             : 
     755             :         if (memcmp(addr1, addr2, bytes)) {
     756             :                 return false;
     757             :         }
     758             : 
     759             :         if (!remain) {
     760             :                 /* No remaining bits, the prefixes are the same as first
     761             :                  * bytes are the same.
     762             :                  */
     763             :                 return true;
     764             :         }
     765             : 
     766             :         /* Create a mask that has remaining most significant bits set */
     767             :         mask = (uint8_t)((0xff << (8 - remain)) ^ 0xff) << remain;
     768             : 
     769             :         return (addr1[bytes] & mask) == (addr2[bytes] & mask);
     770             : }
     771             : 
     772             : 
     773             : /**
     774             :  * @brief Get the IPv6 network address via the unicast address and the prefix mask.
     775             :  *
     776             :  * @param inaddr Unicast IPv6 address.
     777             :  * @param outaddr Prefix masked IPv6 address (network address).
     778             :  * @param prefix_len Prefix length (max length is 128).
     779             :  */
     780           1 : static inline void net_ipv6_addr_prefix_mask(const uint8_t *inaddr,
     781             :                                              uint8_t *outaddr,
     782             :                                              uint8_t prefix_len)
     783             : {
     784             :         uint8_t bits = 128 - prefix_len;
     785             :         uint8_t bytes = prefix_len / 8U;
     786             :         uint8_t remain = bits % 8;
     787             :         uint8_t mask;
     788             : 
     789             :         memset(outaddr, 0, 16U);
     790             :         memcpy(outaddr, inaddr, bytes);
     791             : 
     792             :         if (!remain) {
     793             :                 /* No remaining bits, the prefixes are the same as first
     794             :                  * bytes are the same.
     795             :                  */
     796             :                 return;
     797             :         }
     798             : 
     799             :         /* Create a mask that has remaining most significant bits set */
     800             :         mask = (uint8_t)((0xff << (8 - remain)) ^ 0xff) << remain;
     801             :         outaddr[bytes] = inaddr[bytes] & mask;
     802             : }
     803             : 
     804             : /**
     805             :  * @brief Check if the IPv4 address is a loopback address (127.0.0.0/8).
     806             :  *
     807             :  * @param addr IPv4 address
     808             :  *
     809             :  * @return True if address is a loopback address, False otherwise.
     810             :  */
     811           1 : static inline bool net_ipv4_is_addr_loopback(struct in_addr *addr)
     812             : {
     813             :         return addr->s4_addr[0] == 127U;
     814             : }
     815             : 
     816             : /**
     817             :  *  @brief Check if the IPv4 address is unspecified (all bits zero)
     818             :  *
     819             :  *  @param addr IPv4 address.
     820             :  *
     821             :  *  @return True if the address is unspecified, false otherwise.
     822             :  */
     823           1 : static inline bool net_ipv4_is_addr_unspecified(const struct in_addr *addr)
     824             : {
     825             :         return UNALIGNED_GET(&addr->s_addr) == 0;
     826             : }
     827             : 
     828             : /**
     829             :  * @brief Check if the IPv4 address is a multicast address.
     830             :  *
     831             :  * @param addr IPv4 address
     832             :  *
     833             :  * @return True if address is multicast address, False otherwise.
     834             :  */
     835           1 : static inline bool net_ipv4_is_addr_mcast(const struct in_addr *addr)
     836             : {
     837             :         return (ntohl(UNALIGNED_GET(&addr->s_addr)) & 0xF0000000) == 0xE0000000;
     838             : }
     839             : 
     840             : /**
     841             :  * @brief Check if the given IPv4 address is a link local address.
     842             :  *
     843             :  * @param addr A valid pointer on an IPv4 address
     844             :  *
     845             :  * @return True if it is, false otherwise.
     846             :  */
     847           1 : static inline bool net_ipv4_is_ll_addr(const struct in_addr *addr)
     848             : {
     849             :         return (ntohl(UNALIGNED_GET(&addr->s_addr)) & 0xFFFF0000) == 0xA9FE0000;
     850             : }
     851             : 
     852             : /**
     853             :  * @brief Check if the given IPv4 address is from a private address range.
     854             :  *
     855             :  * See https://en.wikipedia.org/wiki/Reserved_IP_addresses for details.
     856             :  *
     857             :  * @param addr A valid pointer on an IPv4 address
     858             :  *
     859             :  * @return True if it is, false otherwise.
     860             :  */
     861           1 : static inline bool net_ipv4_is_private_addr(const struct in_addr *addr)
     862             : {
     863             :         uint32_t masked_24, masked_16, masked_12, masked_10, masked_8;
     864             : 
     865             :         masked_24 = ntohl(UNALIGNED_GET(&addr->s_addr)) & 0xFFFFFF00;
     866             :         masked_16 = masked_24 & 0xFFFF0000;
     867             :         masked_12 = masked_24 & 0xFFF00000;
     868             :         masked_10 = masked_24 & 0xFFC00000;
     869             :         masked_8 = masked_24 & 0xFF000000;
     870             : 
     871             :         return masked_8  == 0x0A000000 || /* 10.0.0.0/8      */
     872             :                masked_10 == 0x64400000 || /* 100.64.0.0/10   */
     873             :                masked_12 == 0xAC100000 || /* 172.16.0.0/12   */
     874             :                masked_16 == 0xC0A80000 || /* 192.168.0.0/16  */
     875             :                masked_24 == 0xC0000200 || /* 192.0.2.0/24    */
     876             :                masked_24 == 0xC0336400 || /* 192.51.100.0/24 */
     877             :                masked_24 == 0xCB007100;   /* 203.0.113.0/24  */
     878             : }
     879             : 
     880             : /**
     881             :  *  @brief Copy an IPv4 or IPv6 address
     882             :  *
     883             :  *  @param dest Destination IP address.
     884             :  *  @param src Source IP address.
     885             :  *
     886             :  *  @return Destination address.
     887             :  */
     888           1 : #define net_ipaddr_copy(dest, src) \
     889             :         UNALIGNED_PUT(UNALIGNED_GET(src), dest)
     890             : 
     891             : /**
     892             :  *  @brief Copy an IPv4 address raw buffer
     893             :  *
     894             :  *  @param dest Destination IP address.
     895             :  *  @param src Source IP address.
     896             :  */
     897           1 : static inline void net_ipv4_addr_copy_raw(uint8_t *dest,
     898             :                                           const uint8_t *src)
     899             : {
     900             :         net_ipaddr_copy((struct in_addr *)dest, (const struct in_addr *)src);
     901             : }
     902             : 
     903             : /**
     904             :  *  @brief Copy an IPv6 address raw buffer
     905             :  *
     906             :  *  @param dest Destination IP address.
     907             :  *  @param src Source IP address.
     908             :  */
     909           1 : static inline void net_ipv6_addr_copy_raw(uint8_t *dest,
     910             :                                           const uint8_t *src)
     911             : {
     912             :         memcpy(dest, src, sizeof(struct in6_addr));
     913             : }
     914             : 
     915             : /**
     916             :  *  @brief Compare two IPv4 addresses
     917             :  *
     918             :  *  @param addr1 Pointer to IPv4 address.
     919             :  *  @param addr2 Pointer to IPv4 address.
     920             :  *
     921             :  *  @return True if the addresses are the same, false otherwise.
     922             :  */
     923           1 : static inline bool net_ipv4_addr_cmp(const struct in_addr *addr1,
     924             :                                      const struct in_addr *addr2)
     925             : {
     926             :         return UNALIGNED_GET(&addr1->s_addr) == UNALIGNED_GET(&addr2->s_addr);
     927             : }
     928             : 
     929             : /**
     930             :  *  @brief Compare two raw IPv4 address buffers
     931             :  *
     932             :  *  @param addr1 Pointer to IPv4 address buffer.
     933             :  *  @param addr2 Pointer to IPv4 address buffer.
     934             :  *
     935             :  *  @return True if the addresses are the same, false otherwise.
     936             :  */
     937           1 : static inline bool net_ipv4_addr_cmp_raw(const uint8_t *addr1,
     938             :                                          const uint8_t *addr2)
     939             : {
     940             :         return net_ipv4_addr_cmp((const struct in_addr *)addr1,
     941             :                                  (const struct in_addr *)addr2);
     942             : }
     943             : 
     944             : /**
     945             :  *  @brief Compare two IPv6 addresses
     946             :  *
     947             :  *  @param addr1 Pointer to IPv6 address.
     948             :  *  @param addr2 Pointer to IPv6 address.
     949             :  *
     950             :  *  @return True if the addresses are the same, false otherwise.
     951             :  */
     952           1 : static inline bool net_ipv6_addr_cmp(const struct in6_addr *addr1,
     953             :                                      const struct in6_addr *addr2)
     954             : {
     955             :         return !memcmp(addr1, addr2, sizeof(struct in6_addr));
     956             : }
     957             : 
     958             : /**
     959             :  *  @brief Compare two raw IPv6 address buffers
     960             :  *
     961             :  *  @param addr1 Pointer to IPv6 address buffer.
     962             :  *  @param addr2 Pointer to IPv6 address buffer.
     963             :  *
     964             :  *  @return True if the addresses are the same, false otherwise.
     965             :  */
     966           1 : static inline bool net_ipv6_addr_cmp_raw(const uint8_t *addr1,
     967             :                                          const uint8_t *addr2)
     968             : {
     969             :         return net_ipv6_addr_cmp((const struct in6_addr *)addr1,
     970             :                                  (const struct in6_addr *)addr2);
     971             : }
     972             : 
     973             : /**
     974             :  * @brief Check if the given IPv6 address is a link local address.
     975             :  *
     976             :  * @param addr A valid pointer on an IPv6 address
     977             :  *
     978             :  * @return True if it is, false otherwise.
     979             :  */
     980           1 : static inline bool net_ipv6_is_ll_addr(const struct in6_addr *addr)
     981             : {
     982             :         return UNALIGNED_GET(&addr->s6_addr16[0]) == htons(0xFE80);
     983             : }
     984             : 
     985             : /**
     986             :  * @brief Check if the given IPv6 address is a site local address.
     987             :  *
     988             :  * @param addr A valid pointer on an IPv6 address
     989             :  *
     990             :  * @return True if it is, false otherwise.
     991             :  */
     992           1 : static inline bool net_ipv6_is_sl_addr(const struct in6_addr *addr)
     993             : {
     994             :         return UNALIGNED_GET(&addr->s6_addr16[0]) == htons(0xFEC0);
     995             : }
     996             : 
     997             : 
     998             : /**
     999             :  * @brief Check if the given IPv6 address is a unique local address.
    1000             :  *
    1001             :  * @param addr A valid pointer on an IPv6 address
    1002             :  *
    1003             :  * @return True if it is, false otherwise.
    1004             :  */
    1005           1 : static inline bool net_ipv6_is_ula_addr(const struct in6_addr *addr)
    1006             : {
    1007             :         return addr->s6_addr[0] == 0xFD;
    1008             : }
    1009             : 
    1010             : /**
    1011             :  * @brief Check if the given IPv6 address is a global address.
    1012             :  *
    1013             :  * @param addr A valid pointer on an IPv6 address
    1014             :  *
    1015             :  * @return True if it is, false otherwise.
    1016             :  */
    1017           1 : static inline bool net_ipv6_is_global_addr(const struct in6_addr *addr)
    1018             : {
    1019             :         return (addr->s6_addr[0] & 0xE0) == 0x20;
    1020             : }
    1021             : 
    1022             : /**
    1023             :  * @brief Check if the given IPv6 address is from a private/local address range.
    1024             :  *
    1025             :  * See https://en.wikipedia.org/wiki/Reserved_IP_addresses for details.
    1026             :  *
    1027             :  * @param addr A valid pointer on an IPv6 address
    1028             :  *
    1029             :  * @return True if it is, false otherwise.
    1030             :  */
    1031           1 : static inline bool net_ipv6_is_private_addr(const struct in6_addr *addr)
    1032             : {
    1033             :         uint32_t masked_32, masked_7;
    1034             : 
    1035             :         masked_32 = ntohl(UNALIGNED_GET(&addr->s6_addr32[0]));
    1036             :         masked_7 = masked_32 & 0xfc000000;
    1037             : 
    1038             :         return masked_32 == 0x20010db8 || /* 2001:db8::/32 */
    1039             :                masked_7  == 0xfc000000;   /* fc00::/7      */
    1040             : }
    1041             : 
    1042             : /**
    1043             :  * @brief Return pointer to any (all bits zeros) IPv6 address.
    1044             :  *
    1045             :  * @return Any IPv6 address.
    1046             :  */
    1047           1 : const struct in6_addr *net_ipv6_unspecified_address(void);
    1048             : 
    1049             : /**
    1050             :  * @brief Return pointer to any (all bits zeros) IPv4 address.
    1051             :  *
    1052             :  * @return Any IPv4 address.
    1053             :  */
    1054           1 : const struct in_addr *net_ipv4_unspecified_address(void);
    1055             : 
    1056             : /**
    1057             :  * @brief Return pointer to broadcast (all bits ones) IPv4 address.
    1058             :  *
    1059             :  * @return Broadcast IPv4 address.
    1060             :  */
    1061           1 : const struct in_addr *net_ipv4_broadcast_address(void);
    1062             : 
    1063             : struct net_if;
    1064           0 : extern bool net_if_ipv4_addr_mask_cmp(struct net_if *iface,
    1065             :                                       const struct in_addr *addr);
    1066             : 
    1067             : /**
    1068             :  * @brief Check if the given address belongs to same subnet that
    1069             :  * has been configured for the interface.
    1070             :  *
    1071             :  * @param iface A valid pointer on an interface
    1072             :  * @param addr IPv4 address
    1073             :  *
    1074             :  * @return True if address is in same subnet, false otherwise.
    1075             :  */
    1076           1 : static inline bool net_ipv4_addr_mask_cmp(struct net_if *iface,
    1077             :                                           const struct in_addr *addr)
    1078             : {
    1079             :         return net_if_ipv4_addr_mask_cmp(iface, addr);
    1080             : }
    1081             : 
    1082           0 : extern bool net_if_ipv4_is_addr_bcast(struct net_if *iface,
    1083             :                                       const struct in_addr *addr);
    1084             : 
    1085             : /**
    1086             :  * @brief Check if the given IPv4 address is a broadcast address.
    1087             :  *
    1088             :  * @param iface Interface to use. Must be a valid pointer to an interface.
    1089             :  * @param addr IPv4 address
    1090             :  *
    1091             :  * @return True if address is a broadcast address, false otherwise.
    1092             :  */
    1093             : #if defined(CONFIG_NET_NATIVE_IPV4)
    1094             : static inline bool net_ipv4_is_addr_bcast(struct net_if *iface,
    1095             :                                           const struct in_addr *addr)
    1096             : {
    1097             :         if (net_ipv4_addr_cmp(addr, net_ipv4_broadcast_address())) {
    1098             :                 return true;
    1099             :         }
    1100             : 
    1101             :         return net_if_ipv4_is_addr_bcast(iface, addr);
    1102             : }
    1103             : #else
    1104           1 : static inline bool net_ipv4_is_addr_bcast(struct net_if *iface,
    1105             :                                           const struct in_addr *addr)
    1106             : {
    1107             :         ARG_UNUSED(iface);
    1108             :         ARG_UNUSED(addr);
    1109             : 
    1110             :         return false;
    1111             : }
    1112             : #endif
    1113             : 
    1114           0 : extern struct net_if_addr *net_if_ipv4_addr_lookup(const struct in_addr *addr,
    1115             :                                                    struct net_if **iface);
    1116             : 
    1117             : /**
    1118             :  * @brief Check if the IPv4 address is assigned to any network interface
    1119             :  * in the system.
    1120             :  *
    1121             :  * @param addr A valid pointer on an IPv4 address
    1122             :  *
    1123             :  * @return True if IPv4 address is found in one of the network interfaces,
    1124             :  * False otherwise.
    1125             :  */
    1126           1 : static inline bool net_ipv4_is_my_addr(const struct in_addr *addr)
    1127             : {
    1128             :         bool ret;
    1129             : 
    1130             :         ret = net_if_ipv4_addr_lookup(addr, NULL) != NULL;
    1131             :         if (!ret) {
    1132             :                 ret = net_ipv4_is_addr_bcast(NULL, addr);
    1133             :         }
    1134             : 
    1135             :         return ret;
    1136             : }
    1137             : 
    1138             : /**
    1139             :  *  @brief Check if the IPv6 address is unspecified (all bits zero)
    1140             :  *
    1141             :  *  @param addr IPv6 address.
    1142             :  *
    1143             :  *  @return True if the address is unspecified, false otherwise.
    1144             :  */
    1145           1 : static inline bool net_ipv6_is_addr_unspecified(const struct in6_addr *addr)
    1146             : {
    1147             :         return UNALIGNED_GET(&addr->s6_addr32[0]) == 0 &&
    1148             :                 UNALIGNED_GET(&addr->s6_addr32[1]) == 0 &&
    1149             :                 UNALIGNED_GET(&addr->s6_addr32[2]) == 0 &&
    1150             :                 UNALIGNED_GET(&addr->s6_addr32[3]) == 0;
    1151             : }
    1152             : 
    1153             : /**
    1154             :  *  @brief Check if the IPv6 address is solicited node multicast address
    1155             :  *  FF02:0:0:0:0:1:FFXX:XXXX defined in RFC 3513
    1156             :  *
    1157             :  *  @param addr IPv6 address.
    1158             :  *
    1159             :  *  @return True if the address is solicited node address, false otherwise.
    1160             :  */
    1161           1 : static inline bool net_ipv6_is_addr_solicited_node(const struct in6_addr *addr)
    1162             : {
    1163             :         return UNALIGNED_GET(&addr->s6_addr32[0]) == htonl(0xff020000) &&
    1164             :                 UNALIGNED_GET(&addr->s6_addr32[1]) == 0x00000000 &&
    1165             :                 UNALIGNED_GET(&addr->s6_addr32[2]) == htonl(0x00000001) &&
    1166             :                 ((UNALIGNED_GET(&addr->s6_addr32[3]) & htonl(0xff000000)) ==
    1167             :                  htonl(0xff000000));
    1168             : }
    1169             : 
    1170             : /**
    1171             :  * @brief Check if the IPv6 address is a given scope multicast
    1172             :  * address (FFyx::).
    1173             :  *
    1174             :  * @param addr IPv6 address
    1175             :  * @param scope Scope to check
    1176             :  *
    1177             :  * @return True if the address is in given scope multicast address,
    1178             :  * false otherwise.
    1179             :  */
    1180           1 : static inline bool net_ipv6_is_addr_mcast_scope(const struct in6_addr *addr,
    1181             :                                                 int scope)
    1182             : {
    1183             :         return (addr->s6_addr[0] == 0xff) && ((addr->s6_addr[1] & 0xF) == scope);
    1184             : }
    1185             : 
    1186             : /**
    1187             :  * @brief Check if the IPv6 addresses have the same multicast scope (FFyx::).
    1188             :  *
    1189             :  * @param addr_1 IPv6 address 1
    1190             :  * @param addr_2 IPv6 address 2
    1191             :  *
    1192             :  * @return True if both addresses have same multicast scope,
    1193             :  * false otherwise.
    1194             :  */
    1195           1 : static inline bool net_ipv6_is_same_mcast_scope(const struct in6_addr *addr_1,
    1196             :                                                 const struct in6_addr *addr_2)
    1197             : {
    1198             :         return (addr_1->s6_addr[0] == 0xff) && (addr_2->s6_addr[0] == 0xff) &&
    1199             :                         (addr_1->s6_addr[1] == addr_2->s6_addr[1]);
    1200             : }
    1201             : 
    1202             : /**
    1203             :  * @brief Check if the IPv6 address is a global multicast address (FFxE::/16).
    1204             :  *
    1205             :  * @param addr IPv6 address.
    1206             :  *
    1207             :  * @return True if the address is global multicast address, false otherwise.
    1208             :  */
    1209           1 : static inline bool net_ipv6_is_addr_mcast_global(const struct in6_addr *addr)
    1210             : {
    1211             :         return net_ipv6_is_addr_mcast_scope(addr, 0x0e);
    1212             : }
    1213             : 
    1214             : /**
    1215             :  * @brief Check if the IPv6 address is a interface scope multicast
    1216             :  * address (FFx1::).
    1217             :  *
    1218             :  * @param addr IPv6 address.
    1219             :  *
    1220             :  * @return True if the address is a interface scope multicast address,
    1221             :  * false otherwise.
    1222             :  */
    1223           1 : static inline bool net_ipv6_is_addr_mcast_iface(const struct in6_addr *addr)
    1224             : {
    1225             :         return net_ipv6_is_addr_mcast_scope(addr, 0x01);
    1226             : }
    1227             : 
    1228             : /**
    1229             :  * @brief Check if the IPv6 address is a link local scope multicast
    1230             :  * address (FFx2::).
    1231             :  *
    1232             :  * @param addr IPv6 address.
    1233             :  *
    1234             :  * @return True if the address is a link local scope multicast address,
    1235             :  * false otherwise.
    1236             :  */
    1237           1 : static inline bool net_ipv6_is_addr_mcast_link(const struct in6_addr *addr)
    1238             : {
    1239             :         return net_ipv6_is_addr_mcast_scope(addr, 0x02);
    1240             : }
    1241             : 
    1242             : /**
    1243             :  * @brief Check if the IPv6 address is a mesh-local scope multicast
    1244             :  * address (FFx3::).
    1245             :  *
    1246             :  * @param addr IPv6 address.
    1247             :  *
    1248             :  * @return True if the address is a mesh-local scope multicast address,
    1249             :  * false otherwise.
    1250             :  */
    1251           1 : static inline bool net_ipv6_is_addr_mcast_mesh(const struct in6_addr *addr)
    1252             : {
    1253             :         return net_ipv6_is_addr_mcast_scope(addr, 0x03);
    1254             : }
    1255             : 
    1256             : /**
    1257             :  * @brief Check if the IPv6 address is a site scope multicast
    1258             :  * address (FFx5::).
    1259             :  *
    1260             :  * @param addr IPv6 address.
    1261             :  *
    1262             :  * @return True if the address is a site scope multicast address,
    1263             :  * false otherwise.
    1264             :  */
    1265           1 : static inline bool net_ipv6_is_addr_mcast_site(const struct in6_addr *addr)
    1266             : {
    1267             :         return net_ipv6_is_addr_mcast_scope(addr, 0x05);
    1268             : }
    1269             : 
    1270             : /**
    1271             :  * @brief Check if the IPv6 address is an organization scope multicast
    1272             :  * address (FFx8::).
    1273             :  *
    1274             :  * @param addr IPv6 address.
    1275             :  *
    1276             :  * @return True if the address is an organization scope multicast address,
    1277             :  * false otherwise.
    1278             :  */
    1279           1 : static inline bool net_ipv6_is_addr_mcast_org(const struct in6_addr *addr)
    1280             : {
    1281             :         return net_ipv6_is_addr_mcast_scope(addr, 0x08);
    1282             : }
    1283             : 
    1284             : /**
    1285             :  * @brief Check if the IPv6 address belongs to certain multicast group
    1286             :  *
    1287             :  * @param addr IPv6 address.
    1288             :  * @param group Group id IPv6 address, the values must be in network
    1289             :  * byte order
    1290             :  *
    1291             :  * @return True if the IPv6 multicast address belongs to given multicast
    1292             :  * group, false otherwise.
    1293             :  */
    1294           1 : static inline bool net_ipv6_is_addr_mcast_group(const struct in6_addr *addr,
    1295             :                                                 const struct in6_addr *group)
    1296             : {
    1297             :         return UNALIGNED_GET(&addr->s6_addr16[1]) == group->s6_addr16[1] &&
    1298             :                 UNALIGNED_GET(&addr->s6_addr16[2]) == group->s6_addr16[2] &&
    1299             :                 UNALIGNED_GET(&addr->s6_addr16[3]) == group->s6_addr16[3] &&
    1300             :                 UNALIGNED_GET(&addr->s6_addr32[1]) == group->s6_addr32[1] &&
    1301             :                 UNALIGNED_GET(&addr->s6_addr32[2]) == group->s6_addr32[1] &&
    1302             :                 UNALIGNED_GET(&addr->s6_addr32[3]) == group->s6_addr32[3];
    1303             : }
    1304             : 
    1305             : /**
    1306             :  * @brief Check if the IPv6 address belongs to the all nodes multicast group
    1307             :  *
    1308             :  * @param addr IPv6 address
    1309             :  *
    1310             :  * @return True if the IPv6 multicast address belongs to the all nodes multicast
    1311             :  * group, false otherwise
    1312             :  */
    1313             : static inline bool
    1314           1 : net_ipv6_is_addr_mcast_all_nodes_group(const struct in6_addr *addr)
    1315             : {
    1316             :         static const struct in6_addr all_nodes_mcast_group = {
    1317             :                 { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1318             :                     0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
    1319             :         };
    1320             : 
    1321             :         return net_ipv6_is_addr_mcast_group(addr, &all_nodes_mcast_group);
    1322             : }
    1323             : 
    1324             : /**
    1325             :  * @brief Check if the IPv6 address is a interface scope all nodes multicast
    1326             :  * address (FF01::1).
    1327             :  *
    1328             :  * @param addr IPv6 address.
    1329             :  *
    1330             :  * @return True if the address is a interface scope all nodes multicast address,
    1331             :  * false otherwise.
    1332             :  */
    1333             : static inline bool
    1334           1 : net_ipv6_is_addr_mcast_iface_all_nodes(const struct in6_addr *addr)
    1335             : {
    1336             :         return net_ipv6_is_addr_mcast_iface(addr) &&
    1337             :                net_ipv6_is_addr_mcast_all_nodes_group(addr);
    1338             : }
    1339             : 
    1340             : /**
    1341             :  * @brief Check if the IPv6 address is a link local scope all nodes multicast
    1342             :  * address (FF02::1).
    1343             :  *
    1344             :  * @param addr IPv6 address.
    1345             :  *
    1346             :  * @return True if the address is a link local scope all nodes multicast
    1347             :  * address, false otherwise.
    1348             :  */
    1349             : static inline bool
    1350           1 : net_ipv6_is_addr_mcast_link_all_nodes(const struct in6_addr *addr)
    1351             : {
    1352             :         return net_ipv6_is_addr_mcast_link(addr) &&
    1353             :                net_ipv6_is_addr_mcast_all_nodes_group(addr);
    1354             : }
    1355             : 
    1356             : /**
    1357             :  *  @brief Create solicited node IPv6 multicast address
    1358             :  *  FF02:0:0:0:0:1:FFXX:XXXX defined in RFC 3513
    1359             :  *
    1360             :  *  @param src IPv6 address.
    1361             :  *  @param dst IPv6 address.
    1362             :  */
    1363             : static inline
    1364           1 : void net_ipv6_addr_create_solicited_node(const struct in6_addr *src,
    1365             :                                          struct in6_addr *dst)
    1366             : {
    1367             :         dst->s6_addr[0]   = 0xFF;
    1368             :         dst->s6_addr[1]   = 0x02;
    1369             :         UNALIGNED_PUT(0, &dst->s6_addr16[1]);
    1370             :         UNALIGNED_PUT(0, &dst->s6_addr16[2]);
    1371             :         UNALIGNED_PUT(0, &dst->s6_addr16[3]);
    1372             :         UNALIGNED_PUT(0, &dst->s6_addr16[4]);
    1373             :         dst->s6_addr[10]  = 0U;
    1374             :         dst->s6_addr[11]  = 0x01;
    1375             :         dst->s6_addr[12]  = 0xFF;
    1376             :         dst->s6_addr[13]  = src->s6_addr[13];
    1377             :         UNALIGNED_PUT(UNALIGNED_GET(&src->s6_addr16[7]), &dst->s6_addr16[7]);
    1378             : }
    1379             : 
    1380             : /** @brief Construct an IPv6 address from eight 16-bit words.
    1381             :  *
    1382             :  *  @param addr IPv6 address
    1383             :  *  @param addr0 16-bit word which is part of the address
    1384             :  *  @param addr1 16-bit word which is part of the address
    1385             :  *  @param addr2 16-bit word which is part of the address
    1386             :  *  @param addr3 16-bit word which is part of the address
    1387             :  *  @param addr4 16-bit word which is part of the address
    1388             :  *  @param addr5 16-bit word which is part of the address
    1389             :  *  @param addr6 16-bit word which is part of the address
    1390             :  *  @param addr7 16-bit word which is part of the address
    1391             :  */
    1392           1 : static inline void net_ipv6_addr_create(struct in6_addr *addr,
    1393             :                                         uint16_t addr0, uint16_t addr1,
    1394             :                                         uint16_t addr2, uint16_t addr3,
    1395             :                                         uint16_t addr4, uint16_t addr5,
    1396             :                                         uint16_t addr6, uint16_t addr7)
    1397             : {
    1398             :         UNALIGNED_PUT(htons(addr0), &addr->s6_addr16[0]);
    1399             :         UNALIGNED_PUT(htons(addr1), &addr->s6_addr16[1]);
    1400             :         UNALIGNED_PUT(htons(addr2), &addr->s6_addr16[2]);
    1401             :         UNALIGNED_PUT(htons(addr3), &addr->s6_addr16[3]);
    1402             :         UNALIGNED_PUT(htons(addr4), &addr->s6_addr16[4]);
    1403             :         UNALIGNED_PUT(htons(addr5), &addr->s6_addr16[5]);
    1404             :         UNALIGNED_PUT(htons(addr6), &addr->s6_addr16[6]);
    1405             :         UNALIGNED_PUT(htons(addr7), &addr->s6_addr16[7]);
    1406             : }
    1407             : 
    1408             : /**
    1409             :  *  @brief Create link local allnodes multicast IPv6 address
    1410             :  *
    1411             :  *  @param addr IPv6 address
    1412             :  */
    1413           1 : static inline void net_ipv6_addr_create_ll_allnodes_mcast(struct in6_addr *addr)
    1414             : {
    1415             :         net_ipv6_addr_create(addr, 0xff02, 0, 0, 0, 0, 0, 0, 0x0001);
    1416             : }
    1417             : 
    1418             : /**
    1419             :  *  @brief Create link local allrouters multicast IPv6 address
    1420             :  *
    1421             :  *  @param addr IPv6 address
    1422             :  */
    1423           1 : static inline void net_ipv6_addr_create_ll_allrouters_mcast(struct in6_addr *addr)
    1424             : {
    1425             :         net_ipv6_addr_create(addr, 0xff02, 0, 0, 0, 0, 0, 0, 0x0002);
    1426             : }
    1427             : 
    1428             : /**
    1429             :  *  @brief Create IPv4 mapped IPv6 address
    1430             :  *
    1431             :  *  @param addr4 IPv4 address
    1432             :  *  @param addr6 IPv6 address to be created
    1433             :  */
    1434           1 : static inline void net_ipv6_addr_create_v4_mapped(const struct in_addr *addr4,
    1435             :                                                   struct in6_addr *addr6)
    1436             : {
    1437             :         net_ipv6_addr_create(addr6, 0, 0, 0, 0, 0, 0xffff,
    1438             :                              ntohs(addr4->s4_addr16[0]),
    1439             :                              ntohs(addr4->s4_addr16[1]));
    1440             : }
    1441             : 
    1442             : /**
    1443             :  *  @brief Is the IPv6 address an IPv4 mapped one. The v4 mapped addresses
    1444             :  *         look like \::ffff:a.b.c.d
    1445             :  *
    1446             :  *  @param addr IPv6 address
    1447             :  *
    1448             :  *  @return True if IPv6 address is a IPv4 mapped address, False otherwise.
    1449             :  */
    1450           1 : static inline bool net_ipv6_addr_is_v4_mapped(const struct in6_addr *addr)
    1451             : {
    1452             :         if (UNALIGNED_GET(&addr->s6_addr32[0]) == 0 &&
    1453             :             UNALIGNED_GET(&addr->s6_addr32[1]) == 0 &&
    1454             :             UNALIGNED_GET(&addr->s6_addr16[5]) == 0xffff) {
    1455             :                 return true;
    1456             :         }
    1457             : 
    1458             :         return false;
    1459             : }
    1460             : 
    1461             : /**
    1462             :  *  @brief Generate IPv6 address using a prefix and interface identifier.
    1463             :  *         Interface identifier is either generated from EUI-64 (MAC) defined
    1464             :  *         in RFC 4291 or from randomized value defined in RFC 7217.
    1465             :  *
    1466             :  *  @param iface Network interface
    1467             :  *  @param prefix IPv6 prefix, can be left out in which case fe80::/64 is used
    1468             :  *  @param network_id Network identifier (for example SSID in WLAN), this is
    1469             :  *         optional can be set to NULL
    1470             :  *  @param network_id_len Network identifier length, if set to 0 then the
    1471             :  *         network id is ignored.
    1472             :  *  @param dad_counter Duplicate Address Detection counter value, can be set to 0
    1473             :  *         if it is not known.
    1474             :  *  @param addr IPv6 address
    1475             :  *  @param lladdr Link local address
    1476             :  *
    1477             :  *  @return 0 if ok, < 0 if error
    1478             :  */
    1479           1 : int net_ipv6_addr_generate_iid(struct net_if *iface,
    1480             :                                const struct in6_addr *prefix,
    1481             :                                uint8_t *network_id, size_t network_id_len,
    1482             :                                uint8_t dad_counter,
    1483             :                                struct in6_addr *addr,
    1484             :                                struct net_linkaddr *lladdr);
    1485             : 
    1486             : /**
    1487             :  *  @brief Create IPv6 address interface identifier.
    1488             :  *
    1489             :  *  @param addr IPv6 address
    1490             :  *  @param lladdr Link local address
    1491             :  */
    1492           1 : static inline void net_ipv6_addr_create_iid(struct in6_addr *addr,
    1493             :                                             struct net_linkaddr *lladdr)
    1494             : {
    1495             :         (void)net_ipv6_addr_generate_iid(NULL, NULL, NULL, 0, 0, addr, lladdr);
    1496             : }
    1497             : 
    1498             : /**
    1499             :  *  @brief Check if given address is based on link layer address
    1500             :  *
    1501             :  *  @return True if it is, False otherwise
    1502             :  */
    1503           1 : static inline bool net_ipv6_addr_based_on_ll(const struct in6_addr *addr,
    1504             :                                              const struct net_linkaddr *lladdr)
    1505             : {
    1506             :         if (!addr || !lladdr) {
    1507             :                 return false;
    1508             :         }
    1509             : 
    1510             :         switch (lladdr->len) {
    1511             :         case 2:
    1512             :                 if (!memcmp(&addr->s6_addr[14], lladdr->addr, lladdr->len) &&
    1513             :                     addr->s6_addr[8]  == 0U &&
    1514             :                     addr->s6_addr[9]  == 0U &&
    1515             :                     addr->s6_addr[10] == 0U &&
    1516             :                     addr->s6_addr[11] == 0xff &&
    1517             :                     addr->s6_addr[12] == 0xfe) {
    1518             :                         return true;
    1519             :                 }
    1520             : 
    1521             :                 break;
    1522             :         case 6:
    1523             :                 if (lladdr->type == NET_LINK_ETHERNET) {
    1524             :                         if (!memcmp(&addr->s6_addr[9], &lladdr->addr[1], 2) &&
    1525             :                             !memcmp(&addr->s6_addr[13], &lladdr->addr[3], 3) &&
    1526             :                             addr->s6_addr[11] == 0xff &&
    1527             :                             addr->s6_addr[12] == 0xfe &&
    1528             :                             (addr->s6_addr[8] ^ 0x02) == lladdr->addr[0]) {
    1529             :                                 return true;
    1530             :                         }
    1531             :                 }
    1532             : 
    1533             :                 break;
    1534             :         case 8:
    1535             :                 if (!memcmp(&addr->s6_addr[9], &lladdr->addr[1],
    1536             :                             lladdr->len - 1) &&
    1537             :                     (addr->s6_addr[8] ^ 0x02) == lladdr->addr[0]) {
    1538             :                         return true;
    1539             :                 }
    1540             : 
    1541             :                 break;
    1542             :         }
    1543             : 
    1544             :         return false;
    1545             : }
    1546             : 
    1547             : /**
    1548             :  * @brief Get sockaddr_in6 from sockaddr. This is a helper so that
    1549             :  * the code calling this function can be made shorter.
    1550             :  *
    1551             :  * @param addr Socket address
    1552             :  *
    1553             :  * @return Pointer to IPv6 socket address
    1554             :  */
    1555           1 : static inline struct sockaddr_in6 *net_sin6(const struct sockaddr *addr)
    1556             : {
    1557             :         return (struct sockaddr_in6 *)addr;
    1558             : }
    1559             : 
    1560             : /**
    1561             :  * @brief Get sockaddr_in from sockaddr. This is a helper so that
    1562             :  * the code calling this function can be made shorter.
    1563             :  *
    1564             :  * @param addr Socket address
    1565             :  *
    1566             :  * @return Pointer to IPv4 socket address
    1567             :  */
    1568           1 : static inline struct sockaddr_in *net_sin(const struct sockaddr *addr)
    1569             : {
    1570             :         return (struct sockaddr_in *)addr;
    1571             : }
    1572             : 
    1573             : /**
    1574             :  * @brief Get sockaddr_in6_ptr from sockaddr_ptr. This is a helper so that
    1575             :  * the code calling this function can be made shorter.
    1576             :  *
    1577             :  * @param addr Socket address
    1578             :  *
    1579             :  * @return Pointer to IPv6 socket address
    1580             :  */
    1581             : static inline
    1582           1 : struct sockaddr_in6_ptr *net_sin6_ptr(const struct sockaddr_ptr *addr)
    1583             : {
    1584             :         return (struct sockaddr_in6_ptr *)addr;
    1585             : }
    1586             : 
    1587             : /**
    1588             :  * @brief Get sockaddr_in_ptr from sockaddr_ptr. This is a helper so that
    1589             :  * the code calling this function can be made shorter.
    1590             :  *
    1591             :  * @param addr Socket address
    1592             :  *
    1593             :  * @return Pointer to IPv4 socket address
    1594             :  */
    1595             : static inline
    1596           1 : struct sockaddr_in_ptr *net_sin_ptr(const struct sockaddr_ptr *addr)
    1597             : {
    1598             :         return (struct sockaddr_in_ptr *)addr;
    1599             : }
    1600             : 
    1601             : /**
    1602             :  * @brief Get sockaddr_ll_ptr from sockaddr_ptr. This is a helper so that
    1603             :  * the code calling this function can be made shorter.
    1604             :  *
    1605             :  * @param addr Socket address
    1606             :  *
    1607             :  * @return Pointer to linklayer socket address
    1608             :  */
    1609             : static inline
    1610           1 : struct sockaddr_ll_ptr *net_sll_ptr(const struct sockaddr_ptr *addr)
    1611             : {
    1612             :         return (struct sockaddr_ll_ptr *)addr;
    1613             : }
    1614             : 
    1615             : /**
    1616             :  * @brief Get sockaddr_can_ptr from sockaddr_ptr. This is a helper so that
    1617             :  * the code needing this functionality can be made shorter.
    1618             :  *
    1619             :  * @param addr Socket address
    1620             :  *
    1621             :  * @return Pointer to CAN socket address
    1622             :  */
    1623             : static inline
    1624           1 : struct sockaddr_can_ptr *net_can_ptr(const struct sockaddr_ptr *addr)
    1625             : {
    1626             :         return (struct sockaddr_can_ptr *)addr;
    1627             : }
    1628             : 
    1629             : /**
    1630             :  * @brief Convert a string to IP address.
    1631             :  *
    1632             :  * @param family IP address family (AF_INET or AF_INET6)
    1633             :  * @param src IP address in a null terminated string
    1634             :  * @param dst Pointer to struct in_addr if family is AF_INET or
    1635             :  * pointer to struct in6_addr if family is AF_INET6
    1636             :  *
    1637             :  * @note This function doesn't do precise error checking,
    1638             :  * do not use for untrusted strings.
    1639             :  *
    1640             :  * @return 0 if ok, < 0 if error
    1641             :  */
    1642           1 : __syscall int net_addr_pton(sa_family_t family, const char *src, void *dst);
    1643             : 
    1644             : /**
    1645             :  * @brief Convert IP address to string form.
    1646             :  *
    1647             :  * @param family IP address family (AF_INET or AF_INET6)
    1648             :  * @param src Pointer to struct in_addr if family is AF_INET or
    1649             :  *        pointer to struct in6_addr if family is AF_INET6
    1650             :  * @param dst Buffer for IP address as a null terminated string
    1651             :  * @param size Number of bytes available in the buffer
    1652             :  *
    1653             :  * @return dst pointer if ok, NULL if error
    1654             :  */
    1655           1 : __syscall char *net_addr_ntop(sa_family_t family, const void *src,
    1656             :                               char *dst, size_t size);
    1657             : 
    1658             : /**
    1659             :  * @brief Parse a string that contains either IPv4 or IPv6 address
    1660             :  * and optional port, and store the information in user supplied
    1661             :  * sockaddr struct.
    1662             :  *
    1663             :  * @details Syntax of the IP address string:
    1664             :  *   192.0.2.1:80
    1665             :  *   192.0.2.42
    1666             :  *   [2001:db8::1]:8080
    1667             :  *   [2001:db8::2]
    1668             :  *   2001:db::42
    1669             :  * Note that the str_len parameter is used to restrict the amount of
    1670             :  * characters that are checked. If the string does not contain port
    1671             :  * number, then the port number in sockaddr is not modified.
    1672             :  *
    1673             :  * @param str String that contains the IP address.
    1674             :  * @param str_len Length of the string to be parsed.
    1675             :  * @param addr Pointer to user supplied struct sockaddr.
    1676             :  *
    1677             :  * @return True if parsing could be done, false otherwise.
    1678             :  */
    1679           1 : bool net_ipaddr_parse(const char *str, size_t str_len,
    1680             :                       struct sockaddr *addr);
    1681             : 
    1682             : /**
    1683             :  * @brief Set the default port in the sockaddr structure.
    1684             :  * If the port is already set, then do nothing.
    1685             :  *
    1686             :  * @param addr Pointer to user supplied struct sockaddr.
    1687             :  * @param default_port Default port number to set.
    1688             :  *
    1689             :  * @return 0 if ok, <0 if error
    1690             :  */
    1691           1 : int net_port_set_default(struct sockaddr *addr, uint16_t default_port);
    1692             : 
    1693             : /**
    1694             :  * @brief Compare TCP sequence numbers.
    1695             :  *
    1696             :  * @details This function compares TCP sequence numbers,
    1697             :  *          accounting for wraparound effects.
    1698             :  *
    1699             :  * @param seq1 First sequence number
    1700             :  * @param seq2 Seconds sequence number
    1701             :  *
    1702             :  * @return < 0 if seq1 < seq2, 0 if seq1 == seq2, > 0 if seq > seq2
    1703             :  */
    1704           1 : static inline int32_t net_tcp_seq_cmp(uint32_t seq1, uint32_t seq2)
    1705             : {
    1706             :         return (int32_t)(seq1 - seq2);
    1707             : }
    1708             : 
    1709             : /**
    1710             :  * @brief Check that one TCP sequence number is greater.
    1711             :  *
    1712             :  * @details This is convenience function on top of net_tcp_seq_cmp().
    1713             :  *
    1714             :  * @param seq1 First sequence number
    1715             :  * @param seq2 Seconds sequence number
    1716             :  *
    1717             :  * @return True if seq > seq2
    1718             :  */
    1719           1 : static inline bool net_tcp_seq_greater(uint32_t seq1, uint32_t seq2)
    1720             : {
    1721             :         return net_tcp_seq_cmp(seq1, seq2) > 0;
    1722             : }
    1723             : 
    1724             : /**
    1725             :  * @brief Convert a string of hex values to array of bytes.
    1726             :  *
    1727             :  * @details The syntax of the string is "ab:02:98:fa:42:01"
    1728             :  *
    1729             :  * @param buf Pointer to memory where the bytes are written.
    1730             :  * @param buf_len Length of the memory area.
    1731             :  * @param src String of bytes.
    1732             :  *
    1733             :  * @return 0 if ok, <0 if error
    1734             :  */
    1735           1 : int net_bytes_from_str(uint8_t *buf, int buf_len, const char *src);
    1736             : 
    1737             : /**
    1738             :  * @brief Convert Tx network packet priority to traffic class so we can place
    1739             :  * the packet into correct Tx queue.
    1740             :  *
    1741             :  * @param prio Network priority
    1742             :  *
    1743             :  * @return Tx traffic class that handles that priority network traffic.
    1744             :  */
    1745           1 : int net_tx_priority2tc(enum net_priority prio);
    1746             : 
    1747             : /**
    1748             :  * @brief Convert Rx network packet priority to traffic class so we can place
    1749             :  * the packet into correct Rx queue.
    1750             :  *
    1751             :  * @param prio Network priority
    1752             :  *
    1753             :  * @return Rx traffic class that handles that priority network traffic.
    1754             :  */
    1755           1 : int net_rx_priority2tc(enum net_priority prio);
    1756             : 
    1757             : /**
    1758             :  * @brief Convert network packet VLAN priority to network packet priority so we
    1759             :  * can place the packet into correct queue.
    1760             :  *
    1761             :  * @param priority VLAN priority
    1762             :  *
    1763             :  * @return Network priority
    1764             :  */
    1765           1 : static inline enum net_priority net_vlan2priority(uint8_t priority)
    1766             : {
    1767             :         /* Map according to IEEE 802.1Q */
    1768             :         static const uint8_t vlan2priority[] = {
    1769             :                 NET_PRIORITY_BE,
    1770             :                 NET_PRIORITY_BK,
    1771             :                 NET_PRIORITY_EE,
    1772             :                 NET_PRIORITY_CA,
    1773             :                 NET_PRIORITY_VI,
    1774             :                 NET_PRIORITY_VO,
    1775             :                 NET_PRIORITY_IC,
    1776             :                 NET_PRIORITY_NC
    1777             :         };
    1778             : 
    1779             :         if (priority >= ARRAY_SIZE(vlan2priority)) {
    1780             :                 /* Use Best Effort as the default priority */
    1781             :                 return NET_PRIORITY_BE;
    1782             :         }
    1783             : 
    1784             :         return (enum net_priority)vlan2priority[priority];
    1785             : }
    1786             : 
    1787             : /**
    1788             :  * @brief Convert network packet priority to network packet VLAN priority.
    1789             :  *
    1790             :  * @param priority Packet priority
    1791             :  *
    1792             :  * @return VLAN priority (PCP)
    1793             :  */
    1794           1 : static inline uint8_t net_priority2vlan(enum net_priority priority)
    1795             : {
    1796             :         /* The conversion works both ways */
    1797             :         return (uint8_t)net_vlan2priority(priority);
    1798             : }
    1799             : 
    1800             : /**
    1801             :  * @brief Return network address family value as a string. This is only usable
    1802             :  * for debugging.
    1803             :  *
    1804             :  * @param family Network address family code
    1805             :  *
    1806             :  * @return Network address family as a string, or NULL if family is unknown.
    1807             :  */
    1808           1 : const char *net_family2str(sa_family_t family);
    1809             : 
    1810             : /**
    1811             :  * @brief Add IPv6 prefix as a privacy extension filter.
    1812             :  *
    1813             :  * @details Note that the filters can either allow or deny listing.
    1814             :  *
    1815             :  * @param addr IPv6 prefix
    1816             :  * @param is_denylist Tells if this filter is for allowing or denying listing.
    1817             :  *
    1818             :  * @return 0 if ok, <0 if error
    1819             :  */
    1820             : #if defined(CONFIG_NET_IPV6_PE)
    1821             : int net_ipv6_pe_add_filter(struct in6_addr *addr, bool is_denylist);
    1822             : #else
    1823           1 : static inline int net_ipv6_pe_add_filter(struct in6_addr *addr,
    1824             :                                          bool is_denylist)
    1825             : {
    1826             :         ARG_UNUSED(addr);
    1827             :         ARG_UNUSED(is_denylist);
    1828             : 
    1829             :         return -ENOTSUP;
    1830             : }
    1831             : #endif /* CONFIG_NET_IPV6_PE */
    1832             : 
    1833             : /**
    1834             :  * @brief Delete IPv6 prefix from privacy extension filter list.
    1835             :  *
    1836             :  * @param addr IPv6 prefix
    1837             :  *
    1838             :  * @return 0 if ok, <0 if error
    1839             :  */
    1840             : #if defined(CONFIG_NET_IPV6_PE)
    1841             : int net_ipv6_pe_del_filter(struct in6_addr *addr);
    1842             : #else
    1843           1 : static inline int net_ipv6_pe_del_filter(struct in6_addr *addr)
    1844             : {
    1845             :         ARG_UNUSED(addr);
    1846             : 
    1847             :         return -ENOTSUP;
    1848             : }
    1849             : #endif /* CONFIG_NET_IPV6_PE */
    1850             : 
    1851             : #ifdef __cplusplus
    1852             : }
    1853             : #endif
    1854             : 
    1855             : #include <zephyr/syscalls/net_ip.h>
    1856             : 
    1857             : /**
    1858             :  * @}
    1859             :  */
    1860             : 
    1861             : 
    1862             : #endif /* ZEPHYR_INCLUDE_NET_NET_IP_H_ */

Generated by: LCOV version 1.14