/*
 *
 *    Copyright (c) 2014-2017 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 TunnelEndPoint abstraction APIs in the Inet
 *      Layer for creation and management of tunnel interfaces instantiated
 *      within either Linux Sockets or LwIP.
 *
 */

#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif

#include <InetLayer/TunEndPoint.h>
#include <InetLayer/InetLayer.h>

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

#include <Weave/Core/WeaveEncoding.h>
#include <Weave/Support/CodeUtils.h>

#include "arpa-inet-compatibility.h"

namespace nl {
namespace Inet {

using Weave::System::PacketBuffer;

Weave::System::ObjectPool<TunEndPoint, INET_CONFIG_NUM_TUN_ENDPOINTS> TunEndPoint::sPool;

using namespace nl::Weave::Encoding;

/**
 * Initialize the Tunnel EndPoint object.
 *
 * @note
 *  By convention, the \c Init method on \c EndPointBasis
 *  subclasses is \c private. It should not be used outside \c InetLayer.
 *
 * @param[in] inetLayer       A pointer to the Inet layer object that
 *                            created the Tunnel EndPoint.
 *
 */
void TunEndPoint::Init(InetLayer *inetLayer)
{
    InitEndPointBasis(*inetLayer);
}

/**
 * Open a tunnel pseudo interface and create a handle to it.
 *
 * @note
 *  This method has different signatures on LwIP systems and
 *  POSIX systems.  On LwIP, there is an argument for specifying the name
 *  of the tunnel interface.  On POSIX, the method has no arguments and the
 *  name of the tunnel device is implied.
 *
 * @return INET_NO_ERROR on success, else a corresponding INET mapped OS error.
 */
#if WEAVE_SYSTEM_CONFIG_USE_LWIP
INET_ERROR TunEndPoint::Open (void)
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
INET_ERROR TunEndPoint::Open (const char *intfName)
#endif //WEAVE_SYSTEM_CONFIG_USE_SOCKETS
{
    INET_ERROR err = INET_NO_ERROR;

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
    struct netif *tNetif = NULL;
    // Lock LwIP stack
    LOCK_TCPIP_CORE();

    tNetif = netif_add(&mTunNetIf, NULL, NULL, NULL, this, TunInterfaceNetifInit, tcpip_input);

    // UnLock LwIP stack
    UNLOCK_TCPIP_CORE();

    VerifyOrExit(tNetif != NULL, err = INET_ERROR_INTERFACE_INIT_FAILURE);

#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    //Create the tunnel device
    err = TunDevOpen(intfName);
    SuccessOrExit(err);

    printf("Opened tunnel device: %s\n", intfName);

#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    if (err == INET_NO_ERROR)
        mState = kState_Open;

exit:

    return err;
}

/**
 * Close the tunnel pseudo interface device.
 *
 */
void TunEndPoint::Close (void)
{
    if (mState != kState_Closed)
    {

        // For LwIP, we do not remove the netif as it would have
        // an impact on the interface iterator in Weave which
        // might lose reference to a particular netif index that
        // it might be holding on to.
#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
        if (mSocket >= 0)
        {
            Weave::System::Layer& lSystemLayer = SystemLayer();

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

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

#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS
        mState = kState_Closed;
    }
}

/**
 * Close the tunnel pseudo interface device and decrement the reference count
 * of the InetLayer object.
 *
 */
void TunEndPoint::Free()
{
    Close();

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
    DeferredFree(kReleaseDeferralErrorTactic_Release);
#else // !WEAVE_SYSTEM_CONFIG_USE_LWIP
    Release();
#endif // !WEAVE_SYSTEM_CONFIG_USE_LWIP
}

/**
 * Send an IPv6 packet to the tun device to be sent out.
 *
 * @note
 *  This method performs a couple of minimal sanity checks on the packet to
 *  be sure it is IP version 6 then dispatches it for encapsulation in a
 *  Weave tunneling message.
 *
 * @param[in]   message     the IPv6 packet to send.
 *
 * @retval  INET_NO_ERROR   success: packet encapsulated and queued to send
 * @retval  INET_ERROR_NOT_SUPPORTED    packet not IP version 6
 * @retval  INET_ERROR_BAD_ARGS         \c message is a \c NULL pointer
 *
 */
INET_ERROR TunEndPoint::Send (PacketBuffer *msg)
{
    INET_ERROR ret = INET_NO_ERROR;

    ret = CheckV6Sanity(msg);

    if (ret == INET_NO_ERROR)
    {
        ret = TunDevSendMessage(msg);
    }

    return ret;
}

/**
 * Extract the activation state of the tunnel interface.
 *
 * @returns \c true if the tunnel interface is active,
 *          otherwise \c false.
 */
bool TunEndPoint::IsInterfaceUp (void) const
{
    bool ret = false;

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
    // Lock LwIP stack
    LOCK_TCPIP_CORE();

    ret = netif_is_up(&mTunNetIf);

    // UnLock LwIP stack
    UNLOCK_TCPIP_CORE();

    ExitNow();
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
    int sockfd = INET_INVALID_SOCKET_FD;
    struct ::ifreq ifr;

    memset(&ifr, 0, sizeof(ifr));

    //Get interface
    if (TunGetInterface(mSocket, &ifr) < 0)
    {
        ExitNow();
    }

    sockfd = socket(AF_INET6, SOCK_DGRAM | NL_SOCK_CLOEXEC, IPPROTO_IP);
    if (sockfd < 0)
    {
        ExitNow();
    }

    //Get interface flags
    if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0)
    {
        ExitNow();
    }

    ret = ((ifr.ifr_flags & IFF_UP) == IFF_UP);

#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

exit:
#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
    if (sockfd >= 0)
    {
        close(sockfd);
    }
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    return ret;
}

/**
 * Activate the tunnel interface.
 *
 * @retval  INET_NO_ERROR           success: tunnel interface is activated.
 * @retval  other                   another system or platform error
 */
INET_ERROR TunEndPoint::InterfaceUp (void)
{
    INET_ERROR err = INET_NO_ERROR;

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
    // Lock LwIP stack
    LOCK_TCPIP_CORE();

    netif_set_up(&mTunNetIf);

    // UnLock LwIP stack
    UNLOCK_TCPIP_CORE();

    ExitNow();
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
    int sockfd = INET_INVALID_SOCKET_FD;
    struct ::ifreq ifr;

    memset(&ifr, 0, sizeof(ifr));

    //Get interface
    if (TunGetInterface(mSocket, &ifr) < 0)
    {
        ExitNow(err = Weave::System::MapErrorPOSIX(errno));
    }

    sockfd = socket(AF_INET6, SOCK_DGRAM | NL_SOCK_CLOEXEC, IPPROTO_IP);
    if (sockfd < 0)
    {
        ExitNow(err = Weave::System::MapErrorPOSIX(errno));
    }

    //Get interface flags
    if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0)
    {
        ExitNow(err = Weave::System::MapErrorPOSIX(errno));
    }

    //Set flag to activate interface
    ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
    if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0)
    {
        err = Weave::System::MapErrorPOSIX(errno);
    }

    //Set the MTU
    ifr.ifr_mtu = WEAVE_CONFIG_TUNNEL_INTERFACE_MTU;
    if (ioctl(sockfd, SIOCSIFMTU, &ifr) < 0)
    {
        ExitNow(err = Weave::System::MapErrorPOSIX(errno));
    }

#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

exit:
#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
    if (sockfd >= 0)
    {
        close(sockfd);
    }
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    return err;
}

/**
 * @brief   Deactivate the tunnel interface.
 *
 * @retval  INET_NO_ERROR           success: tunnel interface is deactivated.
 * @retval  other                   another system or platform error
 */
INET_ERROR TunEndPoint::InterfaceDown (void)
{
    INET_ERROR err = INET_NO_ERROR;
#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
    int sockfd = INET_INVALID_SOCKET_FD;
    struct ::ifreq ifr;
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
    // Lock LwIP stack
    LOCK_TCPIP_CORE();

    //Remove the link local address from the netif
    memset(&(mTunNetIf.ip6_addr[0]), 0, sizeof(ip6_addr_t));

    netif_set_down(&mTunNetIf);

    // UnLock LwIP stack
    UNLOCK_TCPIP_CORE();

    ExitNow();
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
    memset(&ifr, 0, sizeof(ifr));

    //Get interface
    if (TunGetInterface(mSocket, &ifr) < 0)
    {
        ExitNow(err = Weave::System::MapErrorPOSIX(errno));
    }

    sockfd = socket(AF_INET6, SOCK_DGRAM | NL_SOCK_CLOEXEC, IPPROTO_IP);
    if (sockfd < 0)
    {
        ExitNow(err = Weave::System::MapErrorPOSIX(errno));
    }

    //Get interface flags
    if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0)
    {
        ExitNow(err = Weave::System::MapErrorPOSIX(errno));
    }

    //Set flag to deactivate interface
    ifr.ifr_flags &= ~(IFF_UP);
    if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0)
    {
        err = Weave::System::MapErrorPOSIX(errno);
    }
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

exit:
#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
    if (sockfd >= 0)
    {
        close(sockfd);
    }
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

    return err;
}

/**
 * @brief   Get the tunnel interface identifier.
 *
 * @return  The tunnel interface identifier.
 */
InterfaceId TunEndPoint::GetTunnelInterfaceId(void)
{
#if WEAVE_SYSTEM_CONFIG_USE_LWIP
    return &mTunNetIf;
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
    INET_ERROR err = INET_NO_ERROR;
    InterfaceId tunIntfId = INET_NULL_INTERFACEID;
    const char *tunIntfPtr = &tunIntfName[0];

    err = InterfaceNameToId(tunIntfPtr, tunIntfId);
    if (err != INET_NO_ERROR)
    {
        tunIntfId = INET_NULL_INTERFACEID;
    }

    return tunIntfId;
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS
}

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
/* Function for sending the IPv6 packets over LwIP */
INET_ERROR TunEndPoint::TunDevSendMessage(PacketBuffer *msg)
{
    INET_ERROR ret = INET_NO_ERROR;
    struct pbuf *p = NULL;
    err_t  err = ERR_OK;

    // no packet could be read, silently ignore this
    VerifyOrExit(msg != NULL, ret = INET_ERROR_BAD_ARGS);

    p = (struct pbuf *)msg;

    //Call the input function for the netif object in LWIP.
    //This essentially creates a TCP_IP msg and puts into
    //the mbox message queue for processing by the TCP/IP
    //stack.

    if ((err = tcpip_input(p, &mTunNetIf)) != ERR_OK)
    {
        LWIP_DEBUGF(NETIF_DEBUG, ("tunNetif_input: IP input error\n"));
        ExitNow(ret = Weave::System::MapErrorLwIP(err));
    }

exit:
    return (ret);
}
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
/* Function for sending the IPv6 packets over Linux sockets */
INET_ERROR TunEndPoint::TunDevSendMessage(PacketBuffer *msg)
{
    INET_ERROR ret = INET_NO_ERROR;
    ssize_t lenSent = 0;
    uint8_t *p = NULL;

    // no packet could be read, silently ignore this
    VerifyOrExit(msg != NULL, ret = INET_ERROR_BAD_ARGS);

    p = msg->Start();

    lenSent = write(mSocket, p, msg->DataLength());
    if (lenSent < 0)
    {
       ExitNow(ret = Weave::System::MapErrorPOSIX(errno));
    }
    else if (lenSent < msg->DataLength())
    {
        ExitNow(ret = INET_ERROR_OUTBOUND_MESSAGE_TRUNCATED);
    }

exit:
    if (msg != NULL)
    {
        PacketBuffer::Free(msg);
    }

    return (ret);
}
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

/* Function that performs some basic sanity checks for IPv6 packets */
INET_ERROR TunEndPoint::CheckV6Sanity (PacketBuffer *msg)
{
    INET_ERROR err = INET_NO_ERROR;
    uint8_t *p     = NULL;
    struct ip6_hdr *ip6hdr = NULL;

    p = msg->Start();

    ip6hdr = (struct ip6_hdr *)p;

    VerifyOrExit(ip6hdr != NULL, err = INET_ERROR_BAD_ARGS);

    //Do some IPv6 sanity checks
#if WEAVE_SYSTEM_CONFIG_USE_LWIP
    if (IP6H_V(ip6hdr) != 6)
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
    if ((ip6hdr->ip6_vfc >> 4) != 6)
#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS
    {
        ExitNow(err = INET_ERROR_NOT_SUPPORTED);
    }

exit:

    return err;
}

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
/* Handler to send received packet to upper layer callback */
void TunEndPoint::HandleDataReceived (PacketBuffer *msg)
{
    INET_ERROR err = INET_NO_ERROR;
    if (mState == kState_Open && OnPacketReceived != NULL)
    {
        err = CheckV6Sanity(msg);
        if (err == INET_NO_ERROR)
        {
            OnPacketReceived(this, msg);
        }
        else
        {
            if (OnReceiveError != NULL)
            {
                OnReceiveError(this, err);
            }

            PacketBuffer::Free(msg);
        }
    }
    else
    {
        PacketBuffer::Free(msg);
    }
}

/* Post an event to the Inet layer event queue from LwIP */
err_t TunEndPoint::LwIPPostToInetEventQ (struct netif *netif, struct pbuf *p)
{
    err_t                   lwipErr         = ERR_OK;
    INET_ERROR              err             = INET_NO_ERROR;
    TunEndPoint*            ep              = static_cast<TunEndPoint *>(netif->state);
    Weave::System::Layer&   lSystemLayer    = ep->SystemLayer();
    PacketBuffer*           buf             = PacketBuffer::NewWithAvailableSize(p->tot_len);

    // Starting off with a reserved size of the default WEAVE_SYSTEM_CONFIG_HEADER_RESERVE_SIZE
    // which allows for adding the Weave header and the underlying transport and IP headers
    // encapsulating this tunneled packet.

    VerifyOrExit(buf != NULL, lwipErr = ERR_MEM);

    buf->SetDataLength(p->tot_len);

    // Make a pbuf alloc and copy to post to Inetlayer queue because LwIP would free the
    // passed pbuf as it made a down-call to send it out the tunnel netif.

    lwipErr = pbuf_copy((struct pbuf *)buf, p);
    VerifyOrExit(lwipErr == ERR_OK, (void)lwipErr);

    err = lSystemLayer.PostEvent(*ep, kInetEvent_TunDataReceived, (uintptr_t)buf);
    VerifyOrExit(err == INET_NO_ERROR, lwipErr = ERR_MEM);

    buf = NULL;

exit:
    if (buf != NULL)
    {
        PacketBuffer::Free(buf);
    }

    return lwipErr;
}

#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5
#if LWIP_IPV4
/* Output handler for netif */
err_t TunEndPoint::LwIPOutputIPv4(struct netif *netif, struct pbuf *p, const ip4_addr_t *addr)
{
    LWIP_UNUSED_ARG(addr);

    return LwIPPostToInetEventQ(netif, p);
}
#endif // LWIP_IPV4

#if LWIP_IPV6
/* Output handler for netif */
err_t TunEndPoint::LwIPOutputIPv6(struct netif *netif, struct pbuf *p, const ip6_addr_t *addr)
{
    LWIP_UNUSED_ARG(addr);

    return LwIPPostToInetEventQ(netif, p);
}
#endif // LWIP_IPV4
#else // LWIP_VERSION_MAJOR <= 1 || LWIP_VERSION_MINOR < 5
/* Receive message in LwIP */
err_t TunEndPoint::LwIPReceiveTunMessage (struct netif *netif, struct pbuf *p, ip4_addr_t *addr)
{
    LWIP_UNUSED_ARG(addr);

    return LwIPPostToInetEventQ(netif, p);
}

#if LWIP_IPV6
err_t TunEndPoint::LwIPReceiveTunV6Message (struct netif *netif, struct pbuf *p, ip6_addr_t *addr)
{
    LWIP_UNUSED_ARG(addr);

    return LwIPPostToInetEventQ(netif, p);
}
#endif // LWIP_IPV6
#endif // LWIP_VERSION_MAJOR <= 1 || LWIP_VERSION_MINOR < 5

/* Initialize the LwIP tunnel netif interface */
err_t TunEndPoint::TunInterfaceNetifInit (struct netif *netif)
{
    netif->name[0] = 't';
    netif->name[1] = 'n';
#if LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5
#if LWIP_IPV4
    netif->output = LwIPOutputIPv4;
#endif /* LWIP_IPV6 */
#if LWIP_IPV6
    netif->output_ip6 = LwIPOutputIPv6;
#endif /* LWIP_IPV6 */
#else // LWIP_VERSION_MAJOR <= 1 || LWIP_VERSION_MINOR < 5
    netif->output = LwIPReceiveTunMessage;
#if LWIP_IPV6
    netif->output_ip6 = LwIPReceiveTunV6Message;
#endif /* LWIP_IPV6 */
#endif // LWIP_VERSION_MAJOR <= 1 || LWIP_VERSION_MINOR < 5
    netif->linkoutput = NULL;

    netif->mtu = WEAVE_CONFIG_TUNNEL_INTERFACE_MTU;

    netif->hwaddr_len = 6;
    memset(netif->hwaddr, 0, NETIF_MAX_HWADDR_LEN);
    netif->hwaddr[5] = 1;

#if LWIP_VERSION_MAJOR == 1 && LWIP_VERSION_MINOR < 5
    /* device capabilities */
    netif->flags |= NETIF_FLAG_POINTTOPOINT;
#endif // LWIP_VERSION_MAJOR <= 1 || LWIP_VERSION_MINOR >= 5

    return ERR_OK;
}

#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
/* Open a tun device in linux */
INET_ERROR TunEndPoint::TunDevOpen (const char *intfName)
{
    struct ::ifreq ifr;
    int fd = INET_INVALID_SOCKET_FD;
    INET_ERROR ret = INET_NO_ERROR;

    if ((fd = open(INET_CONFIG_TUNNEL_DEVICE_NAME, O_RDWR | NL_O_CLOEXEC)) < 0)
    {
        ExitNow(ret = Weave::System::MapErrorPOSIX(errno));
    }

    //Keep copy of open device fd
    mSocket = fd;

    memset(&ifr, 0, sizeof(ifr));

    ifr.ifr_flags = IFF_TUN | IFF_NO_PI;

    if (*intfName)
    {
        strncpy(ifr.ifr_name, intfName, sizeof(ifr.ifr_name) - 1);
    }

    if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0)
    {
        ExitNow(ret = Weave::System::MapErrorPOSIX(errno));
    }

    //Verify name
    memset(&ifr, 0, sizeof(ifr));
    if (TunGetInterface(fd, &ifr) < 0)
    {
        ExitNow(ret = Weave::System::MapErrorPOSIX(errno));
    }

    if (ifr.ifr_name[0] != '\0')
    {
        //Keep member copy of interface name and Id
        strncpy(tunIntfName, ifr.ifr_name, sizeof(tunIntfName) - 1);
    }
    else
    {
        ExitNow(ret = Weave::System::MapErrorPOSIX(errno));
    }

exit:

    if (ret != INET_NO_ERROR)
    {
        TunDevClose();
    }

    return ret;
}

/* Close a tun device */
void TunEndPoint::TunDevClose (void)
{
    if (mSocket >= 0)
    {
        close(mSocket);
    }
    mSocket = INET_INVALID_SOCKET_FD;
}

/* Get the tun device interface in Linux */
int TunEndPoint::TunGetInterface (int fd,
                                  struct ::ifreq *ifr)
{
    return ioctl(fd, TUNGETIFF, (void*)ifr);
}

/* Read packets from TUN device in Linux */
INET_ERROR TunEndPoint::TunDevRead (PacketBuffer *msg)
{
    ssize_t rcvLen;
    INET_ERROR err = INET_NO_ERROR;
    uint8_t *p = NULL;
    p = msg->Start();

    rcvLen = read(mSocket, p, msg->AvailableDataLength());
    if (rcvLen < 0)
    {
        err = Weave::System::MapErrorPOSIX(errno);
    }
    else if (rcvLen > msg->AvailableDataLength())
    {
        err = INET_ERROR_INBOUND_MESSAGE_TOO_BIG;
    }
    else
    {
        msg->SetDataLength((uint16_t)rcvLen);
    }

    return err;
}

/* Prepare socket for reading */
SocketEvents TunEndPoint::PrepareIO ()
{
    SocketEvents res;

    if (mState == kState_Open && OnPacketReceived != NULL)
    {
        res.SetRead();
    }

    return res;
}

/* Read from the Tun device in Linux and pass up to upper layer callback */
void TunEndPoint::HandlePendingIO ()
{
    INET_ERROR err = INET_NO_ERROR;

    if (mState == kState_Open && OnPacketReceived != NULL && mPendingIO.IsReadable())
    {

        PacketBuffer *buf = PacketBuffer::New(0);

        if (buf != NULL)
        {
            //Read data from Tun Device
            err = TunDevRead(buf);
            if (err == INET_NO_ERROR)
            {
                err = CheckV6Sanity(buf);
            }
        }
        else
        {
            err = INET_ERROR_NO_MEMORY;
        }

        if (err == INET_NO_ERROR)
        {
            OnPacketReceived(this, buf);
        }
        else
        {
            PacketBuffer::Free(buf);
            if (OnReceiveError != NULL)
            {
                OnReceiveError(this, err);
            }
        }
    }

    mPendingIO.Clear();
}

#endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS

} // namespace Inet
} // namespace nl
