// Copyright 2023 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "patchpanel/rtnl_client.h"

#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <net/ethernet.h>

#include <utility>

#include <base/containers/span.h>
#include <base/logging.h>
#include <chromeos/net-base/mac_address.h>

namespace patchpanel {
namespace {

template <typename Address, unsigned char ip_family>
std::map<Address, net_base::MacAddress> GetNeighborMacTable(
    const base::ScopedFD& rtnl_fd, const std::optional<int>& ifindex) {
  sockaddr_nl kernel;
  memset(&kernel, 0, sizeof(kernel));
  kernel.nl_family = AF_NETLINK;

  struct nl_req {
    nlmsghdr hdr;
    rtgenmsg gen;
  } req;
  memset(&req, 0, sizeof(nl_req));
  req.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(rtgenmsg));
  req.hdr.nlmsg_type = RTM_GETNEIGH;
  req.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
  req.hdr.nlmsg_seq = 1;
  req.gen.rtgen_family = ip_family;

  iovec io_req;
  memset(&io_req, 0, sizeof(io_req));
  io_req.iov_base = &req;
  io_req.iov_len = req.hdr.nlmsg_len;

  msghdr rtnl_req;
  memset(&rtnl_req, 0, sizeof(rtnl_req));
  rtnl_req.msg_name = &kernel;
  rtnl_req.msg_namelen = sizeof(kernel);
  rtnl_req.msg_iov = &io_req;
  rtnl_req.msg_iovlen = 1;

  if (sendmsg(rtnl_fd.get(), &rtnl_req, 0) < 0) {
    PLOG(ERROR) << "sendmsg() failed on rtnetlink socket";
    return {};
  }

  static constexpr size_t kRtnlReplyBufferSize = 32768;
  char reply_buffer[kRtnlReplyBufferSize];

  iovec io_reply;
  memset(&io_reply, 0, sizeof(io_reply));
  io_reply.iov_base = reply_buffer;
  io_reply.iov_len = kRtnlReplyBufferSize;

  msghdr rtnl_reply;
  memset(&rtnl_reply, 0, sizeof(rtnl_reply));
  rtnl_reply.msg_name = &kernel;
  rtnl_reply.msg_namelen = sizeof(kernel);
  rtnl_reply.msg_iov = &io_reply;
  rtnl_reply.msg_iovlen = 1;

  bool done = false;
  std::map<Address, net_base::MacAddress> ret;
  while (!done) {
    ssize_t len = recvmsg(rtnl_fd.get(), &rtnl_reply, 0);
    if (len < 0) {
      PLOG(ERROR) << "recvmsg() failed on rtnetlink socket";
      return ret;
    }

    for (nlmsghdr* msg_ptr = reinterpret_cast<nlmsghdr*>(reply_buffer);
         NLMSG_OK(msg_ptr, len); msg_ptr = NLMSG_NEXT(msg_ptr, len)) {
      switch (msg_ptr->nlmsg_type) {
        case NLMSG_DONE:
          done = true;
          break;
        case RTM_NEWNEIGH: {
          size_t rt_attr_len = RTM_PAYLOAD(msg_ptr);
          ndmsg* nd_msg = reinterpret_cast<ndmsg*>(NLMSG_DATA(msg_ptr));
          // Filter out the special IPs that get resolved into MAC without
          // sending an ARP/NDP packet.
          if (nd_msg->ndm_state & NUD_NOARP) {
            continue;
          }
          // Filter out the IPs from different network interfaces.
          if (ifindex && nd_msg->ndm_ifindex != *ifindex) {
            continue;
          }

          std::optional<Address> addr;
          std::optional<net_base::MacAddress> mac_addr;
          rtattr* rt_attr = reinterpret_cast<rtattr*>(RTM_RTA(nd_msg));
          for (; RTA_OK(rt_attr, rt_attr_len);
               rt_attr = RTA_NEXT(rt_attr, rt_attr_len)) {
            if (rt_attr->rta_type == NDA_DST) {
              addr = Address::CreateFromBytes(base::make_span(
                  reinterpret_cast<const char*>(RTA_DATA(rt_attr)),
                  Address::kAddressLength));
            } else if (rt_attr->rta_type == NDA_LLADDR) {
              mac_addr = net_base::MacAddress::CreateFromBytes(base::make_span(
                  reinterpret_cast<const uint8_t*>(RTA_DATA(rt_attr)),
                  net_base::MacAddress::kAddressLength));
            }
          }

          if (addr && mac_addr) {
            ret[*addr] = *mac_addr;
          }
          break;
        }
        default: {
          LOG(WARNING) << "received unexpected rtnetlink message type "
                       << msg_ptr->nlmsg_type << ", length "
                       << msg_ptr->nlmsg_len;
          break;
        }
      }
    }
  }

  return ret;
}

}  // namespace

// static
std::unique_ptr<RTNLClient> RTNLClient::Create() {
  base::ScopedFD rtnl_fd(
      socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE));
  if (!rtnl_fd.is_valid()) {
    PLOG(ERROR) << "socket() failed for rtnetlink socket";
    return nullptr;
  }

  sockaddr_nl sa;
  memset(&sa, 0, sizeof(sa));
  sa.nl_family = AF_NETLINK;

  if (bind(rtnl_fd.get(), reinterpret_cast<sockaddr*>(&sa), sizeof(sa)) < 0) {
    PLOG(ERROR) << "bind() failed on rtnetlink socket";
    return nullptr;
  }

  return std::unique_ptr<RTNLClient>(new RTNLClient(std::move(rtnl_fd)));
}

RTNLClient::RTNLClient(base::ScopedFD rtnl_fd) : rtnl_fd_(std::move(rtnl_fd)) {}
RTNLClient::~RTNLClient() = default;

std::map<net_base::IPv4Address, net_base::MacAddress>
RTNLClient::GetIPv4NeighborMacTable(const std::optional<int>& ifindex) const {
  return GetNeighborMacTable<net_base::IPv4Address, AF_INET>(rtnl_fd_, ifindex);
}

std::map<net_base::IPv6Address, net_base::MacAddress>
RTNLClient::GetIPv6NeighborMacTable(const std::optional<int>& ifindex) const {
  return GetNeighborMacTable<net_base::IPv6Address, AF_INET6>(rtnl_fd_,
                                                              ifindex);
}

}  // namespace patchpanel
