/*
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *    Copyright (c) 2019 Google LLC.
 *    Copyright (c) 2013-2017 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
 *      Implementation of network interface abstraction layer.
 *
 */

#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif

#include "InetInterface.h"

#include "InetLayer.h"
#include "InetLayerEvents.h"

#include <support/CodeUtils.h>
#include <support/DLLUtil.h>

#if CHIP_SYSTEM_CONFIG_USE_LWIP
#include <lwip/netif.h>
#include <lwip/sys.h>
#include <lwip/tcpip.h>
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
#include <errno.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <unistd.h>
#ifdef HAVE_SYS_SOCKIO_H
#include <sys/sockio.h>
#endif /* HAVE_SYS_SOCKIO_H */
#include <net/if.h>
#include <sys/ioctl.h>
#ifdef __ANDROID__
#include "ifaddrs-android.h"
#else // !defined(__ANDROID__)
#include <ifaddrs.h>
#endif // !defined(__ANDROID__)
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
#include <net/net_if.h>
#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF

#include <stdio.h>
#include <string.h>

namespace chip {
namespace Inet {

/**
 * @brief   Get the name of a network interface
 *
 * @param[in]   intfId      a network interface
 * @param[in]   nameBuf     region of memory to write the interface name
 * @param[in]   nameBufSize size of the region denoted by \c nameBuf
 *
 * @retval  INET_NO_ERROR           successful result, interface name written
 * @retval  INET_ERROR_NO_MEMORY    name is too large to be written in buffer
 * @retval  other                   another system or platform error
 *
 * @details
 *     Writes the name of the network interface as \c NUL terminated text string
 *     at \c nameBuf. The name of the unspecified network interface is the empty
 *     string.
 */
DLL_EXPORT INET_ERROR GetInterfaceName(InterfaceId intfId, char * nameBuf, size_t nameBufSize)
{
    if (intfId != INET_NULL_INTERFACEID)
    {
#if CHIP_SYSTEM_CONFIG_USE_LWIP
        int status = snprintf(nameBuf, nameBufSize, "%c%c%d", intfId->name[0], intfId->name[1], intfId->num);
        if (status >= static_cast<int>(nameBufSize))
            return INET_ERROR_NO_MEMORY;
        return INET_NO_ERROR;
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
        char intfName[IF_NAMESIZE];
        if (if_indextoname(intfId, intfName) == NULL)
            return chip::System::MapErrorPOSIX(errno);
        if (strlen(intfName) >= nameBufSize)
            return INET_ERROR_NO_MEMORY;
        strcpy(nameBuf, intfName);
        return INET_NO_ERROR;
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
        net_if * currentInterface = net_if_get_by_index(intfId);
        if (!currentInterface)
            return INET_ERROR_INCORRECT_STATE;
        const char * name = net_if_get_device(currentInterface)->name;
        if (strlen(name) >= nameBufSize)
            return INET_ERROR_NO_MEMORY;
        strcpy(nameBuf, name);
        return INET_NO_ERROR;

#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
    }
    else
    {
        if (nameBufSize < 1)
            return INET_ERROR_NO_MEMORY;
        nameBuf[0] = 0;
        return INET_NO_ERROR;
    }
}

/**
 * @brief   Search the list of network interfaces for the indicated name.
 *
 * @param[in]   intfName    name of the network interface to find
 * @param[out]  intfId      indicator of the network interface to assign
 *
 * @retval  INET_NO_ERROR                 success, network interface indicated
 * @retval  INET_ERROR_UNKNOWN_INTERFACE  no network interface found
 * @retval  other                   another system or platform error
 *
 * @details
 *     On LwIP, this function must be called with the LwIP stack lock acquired.
 *
 *     The \c intfId parameter is not updated unless the value returned is
 *     \c INET_NO_ERROR. It should be initialized with \c INET_NULL_INTERFACEID
 *     before calling this function.
 */
DLL_EXPORT INET_ERROR InterfaceNameToId(const char * intfName, InterfaceId & intfId)
{
#if CHIP_SYSTEM_CONFIG_USE_LWIP
    if (strlen(intfName) < 3)
        return INET_ERROR_UNKNOWN_INTERFACE;
    char * parseEnd;
    unsigned long intfNum = strtoul(intfName + 2, &parseEnd, 10);
    if (*parseEnd != 0 || intfNum > UINT8_MAX)
        return INET_ERROR_UNKNOWN_INTERFACE;
    struct netif * intf;
#if LWIP_VERSION_MAJOR >= 2 && LWIP_VERSION_MINOR >= 0 && defined(NETIF_FOREACH)
    NETIF_FOREACH(intf)
#else
    for (intf = netif_list; intf != NULL; intf = intf->next)
#endif
    {
        if (intf->name[0] == intfName[0] && intf->name[1] == intfName[1] && intf->num == (uint8_t) intfNum)
        {
            intfId = intf;
            return INET_NO_ERROR;
        }
    }
    intfId = INET_NULL_INTERFACEID;
    return INET_ERROR_UNKNOWN_INTERFACE;
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
    intfId = if_nametoindex(intfName);
    if (intfId == 0)
        return (errno == ENXIO) ? INET_ERROR_UNKNOWN_INTERFACE : chip::System::MapErrorPOSIX(errno);
    return INET_NO_ERROR;
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
    int currentId = 0;
    net_if * currentInterface;

    while ((currentInterface = net_if_get_by_index(++currentId)) != nullptr)
    {
        if (strcmp(net_if_get_device(currentInterface)->name, intfName) == 0)
        {
            intfId = currentId;
            return INET_NO_ERROR;
        }
    }
    return INET_ERROR_UNKNOWN_INTERFACE;
#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
} // namespace Inet

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

static int sIOCTLSocket = -1;

/**
 * @brief   Returns a global general purpose socket useful for invoking certain network IOCTLs.
 *
 * This function is thread-safe on all platforms.
 */
int GetIOCTLSocket(void)
{
    if (sIOCTLSocket == -1)
    {
        int s;
#ifdef SOCK_CLOEXEC
        s = socket(AF_INET, SOCK_STREAM, SOCK_CLOEXEC);
        if (s < 0)
#endif
        {
            s = socket(AF_INET, SOCK_STREAM, 0);
            fcntl(s, O_CLOEXEC);
        }

        if (!__sync_bool_compare_and_swap(&sIOCTLSocket, -1, s))
        {
            close(s);
        }
    }
    return sIOCTLSocket;
}

/**
 * @brief   Close the global socket created by \c GetIOCTLSocket.
 *
 * @details
 *   This function is provided for cases were leaving the global IOCTL socket
 *   open would register as a leak.
 *
 *   NB: This function is NOT thread-safe with respect to \c GetIOCTLSocket.
 */
void CloseIOCTLSocket(void)
{
    if (sIOCTLSocket == -1)
    {
        close(sIOCTLSocket);
        sIOCTLSocket = -1;
    }
}

#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

/**
 * @fn      InterfaceIterator::InterfaceIterator(void)
 *
 * @brief   Constructs an InterfaceIterator object.
 *
 * @details
 *     Starts the iterator at the first network interface. On some platforms,
 *     this constructor may allocate resources recycled by the destructor.
 */

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if __ANDROID__ && __ANDROID_API__ < 24

static struct if_nameindex * backport_if_nameindex(void);
static void backport_if_freenameindex(struct if_nameindex *);

static void backport_if_freenameindex(struct if_nameindex * inArray)
{
    if (inArray == NULL)
    {
        return;
    }

    for (size_t i = 0; inArray[i].if_index != 0; i++)
    {
        if (inArray[i].if_name != NULL)
        {
            free(inArray[i].if_name);
        }
    }

    free(inArray);
}

static struct if_nameindex * backport_if_nameindex(void)
{
    int err;
    unsigned index;
    size_t intfIter              = 0;
    size_t maxIntfNum            = 0;
    size_t numIntf               = 0;
    size_t numAddrs              = 0;
    struct if_nameindex * retval = NULL;
    struct if_nameindex * tmpval = NULL;
    struct ifaddrs * addrList    = NULL;
    struct ifaddrs * addrIter    = NULL;
    const char * lastIntfName    = "";

    err = getifaddrs(&addrList);
    VerifyOrExit(err >= 0, );

    // coalesce on consecutive interface names
    for (addrIter = addrList; addrIter != NULL; addrIter = addrIter->ifa_next)
    {
        numAddrs++;
        if (strcmp(addrIter->ifa_name, lastIntfName) == 0)
        {
            continue;
        }
        numIntf++;
        lastIntfName = addrIter->ifa_name;
    }

    tmpval = (struct if_nameindex *) malloc((numIntf + 1) * sizeof(struct if_nameindex));
    VerifyOrExit(tmpval != NULL, );
    memset(tmpval, 0, (numIntf + 1) * sizeof(struct if_nameindex));

    lastIntfName = "";
    for (addrIter = addrList; addrIter != NULL; addrIter = addrIter->ifa_next)
    {
        if (strcmp(addrIter->ifa_name, lastIntfName) == 0)
        {
            continue;
        }

        index = if_nametoindex(addrIter->ifa_name);
        if (index != 0)
        {
            tmpval[intfIter].if_index = index;
            tmpval[intfIter].if_name  = strdup(addrIter->ifa_name);
            intfIter++;
        }
        lastIntfName = addrIter->ifa_name;
    }

    // coalesce on interface index
    maxIntfNum = 0;
    for (size_t i = 0; tmpval[i].if_index != 0; i++)
    {
        if (maxIntfNum < tmpval[i].if_index)
        {
            maxIntfNum = tmpval[i].if_index;
        }
    }

    retval = (struct if_nameindex *) malloc((maxIntfNum + 1) * sizeof(struct if_nameindex));
    VerifyOrExit(retval != NULL, );
    memset(retval, 0, (maxIntfNum + 1) * sizeof(struct if_nameindex));

    for (size_t i = 0; tmpval[i].if_index != 0; i++)
    {
        struct if_nameindex * intf = &tmpval[i];
        if (retval[intf->if_index - 1].if_index == 0)
        {
            retval[intf->if_index - 1] = *intf;
        }
        else
        {
            free(intf->if_name);
            intf->if_index = 0;
            intf->if_name  = 0;
        }
    }

    intfIter = 0;

    // coalesce potential gaps between indeces
    for (size_t i = 0; i < maxIntfNum; i++)
    {
        if (retval[i].if_index != 0)
        {
            retval[intfIter] = retval[i];
            intfIter++;
        }
    }

    for (size_t i = intfIter; i < maxIntfNum; i++)
    {
        retval[i].if_index = 0;
        retval[i].if_name  = NULL;
    }

exit:
    if (tmpval != NULL)
    {
        free(tmpval);
    }

    if (addrList != NULL)
    {
        freeifaddrs(addrList);
    }

    return retval;
}

#endif // __ANDROID__ && __ANDROID_API__ < 24

InterfaceIterator::InterfaceIterator(void)
{
    mIntfArray       = NULL;
    mCurIntf         = 0;
    mIntfFlags       = 0;
    mIntfFlagsCached = 0;
}

#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
InterfaceIterator::InterfaceIterator() : mCurrentInterface(net_if_get_by_index(mCurrentId)) {}
#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF

/**
 * @fn      InterfaceIterator::~InterfaceIterator(void)
 *
 * @brief   Destroys an InterfaceIterator object.
 *
 * @details
 *     Recycles any resources allocated by the constructor.
 */

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

InterfaceIterator::~InterfaceIterator(void)
{
    if (mIntfArray != NULL)
    {
#if __ANDROID__ && __ANDROID_API__ < 24
        backport_if_freenameindex(mIntfArray);
#else
        if_freenameindex(mIntfArray);
#endif
        mIntfArray = NULL;
    }
}

#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

/**
 * @fn      bool InterfaceIterator::HasCurrent(void)
 *
 * @brief   Test whether the iterator is positioned on an interface
 *
 * @return  \c true if the iterator is positioned on an interface;
 *          \c false if positioned beyond the end of the interface list.
 */

#if CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
bool InterfaceIterator::HasCurrent(void)
{
    return (mIntfArray != NULL) ? mIntfArray[mCurIntf].if_index != 0 : Next();
}
#endif // CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
bool InterfaceIterator::HasCurrent(void)
{
    return mCurrentInterface != nullptr;
}
#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF

/**
 * @fn      bool InterfaceIterator::Next(void)
 *
 * @brief   Advance the iterator to the next network interface.
 *
 * @return  \c false if advanced beyond the end, else \c true.
 *
 * @details
 *     Advances the internal iterator to the next network interface or to a position
 *     beyond the end of the interface list.
 *
 *     On multi-threaded LwIP systems, this method is thread-safe relative to other
 *     threads accessing the global LwIP state provided that: 1) the other threads
 *     hold the LwIP core lock while mutating the list of netifs; and 2) netif objects
 *     themselves are never destroyed.
 *
 *     Iteration is stable in the face of changes to the underlying system's
 *     interfaces, *except* in the case of LwIP systems when the currently selected
 *     interface is removed from the list, which causes iteration to end immediately.
 */
bool InterfaceIterator::Next(void)
{
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

    if (mIntfArray == NULL)
    {
#if __ANDROID__ && __ANDROID_API__ < 24
        mIntfArray = backport_if_nameindex();
#else
        mIntfArray = if_nameindex();
#endif
    }
    else if (mIntfArray[mCurIntf].if_index != 0)
    {
        mCurIntf++;
        mIntfFlags       = 0;
        mIntfFlagsCached = false;
    }
    return (mIntfArray != NULL && mIntfArray[mCurIntf].if_index != 0);

#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
    mCurrentInterface = net_if_get_by_index(++mCurrentId);
    return HasCurrent();
#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF

#if CHIP_SYSTEM_CONFIG_USE_LWIP

    // Lock LwIP stack
    LOCK_TCPIP_CORE();

    // Verify the previous netif is still on the list if netifs.  If so,
    // advance to the next nextif.
    struct netif * prevNetif = mCurNetif;
#if LWIP_VERSION_MAJOR >= 2 && LWIP_VERSION_MINOR >= 0 && defined(NETIF_FOREACH)
    NETIF_FOREACH(mCurNetif)
#else
    for (mCurNetif = netif_list; mCurNetif != NULL; mCurNetif = mCurNetif->next)
#endif
    {
        if (mCurNetif == prevNetif)
        {
            mCurNetif = mCurNetif->next;
            break;
        }
    }

    // Unlock LwIP stack
    UNLOCK_TCPIP_CORE();

    return mCurNetif != NULL;

#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
}

/**
 * @fn      InterfaceId InterfaceIterator::GetInterfaceId(void)
 *
 * @brief   Returns the network interface id at the current iterator position.
 *
 * @retval  INET_NULL_INTERFACEID   if advanced beyond the end of the list.
 * @retval  id                      the current network interface id.
 */

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
InterfaceId InterfaceIterator::GetInterfaceId(void)
{
    return (HasCurrent()) ? mIntfArray[mCurIntf].if_index : INET_NULL_INTERFACEID;
}
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
InterfaceId InterfaceIterator::GetInterfaceId(void)
{
    return HasCurrent() ? mCurrentId : INET_NULL_INTERFACEID;
}
#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF

/**
 * @brief   Get the name of the current network interface
 *
 * @param[in]   nameBuf     region of memory to write the interface name
 * @param[in]   nameBufSize size of the region denoted by \c nameBuf
 *
 * @retval  INET_NO_ERROR           successful result, interface name written
 * @retval  INET_ERROR_INCORRECT_STATE
 *                                  iterator is positioned beyond the end of
 *                                  the list
 * @retval  INET_ERROR_NO_MEMORY    name is too large to be written in buffer
 * @retval  other                   another system or platform error
 *
 * @details
 *     Writes the name of the network interface as \c NUL terminated text string
 *     at \c nameBuf.
 */
INET_ERROR InterfaceIterator::GetInterfaceName(char * nameBuf, size_t nameBufSize)
{
    INET_ERROR err = INET_ERROR_NOT_IMPLEMENTED;

    VerifyOrExit(HasCurrent(), err = INET_ERROR_INCORRECT_STATE);

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
    VerifyOrExit(strlen(mIntfArray[mCurIntf].if_name) < nameBufSize, err = INET_ERROR_NO_MEMORY);
    strncpy(nameBuf, mIntfArray[mCurIntf].if_name, nameBufSize);
    err = INET_NO_ERROR;
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
    err = ::chip::Inet::GetInterfaceName(mCurrentId, nameBuf, nameBufSize);
#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF

#if CHIP_SYSTEM_CONFIG_USE_LWIP
    err = ::chip::Inet::GetInterfaceName(mCurNetif, nameBuf, nameBufSize);
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

exit:
    return err;
}

/**
 * @brief   Returns whether the current network interface is up.
 *
 * @return  \c true if current network interface is up, \c false if not
 *          or if the iterator is positioned beyond the end of the list.
 */
bool InterfaceIterator::IsUp(void)
{
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
    return (GetFlags() & IFF_UP) != 0;
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
    return HasCurrent() && net_if_is_up(mCurrentInterface);
#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF

#if CHIP_SYSTEM_CONFIG_USE_LWIP
    return HasCurrent() && netif_is_up(mCurNetif);
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
}

/**
 * @brief   Returns whether the current network interface supports multicast.
 *
 * @return  \c true if current network interface supports multicast, \c false
 *          if not, or if the iterator is positioned beyond the end of the list.
 */
bool InterfaceIterator::SupportsMulticast(void)
{
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
    return (GetFlags() & IFF_MULTICAST) != 0;
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
    return HasCurrent() && NET_IF_MAX_IPV6_MADDR > 0;
#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF

#if CHIP_SYSTEM_CONFIG_USE_LWIP
    return HasCurrent() &&
#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5
        (mCurNetif->flags & (NETIF_FLAG_IGMP | NETIF_FLAG_MLD6 | NETIF_FLAG_BROADCAST)) != 0;
#else
        (mCurNetif->flags & NETIF_FLAG_POINTTOPOINT) == 0;
#endif // LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
}

/**
 * @brief   Returns whether the current network interface has a broadcast address.
 *
 * @return  \c true if current network interface has a broadcast address, \c false
 *          if not, or if the iterator is positioned beyond the end of the list.
 */
bool InterfaceIterator::HasBroadcastAddress(void)
{
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
    return (GetFlags() & IFF_BROADCAST) != 0;
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
    // Zephyr seems to handle broadcast address for IPv4 implicitly
    return HasCurrent() && INET_CONFIG_ENABLE_IPV4;
#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF

#if CHIP_SYSTEM_CONFIG_USE_LWIP
    return HasCurrent() && (mCurNetif->flags & NETIF_FLAG_BROADCAST) != 0;
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
}

/**
 * @fn      short InterfaceIterator::GetFlags(void)
 *
 * @brief   Returns the ifr_flags value for the current interface.
 */

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

short InterfaceIterator::GetFlags(void)
{
    struct ifreq intfData;

    if (!mIntfFlagsCached && HasCurrent())
    {
        strncpy(intfData.ifr_name, mIntfArray[mCurIntf].if_name, IFNAMSIZ);
        intfData.ifr_name[IFNAMSIZ - 1] = '\0';

        int res = ioctl(GetIOCTLSocket(), SIOCGIFFLAGS, &intfData);
        if (res == 0)
        {
            mIntfFlags       = intfData.ifr_flags;
            mIntfFlagsCached = true;
        }
    }

    return mIntfFlags;
}

#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

/**
 * @fn      InterfaceAddressIterator::InterfaceAddressIterator(void)
 *
 * @brief   Constructs an InterfaceAddressIterator object.
 *
 * @details
 *     Starts the iterator at the first network address. On some platforms,
 *     this constructor may allocate resources recycled by the destructor.
 */

#if CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
InterfaceAddressIterator::InterfaceAddressIterator(void)
{
    mAddrsList = NULL;
    mCurAddr   = NULL;
}
#endif // CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
InterfaceAddressIterator::InterfaceAddressIterator() = default;
#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF

/**
 * @fn      InterfaceAddressIterator::~InterfaceAddressIterator(void)
 *
 * @brief   Destroys an InterfaceAddressIterator object.
 *
 * @details
 *  Recycles any resources allocated by the constructor.
 */

#if CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
InterfaceAddressIterator::~InterfaceAddressIterator(void)
{
    if (mAddrsList != NULL)
    {
        freeifaddrs(mAddrsList);
        mAddrsList = mCurAddr = NULL;
    }
}
#endif // CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

/**
 * @fn      bool InterfaceIterator::HasCurrent(void)
 *
 * @brief   Test whether the iterator is positioned on an interface address
 *
 * @return  \c true if the iterator is positioned on an interface address;
 *          \c false if positioned beyond the end of the address list.
 */
bool InterfaceAddressIterator::HasCurrent(void)
{
#if CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
    return (mAddrsList != NULL) ? (mCurAddr != NULL) : Next();
#endif // CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
    return mIntfIter.HasCurrent() && (mCurAddrIndex >= 0 || Next());
#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF

#if CHIP_SYSTEM_CONFIG_USE_LWIP
    return mIntfIter.HasCurrent() && ((mCurAddrIndex != kBeforeStartIndex) || Next());
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
}

/**
 * @fn      bool InterfaceAddressIterator::Next(void)
 *
 * @brief   Advance the iterator to the next interface address.
 *
 * @return  \c false if advanced beyond the end, else \c true.
 *
 * @details
 *     Advances the iterator to the next interface address or to a position
 *     beyond the end of the address list.
 *
 *     On LwIP, this method is thread-safe provided that: 1) other threads hold
 *     the LwIP core lock while mutating the netif list; and 2) netif objects
 *     themselves are never destroyed.  Additionally, iteration on LwIP systems
 *     will terminate early if the current interface is removed from the list.
 */
bool InterfaceAddressIterator::Next(void)
{
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
    while (true)
    {
        if (mAddrsList == NULL)
        {
            int res = getifaddrs(&mAddrsList);
            if (res < 0)
            {
                return false;
            }
            mCurAddr = mAddrsList;
        }
        else if (mCurAddr != NULL)
        {
            mCurAddr = mCurAddr->ifa_next;
        }

        if (mCurAddr == NULL)
        {
            return false;
        }

        if (mCurAddr->ifa_addr != NULL &&
            (mCurAddr->ifa_addr->sa_family == AF_INET6
#if INET_CONFIG_ENABLE_IPV4
             || mCurAddr->ifa_addr->sa_family == AF_INET
#endif // INET_CONFIG_ENABLE_IPV4
             ))
        {
            return true;
        }
    }
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
    while (mIntfIter.HasCurrent())
    {
        if (mCurAddrIndex == -1) // first address for the current interface
        {
            const net_if_config * config = net_if_get_config(net_if_get_by_index(mIntfIter.GetInterfaceId()));
            mIpv6                        = config->ip.ipv6;
        }

        while (++mCurAddrIndex < NET_IF_MAX_IPV6_ADDR)
            if (mIpv6->unicast[mCurAddrIndex].is_used)
                return true;

        mCurAddrIndex = -1;
        mIntfIter.Next();
    }

    return false;
#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF

#if CHIP_SYSTEM_CONFIG_USE_LWIP
    mCurAddrIndex++;

    while (mIntfIter.HasCurrent())
    {
        struct netif * curIntf = mIntfIter.GetInterfaceId();

        while (mCurAddrIndex < LWIP_IPV6_NUM_ADDRESSES)
        {
            if (ip6_addr_isvalid(netif_ip6_addr_state(curIntf, mCurAddrIndex)))
            {
                return true;
            }
            mCurAddrIndex++;
        }

#if INET_CONFIG_ENABLE_IPV4 && LWIP_IPV4
        if (mCurAddrIndex == LWIP_IPV6_NUM_ADDRESSES)
        {
            if (!ip4_addr_isany(netif_ip4_addr(curIntf)))
            {
                return true;
            }
        }
#endif // INET_CONFIG_ENABLE_IPV4 && LWIP_IPV4

        mIntfIter.Next();
        mCurAddrIndex = 0;
    }

    return false;
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
}

/**
 * @fn      IPAddress InterfaceAddressIterator::GetAddress(void)
 *
 * @brief   Get the current interface address.
 *
 * @return  the current interface address or \c IPAddress::Any if the iterator
 *          is positioned beyond the end of the address list.
 */
IPAddress InterfaceAddressIterator::GetAddress(void)
{
    if (HasCurrent())
    {
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
        return IPAddress::FromSockAddr(*mCurAddr->ifa_addr);
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
        return IPAddress::FromIPv6(mIpv6->unicast[mCurAddrIndex].address.in6_addr);
#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF

#if CHIP_SYSTEM_CONFIG_USE_LWIP
        struct netif * curIntf = mIntfIter.GetInterfaceId();

        if (mCurAddrIndex < LWIP_IPV6_NUM_ADDRESSES)
        {
            return IPAddress::FromIPv6(*netif_ip6_addr(curIntf, mCurAddrIndex));
        }
#if INET_CONFIG_ENABLE_IPV4 && LWIP_IPV4
        else
        {
            return IPAddress::FromIPv4(*netif_ip4_addr(curIntf));
        }
#endif // INET_CONFIG_ENABLE_IPV4 && LWIP_IPV4
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
    }

    return IPAddress::Any;
}

/**
 * @fn      uint8_t InterfaceAddressIterator::GetPrefixLength(void)
 *
 * @brief   Gets the network prefix associated with the current interface address.
 *
 * @return  the network prefix (in bits) or 0 if the iterator is positioned beyond
 *          the end of the address list.
 *
 * @details
 *     On LwIP, this method simply returns the hard-coded constant 64.
 *
 *     Note Well: the standard subnet prefix on all links other than PPP
 *     links is 64 bits. On PPP links and some non-broadcast multipoint access
 *     links, the convention is either 127 bits or 128 bits, but it might be
 *     something else. On most platforms, the system's interface address
 *     structure can represent arbitrary prefix lengths between 0 and 128.
 */
uint8_t InterfaceAddressIterator::GetPrefixLength(void)
{
    if (HasCurrent())
    {
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
        if (mCurAddr->ifa_addr->sa_family == AF_INET6)
        {
            struct sockaddr_in6 & netmask = *(struct sockaddr_in6 *) (mCurAddr->ifa_netmask);
            return NetmaskToPrefixLength(netmask.sin6_addr.s6_addr, 16);
        }
        if (mCurAddr->ifa_addr->sa_family == AF_INET)
        {
            struct sockaddr_in & netmask = *(struct sockaddr_in *) (mCurAddr->ifa_netmask);
            return NetmaskToPrefixLength((const uint8_t *) &netmask.sin_addr.s_addr, 4);
        }
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
        net_if * const iface              = net_if_get_by_index(mIntfIter.GetInterfaceId());
        net_if_ipv6_prefix * const prefix = net_if_ipv6_prefix_get(iface, &mIpv6->unicast[mCurAddrIndex].address.in6_addr);
        return prefix ? prefix->len : 128;
#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF

#if CHIP_SYSTEM_CONFIG_USE_LWIP
        if (mCurAddrIndex < LWIP_IPV6_NUM_ADDRESSES)
        {
            return 64;
        }
#if INET_CONFIG_ENABLE_IPV4 && LWIP_IPV4
        else
        {
            struct netif * curIntf = mIntfIter.GetInterfaceId();
            return NetmaskToPrefixLength((const uint8_t *) netif_ip4_netmask(curIntf), 4);
        }
#endif // INET_CONFIG_ENABLE_IPV4 && LWIP_IPV4
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
    }
    return 0;
}

/**
 * @fn      InterfaceId InterfaceAddressIterator::GetInterfaceId(void)
 *
 * @brief   Returns the network interface id associated with the current
 *          interface address.
 *
 * @return  the interface id or \c INET_NULL_INTERFACEID if the iterator
 *          is positioned beyond the end of the address list.
 */
InterfaceId InterfaceAddressIterator::GetInterfaceId(void)
{
    if (HasCurrent())
    {
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
        return if_nametoindex(mCurAddr->ifa_name);
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_LWIP || CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
        return mIntfIter.GetInterfaceId();
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP || CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
    }
    return INET_NULL_INTERFACEID;
}

/**
 * @fn      INET_ERROR InterfaceAddressIterator::GetInterfaceName(char * nameBuf, size_t nameBufSize)
 *
 * @brief   Get the name of the network interface associated with the
 *          current interface address.
 *
 * @param[in]   nameBuf     region of memory to write the interface name
 * @param[in]   nameBufSize size of the region denoted by \c nameBuf
 *
 * @retval  INET_NO_ERROR           successful result, interface name written
 * @retval  INET_ERROR_NO_MEMORY    name is too large to be written in buffer
 * @retval  INET_ERROR_INCORRECT_STATE
 *                                  the iterator is not currently positioned on an
 *                                  interface address
 * @retval  other                   another system or platform error
 *
 * @details
 *     Writes the name of the network interface as \c NUL terminated text string
 *     at \c nameBuf.
 */
INET_ERROR InterfaceAddressIterator::GetInterfaceName(char * nameBuf, size_t nameBufSize)
{
    INET_ERROR err = INET_ERROR_NOT_IMPLEMENTED;

    VerifyOrExit(HasCurrent(), err = INET_ERROR_INCORRECT_STATE);

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
    VerifyOrExit(strlen(mCurAddr->ifa_name) < nameBufSize, err = INET_ERROR_NO_MEMORY);
    strncpy(nameBuf, mCurAddr->ifa_name, nameBufSize);
    err = INET_NO_ERROR;
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_LWIP || CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
    err = mIntfIter.GetInterfaceName(nameBuf, nameBufSize);
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP || CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF

exit:
    return err;
}

/**
 * @fn      bool InterfaceAddressIterator::IsUp(void)
 *
 * @brief   Returns whether the network interface associated with the current
 *          interface address is up.
 *
 * @return  \c true if current network interface is up, \c false if not, or
 *          if the iterator is not positioned on an interface address.
 */
bool InterfaceAddressIterator::IsUp(void)
{
    if (HasCurrent())
    {
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
        return (mCurAddr->ifa_flags & IFF_UP) != 0;
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_LWIP || CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
        return mIntfIter.IsUp();
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP || CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
    }
    return false;
}

/**
 * @fn      bool InterfaceAddressIterator::SupportsMulticast(void)
 *
 * @brief   Returns whether the network interface associated with the current
 *          interface address supports multicast.
 *
 * @return  \c true if multicast is supported, \c false if not, or
 *          if the iterator is not positioned on an interface address.
 */
bool InterfaceAddressIterator::SupportsMulticast(void)
{
    if (HasCurrent())
    {
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
        return (mCurAddr->ifa_flags & IFF_MULTICAST) != 0;
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_LWIP || CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
        return mIntfIter.SupportsMulticast();
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP || CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
    }
    return false;
}

/**
 * @fn      bool InterfaceAddressIterator::HasBroadcastAddress(void)
 *
 * @brief   Returns whether the network interface associated with the current
 *          interface address has an IPv4 broadcast address.
 *
 * @return  \c true if the interface has a broadcast address, \c false if not, or
 *          if the iterator is not positioned on an interface address.
 */
bool InterfaceAddressIterator::HasBroadcastAddress(void)
{
    if (HasCurrent())
    {
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
        return (mCurAddr->ifa_flags & IFF_BROADCAST) != 0;
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_LWIP || CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
        return mIntfIter.HasBroadcastAddress();
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP || CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
    }
    return false;
}

/**
 * @fn       void InterfaceAddressIterator::GetAddressWithPrefix(IPPrefix & addrWithPrefix)
 *
 * @brief    Returns an IPPrefix containing the address and prefix length
 *           for the current address.
 */
void InterfaceAddressIterator::GetAddressWithPrefix(IPPrefix & addrWithPrefix)
{
    if (HasCurrent())
    {
        addrWithPrefix.IPAddr = GetAddress();
        addrWithPrefix.Length = GetPrefixLength();
    }
    else
    {
        addrWithPrefix = IPPrefix::Zero;
    }
}

/**
 * @fn       uint8_t NetmaskToPrefixLength(const uint8_t * netmask, uint16_t netmaskLen)
 *
 * @brief    Compute a prefix length from a variable-length netmask.
 */
uint8_t NetmaskToPrefixLength(const uint8_t * netmask, uint16_t netmaskLen)
{
    uint8_t prefixLen = 0;

    for (uint16_t i = 0; i < netmaskLen; i++, prefixLen += 8)
    {
        uint8_t b = netmask[i];
        if (b != 0xFF)
        {
            if ((b & 0xF0) == 0xF0)
                prefixLen += 4;
            else
                b = b >> 4;

            if ((b & 0x0C) == 0x0C)
                prefixLen += 2;
            else
                b = b >> 2;

            if ((b & 0x02) == 0x02)
                prefixLen++;

            break;
        }
    }

    return prefixLen;
}

} // namespace Inet
} // namespace chip
