/*
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *    Copyright (c) 2018 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 implements the <tt>Inet::RawEndPoint</tt> class,
 *      where the CHIP Inet Layer encapsulates methods for interacting
 *      interacting with IP network endpoints (SOCK_RAW sockets
 *      on Linux and BSD-derived systems) or LwIP raw protocol
 *      control blocks, as the system is configured accordingly.
 *
 */

#define __APPLE_USE_RFC_3542

#include "RawEndPoint.h"

#include "InetFaultInjection.h"
#include <InetLayer.h>

#include <support/CodeUtils.h>
#include <support/logging/CHIPLogging.h>
#include <system/SystemFaultInjection.h>

#if CHIP_SYSTEM_CONFIG_USE_LWIP
#include <lwip/ip.h>
#include <lwip/raw.h>
#include <lwip/tcpip.h>
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
#include <sys/select.h>
#if HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif // HAVE_SYS_SOCKET_H
#include <errno.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <unistd.h>
#if HAVE_NETINET_ICMP6_H
#include <netinet/icmp6.h>
#endif // HAVE_NETINET_ICMP6_H
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

// SOCK_CLOEXEC not defined on all platforms, e.g. iOS/MacOS:
#ifdef SOCK_CLOEXEC
#define SOCK_FLAGS SOCK_CLOEXEC
#else
#define SOCK_FLAGS 0
#endif

#include <string.h>

namespace chip {
namespace Inet {

using chip::System::PacketBuffer;

chip::System::ObjectPool<RawEndPoint, INET_CONFIG_NUM_RAW_ENDPOINTS> RawEndPoint::sPool;

#if CHIP_SYSTEM_CONFIG_USE_LWIP
/*
 * Note that for LwIP InterfaceId is already defined to be 'struct
 * netif'; consequently, some of the checking performed here could
 * conceivably be optimized out and the HAVE_LWIP_UDP_BIND_NETIF case
 * could simply be:
 *
 *   udp_bind_netif(aUDP, intfId);
 *
 */
static INET_ERROR LwIPBindInterface(struct raw_pcb * aRaw, InterfaceId intfId)
{
    INET_ERROR res = INET_NO_ERROR;

#if HAVE_LWIP_RAW_BIND_NETIF
    if (!IsInterfaceIdPresent(intfId))
        raw_bind_netif(aRaw, NULL);
    else
    {
        struct netif * netifp = IPEndPointBasis::FindNetifFromInterfaceId(intfId);

        if (netifp == NULL)
            res = INET_ERROR_UNKNOWN_INTERFACE;
        else
            raw_bind_netif(aRaw, netifp);
    }
#else
    if (!IsInterfaceIdPresent(intfId))
        aRaw->intf_filter = NULL;
    else
    {
        struct netif * netifp = IPEndPointBasis::FindNetifFromInterfaceId(intfId);

        if (netifp == NULL)
            res = INET_ERROR_UNKNOWN_INTERFACE;
        else
            aRaw->intf_filter = netifp;
    }
#endif // HAVE_LWIP_RAW_BIND_NETIF

    return res;
}
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

/**
 * @brief   Bind the endpoint to an interface IP address.
 *
 * @param[in]   addrType    the protocol version of the IP address
 * @param[in]   addr        the IP address (must be an interface address)
 * @param[in]   intfId      an optional network interface indicator
 *
 * @retval  INET_NO_ERROR               success: endpoint bound to address
 * @retval  INET_ERROR_INCORRECT_STATE  endpoint has been bound previously
 * @retval  INET_NO_MEMORY              insufficient memory for endpoint
 *
 * @retval  INET_ERROR_UNKNOWN_INTERFACE
 *      On some platforms, the optionally specified interface is not
 *      present.
 *
 * @retval  INET_ERROR_WRONG_PROTOCOL_TYPE
 *      \c addrType does not match \c IPVer.
 *
 * @retval  INET_ERROR_WRONG_ADDRESS_TYPE
 *      \c addrType is \c kIPAddressType_Any, or the type of \c addr is not
 *      equal to \c addrType.
 *
 * @retval  other                   another system or platform error
 *
 * @details
 *  Binds the endpoint to the specified network interface IP address.
 *
 *  On LwIP, this method must not be called with the LwIP stack lock
 *  already acquired.
 */
INET_ERROR RawEndPoint::Bind(IPAddressType addrType, IPAddress addr, InterfaceId intfId)
{
    INET_ERROR res = INET_NO_ERROR;

    if (mState != kState_Ready && mState != kState_Bound)
    {
        res = INET_ERROR_INCORRECT_STATE;
        goto exit;
    }

    if ((addr != IPAddress::Any) && (addr.Type() != kIPAddressType_Any) && (addr.Type() != addrType))
    {
        res = INET_ERROR_WRONG_ADDRESS_TYPE;
        goto exit;
    }

#if CHIP_SYSTEM_CONFIG_USE_LWIP

    // Lock LwIP stack
    LOCK_TCPIP_CORE();

    // Make sure we have the appropriate type of PCB.
    res = GetPCB(addrType);

    // Bind the PCB to the specified address.
    if (res == INET_NO_ERROR)
    {
#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5
        ip_addr_t ipAddr = addr.ToLwIPAddr();
#if INET_CONFIG_ENABLE_IPV4
        lwip_ip_addr_type lType = IPAddress::ToLwIPAddrType(addrType);
        IP_SET_TYPE_VAL(ipAddr, lType);
#endif // INET_CONFIG_ENABLE_IPV4
        res = chip::System::MapErrorLwIP(raw_bind(mRaw, &ipAddr));
#else // LWIP_VERSION_MAJOR <= 1 && LWIP_VERSION_MINOR < 5
        if (addrType == kIPAddressType_IPv6)
        {
            ip6_addr_t ipv6Addr = addr.ToIPv6();
            res                 = chip::System::MapErrorLwIP(raw_bind_ip6(mRaw, &ipv6Addr));
        }
#if INET_CONFIG_ENABLE_IPV4
        else if (addrType == kIPAddressType_IPv4)
        {
            ip4_addr_t ipv4Addr = addr.ToIPv4();
            res                 = chip::System::MapErrorLwIP(raw_bind(mRaw, &ipv4Addr));
        }
#endif // INET_CONFIG_ENABLE_IPV4
        else
            res = INET_ERROR_WRONG_ADDRESS_TYPE;
#endif // LWIP_VERSION_MAJOR <= 1 || LWIP_VERSION_MINOR >= 5
    }

    if (res == INET_NO_ERROR)
    {
        res = LwIPBindInterface(mRaw, intfId);
    }

    // Unlock LwIP stack
    UNLOCK_TCPIP_CORE();

    SuccessOrExit(res);

#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
    // Make sure we have the appropriate type of socket.
    res = GetSocket(addrType);
    SuccessOrExit(res);

    res = IPEndPointBasis::Bind(addrType, addr, 0, intfId);
    SuccessOrExit(res);

    mBoundIntfId = intfId;
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

    if (res == INET_NO_ERROR)
    {
        mState = kState_Bound;
    }

exit:
    return res;
}

/**
 * Bind the raw endpoint to an IPv6 link-local scope address at the specified
 * interface index.  Also sets various IPv6 socket options appropriate for
 * transmitting packets to and from on-link destinations.
 *
 * @param[in]   intf    An InterfaceId to identify the scope of the address.
 *
 * @param[in]   addr    An IPv6 link-local scope IPAddress object.
 *
 * @return INET_NO_ERROR on success, or a mapped OS error on failure. An invalid
 * parameter list can result in INET_ERROR_WRONG_ADDRESS_TYPE. If the raw endpoint
 * is already bound or is listening, then returns INET_ERROR_INCORRECT_STATE.
 */
/**
 * @brief   Bind the endpoint to an interface IPv6 link-local address.
 *
 * @param[in]   intf    the indicator of the network interface
 * @param[in]   addr    the IP address (must be an interface address)
 *
 * @retval  INET_NO_ERROR               success: endpoint bound to address
 * @retval  INET_ERROR_INCORRECT_STATE  endpoint has been bound previously
 * @retval  INET_NO_MEMORY              insufficient memory for endpoint
 *
 * @retval  INET_ERROR_WRONG_PROTOCOL_TYPE
 *      \c addrType does not match \c IPVer.
 *
 * @retval  INET_ERROR_WRONG_ADDRESS_TYPE
 *      \c addr is not an IPv6 link-local address or \c intf is
 *      \c INET_NULL_INTERFACEID.
 *
 * @retval  other                   another system or platform error
 *
 * @details
 *  Binds the endpoint to the IPv6 link-local address \c addr on the
 *  network interface indicated by \c intf.
 *
 *  On LwIP, this method must not be called with the LwIP stack lock
 *  already acquired.
 */
INET_ERROR RawEndPoint::BindIPv6LinkLocal(InterfaceId intf, IPAddress addr)
{
    INET_ERROR res = INET_NO_ERROR;

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
    const int lIfIndex = static_cast<int>(intf);
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

    if (mState != kState_Ready && mState != kState_Bound)
    {
        res = INET_ERROR_INCORRECT_STATE;
        goto ret;
    }

    if (!addr.IsIPv6LinkLocal())
    {
        res = INET_ERROR_WRONG_ADDRESS_TYPE;
        goto ret;
    }

#if CHIP_SYSTEM_CONFIG_USE_LWIP

    // Lock LwIP stack
    LOCK_TCPIP_CORE();

    // Make sure we have the appropriate type of PCB.
    res = GetPCB(addr.Type());

    // Bind the PCB to the specified address.
    if (res == INET_NO_ERROR)
    {
#if LWIP_VERSION_MAJOR > 1
        ip_addr_t ipAddr = addr.ToLwIPAddr();
        res              = chip::System::MapErrorLwIP(raw_bind(mRaw, &ipAddr));
#else  // LWIP_VERSION_MAJOR <= 1
        ip6_addr_t ipv6Addr = addr.ToIPv6();
        res                 = chip::System::MapErrorLwIP(raw_bind_ip6(mRaw, &ipv6Addr));
#endif // LWIP_VERSION_MAJOR <= 1

        if (res != INET_NO_ERROR)
        {
            raw_remove(mRaw);
            mRaw              = NULL;
            mLwIPEndPointType = kLwIPEndPointType_Unknown;
        }
    }

    // Unlock LwIP stack
    UNLOCK_TCPIP_CORE();

#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS

    static const int sInt255 = 255;

    // Make sure we have the appropriate type of socket.
    res = GetSocket(kIPAddressType_IPv6);
    if (res != INET_NO_ERROR)
    {
        goto ret;
    }

    if (::setsockopt(mSocket, IPPROTO_IPV6, IPV6_MULTICAST_IF, &lIfIndex, sizeof(lIfIndex)) != 0)
    {
        goto optfail;
    }

    if (::setsockopt(mSocket, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &sInt255, sizeof(sInt255)) != 0)
    {
        goto optfail;
    }

    if (::setsockopt(mSocket, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &sInt255, sizeof(sInt255)) != 0)
    {
        goto optfail;
    }

    mAddrType = kIPAddressType_IPv6;
    goto ret;

optfail:
    res = chip::System::MapErrorPOSIX(errno);
    ::close(mSocket);
    mSocket   = INET_INVALID_SOCKET_FD;
    mAddrType = kIPAddressType_Unknown;

#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

ret:
    if (res == INET_NO_ERROR)
    {
        mState = kState_Bound;
    }

    return res;
}

/**
 * @brief   Prepare the endpoint to receive ICMP messages.
 *
 * @retval  INET_NO_ERROR   always returned.
 *
 * @details
 *  If \c mState is already \c kState_Listening, then no operation is
 *  performed, otherwise the \c mState is set to \c kState_Listening and
 *  the endpoint is prepared to received ICMPv6 messages, according to the
 *  semantics of the platform.
 *
 *  On LwIP, this method must not be called with the LwIP stack lock
 *  already acquired
 */
INET_ERROR RawEndPoint::Listen(void)
{
    INET_ERROR res = INET_NO_ERROR;

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
    chip::System::Layer & lSystemLayer = SystemLayer();
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

    if (mState == kState_Listening)
    {
        res = INET_NO_ERROR;
        goto exit;
    }

    if (mState != kState_Bound)
    {
        res = INET_ERROR_INCORRECT_STATE;
        goto exit;
    }

#if CHIP_SYSTEM_CONFIG_USE_LWIP

    // Lock LwIP stack
    LOCK_TCPIP_CORE();

#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5
    raw_recv(mRaw, LwIPReceiveRawMessage, this);
#else  // LWIP_VERSION_MAJOR <= 1 && LWIP_VERSION_MINOR < 5
    if (PCB_ISIPV6(mRaw))
        raw_recv_ip6(mRaw, LwIPReceiveRawMessage, this);
    else
        raw_recv(mRaw, LwIPReceiveRawMessage, this);
#endif // LWIP_VERSION_MAJOR <= 1 || LWIP_VERSION_MINOR >= 5

    // Unlock LwIP stack
    UNLOCK_TCPIP_CORE();

#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS

    // Wake the thread calling select so that it starts selecting on the new socket.
    lSystemLayer.WakeSelect();

#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

    if (res == INET_NO_ERROR)
    {
        mState = kState_Listening;
    }

exit:
    return res;
}

/**
 * @brief   Close the endpoint.
 *
 * @details
 *  If <tt>mState != kState_Closed</tt>, then closes the endpoint, removing
 *  it from the set of endpoints eligible for communication events.
 *
 *  On LwIP systems, this method must not be called with the LwIP stack
 *  lock already acquired.
 */
void RawEndPoint::Close(void)
{
    if (mState != kState_Closed)
    {
#if CHIP_SYSTEM_CONFIG_USE_LWIP

        // Lock LwIP stack
        LOCK_TCPIP_CORE();

        // Since Raw PCB is released synchronously here, but Raw endpoint itself might have to wait
        // for destruction asynchronously, there could be more allocated Raw endpoints than Raw PCBs.
        if (mRaw != NULL)
        {
            raw_remove(mRaw);
            mRaw              = NULL;
            mLwIPEndPointType = kLwIPEndPointType_Unknown;
        }

        // Unlock LwIP stack
        UNLOCK_TCPIP_CORE();

#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS

        if (mSocket != INET_INVALID_SOCKET_FD)
        {
            chip::System::Layer & lSystemLayer = SystemLayer();

            // Wake the thread calling select so that it recognizes the socket is closed.
            lSystemLayer.WakeSelect();

            close(mSocket);
            mSocket = INET_INVALID_SOCKET_FD;
        }

        // Clear any results from select() that indicate pending I/O for the socket.
        mPendingIO.Clear();

#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

        mState = kState_Closed;
    }
}

/**
 * @brief   Close the endpoint and recycle its memory.
 *
 * @details
 *  Invokes the \c Close method, then invokes the
 *  <tt>InetLayerBasis::Release</tt> method to return the object to its
 *  memory pool.
 *
 *  On LwIP systems, this method must not be called with the LwIP stack
 *  lock already acquired.
 */
void RawEndPoint::Free(void)
{
    Close();

#if CHIP_SYSTEM_CONFIG_USE_LWIP
    DeferredFree(kReleaseDeferralErrorTactic_Die);
#else  // !CHIP_SYSTEM_CONFIG_USE_LWIP
    Release();
#endif // !CHIP_SYSTEM_CONFIG_USE_LWIP
}

/**
 *  A synonym for <tt>SendTo(addr, INET_NULL_INTERFACEID, msg,
 *  sendFlags)</tt>.
 */
INET_ERROR RawEndPoint::SendTo(IPAddress addr, chip::System::PacketBuffer * msg, uint16_t sendFlags)
{
    return SendTo(addr, INET_NULL_INTERFACEID, msg, sendFlags);
}

/**
 * @brief   Send an ICMP message to the specified destination address.
 *
 * @param[in]   addr        the destination IP address
 * @param[in]   intfId      an optional network interface indicator
 * @param[in]   msg         the packet buffer containing the UDP message
 * @param[in]   sendFlags   optional transmit option flags
 *
 * @retval  INET_NO_ERROR
 *      success: \c msg is queued for transmit.
 *
 * @retval  INET_ERROR_NOT_SUPPORTED
 *      the system does not support the requested operation.
 *
 * @retval  INET_ERROR_WRONG_ADDRESS_TYPE
 *      the destination address and the bound interface address do not
 *      have matching protocol versions or address type.
 *
 * @retval  INET_ERROR_MESSAGE_TOO_LONG
 *      \c msg does not contain the whole ICMP message.
 *
 * @retval  INET_ERROR_OUTBOUND_MESSAGE_TRUNCATED
 *      On some platforms, only a truncated portion of \c msg was queued
 *      for transmit.
 *
 * @retval  other                   another system or platform error
 *
 * @details
 *      Send the ICMP message in \c msg to the destination given in \c addr.
 *
 *      Where <tt>(sendFlags & kSendFlag_RetainBuffer) != 0</tt>, calls
 *      <tt>chip::System::PacketBuffer::Free</tt> on behalf of the caller, otherwise this
 *      method deep-copies \c msg into a fresh object, and queues that for
 *      transmission, leaving the original \c msg available after return.
 */
INET_ERROR RawEndPoint::SendTo(IPAddress addr, InterfaceId intfId, chip::System::PacketBuffer * msg, uint16_t sendFlags)
{
    IPPacketInfo pktInfo;
    pktInfo.Clear();
    pktInfo.DestAddress = addr;
    pktInfo.Interface   = intfId;
    return SendMsg(&pktInfo, msg, sendFlags);
}

/**
 * @brief   Send an ICMP message to the specified destination.
 *
 * @param[in]   pktInfo     destination information for the message
 * @param[in]   msg         the packet buffer containing the UDP message
 * @param[in]   sendFlags   optional transmit option flags
 *
 * @retval  INET_NO_ERROR
 *      success: \c msg is queued for transmit.
 *
 * @retval  INET_ERROR_NOT_SUPPORTED
 *      the system does not support the requested operation.
 *
 * @retval  INET_ERROR_WRONG_ADDRESS_TYPE
 *      the destination address and the bound interface address do not
 *      have matching protocol versions or address type.
 *
 * @retval  INET_ERROR_MESSAGE_TOO_LONG
 *      \c msg does not contain the whole ICMP message.
 *
 * @retval  INET_ERROR_OUTBOUND_MESSAGE_TRUNCATED
 *      On some platforms, only a truncated portion of \c msg was queued
 *      for transmit.
 *
 * @retval  other                   another system or platform error
 *
 * @details
 *      Send the ICMP message \c msg using the destination information given in \c addr.
 *
 *      Where <tt>(sendFlags & kSendFlag_RetainBuffer) != 0</tt>, calls
 *      <tt>chip::System::PacketBuffer::Free</tt> on behalf of the caller, otherwise this
 *      method deep-copies \c msg into a fresh object, and queues that for
 *      transmission, leaving the original \c msg available after return.
 */
INET_ERROR RawEndPoint::SendMsg(const IPPacketInfo * pktInfo, chip::System::PacketBuffer * msg, uint16_t sendFlags)
{
    INET_ERROR res         = INET_NO_ERROR;
    const IPAddress & addr = pktInfo->DestAddress;

    INET_FAULT_INJECT(FaultInjection::kFault_Send, if ((sendFlags & kSendFlag_RetainBuffer) == 0) PacketBuffer::Free(msg);
                      return INET_ERROR_UNKNOWN_INTERFACE;);
    INET_FAULT_INJECT(FaultInjection::kFault_SendNonCritical,
                      if ((sendFlags & kSendFlag_RetainBuffer) == 0) PacketBuffer::Free(msg);
                      return INET_ERROR_NO_MEMORY;);

    // Do not allow sending an IPv4 address on an IPv6 end point and
    // vice versa.

    if (IPVer == kIPVersion_6 && addr.Type() != kIPAddressType_IPv6)
    {
        return INET_ERROR_WRONG_ADDRESS_TYPE;
    }
#if INET_CONFIG_ENABLE_IPV4
    else if (IPVer == kIPVersion_4 && addr.Type() != kIPAddressType_IPv4)
    {
        return INET_ERROR_WRONG_ADDRESS_TYPE;
    }
#endif // INET_CONFIG_ENABLE_IPV4

#if CHIP_SYSTEM_CONFIG_USE_LWIP

    if (sendFlags & kSendFlag_RetainBuffer)
    {
        // when retaining a buffer, the caller expects the msg to be
        // unmodified.  LwIP stack will normally prepend the packet
        // headers as the packet traverses the IP/netif layers,
        // which normally modifies the packet.  We prepend a small
        // pbuf to the beginning of the pbuf chain, s.t. all headers
        // are added to the temporary space, just large enough to hold
        // the transport headers. Careful reader will note:
        //
        // * we're actually oversizing the reserved space, the
        //   transport header is large enough for the TCP header which
        //   is larger than the UDP header, but it seemed cleaner than
        //   the combination of PBUF_IP for reserve space, UDP_HLEN
        //   for payload, and post allocation adjustment of the header
        //   space).
        //
        // * the code deviates from the existing PacketBuffer
        //   abstractions and needs to reach into the underlying pbuf
        //   code.  The code in PacketBuffer also forces us to perform
        //   (effectively) a reinterpret_cast rather than a
        //   static_cast.  JIRA WEAV-811 is filed to track the
        //   re-architecting of the memory management.

        pbuf * msgCopy = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_RAM);

        if (msgCopy == NULL)
        {
            return INET_ERROR_NO_MEMORY;
        }

        pbuf_chain(msgCopy, (pbuf *) msg);
        msg = (PacketBuffer *) msgCopy;
    }

    // Lock LwIP stack
    LOCK_TCPIP_CORE();

    // Make sure we have the appropriate type of PCB based on the destination address.
    res = GetPCB(addr.Type());
    SuccessOrExit(res);

    // Send the message to the specified address/port.
    {
        err_t lwipErr = ERR_VAL;

#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5
        ip_addr_t ipAddr = addr.ToLwIPAddr();

        lwipErr = raw_sendto(mRaw, (pbuf *) msg, &ipAddr);
#else // LWIP_VERSION_MAJOR <= 1 && LWIP_VERSION_MINOR < 5
        if (PCB_ISIPV6(mRaw))
        {
            ip6_addr_t ipv6Addr = addr.ToIPv6();

            lwipErr = raw_sendto_ip6(mRaw, (pbuf *) msg, &ipv6Addr);
        }
#if INET_CONFIG_ENABLE_IPV4
        else
        {
            ip4_addr_t ipv4Addr = addr.ToIPv4();

            lwipErr = raw_sendto(mRaw, (pbuf *) msg, &ipv4Addr);
        }
#endif // INET_CONFIG_ENABLE_IPV4
#endif // LWIP_VERSION_MAJOR <= 1 || LWIP_VERSION_MINOR >= 5

        if (lwipErr != ERR_OK)
            res = chip::System::MapErrorLwIP(lwipErr);
    }

    // Unlock LwIP stack
    UNLOCK_TCPIP_CORE();

    PacketBuffer::Free(msg);
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
    // Make sure we have the appropriate type of socket based on the
    // destination address.

    res = GetSocket(addr.Type());
    SuccessOrExit(res);

    res = IPEndPointBasis::SendMsg(pktInfo, msg, sendFlags);

    if ((sendFlags & kSendFlag_RetainBuffer) == 0)
        PacketBuffer::Free(msg);
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

exit:
    CHIP_SYSTEM_FAULT_INJECT_ASYNC_EVENT();

    return res;
}

/**
 * @brief   Set the ICMP6 filter parameters in the network stack.
 *
 * @param[in]   numICMPTypes    length of array at \c aICMPTypes
 * @param[in]   aICMPTypes      the set of ICMPv6 type codes to filter.
 *
 * @retval  INET_NO_ERROR                   success: filter parameters set
 * @retval  INET_ERROR_NOT_IMPLEMENTED      system does not implement
 * @retval  INET_ERROR_WRONG_ADDRESS_TYPE   endpoint not IPv6 type
 * @retval  INET_ERROR_WRONG_PROTOCOL_TYPE  endpoint not ICMP6 type
 *
 * @retval  other                   another system or platform error
 *
 * @details
 *  Apply the ICMPv6 filtering parameters for the codes in \c aICMPTypes to
 *  the underlying endpoint in the system networking stack.
 */
INET_ERROR RawEndPoint::SetICMPFilter(uint8_t numICMPTypes, const uint8_t * aICMPTypes)
{
    INET_ERROR err;

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
#if !(HAVE_NETINET_ICMP6_H && HAVE_ICMP6_FILTER)
    err = INET_ERROR_NOT_IMPLEMENTED;
    ExitNow();
#endif //!(HAVE_NETINET_ICMP6_H && HAVE_ICMP6_FILTER)
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

    VerifyOrExit(IPVer == kIPVersion_6, err = INET_ERROR_WRONG_ADDRESS_TYPE);
    VerifyOrExit(IPProto == kIPProtocol_ICMPv6, err = INET_ERROR_WRONG_PROTOCOL_TYPE);
    VerifyOrExit((numICMPTypes == 0 && aICMPTypes == NULL) || (numICMPTypes != 0 && aICMPTypes != NULL), err = INET_ERROR_BAD_ARGS);

    err = INET_NO_ERROR;

#if CHIP_SYSTEM_CONFIG_USE_LWIP
    LOCK_TCPIP_CORE();
    NumICMPTypes = numICMPTypes;
    ICMPTypes    = aICMPTypes;
    UNLOCK_TCPIP_CORE();
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
#if HAVE_NETINET_ICMP6_H && HAVE_ICMP6_FILTER
    struct icmp6_filter filter;
    if (numICMPTypes > 0)
    {
        ICMP6_FILTER_SETBLOCKALL(&filter);
        for (int j = 0; j < numICMPTypes; ++j)
        {
            ICMP6_FILTER_SETPASS(aICMPTypes[j], &filter);
        }
    }
    else
    {
        ICMP6_FILTER_SETPASSALL(&filter);
    }
    if (setsockopt(mSocket, IPPROTO_ICMPV6, ICMP6_FILTER, &filter, sizeof(filter)) == -1)
    {
        err = chip::System::MapErrorPOSIX(errno);
    }
#endif // HAVE_NETINET_ICMP6_H && HAVE_ICMP6_FILTER
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

exit:
    return err;
}

/**
 * @brief   Bind the endpoint to a network interface.
 *
 * @param[in]   addrType    the protocol version of the IP address.
 *
 * @param[in]   intf        indicator of the network interface.
 *
 * @retval  INET_NO_ERROR               success: endpoint bound to address
 * @retval  INET_NO_MEMORY              insufficient memory for endpoint
 * @retval  INET_ERROR_NOT_IMPLEMENTED  system implementation not complete.
 *
 * @retval  INET_ERROR_UNKNOWN_INTERFACE
 *      On some platforms, the interface is not present.
 *
 * @retval  other                   another system or platform error
 *
 * @details
 *  Binds the endpoint to the specified network interface IP address.
 *
 *  On LwIP, this method must not be called with the LwIP stack lock
 *  already acquired.
 */
INET_ERROR RawEndPoint::BindInterface(IPAddressType addrType, InterfaceId intfId)
{
    INET_ERROR err = INET_NO_ERROR;

    // A lock is required because the LwIP thread may be referring to intf_filter,
    // while this code running in the Inet application is potentially modifying it.
    // NOTE: this only supports LwIP interfaces whose number is no bigger than 9.

    if (mState != kState_Ready && mState != kState_Bound)
        return INET_ERROR_INCORRECT_STATE;

#if CHIP_SYSTEM_CONFIG_USE_LWIP
    LOCK_TCPIP_CORE();

    // Make sure we have the appropriate type of PCB.
    err = GetPCB(addrType);
    SuccessOrExit(err);

    err = LwIPBindInterface(mRaw, intfId);

    UNLOCK_TCPIP_CORE();

    SuccessOrExit(err);

#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
    // Make sure we have the appropriate type of socket.
    err = GetSocket(addrType);
    SuccessOrExit(err);

    err = IPEndPointBasis::BindInterface(addrType, intfId);
    SuccessOrExit(err);
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

    if (err == INET_NO_ERROR)
    {
        mState = kState_Bound;
    }

exit:
    return err;
}

void RawEndPoint::Init(InetLayer * inetLayer, IPVersion ipVer, IPProtocol ipProto)
{
    IPEndPointBasis::Init(inetLayer);

    IPVer   = ipVer;
    IPProto = ipProto;
}

/**
 * Get the bound interface on this endpoint.
 *
 * @return InterfaceId   The bound interface id.
 */
InterfaceId RawEndPoint::GetBoundInterface(void)
{
#if CHIP_SYSTEM_CONFIG_USE_LWIP
#if HAVE_LWIP_RAW_BIND_NETIF
    return netif_get_by_index(mRaw->netif_idx);
#else
    return mRaw->intf_filter;
#endif
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
    return mBoundIntfId;
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
}

#if CHIP_SYSTEM_CONFIG_USE_LWIP

void RawEndPoint::HandleDataReceived(PacketBuffer * msg)
{
    IPEndPointBasis::HandleDataReceived(msg);
}

INET_ERROR RawEndPoint::GetPCB(IPAddressType addrType)
{
    INET_ERROR lRetval = INET_NO_ERROR;

    // IMPORTANT: This method MUST be called with the LwIP stack LOCKED!

#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5
    if (mRaw == NULL)
    {
        switch (addrType)
        {
        case kIPAddressType_IPv6:
#if INET_CONFIG_ENABLE_IPV4
        case kIPAddressType_IPv4:
#endif // INET_CONFIG_ENABLE_IPV4
            mRaw = raw_new_ip_type(IPAddress::ToLwIPAddrType(addrType), IPProto);
            break;

        default:
            lRetval = INET_ERROR_WRONG_ADDRESS_TYPE;
            goto exit;
        }

        if (mRaw == NULL)
        {
            ChipLogError(Inet, "raw_new_ip_type failed");
            lRetval = INET_ERROR_NO_MEMORY;
            goto exit;
        }
        else
        {
            mLwIPEndPointType = kLwIPEndPointType_Raw;
        }
    }
    else
    {
        const lwip_ip_addr_type lLwIPAddrType = static_cast<lwip_ip_addr_type>(IP_GET_TYPE(&mRaw->local_ip));

        switch (lLwIPAddrType)
        {
        case IPADDR_TYPE_V6:
            VerifyOrExit(addrType == kIPAddressType_IPv6, lRetval = INET_ERROR_WRONG_ADDRESS_TYPE);
            break;

#if INET_CONFIG_ENABLE_IPV4
        case IPADDR_TYPE_V4:
            VerifyOrExit(addrType == kIPAddressType_IPv4, lRetval = INET_ERROR_WRONG_ADDRESS_TYPE);
            break;
#endif // INET_CONFIG_ENABLE_IPV4

        default:
            break;
        }
    }
#else // LWIP_VERSION_MAJOR <= 1 && LWIP_VERSION_MINOR < 5
    if (mRaw == NULL)
    {
        if (IPVer == kIPVersion_6)
        {
            mRaw = raw_new_ip6(IPProto);
            if (mRaw != NULL)
                ip_set_option(mRaw, SOF_REUSEADDR);
        }
#if INET_CONFIG_ENABLE_IPV4
        else if (IPVer == kIPVersion_4)
        {
            mRaw = raw_new(IPProto);
        }
#endif // INET_CONFIG_ENABLE_IPV4
        else
        {
            lRetval = INET_ERROR_WRONG_ADDRESS_TYPE;
            goto exit;
        }

        if (mRaw == NULL)
        {
            ChipLogError(Inet, "raw_new failed");
            lRetval = INET_ERROR_NO_MEMORY;
            goto exit;
        }
        else
        {
            mLwIPEndPointType = kLwIPEndPointType_Raw;
        }
    }
    else
    {
#if INET_CONFIG_ENABLE_IPV4
        const IPAddressType pcbType = PCB_ISIPV6(mRaw) ? kIPAddressType_IPv6 : kIPAddressType_IPv4;
#else  // !INET_CONFIG_ENABLE_IPV4
        const IPAddressType pcbType = kIPAddressType_IPv6;
#endif // !INET_CONFIG_ENABLE_IPV4

        if (addrType != pcbType)
        {
            lRetval = INET_ERROR_WRONG_ADDRESS_TYPE;
            goto exit;
        }
    }
#endif // LWIP_VERSION_MAJOR <= 1 || LWIP_VERSION_MINOR >= 5

exit:
    return (lRetval);
}

/* This function is executed when a raw_pcb is listening and an IP datagram (v4 or v6) is received.
 * NOTE: currently ICMPv4 filtering is currently not implemented, but it can easily be added later.
 * This fn() may be executed concurrently with SetICMPFilter()
 * - this fn() runs in the LwIP thread (and the lock has already been taken)
 * - SetICMPFilter() runs in the Inet thread.
 */
#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5
u8_t RawEndPoint::LwIPReceiveRawMessage(void * arg, struct raw_pcb * pcb, struct pbuf * p, const ip_addr_t * addr)
#else  // LWIP_VERSION_MAJOR <= 1 && LWIP_VERSION_MINOR < 5
u8_t RawEndPoint::LwIPReceiveRawMessage(void * arg, struct raw_pcb * pcb, struct pbuf * p, ip_addr_t * addr)
#endif // LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5
{
    RawEndPoint * ep                   = static_cast<RawEndPoint *>(arg);
    PacketBuffer * buf                 = reinterpret_cast<PacketBuffer *>(static_cast<void *>(p));
    chip::System::Layer & lSystemLayer = ep->SystemLayer();
    IPPacketInfo * pktInfo             = NULL;
    uint8_t enqueue                    = 1;

    // Filtering based on the saved ICMP6 types (the only protocol currently supported.)
    if ((ep->IPVer == kIPVersion_6) && (ep->IPProto == kIPProtocol_ICMPv6))
    {
        if (ep->NumICMPTypes > 0)
        { // When no filter is defined, let all ICMPv6 packets pass
          // The type is the first 8 bits field of an ICMP (v4 or v6) packet
            uint8_t icmp_type       = *(buf->Start() + ip_current_header_tot_len());
            uint8_t icmp_type_found = 0;
            for (int j = 0; j < ep->NumICMPTypes; ++j)
            {
                if (ep->ICMPTypes[j] == icmp_type)
                {
                    icmp_type_found = 1;
                    break;
                }
            }
            if (!icmp_type_found)
            {
                enqueue = 0; // do not eat it
            }
        }
    }

    if (enqueue)
    {
        pktInfo = GetPacketInfo(buf);

        if (pktInfo != NULL)
        {
#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5
            pktInfo->SrcAddress  = IPAddress::FromLwIPAddr(*addr);
            pktInfo->DestAddress = IPAddress::FromLwIPAddr(*ip_current_dest_addr());
#else // LWIP_VERSION_MAJOR <= 1
            if (PCB_ISIPV6(pcb))
            {
                pktInfo->SrcAddress = IPAddress::FromIPv6(*(ip6_addr_t *) addr);
                pktInfo->DestAddress = IPAddress::FromIPv6(*ip6_current_dest_addr());
            }
#if INET_CONFIG_ENABLE_IPV4
            else
            {
                pktInfo->SrcAddress = IPAddress::FromIPv4(*addr);
                pktInfo->DestAddress = IPAddress::FromIPv4(*ip_current_dest_addr());
            }
#endif // INET_CONFIG_ENABLE_IPV4
#endif // LWIP_VERSION_MAJOR <= 1

            pktInfo->Interface = ip_current_netif();
            pktInfo->SrcPort   = 0;
            pktInfo->DestPort  = 0;
        }

        if (lSystemLayer.PostEvent(*ep, kInetEvent_RawDataReceived, (uintptr_t) buf) != INET_NO_ERROR)
            PacketBuffer::Free(buf);
    }

    return enqueue;
}

#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
INET_ERROR RawEndPoint::GetSocket(IPAddressType aAddressType)
{
    INET_ERROR lRetval = INET_NO_ERROR;
    const int lType    = (SOCK_RAW | SOCK_FLAGS);
    int lProtocol;

    switch (aAddressType)
    {
    case kIPAddressType_IPv6:
        lProtocol = IPPROTO_ICMPV6;
        break;

#if INET_CONFIG_ENABLE_IPV4
    case kIPAddressType_IPv4:
        lProtocol = IPPROTO_ICMP;
        break;
#endif // INET_CONFIG_ENABLE_IPV4

    default:
        lRetval = INET_ERROR_WRONG_ADDRESS_TYPE;
        goto exit;
    }

    lRetval = IPEndPointBasis::GetSocket(aAddressType, lType, lProtocol);
    SuccessOrExit(lRetval);

exit:
    return (lRetval);
}

SocketEvents RawEndPoint::PrepareIO(void)
{
    return (IPEndPointBasis::PrepareIO());
}

void RawEndPoint::HandlePendingIO(void)
{
    if (mState == kState_Listening && OnMessageReceived != NULL && mPendingIO.IsReadable())
    {
        const uint16_t lPort = 0;

        IPEndPointBasis::HandlePendingIO(lPort);
    }

    mPendingIO.Clear();
}

#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

} // namespace Inet
} // namespace chip
