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

#include "patchpanel/multicast_forwarder.h"

#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/ip.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>

#include <utility>

#include <base/bind.h>
#include <base/logging.h>
#include <base/message_loop/message_loop.h>

#include "patchpanel/dns/dns_protocol.h"
#include "patchpanel/dns/dns_response.h"
#include "patchpanel/net_util.h"
#include "patchpanel/socket.h"

namespace {

const int kBufSize = 1536;

// Returns the IPv4 address assigned to the interface on which the given socket
// is bound. Or returns INADDR_ANY if the interface has no IPv4 address.
struct in_addr GetInterfaceIp(int fd, const std::string& ifname) {
  if (ifname.empty()) {
    LOG(WARNING) << "Empty interface name";
    return {0};
  }

  struct ifreq ifr;
  memset(&ifr, 0, sizeof(ifr));
  strncpy(ifr.ifr_name, ifname.c_str(), IFNAMSIZ);
  if (ioctl(fd, SIOCGIFADDR, &ifr) < 0) {
    // Ignore EADDRNOTAVAIL: IPv4 was not provisioned.
    if (errno != EADDRNOTAVAIL) {
      PLOG(ERROR) << "SIOCGIFADDR failed for " << ifname;
    }
    return {0};
  }

  struct sockaddr_in* if_addr =
      reinterpret_cast<struct sockaddr_in*>(&ifr.ifr_addr);
  return if_addr->sin_addr;
}

// Fills sockaddr_storage values.
void SetSockaddr(struct sockaddr_storage* saddr_storage,
                 sa_family_t sa_family,
                 uint16_t port,
                 char* addr) {
  struct sockaddr* saddr = reinterpret_cast<sockaddr*>(saddr_storage);
  if (sa_family == AF_INET) {
    struct sockaddr_in* saddr4 = reinterpret_cast<struct sockaddr_in*>(saddr);
    saddr4->sin_family = AF_INET;
    saddr4->sin_port = htons(port);
    if (addr)
      memcpy(&saddr4->sin_addr, addr, sizeof(struct in_addr));
    return;
  }
  if (sa_family == AF_INET6) {
    struct sockaddr_in6* saddr6 = reinterpret_cast<sockaddr_in6*>(saddr);
    saddr6->sin6_family = AF_INET6;
    saddr6->sin6_port = htons(port);
    if (addr)
      memcpy(&saddr6->sin6_addr, addr, sizeof(struct in6_addr));
    return;
  }
  LOG(ERROR) << "Invalid socket family " << sa_family;
}

}  // namespace

namespace patchpanel {

MulticastForwarder::Socket::Socket(
    base::ScopedFD fd,
    sa_family_t sa_family,
    const base::Callback<void(int, sa_family_t)>& callback)
    : fd(std::move(fd)) {
  watcher = base::FileDescriptorWatcher::WatchReadable(
      Socket::fd.get(),
      base::BindRepeating(callback, Socket::fd.get(), sa_family));
}

MulticastForwarder::MulticastForwarder(const std::string& lan_ifname,
                                       uint32_t mcast_addr,
                                       const std::string& mcast_addr6,
                                       uint16_t port)
    : lan_ifname_(lan_ifname), port_(port) {
  mcast_addr_.s_addr = mcast_addr;
  CHECK(inet_pton(AF_INET6, mcast_addr6.c_str(), mcast_addr6_.s6_addr));

  base::ScopedFD lan_fd(Bind(AF_INET, lan_ifname_));
  if (!lan_fd.is_valid()) {
    LOG(WARNING) << "Could not bind socket on " << lan_ifname_ << " for "
                 << mcast_addr_ << ":" << port_;
  }

  base::ScopedFD lan_fd6(Bind(AF_INET6, lan_ifname_));
  if (!lan_fd6.is_valid()) {
    LOG(WARNING) << "Could not bind socket on " << lan_ifname_ << " for "
                 << mcast_addr6_ << ":" << port_;
  }

  lan_socket_.emplace(
      AF_INET, new Socket(std::move(lan_fd), AF_INET,
                          base::BindRepeating(
                              &MulticastForwarder::OnFileCanReadWithoutBlocking,
                              base::Unretained(this))));

  lan_socket_.emplace(
      AF_INET6,
      new Socket(
          std::move(lan_fd6), AF_INET6,
          base::BindRepeating(&MulticastForwarder::OnFileCanReadWithoutBlocking,
                              base::Unretained(this))));
}

base::ScopedFD MulticastForwarder::Bind(sa_family_t sa_family,
                                        const std::string& ifname) {
  char mcast_addr[INET6_ADDRSTRLEN];
  inet_ntop(sa_family,
            sa_family == AF_INET ? reinterpret_cast<const void*>(&mcast_addr_)
                                 : reinterpret_cast<const void*>(&mcast_addr6_),
            mcast_addr, INET6_ADDRSTRLEN);

  base::ScopedFD fd(socket(sa_family, SOCK_DGRAM, 0));
  if (!fd.is_valid()) {
    PLOG(ERROR) << "socket() failed on " << ifname << " for " << mcast_addr
                << ":" << port_;
    return base::ScopedFD();
  }

  // The socket needs to be bound to INADDR_ANY rather than a specific
  // interface, or it will not receive multicast traffic.  Therefore
  // we use SO_BINDTODEVICE to force TX from this interface, and
  // specify the interface address in IP_ADD_MEMBERSHIP to control RX.
  struct ifreq ifr;
  memset(&ifr, 0, sizeof(ifr));
  strncpy(ifr.ifr_name, ifname.c_str(), IFNAMSIZ);
  if (setsockopt(fd.get(), SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr))) {
    PLOG(ERROR) << "setsockopt(SO_BINDTODEVICE) failed on " << ifname << " for "
                << mcast_addr << ":" << port_;
    return base::ScopedFD();
  }

  int ifindex = if_nametoindex(ifname.c_str());
  if (ifindex == 0) {
    PLOG(ERROR) << "Could not obtain interface index of " << ifname << " for "
                << mcast_addr << ":" << port_;
    return base::ScopedFD();
  }

  int level, optname;
  if (sa_family == AF_INET) {
    struct ip_mreqn mreqn;
    memset(&mreqn, 0, sizeof(mreqn));
    mreqn.imr_multiaddr = mcast_addr_;
    mreqn.imr_address.s_addr = htonl(INADDR_ANY);
    mreqn.imr_ifindex = ifindex;
    if (setsockopt(fd.get(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreqn,
                   sizeof(mreqn)) < 0) {
      PLOG(ERROR) << "Can't add IPv4 multicast membership for on " << ifname
                  << " for " << mcast_addr_ << ":" << port_;
      return base::ScopedFD();
    }

    level = IPPROTO_IP;
    optname = IP_MULTICAST_LOOP;
  } else if (sa_family == AF_INET6) {
    struct ipv6_mreq mreqn;
    memset(&mreqn, 0, sizeof(mreqn));
    mreqn.ipv6mr_multiaddr = mcast_addr6_;
    mreqn.ipv6mr_interface = ifindex;
    if (setsockopt(fd.get(), IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreqn,
                   sizeof(mreqn)) < 0) {
      PLOG(ERROR) << "Can't add IPv6 multicast membership on " << ifname
                  << " for " << mcast_addr6_ << ":" << port_;
      return base::ScopedFD();
    }

    level = IPPROTO_IPV6;
    optname = IPV6_MULTICAST_LOOP;
  } else {
    return base::ScopedFD();
  }

  int off = 0;
  if (setsockopt(fd.get(), level, optname, &off, sizeof(off))) {
    PLOG(ERROR) << "setsockopt(IP_MULTICAST_LOOP) failed on " << ifname
                << " for " << mcast_addr << ":" << port_;
    return base::ScopedFD();
  }

  int on = 1;
  if (setsockopt(fd.get(), SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
    PLOG(ERROR) << "setsockopt(SO_REUSEADDR) failed on " << ifname << " for "
                << mcast_addr << ":" << port_;
    return base::ScopedFD();
  }

  struct sockaddr_storage bind_addr = {0};
  SetSockaddr(&bind_addr, sa_family, port_, nullptr);

  if (bind(fd.get(), (const struct sockaddr*)&bind_addr,
           sizeof(struct sockaddr_storage)) < 0) {
    PLOG(ERROR) << "bind(" << port_ << ") failed for on " << ifname << " for "
                << mcast_addr << ":" << port_;
    return base::ScopedFD();
  }

  return fd;
}

bool MulticastForwarder::AddGuest(const std::string& int_ifname) {
  if (int_sockets_.find(std::make_pair(AF_INET, int_ifname)) !=
          int_sockets_.end() ||
      int_sockets_.find(std::make_pair(AF_INET6, int_ifname)) !=
          int_sockets_.end()) {
    LOG(WARNING) << "Forwarding is already started between " << lan_ifname_
                 << " and " << int_ifname;
    return false;
  }

  bool success = false;

  // Set up IPv4 multicast forwarder.
  base::ScopedFD int_fd4(Bind(AF_INET, int_ifname));
  if (int_fd4.is_valid()) {
    int_fds_.emplace(std::make_pair(AF_INET, int_fd4.get()));

    std::unique_ptr<Socket> int_socket4 = std::make_unique<Socket>(
        std::move(int_fd4), AF_INET,
        base::BindRepeating(&MulticastForwarder::OnFileCanReadWithoutBlocking,
                            base::Unretained(this)));

    int_sockets_.emplace(std::make_pair(AF_INET, int_ifname),
                         std::move(int_socket4));

    success = true;
    LOG(INFO) << "Started IPv4 forwarding between " << lan_ifname_ << " and "
              << int_ifname << " for " << mcast_addr_ << ":" << port_;
  } else {
    LOG(WARNING) << "Could not bind socket on " << int_ifname << " for "
                 << mcast_addr_ << ":" << port_;
  }

  // Set up IPv6 multicast forwarder.
  base::ScopedFD int_fd6(Bind(AF_INET6, int_ifname));
  if (int_fd6.is_valid()) {
    int_fds_.emplace(std::make_pair(AF_INET6, int_fd6.get()));

    std::unique_ptr<Socket> int_socket6 = std::make_unique<Socket>(
        std::move(int_fd6), AF_INET6,
        base::BindRepeating(&MulticastForwarder::OnFileCanReadWithoutBlocking,
                            base::Unretained(this)));

    int_sockets_.emplace(std::make_pair(AF_INET6, int_ifname),
                         std::move(int_socket6));

    success = true;
    LOG(INFO) << "Started IPv6 forwarding between " << lan_ifname_ << " and "
              << int_ifname << " for " << mcast_addr6_ << ":" << port_;
  } else {
    LOG(WARNING) << "Could not bind socket on " << int_ifname << " for "
                 << mcast_addr6_ << ":" << port_;
  }

  return success;
}

void MulticastForwarder::RemoveGuest(const std::string& int_ifname) {
  const auto& socket4 = int_sockets_.find(std::make_pair(AF_INET, int_ifname));
  if (socket4 != int_sockets_.end()) {
    int_fds_.erase(std::make_pair(AF_INET, socket4->second->fd.get()));
    int_sockets_.erase(socket4);
  } else {
    LOG(WARNING) << "IPv4 forwarding is not started between " << lan_ifname_
                 << " and " << int_ifname;
  }

  const auto& socket6 = int_sockets_.find(std::make_pair(AF_INET6, int_ifname));
  if (socket6 != int_sockets_.end()) {
    int_fds_.erase(std::make_pair(AF_INET6, socket6->second->fd.get()));
    int_sockets_.erase(socket6);
  } else {
    LOG(WARNING) << "IPv6 forwarding is not started between " << lan_ifname_
                 << " and " << int_ifname;
  }
}

void MulticastForwarder::OnFileCanReadWithoutBlocking(int fd,
                                                      sa_family_t sa_family) {
  CHECK(sa_family == AF_INET || sa_family == AF_INET6);

  char data[kBufSize];

  struct sockaddr_storage fromaddr_storage = {0};
  struct sockaddr* fromaddr =
      reinterpret_cast<struct sockaddr*>(&fromaddr_storage);

  socklen_t addrlen = sizeof(struct sockaddr_storage);

  ssize_t len = recvfrom(fd, data, kBufSize, 0, fromaddr, &addrlen);
  if (len < 0) {
    PLOG(WARNING) << "recvfrom failed";
    return;
  }

  socklen_t expectlen = sa_family == AF_INET ? sizeof(struct sockaddr_in)
                                             : sizeof(struct sockaddr_in6);
  if (addrlen != expectlen) {
    LOG(WARNING) << "recvfrom failed: src addr length was " << addrlen
                 << " but expected " << expectlen;
    return;
  }

  struct sockaddr_storage dst_storage = {0};
  struct sockaddr* dst = reinterpret_cast<struct sockaddr*>(&dst_storage);
  uint16_t src_port;

  if (sa_family == AF_INET) {
    const struct sockaddr_in* addr4 =
        reinterpret_cast<const struct sockaddr_in*>(fromaddr);
    src_port = ntohs(addr4->sin_port);
  } else if (sa_family == AF_INET6) {
    const struct sockaddr_in6* addr6 =
        reinterpret_cast<const struct sockaddr_in6*>(fromaddr);
    src_port = ntohs(addr6->sin6_port);
  }
  SetSockaddr(&dst_storage, sa_family, port_,
              sa_family == AF_INET ? reinterpret_cast<char*>(&mcast_addr_)
                                   : reinterpret_cast<char*>(&mcast_addr6_));

  // Forward ingress traffic to all guests.
  const auto& lan_socket = lan_socket_.find(sa_family);
  if ((lan_socket != lan_socket_.end() && fd == lan_socket->second->fd.get())) {
    SendToGuests(data, len, dst, addrlen);
    return;
  }

  const auto& int_fd = int_fds_.find(std::make_pair(sa_family, fd));
  if (int_fd == int_fds_.end() || lan_socket == lan_socket_.end())
    return;

  // Forward egress traffic from one guest to all other guests.
  // No IP translation is required as other guests can route to each other
  // behind the SNAT setup.
  SendToGuests(data, len, dst, addrlen, fd);

  // On mDNS, sending to physical network requires translating any IPv4
  // address specific to the guest and not visible to the physical network.
  if (sa_family == AF_INET && port_ == kMdnsPort) {
    // TODO(b/132574450) The replacement address should instead be specified
    // as an input argument, based on the properties of the network
    // currently connected on |lan_ifname_|.
    const struct in_addr lan_ip =
        GetInterfaceIp(lan_socket->second->fd.get(), lan_ifname_);
    if (lan_ip.s_addr == htonl(INADDR_ANY)) {
      // When the physical interface has no IPv4 address, IPv4 is not
      // provisioned and there is no point in trying to forward traffic in
      // either direction.
      return;
    }
    TranslateMdnsIp(
        lan_ip, reinterpret_cast<const struct sockaddr_in*>(fromaddr)->sin_addr,
        data, len);
  }

  // Forward egress traffic from one guest to outside network.
  SendTo(src_port, data, len, dst, addrlen);
}

bool MulticastForwarder::SendTo(uint16_t src_port,
                                const void* data,
                                ssize_t len,
                                const struct sockaddr* dst,
                                socklen_t dst_len) {
  if (src_port == port_) {
    int lan_fd = lan_socket_.find(dst->sa_family)->second->fd.get();
    if (sendto(lan_fd, data, len, 0, dst, dst_len) < 0) {
      PLOG(WARNING) << "sendto " << *dst << " on " << lan_ifname_
                    << " from port " << src_port << " failed";
      return false;
    }
    return true;
  }

  patchpanel::Socket temp_socket(dst->sa_family, SOCK_DGRAM);

  struct ifreq ifr;
  memset(&ifr, 0, sizeof(ifr));
  strncpy(ifr.ifr_name, lan_ifname_.c_str(), IFNAMSIZ);
  if (setsockopt(temp_socket.fd(), SOL_SOCKET, SO_BINDTODEVICE, &ifr,
                 sizeof(ifr))) {
    PLOG(ERROR) << "setsockopt(SO_BINDTODEVICE) failed";
    return false;
  }

  int level, optname;
  struct sockaddr_storage bind_addr_storage = {0};
  struct sockaddr* bind_addr = reinterpret_cast<sockaddr*>(&bind_addr_storage);
  if (dst->sa_family == AF_INET) {
    level = IPPROTO_IP;
    optname = IP_MULTICAST_LOOP;
  } else if (dst->sa_family == AF_INET6) {
    level = IPPROTO_IPV6;
    optname = IPV6_MULTICAST_LOOP;
  } else {
    LOG(ERROR) << "Unexpected sa_family " << dst->sa_family;
    return false;
  }
  SetSockaddr(&bind_addr_storage, dst->sa_family, src_port, nullptr);

  int flag = 0;
  if (setsockopt(temp_socket.fd(), level, optname, &flag, sizeof(flag))) {
    PLOG(ERROR) << "setsockopt(IP_MULTICAST_LOOP) failed";
    return false;
  }

  flag = 1;
  if (setsockopt(temp_socket.fd(), SOL_SOCKET, SO_REUSEADDR, &flag,
                 sizeof(flag))) {
    PLOG(ERROR) << "setsockopt(SO_REUSEADDR) failed";
    return false;
  }

  if (!temp_socket.Bind(bind_addr, sizeof(struct sockaddr_storage)))
    return false;

  if (!temp_socket.SendTo(data, len, dst, dst_len)) {
    PLOG(WARNING) << "sendto " << *dst << " on " << lan_ifname_ << " from port "
                  << src_port << " failed";
    return false;
  }
  return true;
}

bool MulticastForwarder::SendToGuests(const void* data,
                                      ssize_t len,
                                      const struct sockaddr* dst,
                                      socklen_t dst_len,
                                      int ignore_fd) {
  bool success = true;
  for (const auto& socket : int_sockets_) {
    if (socket.first.first != dst->sa_family)
      continue;
    int fd = socket.second->fd.get();
    if (fd == ignore_fd)
      continue;

    // Use already created multicast fd.
    if (sendto(fd, data, len, 0, dst, dst_len) < 0) {
      PLOG(WARNING) << "sendto " << socket.first.second << " failed";
      success = false;
    }
  }
  return success;
}

// static
void MulticastForwarder::TranslateMdnsIp(const struct in_addr& lan_ip,
                                         const struct in_addr& guest_ip,
                                         char* data,
                                         ssize_t len) {
  if (guest_ip.s_addr == htonl(INADDR_ANY)) {
    return;
  }

  // Make sure this is a valid, successful DNS response from the Android
  // host.
  if (len > net::dns_protocol::kMaxUDPSize || len <= 0) {
    return;
  }

  net::DnsResponse resp;
  memcpy(resp.io_buffer()->data(), data, len);
  if (!resp.InitParseWithoutQuery(len) ||
      !(resp.flags() & net::dns_protocol::kFlagResponse) ||
      resp.rcode() != net::dns_protocol::kRcodeNOERROR) {
    return;
  }

  // Check all A records for the internal IP, and replace it with |lan_ip|
  // if it is found.
  net::DnsRecordParser parser = resp.Parser();
  while (!parser.AtEnd()) {
    const size_t ipv4_addr_len = sizeof(lan_ip.s_addr);

    net::DnsResourceRecord record;
    if (!parser.ReadRecord(&record)) {
      break;
    }
    if (record.type == net::dns_protocol::kTypeA &&
        record.rdata.size() == ipv4_addr_len) {
      struct in_addr rr_ip;
      memcpy(&rr_ip, record.rdata.data(), ipv4_addr_len);
      if (guest_ip.s_addr == rr_ip.s_addr) {
        // HACK: This is able to calculate the (variable) offset of the IPv4
        // address inside the resource record by assuming that the
        // StringPiece returns a pointer inside the io_buffer.  It works
        // today, but future libchrome changes might break it.
        size_t ip_offset = record.rdata.data() - resp.io_buffer()->data();
        CHECK(ip_offset <= len - ipv4_addr_len);
        memcpy(&data[ip_offset], &lan_ip.s_addr, ipv4_addr_len);
      }
    }
  }
}

}  // namespace patchpanel
