// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// clang-format: off
#include <sys/socket.h>
// clang-format: on

#include <linux/ethtool.h>
#include <linux/if_arp.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/sockios.h>
#include <linux/wireless.h>
#include <netinet/ip.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <unistd.h>

#include <algorithm>
#include <cstring>

#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "platform/api/network_interface.h"
#include "platform/base/ip_address.h"
#include "platform/impl/network_interface.h"
#include "platform/impl/scoped_pipe.h"
#include "util/osp_logging.h"

namespace openscreen {
namespace {

constexpr int kNetlinkRecvmsgBufSize = 8192;

// Safely reads the system name for the interface from the (probably)
// null-terminated string |kernel_name| and returns a std::string.
std::string GetInterfaceName(absl::string_view kernel_name) {
  OSP_CHECK_LT(kernel_name.length(), IFNAMSIZ);
  return std::string(kernel_name);
}

// Returns the type of the interface identified by the name |ifname|, if it can
// be determined, otherwise returns InterfaceInfo::Type::kOther.
InterfaceInfo::Type GetInterfaceType(const std::string& ifname) {
  // Determine type after name has been set.
  ScopedFd s(socket(AF_INET6, SOCK_DGRAM, 0));
  if (!s) {
    s = ScopedFd(socket(AF_INET, SOCK_DGRAM, 0));
    if (!s)
      return InterfaceInfo::Type::kOther;
  }

  // Note: This uses Wireless Extensions to test the interface, which is
  // deprecated.  However, it's much easier than using the new nl80211
  // interface for this purpose.  If Wireless Extensions are ever actually
  // removed though, this will need to use nl80211.
  struct iwreq wr;
  static_assert(sizeof(wr.ifr_name) == IFNAMSIZ,
                "expected size of interface name fields");
  OSP_CHECK_LT(ifname.size(), IFNAMSIZ);
  wr.ifr_name[IFNAMSIZ - 1] = 0;
  strncpy(wr.ifr_name, ifname.c_str(), IFNAMSIZ - 1);
  if (ioctl(s.get(), SIOCGIWNAME, &wr) != -1)
    return InterfaceInfo::Type::kWifi;

  struct ethtool_cmd ecmd;
  ecmd.cmd = ETHTOOL_GSET;
  struct ifreq ifr;
  static_assert(sizeof(ifr.ifr_name) == IFNAMSIZ,
                "expected size of interface name fields");
  OSP_CHECK_LT(ifname.size(), IFNAMSIZ);
  wr.ifr_name[IFNAMSIZ - 1] = 0;
  strncpy(ifr.ifr_name, ifname.c_str(), IFNAMSIZ - 1);
  ifr.ifr_data = &ecmd;
  if (ioctl(s.get(), SIOCETHTOOL, &ifr) != -1) {
    return InterfaceInfo::Type::kEthernet;
  }

  return InterfaceInfo::Type::kOther;
}

// Reads an interface's name, hardware address, and type from |rta| and places
// the results in |info|.  |rta| is the first attribute structure returned as
// part of an RTM_NEWLINK message.  |attrlen| is the total length of the buffer
// pointed to by |rta|.
void GetInterfaceAttributes(struct rtattr* rta,
                            unsigned int attrlen,
                            bool is_loopback,
                            InterfaceInfo* info) {
  for (; RTA_OK(rta, attrlen); rta = RTA_NEXT(rta, attrlen)) {
    if (rta->rta_type == IFLA_IFNAME) {
      info->name =
          GetInterfaceName(reinterpret_cast<const char*>(RTA_DATA(rta)));
    } else if (rta->rta_type == IFLA_ADDRESS) {
      OSP_CHECK_EQ(sizeof(info->hardware_address), RTA_PAYLOAD(rta));
      std::memcpy(info->hardware_address.data(), RTA_DATA(rta),
                  sizeof(info->hardware_address));
    }
  }

  if (is_loopback) {
    info->type = InterfaceInfo::Type::kLoopback;
  } else {
    info->type = GetInterfaceType(info->name);
  }
}

// Reads the IPv4 or IPv6 address that comes from an RTM_NEWADDR message and
// places the result in |address|. |rta| is the first attribute structure
// returned by the message and |attrlen| is the total length of the buffer
// pointed to by |rta|. |ifname| is the name of the interface to which we
// believe the address belongs based on interface index matching. It is only
// used for sanity checking.
absl::optional<IPAddress> GetIPAddressOrNull(struct rtattr* rta,
                                             unsigned int attrlen,
                                             IPAddress::Version version,
                                             const std::string& ifname) {
  const size_t expected_address_size = version == IPAddress::Version::kV4
                                           ? IPAddress::kV4Size
                                           : IPAddress::kV6Size;

  bool have_local = false;
  IPAddress address;
  IPAddress local;
  for (; RTA_OK(rta, attrlen); rta = RTA_NEXT(rta, attrlen)) {
    if (rta->rta_type == IFA_LABEL) {
      const char* const label = reinterpret_cast<const char*>(RTA_DATA(rta));
      if (ifname != label) {
        OSP_LOG_ERROR << "Interface label mismatch! Expected: " << ifname
                      << ", Have: " << label;
        return absl::nullopt;
      }
    } else if (rta->rta_type == IFA_ADDRESS) {
      OSP_DCHECK_EQ(expected_address_size, RTA_PAYLOAD(rta));
      address = IPAddress(version, static_cast<uint8_t*>(RTA_DATA(rta)));
    } else if (rta->rta_type == IFA_LOCAL) {
      OSP_DCHECK_EQ(expected_address_size, RTA_PAYLOAD(rta));
      have_local = true;
      local = IPAddress(version, static_cast<uint8_t*>(RTA_DATA(rta)));
    }
  }
  return have_local ? local : address;
}

std::vector<InterfaceInfo> GetLinkInfo() {
  ScopedFd fd(socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE));
  if (!fd) {
    OSP_LOG_WARN << "netlink socket() failed: " << errno << " - "
                 << strerror(errno);
    return {};
  }

  {
    // nl_pid = 0 for the kernel.
    struct sockaddr_nl peer = {};
    peer.nl_family = AF_NETLINK;
    struct {
      struct nlmsghdr header;
      struct ifinfomsg msg;
    } request;

    request.header.nlmsg_len = sizeof(request);
    request.header.nlmsg_type = RTM_GETLINK;
    request.header.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
    request.header.nlmsg_seq = 0;
    request.header.nlmsg_pid = 0;
    request.msg.ifi_family = AF_UNSPEC;
    struct iovec iov = {&request, request.header.nlmsg_len};
    struct msghdr msg = {&peer,
                         sizeof(peer),
                         &iov,
                         /* msg_iovlen */ 1,
                         /* msg_control */ nullptr,
                         /* msg_controllen */ 0,
                         /* msg_flags */ 0};
    if (sendmsg(fd.get(), &msg, 0) < 0) {
      OSP_LOG_ERROR << "netlink sendmsg() failed: " << errno << " - "
                    << strerror(errno);
      return {};
    }
  }

  std::vector<InterfaceInfo> info_list;
  {
    char buf[kNetlinkRecvmsgBufSize];
    struct iovec iov = {buf, sizeof(buf)};
    struct sockaddr_nl source_address;
    struct msghdr msg;
    struct nlmsghdr* netlink_header;

    msg = {&source_address,           sizeof(source_address), &iov,
           /* msg_iovlen */ 1,
           /* msg_control */ nullptr,
           /* msg_controllen */ 0,
           /* msg_flags */ 0};

    bool done = false;
    while (!done) {
      size_t len = recvmsg(fd.get(), &msg, 0);

      for (netlink_header = reinterpret_cast<struct nlmsghdr*>(buf);
           NLMSG_OK(netlink_header, len);
           netlink_header = NLMSG_NEXT(netlink_header, len)) {
        // The end of multipart message.
        if (netlink_header->nlmsg_type == NLMSG_DONE) {
          done = true;
          break;
        } else if (netlink_header->nlmsg_type == NLMSG_ERROR) {
          done = true;
          OSP_LOG_ERROR << "netlink error msg: "
                        << reinterpret_cast<struct nlmsgerr*>(
                               NLMSG_DATA(netlink_header))
                               ->error;
          continue;
        } else if ((netlink_header->nlmsg_flags & NLM_F_MULTI) == 0) {
          // If this is not a multi-part message, we don't need to wait for an
          // NLMSG_DONE message; this is the only message.
          done = true;
        }

        // RTM_NEWLINK messages describe existing network links on the host.
        if (netlink_header->nlmsg_type != RTM_NEWLINK)
          continue;

        struct ifinfomsg* interface_info =
            static_cast<struct ifinfomsg*>(NLMSG_DATA(netlink_header));
        // Only process interfaces which are active (up).
        if (!(interface_info->ifi_flags & IFF_UP)) {
          continue;
        }

        info_list.emplace_back();
        InterfaceInfo& info = info_list.back();
        info.index = interface_info->ifi_index;
        GetInterfaceAttributes(IFLA_RTA(interface_info),
                               IFLA_PAYLOAD(netlink_header),
                               interface_info->ifi_flags & IFF_LOOPBACK, &info);
      }
    }
  }

  return info_list;
}

void PopulateSubnetsOrClearList(std::vector<InterfaceInfo>* info_list) {
  ScopedFd fd(socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE));
  if (!fd) {
    OSP_LOG_ERROR << "netlink socket() failed: " << errno << " - "
                  << strerror(errno);
    info_list->clear();
    return;
  }

  {
    // nl_pid = 0 for the kernel.
    struct sockaddr_nl peer = {};
    peer.nl_family = AF_NETLINK;
    struct {
      struct nlmsghdr header;
      struct ifaddrmsg msg;
    } request;

    request.header.nlmsg_len = sizeof(request);
    request.header.nlmsg_type = RTM_GETADDR;
    request.header.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
    request.header.nlmsg_seq = 1;
    request.header.nlmsg_pid = 0;
    request.msg.ifa_family = AF_UNSPEC;
    struct iovec iov = {&request, request.header.nlmsg_len};
    struct msghdr msg = {&peer,
                         sizeof(peer),
                         &iov,
                         /* msg_iovlen */ 1,
                         /* msg_control */ nullptr,
                         /* msg_controllen */ 0,
                         /* msg_flags */ 0};
    if (sendmsg(fd.get(), &msg, 0) < 0) {
      OSP_LOG_ERROR << "sendmsg failed: " << errno << " - " << strerror(errno);
      info_list->clear();
      return;
    }
  }

  {
    char buf[kNetlinkRecvmsgBufSize];
    struct iovec iov = {buf, sizeof(buf)};
    struct sockaddr_nl source_address;
    struct msghdr msg;
    struct nlmsghdr* netlink_header;

    msg = {&source_address,           sizeof(source_address), &iov,
           /* msg_iovlen */ 1,
           /* msg_control */ nullptr,
           /* msg_controllen */ 0,
           /* msg_flags */ 0};
    bool done = false;
    while (!done) {
      size_t len = recvmsg(fd.get(), &msg, 0);

      for (netlink_header = reinterpret_cast<struct nlmsghdr*>(buf);
           NLMSG_OK(netlink_header, len);
           netlink_header = NLMSG_NEXT(netlink_header, len)) {
        if (netlink_header->nlmsg_type == NLMSG_DONE) {
          done = true;
          break;
        } else if (netlink_header->nlmsg_type == NLMSG_ERROR) {
          done = true;
          OSP_LOG_ERROR << "netlink error msg: "
                        << reinterpret_cast<struct nlmsgerr*>(
                               NLMSG_DATA(netlink_header))
                               ->error;
          continue;
        } else if ((netlink_header->nlmsg_flags & NLM_F_MULTI) == 0) {
          // If this is not a multi-part message, we don't need to wait for an
          // NLMSG_DONE message; this is the only message.
          done = true;
        }

        if (netlink_header->nlmsg_type != RTM_NEWADDR)
          continue;

        struct ifaddrmsg* interface_address =
            static_cast<struct ifaddrmsg*>(NLMSG_DATA(netlink_header));

        const auto it = std::find_if(
            info_list->begin(), info_list->end(),
            [index = interface_address->ifa_index](const InterfaceInfo& info) {
              return info.index == index;
            });
        if (it == info_list->end()) {
          OSP_DVLOG << "skipping address for interface "
                    << interface_address->ifa_index;
          continue;
        }

        if (interface_address->ifa_family == AF_INET ||
            interface_address->ifa_family == AF_INET6) {
          const auto address_or_null = GetIPAddressOrNull(
              IFA_RTA(interface_address), IFA_PAYLOAD(netlink_header),
              interface_address->ifa_family == AF_INET
                  ? IPAddress::Version::kV4
                  : IPAddress::Version::kV6,
              it->name);
          if (address_or_null) {
            it->addresses.emplace_back(*address_or_null,
                                       interface_address->ifa_prefixlen);
          }
        } else {
          OSP_LOG_ERROR << "Unknown address family: "
                        << interface_address->ifa_family;
        }
      }
    }
  }
}

}  // namespace

std::vector<InterfaceInfo> GetAllInterfaces() {
  std::vector<InterfaceInfo> interfaces = GetLinkInfo();
  PopulateSubnetsOrClearList(&interfaces);
  return interfaces;
}

}  // namespace openscreen
