// Copyright 2020 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/broadcast_forwarder.h"

#include <arpa/inet.h>
#include <errno.h>
#include <linux/filter.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <linux/rtnetlink.h>
#include <net/if.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <shill/net/rtnl_handler.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>

#include <utility>

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

#include "patchpanel/socket.h"

namespace {

constexpr int kBufSize = 4096;
constexpr uint16_t kIpFragOffsetMask = 0x1FFF;
// Broadcast forwarder will not forward system ports (0 - 1023).
constexpr uint16_t kMinValidPort = 1024;

// SetBcastSockFilter filters out packets by only accepting (all conditions
// must be fulfilled):
// - UDP protocol,
// - Destination address equals to 255.255.255.255 or |bcast_addr|,
// - Source and destination port is not a system port (>= 1024).
bool SetBcastSockFilter(int fd, uint32_t bcast_addr) {
  sock_filter kBcastFwdBpfInstructions[] = {
      // Load IP protocol value.
      BPF_STMT(BPF_LD | BPF_B | BPF_ABS, offsetof(iphdr, protocol)),
      // Check if equals UDP, if not, then goto return 0.
      BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, IPPROTO_UDP, 0, 8),
      // Load IP destination address.
      BPF_STMT(BPF_LD | BPF_W | BPF_IND, offsetof(iphdr, daddr)),
      // Check if it is a broadcast address.
      // All 1s.
      BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, patchpanel::kBcastAddr, 1, 0),
      // Current interface broadcast address.
      BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, htonl(bcast_addr), 0, 5),
      // Move index to start of UDP header.
      BPF_STMT(BPF_LDX | BPF_IMM, sizeof(iphdr)),
      // Load UDP source port.
      BPF_STMT(BPF_LD | BPF_H | BPF_IND, offsetof(udphdr, uh_sport)),
      // Check if it is a valid source port (>= 1024).
      BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, kMinValidPort, 0, 2),
      // Load UDP destination port.
      BPF_STMT(BPF_LD | BPF_H | BPF_IND, offsetof(udphdr, uh_dport)),
      // Check if it is a valid destination port (>= 1024).
      BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, kMinValidPort, 1, 0),
      // Return 0.
      BPF_STMT(BPF_RET | BPF_K, 0),
      // Return MAX.
      BPF_STMT(BPF_RET | BPF_K, IP_MAXPACKET),
  };
  sock_fprog kBcastFwdBpfProgram = {
      .len = sizeof(kBcastFwdBpfInstructions) / sizeof(sock_filter),
      .filter = kBcastFwdBpfInstructions};

  if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &kBcastFwdBpfProgram,
                 sizeof(kBcastFwdBpfProgram)) != 0) {
    PLOG(ERROR)
        << "setsockopt(SO_ATTACH_FILTER) failed for broadcast forwarder";
    return false;
  }
  return true;
}

void Ioctl(int fd,
           const std::string& ifname,
           unsigned int cmd,
           struct ifreq* ifr) {
  if (ifname.empty()) {
    LOG(WARNING) << "Empty interface name";
    return;
  }

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

uint32_t GetIfreqAddr(const struct ifreq& ifr) {
  return reinterpret_cast<const struct sockaddr_in*>(&ifr.ifr_addr)
      ->sin_addr.s_addr;
}

uint32_t GetIfreqBroadaddr(const struct ifreq& ifr) {
  return reinterpret_cast<const struct sockaddr_in*>(&ifr.ifr_broadaddr)
      ->sin_addr.s_addr;
}

uint32_t GetIfreqNetmask(const struct ifreq& ifr) {
  return reinterpret_cast<const struct sockaddr_in*>(&ifr.ifr_netmask)
      ->sin_addr.s_addr;
}

}  // namespace

namespace patchpanel {

BroadcastForwarder::Socket::Socket(base::ScopedFD fd,
                                   base::RepeatingCallback<void(int)> callback,
                                   uint32_t addr,
                                   uint32_t broadaddr,
                                   uint32_t netmask)
    : fd(std::move(fd)), addr(addr), broadaddr(broadaddr), netmask(netmask) {
  watcher = base::FileDescriptorWatcher::WatchReadable(
      Socket::fd.get(),
      base::BindRepeating(std::move(callback), Socket::fd.get()));
}

BroadcastForwarder::BroadcastForwarder(const std::string& dev_ifname)
    : dev_ifname_(dev_ifname) {
  addr_listener_ = std::make_unique<shill::RTNLListener>(
      shill::RTNLHandler::kRequestAddr,
      base::BindRepeating(&BroadcastForwarder::AddrMsgHandler,
                          weak_factory_.GetWeakPtr()));
  shill::RTNLHandler::GetInstance()->Start(RTMGRP_IPV4_IFADDR);
}

void BroadcastForwarder::AddrMsgHandler(const shill::RTNLMessage& msg) {
  if (!msg.HasAttribute(IFA_LABEL)) {
    LOG(ERROR) << "Address event message does not have IFA_LABEL";
    return;
  }

  if (msg.mode() != shill::RTNLMessage::kModeAdd)
    return;

  shill::ByteString b(msg.GetAttribute(IFA_LABEL));
  std::string ifname(reinterpret_cast<const char*>(
      b.GetSubstring(0, IFNAMSIZ).GetConstData()));
  if (ifname != dev_ifname_)
    return;

  // Interface address is added.
  if (msg.HasAttribute(IFA_ADDRESS)) {
    shill::ByteString b(msg.GetAttribute(IFA_ADDRESS));
    memcpy(&dev_socket_->addr, b.GetConstData(), b.GetLength());
  }

  // Broadcast address is added.
  if (msg.HasAttribute(IFA_BROADCAST)) {
    shill::ByteString b(msg.GetAttribute(IFA_BROADCAST));
    memcpy(&dev_socket_->broadaddr, b.GetConstData(), b.GetLength());

    base::ScopedFD dev_fd(BindRaw(dev_ifname_));
    if (!dev_fd.is_valid()) {
      LOG(WARNING) << "Could not bind socket on " << dev_ifname_;
      return;
    }
    dev_socket_.reset(new Socket(
        std::move(dev_fd),
        base::BindRepeating(&BroadcastForwarder::OnFileCanReadWithoutBlocking,
                            base::Unretained(this)),
        dev_socket_->addr, dev_socket_->broadaddr));
  }
}

base::ScopedFD BroadcastForwarder::Bind(const std::string& ifname,
                                        uint16_t port) {
  base::ScopedFD fd(socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0));
  if (!fd.is_valid()) {
    PLOG(ERROR) << "socket() failed for broadcast forwarder on " << ifname
                << " for port: " << port;
    return base::ScopedFD();
  }

  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(SOL_SOCKET) failed for broadcast forwarder on "
                << ifname << " for port: " << port;
    return base::ScopedFD();
  }

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

  if (setsockopt(fd.get(), SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
    PLOG(ERROR) << "setsockopt(SO_REUSEADDR) failed for broadcast forwarder on "
                << ifname << " for: " << port;
    return base::ScopedFD();
  }

  struct sockaddr_in bind_addr;
  memset(&bind_addr, 0, sizeof(bind_addr));
  bind_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  bind_addr.sin_family = AF_INET;
  bind_addr.sin_port = htons(port);

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

  return fd;
}

base::ScopedFD BroadcastForwarder::BindRaw(const std::string& ifname) {
  base::ScopedFD fd(
      socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, htons(ETH_P_IP)));
  if (!fd.is_valid()) {
    PLOG(ERROR) << "socket() failed for raw socket";
    return base::ScopedFD();
  }

  struct ifreq ifr;
  memset(&ifr, 0, sizeof(ifr));
  strncpy(ifr.ifr_name, ifname.c_str(), IFNAMSIZ);
  if (ioctl(fd.get(), SIOCGIFINDEX, &ifr) < 0) {
    PLOG(ERROR) << "SIOCGIFINDEX failed for " << ifname;
    return base::ScopedFD();
  }

  struct sockaddr_ll bindaddr;
  memset(&bindaddr, 0, sizeof(bindaddr));
  bindaddr.sll_family = AF_PACKET;
  bindaddr.sll_protocol = htons(ETH_P_IP);
  bindaddr.sll_ifindex = ifr.ifr_ifindex;

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

  Ioctl(fd.get(), ifname, SIOCGIFBRDADDR, &ifr);
  uint32_t bcast_addr = GetIfreqBroadaddr(ifr);

  if (!SetBcastSockFilter(fd.get(), bcast_addr)) {
    return base::ScopedFD();
  }

  return fd;
}

bool BroadcastForwarder::AddGuest(const std::string& br_ifname) {
  if (br_sockets_.find(br_ifname) != br_sockets_.end()) {
    LOG(WARNING) << "Forwarding is already started between " << dev_ifname_
                 << " and " << br_ifname;
    return false;
  }

  base::ScopedFD br_fd(BindRaw(br_ifname));
  if (!br_fd.is_valid()) {
    LOG(WARNING) << "Could not bind socket on " << br_ifname;
    return false;
  }

  struct ifreq ifr;
  Ioctl(br_fd.get(), br_ifname, SIOCGIFADDR, &ifr);
  uint32_t br_addr = GetIfreqAddr(ifr);
  Ioctl(br_fd.get(), br_ifname, SIOCGIFBRDADDR, &ifr);
  uint32_t br_broadaddr = GetIfreqBroadaddr(ifr);
  Ioctl(br_fd.get(), br_ifname, SIOCGIFNETMASK, &ifr);
  uint32_t br_netmask = GetIfreqNetmask(ifr);

  std::unique_ptr<Socket> br_socket = std::make_unique<Socket>(
      std::move(br_fd),
      base::BindRepeating(&BroadcastForwarder::OnFileCanReadWithoutBlocking,
                          base::Unretained(this)),
      br_addr, br_broadaddr, br_netmask);

  br_sockets_.emplace(br_ifname, std::move(br_socket));

  // Broadcast forwarder is not started yet.
  if (dev_socket_ == nullptr) {
    base::ScopedFD dev_fd(BindRaw(dev_ifname_));
    if (!dev_fd.is_valid()) {
      LOG(WARNING) << "Could not bind socket on " << dev_ifname_;
      br_sockets_.clear();
      return false;
    }

    Ioctl(dev_fd.get(), dev_ifname_, SIOCGIFADDR, &ifr);
    uint32_t dev_addr = GetIfreqAddr(ifr);
    Ioctl(dev_fd.get(), dev_ifname_, SIOCGIFBRDADDR, &ifr);
    uint32_t dev_broadaddr = GetIfreqBroadaddr(ifr);

    dev_socket_.reset(new Socket(
        std::move(dev_fd),
        base::BindRepeating(&BroadcastForwarder::OnFileCanReadWithoutBlocking,
                            base::Unretained(this)),
        dev_addr, dev_broadaddr));
  }
  return true;
}

void BroadcastForwarder::RemoveGuest(const std::string& br_ifname) {
  const auto& socket = br_sockets_.find(br_ifname);
  if (socket == br_sockets_.end()) {
    LOG(WARNING) << "Forwarding is not started between " << dev_ifname_
                 << " and " << br_ifname;
    return;
  }
  br_sockets_.erase(socket);
}

void BroadcastForwarder::OnFileCanReadWithoutBlocking(int fd) {
  alignas(4) uint8_t buffer[kBufSize];
  uint8_t* data = buffer + sizeof(iphdr) + sizeof(udphdr);

  sockaddr_ll dst_addr;
  struct iovec iov = {
      .iov_base = buffer,
      .iov_len = kBufSize,
  };
  msghdr hdr = {
      .msg_name = &dst_addr,
      .msg_namelen = sizeof(dst_addr),
      .msg_iov = &iov,
      .msg_iovlen = 1,
      .msg_control = nullptr,
      .msg_controllen = 0,
      .msg_flags = 0,
  };

  ssize_t msg_len = recvmsg(fd, &hdr, 0);
  if (msg_len < 0) {
    // Ignore ENETDOWN: this can happen if the interface is not yet configured.
    if (errno != ENETDOWN) {
      PLOG(WARNING) << "recvmsg() failed";
    }
    return;
  }

  // These headers are taken directly from the buffer and is 4 bytes aligned.
  struct iphdr* ip_hdr = (struct iphdr*)(buffer);
  struct udphdr* udp_hdr = (struct udphdr*)(buffer + sizeof(iphdr));

  // Drop fragmented packets.
  if ((ntohs(ip_hdr->frag_off) & (kIpFragOffsetMask | IP_MF)) != 0)
    return;

  // Store the length of the message without its headers.
  ssize_t len = ntohs(udp_hdr->len) - sizeof(udphdr);

  // Validate UDP length.
  if ((len + sizeof(udphdr) + sizeof(iphdr) > msg_len) || (len < 0))
    return;

  struct sockaddr_in fromaddr = {0};
  fromaddr.sin_family = AF_INET;
  fromaddr.sin_port = udp_hdr->uh_sport;
  fromaddr.sin_addr.s_addr = ip_hdr->saddr;

  struct sockaddr_in dst = {0};
  dst.sin_family = AF_INET;
  dst.sin_port = udp_hdr->uh_dport;
  dst.sin_addr.s_addr = ip_hdr->daddr;

  // Forward ingress traffic to guests.
  if (fd == dev_socket_->fd.get()) {
    // Prevent looped back broadcast packets to be forwarded.
    if (fromaddr.sin_addr.s_addr == dev_socket_->addr)
      return;

    SendToGuests(buffer, len, dst);
    return;
  }

  for (auto const& socket : br_sockets_) {
    if (fd != socket.second->fd.get())
      continue;

    // Prevent looped back broadcast packets to be forwarded.
    if (fromaddr.sin_addr.s_addr == socket.second->addr)
      return;

    // We are spoofing packets source IP to be the actual sender source IP.
    // Prevent looped back broadcast packets by not forwarding anything from
    // outside the interface netmask.
    if ((fromaddr.sin_addr.s_addr & socket.second->netmask) !=
        (socket.second->addr & socket.second->netmask))
      return;

    // Forward egress traffic from one guest to outside network.
    SendToNetwork(ntohs(fromaddr.sin_port), data, len, dst);
  }
}

bool BroadcastForwarder::SendToNetwork(uint16_t src_port,
                                       const void* data,
                                       ssize_t len,
                                       const struct sockaddr_in& dst) {
  base::ScopedFD temp_fd(Bind(dev_ifname_, src_port));
  if (!temp_fd.is_valid()) {
    LOG(WARNING) << "Could not bind socket on " << dev_ifname_ << " for port "
                 << src_port;
    return false;
  }

  struct sockaddr_in dev_dst = {0};
  memcpy(&dev_dst, &dst, sizeof(sockaddr_in));

  if (dev_dst.sin_addr.s_addr != kBcastAddr)
    dev_dst.sin_addr.s_addr = dev_socket_->broadaddr;

  if (sendto(temp_fd.get(), data, len, 0,
             reinterpret_cast<const struct sockaddr*>(&dev_dst),
             sizeof(struct sockaddr_in)) < 0) {
    // Ignore ENETDOWN: this can happen if the interface is not yet configured.
    if (errno != ENETDOWN) {
      PLOG(WARNING) << "sendto() failed";
    }
    return false;
  }
  return true;
}

bool BroadcastForwarder::SendToGuests(const void* ip_pkt,
                                      ssize_t len,
                                      const struct sockaddr_in& dst) {
  bool success = true;

  base::ScopedFD raw(socket(AF_INET, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_UDP));
  if (!raw.is_valid()) {
    PLOG(ERROR) << "socket() failed for raw socket";
    return false;
  }

  int on = 1;
  if (setsockopt(raw.get(), IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0) {
    PLOG(ERROR) << "setsockopt(IP_HDRINCL) failed";
    return false;
  }
  if (setsockopt(raw.get(), SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) {
    PLOG(ERROR) << "setsockopt(SO_BROADCAST) failed";
    return false;
  }

  // Copy IP packet received by the lan interface and only change its
  // destination address.
  alignas(4) uint8_t buffer[kBufSize];
  memset(buffer, 0, kBufSize);
  memcpy(buffer, reinterpret_cast<const uint8_t*>(ip_pkt),
         sizeof(iphdr) + sizeof(udphdr) + len);

  // These headers are taken directly from the buffer and is 4 bytes aligned.
  struct iphdr* ip_hdr = (struct iphdr*)buffer;
  struct udphdr* udp_hdr = (struct udphdr*)(buffer + sizeof(struct iphdr));

  ip_hdr->check = 0;
  udp_hdr->check = 0;

  struct sockaddr_in br_dst = {0};
  memcpy(&br_dst, &dst, sizeof(struct sockaddr_in));

  for (auto const& socket : br_sockets_) {
    // Set destination address.
    if (br_dst.sin_addr.s_addr != kBcastAddr) {
      br_dst.sin_addr.s_addr = socket.second->broadaddr;
      ip_hdr->daddr = socket.second->broadaddr;
      ip_hdr->check = Ipv4Checksum(ip_hdr);
    }
    udp_hdr->check = Udpv4Checksum(ip_hdr, udp_hdr);

    struct ifreq ifr;
    memset(&ifr, 0, sizeof(ifr));
    strncpy(ifr.ifr_name, socket.first.c_str(), IFNAMSIZ);
    if (setsockopt(raw.get(), SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr))) {
      PLOG(ERROR) << "setsockopt(SOL_SOCKET) failed for broadcast forwarder on "
                  << socket.first;
      continue;
    }

    // Use already created broadcast fd.
    if (sendto(raw.get(), buffer,
               sizeof(struct iphdr) + sizeof(struct udphdr) + len, 0,
               reinterpret_cast<const struct sockaddr*>(&br_dst),
               sizeof(struct sockaddr_in)) < 0) {
      PLOG(WARNING) << "sendto failed";
      success = false;
    }
  }
  return success;
}

}  // namespace patchpanel
