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

namespace {

fuchsia::net::tun::BaseConfig DefaultBaseConfig() {
  fuchsia::net::tun::BaseConfig config;
  std::vector<fuchsia::hardware::network::FrameType> rxFrameTypes;
  std::vector<fuchsia::hardware::network::FrameTypeSupport> txFrameTypes;

  // Add both ipv4 and ipv6 for supported rx frame types.
  rxFrameTypes.push_back(fuchsia::hardware::network::FrameType::IPV4);
  rxFrameTypes.push_back(fuchsia::hardware::network::FrameType::IPV6);
  config.set_rx_types(rxFrameTypes);

  // Configure default MTU
  config.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.
  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)});
  config.set_tx_types(txFrameTypes);

  return config;
}

fuchsia::net::tun::DeviceConfig DefaultDeviceConfig() {
  fuchsia::net::tun::DeviceConfig config;
  config.set_base(DefaultBaseConfig());
  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;
  }
  mTunCtl->CreateDevice(std::move(config), mTunDevice.NewRequest());
  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::DeviceSyncPtr& 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\n");
    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\n", 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::DeviceSyncPtr device;
  fuchsia::net::tun::Protocols protos;
  protos.set_network_device(device.NewRequest());
  mTunDevice->ConnectProtocols(std::move(protos));
  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\n", 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\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 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;
    mTunDevice->SetOnline(true);
    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\n");
      ExitNow(err = ZX_ERR_BAD_STATE);
    }
    // Set offline and disable the interface.
    mTunDevice->SetOnline(false);

    err = mStackPtr->DisableInterface(mInterfaceId, &result);
    if (err != ZX_OK) {
      WeaveLogError(Inet, "DisableInterface failed: %s\n", 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\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;
    uint8_t *p = NULL;

#if WEAVE_SYSTEM_CONFIG_USE_FUCHSIA_TUN
    fuchsia::net::tun::Frame frame;
    fuchsia::net::tun::Device_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\n");
      return ZX_ERR_BAD_STATE;
    }

    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\n", ret);
      return ret;
    }

    ret = CreateHostDevice(intfName);
    if (ret != 0) {
      WeaveLogError(Inet, "CreateHostDevice failed %d\n", 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\n");
    return;
  }
  err = mStackPtr->DelEthernetInterface(mInterfaceId, &result);
  if (err != ZX_OK) {
    WeaveLogError(Inet, "DelInterface failed %d: %s\n", 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::Device_ReadFrame_Result result;
    if (!mTunCtl.is_bound()) {
      WeaveLogError(Inet, "Can't read as mTunCtl is not bound\n");
      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
