/*
 *
 *    Copyright (c) 2018 Google LLC.
 *    Copyright (c) 2013-2018 Nest Labs, Inc.
 *    All rights reserved.
 *
 *    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>nl::Inet::RawEndPoint</tt> class,
 *      where the Nest 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 <string.h>

#include <InetLayer/RawEndPoint.h>
#include <InetLayer/InetLayer.h>
#include <InetLayer/InetFaultInjection.h>
#include <SystemLayer/SystemFaultInjection.h>

#include <Weave/Support/CodeUtils.h>
#include <Weave/Support/logging/WeaveLogging.h>

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

#if WEAVE_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 <unistd.h>
#include <net/if.h>
#include <sys/ioctl.h>
#if HAVE_NETINET_ICMP6_H
#include <netinet/icmp6.h>
#endif // HAVE_NETINET_ICMP6_H
#endif // WEAVE_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

namespace nl {
namespace Inet {

using Weave::System::PacketBuffer;

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

#if WEAVE_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 // WEAVE_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 WEAVE_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 = Weave::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 = Weave::System::MapErrorLwIP(raw_bind_ip6(mRaw, &ipv6Addr));
        }
#if INET_CONFIG_ENABLE_IPV4
        else if (addrType == kIPAddressType_IPv4)
        {
            ip4_addr_t ipv4Addr = addr.ToIPv4();
            res = Weave::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 // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_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 // WEAVE_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 WEAVE_SYSTEM_CONFIG_USE_SOCKETS
    const int lIfIndex = static_cast<int>(intf);
#endif // WEAVE_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 WEAVE_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 = Weave::System::MapErrorLwIP(raw_bind(mRaw, &ipAddr));
#else // LWIP_VERSION_MAJOR <= 1
        ip6_addr_t ipv6Addr = addr.ToIPv6();
        res = Weave::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 // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_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 = Weave::System::MapErrorPOSIX(errno);
    ::close(mSocket);
    mSocket = INET_INVALID_SOCKET_FD;
    mAddrType = kIPAddressType_Unknown;

#endif // WEAVE_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 WEAVE_SYSTEM_CONFIG_USE_SOCKETS
    Weave::System::Layer& lSystemLayer = SystemLayer();
#endif // WEAVE_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 WEAVE_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 // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS

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

#endif // WEAVE_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 WEAVE_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 // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS

        if (mSocket != INET_INVALID_SOCKET_FD)
        {
            Weave::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 // WEAVE_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 WEAVE_SYSTEM_CONFIG_USE_LWIP
    DeferredFree(kReleaseDeferralErrorTactic_Die);
#else // !WEAVE_SYSTEM_CONFIG_USE_LWIP
    Release();
#endif // !WEAVE_SYSTEM_CONFIG_USE_LWIP
}

/**
 *  A synonym for <tt>SendTo(addr, INET_NULL_INTERFACEID, msg,
 *  sendFlags)</tt>.
 */
INET_ERROR RawEndPoint::SendTo(IPAddress addr, Weave::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>Weave::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, Weave::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>Weave::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, Weave::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 WEAVE_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 = Weave::System::MapErrorLwIP(lwipErr);
    }

    // Unlock LwIP stack
    UNLOCK_TCPIP_CORE();

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

#if WEAVE_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 // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

exit:
    WEAVE_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 WEAVE_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 // WEAVE_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 WEAVE_SYSTEM_CONFIG_USE_LWIP
    LOCK_TCPIP_CORE();
    NumICMPTypes = numICMPTypes;
    ICMPTypes = aICMPTypes;
    UNLOCK_TCPIP_CORE();
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_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 = Weave::System::MapErrorPOSIX(errno);
    }
#endif // HAVE_NETINET_ICMP6_H && HAVE_ICMP6_FILTER
#endif // WEAVE_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 WEAVE_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 // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_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 // WEAVE_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 WEAVE_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 // WEAVE_SYSTEM_CONFIG_USE_LWIP

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

#if WEAVE_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)
        {
            WeaveLogError(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)
        {
            WeaveLogError(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));
    Weave::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 // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_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 // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

} // namespace Inet
} // namespace nl
