/*
 *  Copyright (c) 2018, The OpenThread Authors.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. Neither the name of the copyright holder nor the
 *     names of its contributors may be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @file
 *   This file implements the platform network on Linux.
 */
#include "openthread-core-config.h"
#include "platform-posix.h"

#include <arpa/inet.h>
#include <assert.h>
#include <fcntl.h>
#include <ifaddrs.h>
#if __linux__
#include <linux/if_tun.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#endif
#include <net/if.h>
#include <net/if_arp.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <openthread/icmp6.h>
#include <openthread/instance.h>
#include <openthread/ip6.h>
#include <openthread/message.h>

#include "common/code_utils.hpp"
#include "common/logging.hpp"
#include "net/ip6_address.hpp"

#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE

#ifndef OPENTHREAD_POSIX_TUN_DEVICE
#define OPENTHREAD_POSIX_TUN_DEVICE "/dev/net/tun"
#endif // OPENTHREAD_TUN_DEVICE

// from linux/ipv6.h
struct in6_ifreq
{
    struct in6_addr ifr6_addr;
    __u32           ifr6_prefixlen;
    int             ifr6_ifindex;
};

static otInstance * sInstance  = NULL;
static int          sTunFd     = -1; ///< Used to exchange IPv6 packets.
static int          sIpFd      = -1; ///< Used to manage IPv6 stack on Thread interface.
static int          sNetlinkFd = -1; ///< Used to receive netlink events.
static unsigned int sTunIndex  = 0;
static char         sTunName[IFNAMSIZ];

static const size_t kMaxIp6Size = 1536;

static void UpdateUnicast(otInstance *aInstance, const otIp6Address &aAddress, uint8_t aPrefixLength, bool aIsAdded)
{
    struct in6_ifreq ifr6;
    otError          error = OT_ERROR_NONE;

    assert(sInstance == aInstance);

    VerifyOrExit(sIpFd > 0, error = OT_ERROR_INVALID_STATE);

    memcpy(&ifr6.ifr6_addr, &aAddress, sizeof(ifr6.ifr6_addr));

    ifr6.ifr6_ifindex   = static_cast<int>(sTunIndex);
    ifr6.ifr6_prefixlen = aPrefixLength;

    if (aIsAdded)
    {
        VerifyOrDie(ioctl(sIpFd, SIOCSIFADDR, &ifr6) == 0, OT_EXIT_ERROR_ERRNO);
    }
    else
    {
        VerifyOrExit(ioctl(sIpFd, SIOCDIFADDR, &ifr6) == 0, perror("ioctl"); error = OT_ERROR_FAILED);
    }

exit:
    if (error != OT_ERROR_NONE)
    {
        otLogWarnPlat("%s: %s", __func__, otThreadErrorToString(error));
    }
    else
    {
        otLogInfoPlat("%s: %s", __func__, otThreadErrorToString(error));
    }
}

static void UpdateMulticast(otInstance *aInstance, const otIp6Address &aAddress, bool aIsAdded)
{
    struct ipv6_mreq mreq;
    otError          error = OT_ERROR_NONE;

    assert(sInstance == aInstance);

    VerifyOrExit(sIpFd > 0);
    memcpy(&mreq.ipv6mr_multiaddr, &aAddress, sizeof(mreq.ipv6mr_multiaddr));
    mreq.ipv6mr_interface = sTunIndex;

    VerifyOrExit(
        setsockopt(sIpFd, IPPROTO_IPV6, (aIsAdded ? IPV6_JOIN_GROUP : IPV6_LEAVE_GROUP), &mreq, sizeof(mreq)) == 0,
        perror("setsockopt");
        error = OT_ERROR_FAILED);

exit:
    SuccessOrDie(error);
    otLogInfoPlat("%s: %s", __func__, otThreadErrorToString(error));
}

static void UpdateLink(otInstance *aInstance)
{
    otError      error = OT_ERROR_NONE;
    struct ifreq ifr;

    assert(sInstance == aInstance);

    VerifyOrExit(sIpFd > 0);
    memset(&ifr, 0, sizeof(ifr));
    strncpy(ifr.ifr_name, sTunName, sizeof(ifr.ifr_name));
    VerifyOrExit(ioctl(sIpFd, SIOCGIFFLAGS, &ifr) == 0, perror("ioctl"); error = OT_ERROR_FAILED);

    if (otIp6IsEnabled(aInstance))
    {
        ifr.ifr_flags |= IFF_UP;
    }
    else
    {
        ifr.ifr_flags &= ~IFF_UP;
    }

    VerifyOrExit(ioctl(sIpFd, SIOCSIFFLAGS, &ifr) == 0, perror("ioctl"); error = OT_ERROR_FAILED);

exit:
    if (error == OT_ERROR_NONE)
    {
        otLogInfoPlat("%s: %s", __func__, otThreadErrorToString(error));
    }
    else
    {
        otLogWarnPlat("%s: %s", __func__, otThreadErrorToString(error));
    }
}

static void processAddressChange(const otIp6Address *aAddress, uint8_t aPrefixLength, bool aIsAdded, void *aContext)
{
    if (aAddress->mFields.m8[0] == 0xff)
    {
        UpdateMulticast(static_cast<otInstance *>(aContext), *aAddress, aIsAdded);
    }
    else
    {
        UpdateUnicast(static_cast<otInstance *>(aContext), *aAddress, aPrefixLength, aIsAdded);
    }
}

static void processStateChange(otChangedFlags aFlags, void *aContext)
{
    if (OT_CHANGED_THREAD_NETIF_STATE | aFlags)
    {
        UpdateLink(static_cast<otInstance *>(aContext));
    }
}

static void processReceive(otMessage *aMessage, void *aContext)
{
    char     packet[kMaxIp6Size];
    otError  error  = OT_ERROR_NONE;
    uint16_t length = otMessageGetLength(aMessage);

    assert(sInstance == aContext);

    VerifyOrExit(sTunFd > 0);

    VerifyOrExit(otMessageRead(aMessage, 0, packet, sizeof(packet)) == length, error = OT_ERROR_NO_BUFS);

    VerifyOrExit(write(sTunFd, packet, length) == length, perror("write"); error = OT_ERROR_FAILED);

exit:
    otMessageFree(aMessage);

    if (error == OT_ERROR_NONE)
    {
        otLogInfoPlat("%s: %s", __func__, otThreadErrorToString(error));
    }
    else
    {
        otLogWarnPlat("%s: %s", __func__, otThreadErrorToString(error));
    }
}

static void processTransmit(otInstance *aInstance)
{
    otMessage *message = NULL;
    ssize_t    rval;
    char       packet[kMaxIp6Size];
    otError    error = OT_ERROR_NONE;

    assert(sInstance == aInstance);

    rval = read(sTunFd, packet, sizeof(packet));
    VerifyOrExit(rval > 0, error = OT_ERROR_FAILED);

    message = otIp6NewMessage(aInstance, NULL);
    VerifyOrExit(message != NULL, error = OT_ERROR_NO_BUFS);

    SuccessOrExit(error = otMessageAppend(message, packet, static_cast<uint16_t>(rval)));

    error   = otIp6Send(aInstance, message);
    message = NULL;

exit:
    if (message != NULL)
    {
        otMessageFree(message);
    }

    if (error == OT_ERROR_NONE)
    {
        otLogInfoPlat("%s: %s", __func__, otThreadErrorToString(error));
    }
    else
    {
        otLogWarnPlat("%s: %s", __func__, otThreadErrorToString(error));
    }
}

static void processNetifAddrEvent(otInstance *aInstance, struct nlmsghdr *aNetlinkMessage)
{
    struct ifaddrmsg *ifaddr = reinterpret_cast<struct ifaddrmsg *>(NLMSG_DATA(aNetlinkMessage));
    size_t            rtaLength;
    otError           error = OT_ERROR_NONE;

    VerifyOrExit(ifaddr->ifa_index == static_cast<unsigned int>(sTunIndex) && ifaddr->ifa_family == AF_INET6);

    rtaLength = IFA_PAYLOAD(aNetlinkMessage);

    for (struct rtattr *rta = reinterpret_cast<struct rtattr *>(IFA_RTA(ifaddr)); RTA_OK(rta, rtaLength);
         rta                = RTA_NEXT(rta, rtaLength))
    {
        switch (rta->rta_type)
        {
        case IFA_ADDRESS:
        case IFA_LOCAL:
        case IFA_BROADCAST:
        case IFA_ANYCAST:
        {
            ot::Ip6::Address addr;
            memcpy(&addr, RTA_DATA(rta), sizeof(addr));

            if (aNetlinkMessage->nlmsg_type == RTM_NEWADDR)
            {
                if (!addr.IsMulticast())
                {
                    otNetifAddress netAddr;

                    netAddr.mAddress      = addr;
                    netAddr.mPrefixLength = ifaddr->ifa_prefixlen;
                    SuccessOrExit(error = otIp6AddUnicastAddress(aInstance, &netAddr));
                }
                else
                {
                    SuccessOrExit(error = otIp6SubscribeMulticastAddress(aInstance, &addr));
                }
            }
            else if (aNetlinkMessage->nlmsg_type == RTM_DELADDR)
            {
                if (!addr.IsMulticast())
                {
                    otIp6RemoveUnicastAddress(aInstance, &addr);
                }
                else
                {
                    otIp6UnsubscribeMulticastAddress(aInstance, &addr);
                }
            }
            else
            {
                continue;
            }
            break;
        }
        default:
            break;
        }
    }

exit:
    if (error == OT_ERROR_NONE)
    {
        otLogInfoPlat("%s: %s", __func__, otThreadErrorToString(error));
    }
    else
    {
        otLogWarnPlat("%s: %s", __func__, otThreadErrorToString(error));
    }
}

static void processNetifLinkEvent(otInstance *aInstance, struct nlmsghdr *aNetlinkMessage)
{
    struct ifinfomsg *ifinfo = reinterpret_cast<struct ifinfomsg *>(NLMSG_DATA(aNetlinkMessage));
    otError           error  = OT_ERROR_NONE;

    VerifyOrExit(ifinfo->ifi_index == static_cast<int>(sTunIndex));
    SuccessOrExit(error = otIp6SetEnabled(aInstance, ifinfo->ifi_flags & IFF_UP));

exit:
    if (error == OT_ERROR_NONE)
    {
        otLogInfoPlat("%s: %s", __func__, otThreadErrorToString(error));
    }
    else
    {
        otLogWarnPlat("%s: %s", __func__, otThreadErrorToString(error));
    }
}

static void processNetifEvent(otInstance *aInstance)
{
    const size_t kMaxNetifEvent = 8192;
    ssize_t      length;
    char         buffer[kMaxNetifEvent];

    length = recv(sNetlinkFd, buffer, sizeof(buffer), 0);

    VerifyOrExit(length > 0);

    for (struct nlmsghdr *msg = reinterpret_cast<struct nlmsghdr *>(buffer); NLMSG_OK(msg, length);
         msg                  = NLMSG_NEXT(msg, length))
    {
        switch (msg->nlmsg_type)
        {
        case RTM_NEWADDR:
        case RTM_DELADDR:
            processNetifAddrEvent(aInstance, msg);
            break;

        case RTM_NEWLINK:
        case RTM_DELLINK:
            processNetifLinkEvent(aInstance, msg);
            break;

        default:
            break;
        }
    }

exit:
    return;
}

void platformNetifInit(otInstance *aInstance)
{
    struct ifreq ifr;

    sIpFd = SocketWithCloseExec(AF_INET6, SOCK_DGRAM, IPPROTO_IP);
    VerifyOrExit(sIpFd >= 0);

    sNetlinkFd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
    VerifyOrExit(sNetlinkFd > 0);

    otIcmp6SetEchoMode(aInstance, OT_ICMP6_ECHO_HANDLER_DISABLED);

    {
        struct sockaddr_nl sa;

        memset(&sa, 0, sizeof(sa));
        sa.nl_family = AF_NETLINK;
        sa.nl_groups = RTMGRP_LINK | RTMGRP_IPV6_IFADDR;
        VerifyOrExit(bind(sNetlinkFd, reinterpret_cast<struct sockaddr *>(&sa), sizeof(sa)) == 0);
    }

    sTunFd = open(OPENTHREAD_POSIX_TUN_DEVICE, O_RDWR | O_CLOEXEC);
    VerifyOrExit(sTunFd > 0, otLogCritPlat("Unable to open tun device %s", OPENTHREAD_POSIX_TUN_DEVICE));

    memset(&ifr, 0, sizeof(ifr));
    ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
    strncpy(ifr.ifr_name, "wpan%d", IFNAMSIZ);

    VerifyOrExit(ioctl(sTunFd, TUNSETIFF, static_cast<void *>(&ifr)) == 0,
                 otLogCritPlat("Unable to configure tun device %s", OPENTHREAD_POSIX_TUN_DEVICE));
    VerifyOrExit(ioctl(sTunFd, TUNSETLINK, ARPHRD_VOID) == 0,
                 otLogCritPlat("Unable to set link type of tun device %s", OPENTHREAD_POSIX_TUN_DEVICE));

    sTunIndex = if_nametoindex(ifr.ifr_name);
    VerifyOrExit(sTunIndex > 0);

    strncpy(sTunName, ifr.ifr_name, sizeof(sTunName));
#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
    platformUdpInit(sTunName);
#endif

    otIp6SetReceiveCallback(aInstance, processReceive, aInstance);
    otIp6SetAddressCallback(aInstance, processAddressChange, aInstance);
    otSetStateChangedCallback(aInstance, processStateChange, aInstance);
    sInstance = aInstance;

exit:
    if (sTunIndex == 0)
    {
        if (sTunFd != -1)
        {
            close(sTunFd);
            sTunFd = -1;
        }

        if (sIpFd != -1)
        {
            close(sIpFd);
            sIpFd = -1;
        }

        if (sNetlinkFd != -1)
        {
            close(sNetlinkFd);
            sNetlinkFd = -1;
        }

        DieNow(OT_EXIT_FAILURE);
    }
}

void platformNetifUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, fd_set *aErrorFdSet, int *aMaxFd)
{
    OT_UNUSED_VARIABLE(aWriteFdSet);

    VerifyOrExit(sTunIndex > 0);

    assert(sTunFd > 0);
    assert(sNetlinkFd > 0);
    assert(sIpFd > 0);

    FD_SET(sTunFd, aReadFdSet);
    FD_SET(sTunFd, aErrorFdSet);
    FD_SET(sNetlinkFd, aReadFdSet);
    FD_SET(sNetlinkFd, aErrorFdSet);

    if (sTunFd > *aMaxFd)
    {
        *aMaxFd = sTunFd;
    }

    if (sNetlinkFd > *aMaxFd)
    {
        *aMaxFd = sNetlinkFd;
    }

exit:
    return;
}

void platformNetifProcess(const fd_set *aReadFdSet, const fd_set *aWriteFdSet, const fd_set *aErrorFdSet)
{
    OT_UNUSED_VARIABLE(aWriteFdSet);
    VerifyOrExit(sTunIndex > 0);

    if (FD_ISSET(sTunFd, aErrorFdSet))
    {
        close(sTunFd);
        DieNow(OT_EXIT_FAILURE);
    }

    if (FD_ISSET(sNetlinkFd, aErrorFdSet))
    {
        close(sNetlinkFd);
        DieNow(OT_EXIT_FAILURE);
    }

    if (FD_ISSET(sTunFd, aReadFdSet))
    {
        processTransmit(sInstance);
    }

    if (FD_ISSET(sNetlinkFd, aReadFdSet))
    {
        processNetifEvent(sInstance);
    }

exit:
    return;
}

#endif // OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
