/*
 *
 *    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"

#if WEAVE_SYSTEM_CONFIG_USE_FUCHSIA_TUN
#include <fuchsia/netstack/cpp/fidl.h>
#endif

namespace nl {
namespace Inet {

using Weave::System::PacketBuffer;

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

using namespace nl::Weave::Encoding;

#if WEAVE_SYSTEM_CONFIG_USE_FUCHSIA_TUN

constexpr uint32_t kDefaultMtu = 1500;
constexpr uint8_t kTunPortId = 0;

namespace {

fuchsia::net::tun::DevicePortConfig DefaultPortConfig() {
  fuchsia::net::tun::BasePortConfig base;
  base.set_id(kTunPortId);

  // Add both ipv4 and ipv6 for supported rx frame types.
  std::vector<fuchsia::hardware::network::FrameType> rxFrameTypes;
  rxFrameTypes.push_back(fuchsia::hardware::network::FrameType::IPV4);
  rxFrameTypes.push_back(fuchsia::hardware::network::FrameType::IPV6);
  base.set_rx_types(std::move(rxFrameTypes));

  // Configure default MTU
  base.set_mtu(kDefaultMtu);

  // Add both ipv4 and ipv6 for supported tx frame types.
  // FrameType specifies the type of frame(IPv4/IPv6), features specific to
  // the frametype and the supported flags. We set both to 0, as we don't
  // need any specific features or flags.
  std::vector<fuchsia::hardware::network::FrameTypeSupport> txFrameTypes;
  txFrameTypes.push_back(fuchsia::hardware::network::FrameTypeSupport{
      fuchsia::hardware::network::FrameType::IPV4, 0,
      static_cast<fuchsia::hardware::network::TxFlags>(0)});
  txFrameTypes.push_back(fuchsia::hardware::network::FrameTypeSupport{
      fuchsia::hardware::network::FrameType::IPV6, 0,
      static_cast<fuchsia::hardware::network::TxFlags>(0)});
  base.set_tx_types(std::move(txFrameTypes));

  fuchsia::net::tun::DevicePortConfig config;
  config.set_base(std::move(base));

  return config;
}

fuchsia::net::tun::DeviceConfig2 DefaultDeviceConfig() {
  fuchsia::net::tun::DeviceConfig2 config;
  config.set_blocking(false);
  return config;
}
} // namespace

// Creates a tun device.
INET_ERROR TunEndPoint::CreateTunDevice(void) {
  fidl::InterfaceHandle<fuchsia::net::tun::Control> tun;
  auto config = DefaultDeviceConfig();
  zx_status_t err;
  InetLayer::FuchsiaPlatformData *platformData = static_cast<InetLayer::FuchsiaPlatformData*>(Layer().GetPlatformData());
  if (platformData == NULL || platformData->ctx == NULL) {
    WeaveLogError(Inet, "PlatformData is NULL");
    return INET_ERROR_INCORRECT_STATE;
  }
  err = platformData->ctx->svc()->Connect(tun.NewRequest());
  if (err != ZX_OK) {
    WeaveLogError(Inet, "Connect to network tun failed:  %s", zx_status_get_string(err));
    return err;
  }
  mTunCtl = tun.BindSync();
  if (!mTunCtl.is_bound()) {
    WeaveLogError(Inet, "tunctl is not bound");
    return INET_ERROR_INTERFACE_INIT_FAILURE;
  }
  err = mTunCtl->CreateDevice2(std::move(config), mTunDevice.NewRequest());
  if(err != ZX_OK) {
    WeaveLogError(Inet, "tunctl failed to create device: %s", zx_status_get_string(err));
    return INET_ERROR_INTERFACE_INIT_FAILURE;
  }
  err = mTunDevice->AddPort(DefaultPortConfig(), mTunPort.NewRequest());
  if(err != ZX_OK) {
    WeaveLogError(Inet, "tunctl failed to add device port: %s", zx_status_get_string(err));
    return INET_ERROR_INTERFACE_INIT_FAILURE;
  }
  return INET_NO_ERROR;
}

// Add the tun interface to netstack. If successful the tun interface shows up in "net if list".
INET_ERROR TunEndPoint::AddInterfaceToNetstack(fuchsia::hardware::network::DeviceHandle & device, const char *intfName) {
  zx_status_t err;
  fuchsia::net::stack::DeviceDefinition deviceDefinition;
  fuchsia::net::stack::InterfaceConfig config;
  config.set_name(intfName);
  deviceDefinition.set_ip(std::move(device));
  InetLayer::FuchsiaPlatformData *platformData = static_cast<InetLayer::FuchsiaPlatformData*>(Layer().GetPlatformData());
  if (platformData == NULL || platformData->ctx == NULL) {
    WeaveLogError(Inet, "PlatformData is NULL");
    return INET_ERROR_BAD_ARGS;
  }
  err = platformData->ctx->svc()->Connect(mStackPtr.NewRequest());
  if (err != ZX_OK) {
    WeaveLogError(Inet,"connect to stack fidl failed");
    return err;
  }

  fuchsia::net::stack::Stack_AddInterface_Result result;
  err = mStackPtr->AddInterface(std::move(config), std::move(deviceDefinition), &result);
  if (err != ZX_OK || result.is_err()) {
    WeaveLogError(Inet,"AddInterface failed %d:%s", err, zx_status_get_string(err));
    return err;
  }

  mInterfaceId = result.response().id;
  return INET_NO_ERROR;
}

INET_ERROR TunEndPoint::CreateHostDevice(const char *intfName) {
  fuchsia::hardware::network::DeviceHandle device;
  mTunDevice->GetDevice(device.NewRequest());
  return AddInterfaceToNetstack(device, intfName);
}

/* Read packets from TUN device in Linux */
zx_status_t TunEndPoint::GetSignalsEventPair(zx::eventpair &events)
{
  if (!mTunCtl.is_bound()) {
    WeaveLogError(Inet, "Can't read as mtunctl is not bound");
    return ZX_ERR_INTERNAL;
  }

  zx_status_t status = mTunDevice->GetSignals(&events);
  if (status != 0) {
    WeaveLogError(Inet, "Failed to get signals from Tun: %s", zx_status_get_string(status));
    return status;
  }

  return ZX_OK;
}
#endif //WEAVE_SYSTEM_CONFIG_USE_FUCHSIA_TUN

/**
 * 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);

    WeaveLogProgress(Inet, "Opened tunnel device: %s", 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 WEAVE_SYSTEM_CONFIG_USE_FUCHSIA_TUN
        if (mInterfaceId >= 0)
#else
        if (mSocket >= 0)
#endif // WEAVE_SYSTEM_CONFIG_USE_FUCHSIA_TUN
        {
            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_FUCHSIA_TUN
    if (!mStackPtr.is_bound()) {
      WeaveLogError(Inet, "mStackPtr is not bound");
      ExitNow(ret = false);
    }
    else {
      zx_status_t err;
      fuchsia::net::stack::Stack_GetInterfaceInfo_Result result;
      err = mStackPtr->GetInterfaceInfo(mInterfaceId, &result);
      if (err != ZX_OK) {
        WeaveLogError(Inet, "GetInterfaceInfo failed: %s", zx_status_get_string(err));
        ExitNow(ret = false);
      }
      fuchsia::net::stack::Stack_GetInterfaceInfo_Response resp = std::move(result.response());
      if (resp.info.properties.administrative_status == fuchsia::net::stack::AdministrativeStatus::ENABLED &&
          resp.info.properties.physical_status == fuchsia::net::stack::PhysicalStatus::UP) {
        ExitNow(ret = true);
      }
    }
#elif 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 && !WEAVE_SYSTEM_CONFIG_USE_FUCHSIA_TUN
    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_FUCHSIA_TUN
    // Set tun device to online.
    fuchsia::net::stack::Stack_EnableInterface_Result result;
    err = mTunPort->SetOnline(true);
    if (err != ZX_OK) {
      WeaveLogError(Inet, "InterfaceUp failed due to SetOnline error: %s", zx_status_get_string(err));
      ExitNow();
    }
    if (!mStackPtr.is_bound()) {
      ExitNow(err = ZX_ERR_BAD_STATE);
    }

    // Enable the tun interface.
    err = mStackPtr->EnableInterface(mInterfaceId, &result);
#elif 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 && !WEAVE_SYSTEM_CONFIG_USE_FUCHSIA_TUN
    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_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_FUCHSIA_TUN
    fuchsia::net::stack::Stack_DisableInterface_Result result;
    if (!mStackPtr.is_bound()) {
      WeaveLogError(Inet, "InterfaceDown failed as mStackPtr is not bound");
      ExitNow(err = ZX_ERR_BAD_STATE);
    }
    // Set offline and disable the interface.
    err = mTunPort->SetOnline(false);
    if (err != ZX_OK) {
      WeaveLogError(Inet, "InterfaceDown failed due to SetOnline error: %s", zx_status_get_string(err));
      ExitNow();
    }

    err = mStackPtr->DisableInterface(mInterfaceId, &result);
    if (err != ZX_OK) {
      WeaveLogError(Inet, "DisableInterface failed: %s", zx_status_get_string(err));
      return err;
    }

#elif 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 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 && !WEAVE_SYSTEM_CONFIG_USE_FUCHSIA_TUN
    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 && !WEAVE_SYSTEM_CONFIG_USE_FUCHSIA_TUN
    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_FUCHSIA_TUN
    return mInterfaceId;
#endif
}

#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"));
        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;
    uint8_t *p = NULL;

#if WEAVE_SYSTEM_CONFIG_USE_FUCHSIA_TUN
    fuchsia::net::tun::Frame frame;
    fuchsia::net::tun::Device2_WriteFrame_Result result;
    if (msg == NULL) {
      return INET_ERROR_BAD_ARGS;
    }
    p = msg->Start();
    std::vector<uint8_t> data(p, p + msg->DataLength());
    if (!mTunCtl.is_bound()) {
      WeaveLogError(Inet, "send failed as tunctl is not bound");
      return ZX_ERR_BAD_STATE;
    }

    frame.set_port(kTunPortId);
    frame.set_frame_type(fuchsia::hardware::network::FrameType::IPV6);
    frame.set_data(data);
    ret = mTunDevice->WriteFrame(std::move(frame), &result);
    if (ret != ZX_OK) {
      WeaveLogError(Inet, "write failed: %s", zx_status_get_string(ret));
      return ret;
    }
    if (result.is_err()) {
      WeaveLogError(Inet, "write failed: %s", zx_status_get_string(result.err()));
      return result.err();
    }
#else
    ssize_t lenSent = 0;
    // 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:
#endif
    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();

    // Allocate space for the tunneled IP packet. The reserved space will be the
    // default for the Weave and underlying TCP/IP headers (WEAVE_SYSTEM_CONFIG_HEADER_RESERVE_SIZE).
    // The requested data size will include the full pbuf received from LwIP plus
    // WEAVE_TRAILER_RESERVE_SIZE for holding the HMAC.
    PacketBuffer* buf = PacketBuffer::NewWithAvailableSize(p->tot_len + WEAVE_TRAILER_RESERVE_SIZE);
    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)
{
#if WEAVE_SYSTEM_CONFIG_USE_FUCHSIA_TUN
    INET_ERROR ret = INET_NO_ERROR;
    //Create the tunnel device
    ret = CreateTunDevice();
    if (ret != 0) {
      WeaveLogError(Inet, "CreateTunDevice failed %d", ret);
      return ret;
    }

    ret = CreateHostDevice(intfName);
    if (ret != 0) {
      WeaveLogError(Inet, "CreateHostDevice failed %d", ret);
      return ret;
    }
    return ret;
#else
    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);
        tunIntfName[sizeof(tunIntfName) - 1] = '\0';
    }
    else
    {
        ExitNow(ret = Weave::System::MapErrorPOSIX(errno));
    }

exit:

    if (ret != INET_NO_ERROR)
    {
        TunDevClose();
    }
    return ret;
#endif
}

/* Close a tun device */
void TunEndPoint::TunDevClose (void)
{
#if WEAVE_SYSTEM_CONFIG_USE_FUCHSIA_TUN
  INET_ERROR err = INET_NO_ERROR;
  fuchsia::net::stack::Stack_DelEthernetInterface_Result result;
  if (!mStackPtr.is_bound()) {
    WeaveLogError(Inet, "TunDevClose failed as mStackPtr is not bound to service");
    return;
  }
  err = mStackPtr->DelEthernetInterface(mInterfaceId, &result);
  if (err != ZX_OK) {
    WeaveLogError(Inet, "DelInterface failed %d: %s", err, zx_status_get_string(err));
  }
  mInterfaceId = 0;
#else
    if (mSocket >= 0)
    {
        close(mSocket);
    }
    mSocket = INET_INVALID_SOCKET_FD;
#endif
}

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

INET_ERROR TunEndPoint::TunDevRead (PacketBuffer *msg)
{
    INET_ERROR err = INET_NO_ERROR;
    uint8_t *p = NULL;
    p = msg->Start();

#ifdef WEAVE_SYSTEM_CONFIG_USE_FUCHSIA_TUN
    fuchsia::net::tun::Device2_ReadFrame_Result result;
    if (!mTunCtl.is_bound()) {
      WeaveLogError(Inet, "Can't read as mTunCtl is not bound");
      ExitNow(err = ZX_ERR_BAD_STATE);
    }
    err = mTunDevice->ReadFrame(&result);
    if (result.is_err()) {
      ExitNow(err = result.err());
    }
    if (result.is_response()) {
      std::vector<uint8_t> data = result.response().frame.data();
      memcpy(p, data.data(), data.size());
      msg->SetDataLength((uint16_t)data.size());
    }
#else
    ssize_t rcvLen;
    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);
    }
#endif //WEAVE_SYSTEM_CONFIG_USE_FUCHSIA_TUN
exit:
    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
