/*
 *
 *    Copyright (c) 2020-2021 Project CHIP Authors
 *    Copyright (c) 2019 Google LLC.
 *    Copyright (c) 2013-2018 Nest Labs, Inc.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 *    @file
 *      This file defines the class <tt>Inet::IPAddress</tt> and
 *      related enumerated constants. The CHIP Inet Layer uses objects
 *      of this class to represent Internet protocol addresses of both
 *      IPv4 and IPv6 address families. (IPv4 addresses are stored
 *      internally as IPv4-Mapped IPv6 addresses.)
 */

#pragma once

#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <type_traits>

#include <lib/core/CHIPError.h>
#include <lib/support/BitFlags.h>
#include <lib/support/DLLUtil.h>

#include <inet/InetConfig.h>
#include <inet/InetError.h>

#include "inet/IANAConstants.h"

#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
#include <lwip/init.h>
#include <lwip/ip_addr.h>
#if INET_CONFIG_ENABLE_IPV4
#include <lwip/ip4_addr.h>
#endif // INET_CONFIG_ENABLE_IPV4
#include <lwip/inet.h>
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
#include <openthread/icmp6.h>
#include <openthread/ip6.h>
#endif // CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
#include <net/if.h>
#include <netinet/in.h>
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
#include <sys/socket.h>
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

#if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT && INET_CONFIG_ENABLE_IPV4
#error Forbidden : native Open Thread implementation with IPV4 enabled
#endif

#include <inet/InetInterface.h>

#define NL_INET_IPV6_ADDR_LEN_IN_BYTES (16)
#define NL_INET_IPV6_MCAST_GROUP_LEN_IN_BYTES (14)

namespace chip {
namespace Inet {

/**
 * Internet protocol address family
 */
enum class IPAddressType : uint8_t
{
    kUnknown = 0, ///< Not used.
#if INET_CONFIG_ENABLE_IPV4
    kIPv4 = 1, ///< Internet protocol version 4.
#endif         // INET_CONFIG_ENABLE_IPV4
    kIPv6 = 2, ///< Internet protocol version 6.
    kAny  = 3  ///< The unspecified internet address (independent of protocol version).
};

/**
 * Internet protocol v6 multicast flags
 *
 *  Values of the \c IPv6MulticastFlag type are used to call the <tt>IPAddress::MakeIPv6Multicast()</tt> methods.
 *  They indicate the type of IPv6 multicast address to create. These numbers are registered by IETF with IANA.
 */
enum class IPv6MulticastFlag : uint8_t
{
    /** The multicast address is (1) transient (i.e., dynamically-assigned) rather than (0) well-known (i.e, IANA-assigned). */
    kTransient = 0x01,

    /** The multicast address is (1) based on a network prefix. */
    kPrefix = 0x02
};
using IPv6MulticastFlags = BitFlags<IPv6MulticastFlag>;

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
union SockAddr
{
    sockaddr any;
    sockaddr_in in;
    sockaddr_in6 in6;
    sockaddr_storage storage;
};
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

/**
 * @brief   Internet protocol address
 *
 * @details
 *  The CHIP Inet Layer uses objects of this class to represent Internet
 *  protocol addresses (independent of protocol version).
 *
 */
class DLL_EXPORT IPAddress
{
public:
    /**
     * Maximum length of the string representation of an IP address, including a terminating NUL.
     */
#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
    static constexpr uint16_t kMaxStringLength = IP6ADDR_STRLEN_MAX;
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
    static constexpr uint16_t kMaxStringLength = INET6_ADDRSTRLEN;
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK

#if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
#ifndef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN OT_IP6_ADDRESS_STRING_SIZE
#endif
    static constexpr uint16_t kMaxStringLength = OT_IP6_ADDRESS_STRING_SIZE;
#endif

    IPAddress() = default;

#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
    explicit IPAddress(const ip6_addr_t & ipv6Addr);
#if INET_CONFIG_ENABLE_IPV4 || LWIP_IPV4
    explicit IPAddress(const ip4_addr_t & ipv4Addr);
    explicit IPAddress(const ip_addr_t & addr);
#endif // INET_CONFIG_ENABLE_IPV4
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
    explicit IPAddress(const struct in6_addr & ipv6Addr);
#if INET_CONFIG_ENABLE_IPV4
    explicit IPAddress(const struct in_addr & ipv4Addr);
#endif // INET_CONFIG_ENABLE_IPV4
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK

#if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
    explicit IPAddress(const otIp6Address & ipv6Addr);
#endif

    /**
     * @brief   Opaque word array to contain IP addresses (independent of protocol version)
     *
     * @details
     *  IPv6 address use all 128-bits split into four 32-bit network byte
     *  ordered unsigned integers. IPv4 addresses are IPv4-Mapped IPv6 addresses,
     *  i.e. the first two words are zero, the third word contains 0xFFFF in
     *  network byte order, and the fourth word contains the IPv4
     *  address in network byte order.
     */
    uint32_t Addr[4];

    /**
     * @brief   Test whether address is IPv6 compatible.
     *
     * @details
     *  Use this method to check if the address belongs to the IPv6 address
     *  family. Note well: the unspecified address is not an IPv6 address.
     *
     * @retval true   The address is IPv6 and not the unspecified address.
     * @retval false  The address is IPv4 or the unspecified address.
     */
    bool IsIPv6() const;

    /**
     * @brief   Test whether address is IPv6 global unicast address.
     *
     * @details
     *  Use this method to check if the address belongs to the IPv6 address
     *  family and has the global unicast address prefix.
     *
     * @retval true  Address is IPv6 global unicast
     * @retval false Otherwise
     */
    bool IsIPv6GlobalUnicast() const;

    /**
     * @brief   Test whether address is IPv6 unique-local address (ULA).
     *
     * @details
     *  Use this method to check if the address belongs to the IPv6 address
     *  family and has the reserved IPv6 unique-local address prefix.
     *
     * @retval true  Address is IPv6 unique-local
     * @retval false Otherwise
     */
    bool IsIPv6ULA() const;

    /**
     * @brief   Test whether address is IPv6 link-local address (LL).
     *
     * @details
     *  Use this method to check if the address belongs to the IPv6 address
     *  family and has the reserved IPv6 link-local address prefix.
     *
     * @retval true  Address is IPv6 link-local
     * @retval false Otherwise
     */
    bool IsIPv6LinkLocal() const;

    /**
     * @brief   Test whether address is IPv6 multicast.
     *
     * @details
     *  Use this method to check if the address belongs to the IPv6 address
     *  family and has the reserved IPv6 multicast address prefix.
     *
     * @retval true  Address is IPv6 multicast
     * @retval false Otherwise
     */
    bool IsIPv6Multicast() const;

    /**
     * @brief   Test whether address is IPv4 or IPv6 multicast.
     *
     * @details
     *  Use this method to check if the address belongs to the IPv4 or IPv6 address
     *  family and has the reserved IPv4 or IPv6 multicast address prefix.
     *
     * @retval true  Address is IPv4 or IPv6 multicast
     * @retval false Otherwise
     */
    bool IsMulticast() const;

    /**
     * @brief   Extract the IID of an IPv6 ULA address.
     *
     * @details
     *  Use this method with an IPv6 unique-local address (ULA) to extract the
     *  identifier identifier (IID), which is the least significant 64 bits of
     *  the address.
     *
     * @return 64-bit interface identifier, or zero if the IP address is not
     *  an IPv6 unique-local address.
     */
    uint64_t InterfaceId() const;

    /**
     * @brief   Extract the 16-bit subnet identifier of an IPv6 ULA address.
     *
     * @details
     *  Use this method with an IPv6 unique-local address (ULA) to extract the
     *  subnet identifier, which is the least significant 16 bits of the
     *  network prefix. The network prefix is the most significant 64 bits of
     *  of the address. In other words, the subnet identifier is located in
     *  the 7th and 8th bytes of a 16-byte address.
     *
     * @return 16-bit subnet identifier, or zero if the IP address is not
     *  an IPv6 unique-local address.
     */
    uint16_t Subnet() const;

    /**
     * @brief   Extract the 16-bit global network identifier of an IPv6 ULA
     *  address.
     *
     * @details
     *  Use this method with an IPv6 unique-local address (ULA) to extract the
     *  global network identifier, which is the 40 bits immediately following
     *  the distinguished ULA network prefix, i.e. fd00::/8. In other words,
     *  the global network identifier is located in the five bytes from the 2nd
     *  2nd through the 6th bytes in the address.
     *
     * @return 40-bit global network identifier, or zero if the IP address
     *  is not an IPv6 unique-local address.
     */
    uint64_t GlobalId() const;

    /**
     * @brief   Extract the type of the IP address.
     *
     * @details
     *  Use this method to return an value of the enumerated type \c
     *  IPAddressType to indicate the type of the IP address.
     *
     * @retval  IPAddressType::kIPv4 The address is IPv4.
     * @retval  IPAddressType::kIPv6 The address is IPv6.
     * @retval  IPAddressType::kAny  The address is the unspecified address.
     */
    IPAddressType Type() const;

    /**
     * @brief   Compare this IP address with another for equivalence.
     *
     * @param[in]   other   The address to compare.
     *
     * @retval true  If equivalent to \c other
     * @retval false Otherwise
     */
    bool operator==(const IPAddress & other) const;

    /**
     * @brief   Compare this IP address with another for inequivalence.
     *
     * @param[in]   other   The address to compare.
     *
     * @retval true  If equivalent to \c other
     * @retval false Otherwise
     */
    bool operator!=(const IPAddress & other) const;

    /**
     * @brief   Emit the IP address in conventional text presentation format.
     *
     * @param[out]  buf         The address of the emitted text.
     * @param[in]   bufSize     The size of the buffer for the emitted text.
     *
     * @details
     *  Use <tt>ToString(char *buf, uint32_t bufSize) const</tt> to write the
     *  conventional text presentation form of the IP address to the memory
     *  located at \c buf and extending as much as \c bufSize bytes, including
     *  its NUL termination character.
     *
     *  Note Well: not compliant with RFC 5952 on some platforms. Specifically,
     *  zero compression may not be applied according to section 4.2.
     *
     * @return  The argument \c buf if no formatting error, or zero otherwise.
     */
    char * ToString(char * buf, uint32_t bufSize) const;

    /**
     * A version of ToString that writes to a literal and deduces how much space
     * it as to work with.
     */
    template <uint32_t N>
    inline char * ToString(char (&buf)[N]) const
    {
        return ToString(buf, N);
    }

    /**
     * @brief   Scan the IP address from its conventional presentation text.
     *
     * @param[in]   str     The address of the emitted text.
     * @param[out]  output  The object to set to the scanned address.
     *
     * @details
     *  Use <tt>FromString(const char *str, IPAddress& output)</tt> to
     *  overwrite an IP address by scanning the conventional text presentation
     *  located at \c str.
     *
     * @retval true  The presentation format is valid
     * @retval false Otherwise
     */
    static bool FromString(const char * str, IPAddress & output);

    /**
     * @brief   Scan the IP address from its conventional presentation text.
     *
     * @param[in]   str     A pointer to the text to be scanned.
     * @param[in]   strLen  The length of the text to be scanned.
     * @param[out]  output  The object to set to the scanned address.
     *
     * @details
     *  Use <tt>FromString(const char *str, size_t strLen, IPAddress& output)</tt> to
     *  overwrite an IP address by scanning the conventional text presentation
     *  located at \c str.
     *
     * @retval true  The presentation format is valid
     * @retval false Otherwise
     */
    static bool FromString(const char * str, size_t strLen, IPAddress & output);

    /**
     * @brief
     *   Scan the IP address from its conventional presentation text, including
     *   the interface ID if present. (e.g. "fe80::2%wlan0"). If no interface ID
     *   is present, then ifaceOutput will be set to the null interface ID.
     *
     * @param[in]    str          A pointer to the text to be scanned.
     * @param[out]   addrOutput   The object to set to the IP address.
     * @param[out]   ifaceOutput  The object to set to the interface ID.
     *
     * @retval true  The presentation format is valid
     * @retval false Otherwise
     */
    static bool FromString(const char * str, IPAddress & addrOutput, class InterfaceId & ifaceOutput);

    /**
     * @brief   Emit the IP address in standard network representation.
     *
     * @param[in,out]   p   Reference to the cursor to use for writing.
     *
     * @details
     *  Use <tt>WriteAddress(uint8_t *&p)</tt> to encode the IP address in
     *  the binary format defined by RFC 4291 for IPv6 addresses.  IPv4
     *  addresses are encoded according to section 2.5.5.2 "IPv4-Mapped
     *  IPv6 Address".
     */
    void WriteAddress(uint8_t *& p) const;

    /**
     * @brief   Emit the IP address in standard network representation.
     *
     * @param[in,out]   p       Reference to the cursor to use for reading.
     * @param[out]      output  Object to receive decoded IP address.
     *
     * @details
     *  Use <tt>ReadAddress(uint8_t *&p, IPAddress &output)</tt> to decode
     *  the IP address at \c p to the object \c output.
     */
    static void ReadAddress(const uint8_t *& p, IPAddress & output);

    /**
     * @brief   Test whether address is IPv4 compatible.
     *
     * @details
     *  Use this method to check if the address belongs to the IPv4 address
     *  family. Note well: the unspecified address is not an IPv4 address.
     *
     * @retval true   The address is IPv4 and not the unspecified address.
     * @retval false  The address is IPv6 or the unspecified address.
     */
    bool IsIPv4() const;

    /**
     * @brief   Test whether address is IPv4 multicast.
     *
     * @details
     *  Use this method to check if the address is an IPv4 multicast
     *  address.
     *
     * @retval true  Address is the IPv4 multicast
     * @retval false Otherwise
     */
    bool IsIPv4Multicast() const;

    /**
     * @brief   Test whether address is IPv4 broadcast.
     *
     * @details
     *  Use this method to check if the address is the special purpose IPv4
     *  broadcast address.
     *
     * @retval true  Address is the IPv4 broadcast
     * @retval false Otherwise
     */
    bool IsIPv4Broadcast() const;

    /**
     * @fn      ToIPv4() const
     *
     * @brief   Extract the IPv4 address as a platform data structure.
     *
     * @details
     *  Use <tt>ToIPv4() const</tt> to extract the content as an IPv4 address,
     *  if possible. IPv6 addresses and the unspecified address are
     *  extracted as <tt>0.0.0.0</tt>.
     *
     *  The result is either of type <tt>struct in_addr</tt> (on POSIX) or
     *  <tt>ip4_addr_t</tt> (on LwIP).
     *
     * @return  The encapsulated IPv4 address, or \c 0.0.0.0 if the address is
     *      either unspecified or not an IPv4 address.
     */

    /**
     * @fn      ToIPv6() const
     *
     * @brief   Extract the IPv6 address as a platform data structure.
     *
     * @details
     *  Use <tt>ToIPv6() const</tt> to extract the content as an IPv6 address,
     *  if possible. IPv4 addresses and the unspecified address are extracted
     *  as <tt>[::]</tt>.
     *
     *  The result is either of type <tt>struct in6_addr</tt> (on POSIX) or
     *  <tt>ip6_addr_t</tt> (on LwIP).
     *
     * @return  The encapsulated IPv4 address, or \c [::] if the address is
     *      either unspecified or not an IPv4 address.
     */

#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT

    /**
     * @fn      ToLwIPAddr() const
     *
     * @brief   Extract the IP address as a LwIP ip_addr_t structure.
     *
     * @details
     *  Use <tt>ToLwIPAddr() const</tt> to extract the content as an IP address,
     *  if possible.
     *
     * @return  An LwIP ip_addr_t structure corresponding to the IP address.
     */
    ip_addr_t ToLwIPAddr(void) const;

    /**
     * Extract the IP address as a LwIP ip_addr_t structure.
     *
     * If the IP address is Any, the result is IP6_ADDR_ANY unless the requested addressType is kIPv4.
     * If the requested addressType is IPAddressType::kAny, extracts the IP address as an LwIP ip_addr_t structure.
     * Otherwise, returns INET_ERROR_WRONG_ADDRESS_TYPE if the requested addressType does not match the IP address.
     */
    CHIP_ERROR ToLwIPAddr(IPAddressType addressType, ip_addr_t & outAddress) const;

    /**
     * @brief   Convert the INET layer address type to its underlying LwIP type.
     *
     * @details
     *  Use <tt>ToLwIPAddrType(IPAddressType)</tt> to convert the IP address type
     *  to its underlying LwIP address type code.
     */
    static lwip_ip_addr_type ToLwIPAddrType(IPAddressType);

    ip6_addr_t ToIPv6(void) const;

#if INET_CONFIG_ENABLE_IPV4
    ip4_addr_t ToIPv4(void) const;
#endif // INET_CONFIG_ENABLE_IPV4

#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK

    struct in6_addr ToIPv6() const;

#if INET_CONFIG_ENABLE_IPV4
    struct in_addr ToIPv4() const;
#endif // INET_CONFIG_ENABLE_IPV4

    /**
     * Get the IP address from a SockAddr.
     */
    static CHIP_ERROR GetIPAddressFromSockAddr(const SockAddr & sockaddr, IPAddress & outIPAddress);
    static CHIP_ERROR GetIPAddressFromSockAddr(const sockaddr & sockaddr, IPAddress & outIPAddress)
    {
        return GetIPAddressFromSockAddr(reinterpret_cast<const SockAddr &>(sockaddr), outIPAddress);
    }
    static IPAddress FromSockAddr(const sockaddr_in6 & sockaddr) { return IPAddress(sockaddr.sin6_addr); }
#if INET_CONFIG_ENABLE_IPV4
    static IPAddress FromSockAddr(const sockaddr_in & sockaddr) { return IPAddress(sockaddr.sin_addr); }
#endif // INET_CONFIG_ENABLE_IPV4

#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_USE_NETWORK_FRAMEWORK

#if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
    otIp6Address ToIPv6() const;
    static IPAddress FromOtAddr(const otIp6Address & address);
#endif // CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT

    /**
     * @brief   Construct an IPv6 unique-local address (ULA) from its parts.
     *
     * @details
     *  Use <tt>MakeULA(uint64_t globalId, uint16_t subnet, uint64_t
     *  interfaceId)</tt> to construct a unique-local address (ULA) with global
     *  network identifier \c globalId, subnet identifier \c subnet and
     *  interface identifier (IID) \c interfaceId.
     *
     * @return  The constructed IP address.
     */
    static IPAddress MakeULA(uint64_t globalId, uint16_t subnet, uint64_t interfaceId);

    /**
     * @brief   Construct an IPv6 link-local address (LL) from its IID.
     *
     * @details
     *  Use <tt>MakeLLA(uint64_t interfaceId)</tt> to construct an IPv6
     *  link-local address (LL) with interface identifier \c interfaceId.
     *
     * @return  The constructed IP address.
     */
    static IPAddress MakeLLA(uint64_t interfaceId);

    /**
     * @brief   Construct an IPv6 multicast address from its parts.
     *
     * @details
     *  Use <tt>MakeIPv6Multicast(uint8_t flags, uint8_t scope,
     *  uint8_t groupId[14])</tt> to construct an IPv6 multicast
     *  address with \c flags for routing scope \c scope and group
     *  identifier octets \c groupId.
     *
     * @return  The constructed IP address.
     */
    static IPAddress MakeIPv6Multicast(IPv6MulticastFlags aFlags, uint8_t aScope,
                                       const uint8_t aGroupId[NL_INET_IPV6_MCAST_GROUP_LEN_IN_BYTES]);

    /**
     * @brief   Construct an IPv6 multicast address from its parts.
     *
     * @details
     *  Use <tt>MakeIPv6Multicast(uint8_t flags, uint8_t scope,
     *  uint32_t groupId)</tt> to construct an IPv6 multicast
     *  address with \c flags for routing scope \c scope and group
     *  identifier \c groupId.
     *
     * @return  The constructed IP address.
     */
    static IPAddress MakeIPv6Multicast(IPv6MulticastFlags aFlags, uint8_t aScope, uint32_t aGroupId);

    /**
     * @brief   Construct a well-known IPv6 multicast address from its parts.
     *
     * @details
     *  Use <tt>MakeIPv6WellKnownMulticast(uint8_t scope, uint32_t
     *  groupId)</tt> to construct an IPv6 multicast address for
     *  routing scope \c scope and group identifier \c groupId.
     *
     * @return  The constructed IP address.
     */
    static IPAddress MakeIPv6WellKnownMulticast(uint8_t aScope, uint32_t aGroupId);

    /**
     * @brief   Construct a transient IPv6 multicast address from its parts.
     *
     * @details
     *  Use <tt>MakeIPv6TransientMulticast(uint8_t flags, uint8_t scope,
     *  uint8_t groupId[14])</tt> to construct a transient IPv6
     *  multicast address with \c flags for routing scope \c scope and
     *  group identifier octets \c groupId.
     *
     * @return  The constructed IP address.
     */
    static IPAddress MakeIPv6TransientMulticast(IPv6MulticastFlags aFlags, uint8_t aScope,
                                                const uint8_t aGroupId[NL_INET_IPV6_MCAST_GROUP_LEN_IN_BYTES]);

    /**
     * @brief   Construct a transient, prefix IPv6 multicast address from its parts.
     *
     * @details
     *  Use <tt>MakeIPv6PrefixMulticast(uint8_t scope, uint8_t
     *  prefixlen, const uint64_t prefix, uint32_t groupId)</tt> to
     *  construct a transient, prefix IPv6 multicast address with for
     *  routing scope \c scope and group identifier octets \c groupId,
     *  qualified by the prefix \c prefix of length \c prefixlen bits.
     *
     * @return  The constructed IP address.
     */
    static IPAddress MakeIPv6PrefixMulticast(uint8_t aScope, uint8_t aPrefixLength, const uint64_t & aPrefix, uint32_t aGroupId);

    /**
     * @brief   Construct an IPv4 broadcast address.
     *
     * @return  The constructed IP address.
     */
    static IPAddress MakeIPv4Broadcast();

    /**
     * @brief   The distinguished unspecified IP address object.
     *
     * @details
     *  This object is used as a constant for equivalence comparisons. It must
     *  not be modified by users of the CHIP Inet Layer.
     */
    static IPAddress Any;
};

static_assert(std::is_trivial<IPAddress>::value, "IPAddress is not trivial");

} // namespace Inet
} // namespace chip
