// Copyright 2019 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/ndproxy.h"

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <unistd.h>

#include <arpa/inet.h>
#include <linux/filter.h>
#include <linux/if_packet.h>
#include <linux/in6.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <netinet/icmp6.h>
#include <sys/ioctl.h>
#include <sys/socket.h>

#include <fstream>
#include <string>
#include <utility>

#include <base/functional/bind.h>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_split.h>

#include "patchpanel/ipc.h"
#include "patchpanel/minijailed_process_runner.h"
#include "patchpanel/net_util.h"

namespace patchpanel {
namespace {
// Currently when we are unable to resolve the destination MAC for a proxied
// packet (note this can only happen for unicast NA and NS), we send the packet
// using all-nodes multicast MAC. Change this flag to true to drop those packets
// on uplinks instead.
// TODO(b/244271776): Investigate if it is safe to drop such packets, or if
// there is a legitimate case that these packets are actually required.
constexpr bool kDropUnresolvableUnicastToUpstream = false;

const unsigned char kZeroMacAddress[] = {0, 0, 0, 0, 0, 0};
const unsigned char kAllNodesMulticastMacAddress[] = {0x33, 0x33, 0,
                                                      0,    0,    0x01};
const unsigned char kAllRoutersMulticastMacAddress[] = {0x33, 0x33, 0,
                                                        0,    0,    0x02};
const unsigned char kSolicitedNodeMulticastMacAddressPrefix[] = {
    0x33, 0x33, 0xff, 0, 0, 0};
const struct in6_addr kAllNodesMulticastAddress = {
    {.u6_addr8 = {0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}}};
const struct in6_addr kAllRoutersMulticastAddress = {
    {.u6_addr8 = {0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x02}}};
const struct in6_addr kSolicitedNodeMulticastAddressPrefix = {
    {.u6_addr8 = {0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01, 0xff, 0, 0, 0}}};
constexpr int kSolicitedGroupSuffixLength = 3;

// These filter instructions assume that the input is an IPv6 packet and check
// that the packet is an ICMPv6 packet of whose ICMPv6 type is one of: neighbor
// solicitation, neighbor advertisement, router solicitation, or router
// advertisement.
sock_filter kNDPacketBpfInstructions[] = {
    // Load IPv6 next header.
    BPF_STMT(BPF_LD | BPF_B | BPF_IND, offsetof(ip6_hdr, ip6_nxt)),
    // Check if equals ICMPv6, if not, then goto return 0.
    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, IPPROTO_ICMPV6, 0, 6),
    // Move index to start of ICMPv6 header.
    BPF_STMT(BPF_LDX | BPF_IMM, sizeof(ip6_hdr)),
    // Load ICMPv6 type.
    BPF_STMT(BPF_LD | BPF_B | BPF_IND, offsetof(icmp6_hdr, icmp6_type)),
    // Check if is ND ICMPv6 message.
    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, ND_ROUTER_SOLICIT, 4, 0),
    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, ND_ROUTER_ADVERT, 3, 0),
    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, ND_NEIGHBOR_SOLICIT, 2, 0),
    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, ND_NEIGHBOR_ADVERT, 1, 0),
    // Return 0.
    BPF_STMT(BPF_RET | BPF_K, 0),
    // Return MAX.
    BPF_STMT(BPF_RET | BPF_K, IP_MAXPACKET),
};
const sock_fprog kNDPacketBpfProgram = {
    .len = sizeof(kNDPacketBpfInstructions) / sizeof(sock_filter),
    .filter = kNDPacketBpfInstructions};

std::string Icmp6TypeName(uint32_t type) {
  switch (type) {
    case ND_ROUTER_SOLICIT:
      return "ND_ROUTER_SOLICIT";
    case ND_ROUTER_ADVERT:
      return "ND_ROUTER_ADVERT";
    case ND_NEIGHBOR_SOLICIT:
      return "ND_NEIGHBOR_SOLICIT";
    case ND_NEIGHBOR_ADVERT:
      return "ND_NEIGHBOR_ADVERT";
    default:
      return "UNKNOWN";
  }
}

[[maybe_unused]] std::string Icmp6ToString(const uint8_t* packet, size_t len) {
  const ip6_hdr* ip6 = reinterpret_cast<const ip6_hdr*>(packet);
  const icmp6_hdr* icmp6 =
      reinterpret_cast<const icmp6_hdr*>(packet + sizeof(ip6_hdr));

  if (len < sizeof(ip6_hdr) + sizeof(icmp6_hdr))
    return "<packet too small>";

  if (ip6->ip6_nxt != IPPROTO_ICMPV6)
    return "<not ICMP6 packet>";

  if (icmp6->icmp6_type < ND_ROUTER_SOLICIT ||
      icmp6->icmp6_type > ND_NEIGHBOR_ADVERT)
    return "<not ND ICMP6 packet>";

  std::stringstream ss;
  ss << Icmp6TypeName(icmp6->icmp6_type) << " "
     << IPv6AddressToString(ip6->ip6_src) << " -> "
     << IPv6AddressToString(ip6->ip6_dst);
  switch (icmp6->icmp6_type) {
    case ND_NEIGHBOR_SOLICIT:
    case ND_NEIGHBOR_ADVERT: {
      // NS and NA has same packet format for Target Address
      ss << ", target "
         << IPv6AddressToString(
                reinterpret_cast<const nd_neighbor_solicit*>(icmp6)
                    ->nd_ns_target);
      break;
    }
    case ND_ROUTER_SOLICIT:
      // Nothing extra to print here
      break;
    case ND_ROUTER_ADVERT: {
      const nd_opt_prefix_info* prefix_info = NDProxy::GetPrefixInfoOption(
          reinterpret_cast<const uint8_t*>(icmp6), len - sizeof(ip6_hdr));
      if (prefix_info != nullptr) {
        ss << ", prefix " << IPv6AddressToString(prefix_info->nd_opt_pi_prefix)
           << "/" << static_cast<int>(prefix_info->nd_opt_pi_prefix_len);
      }
      break;
    }
    default: {
      NOTREACHED();
    }
  }
  return ss.str();
}

}  // namespace

NDProxy::NDProxy() {}

// static
base::ScopedFD NDProxy::PreparePacketSocket() {
  base::ScopedFD fd(
      socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, htons(ETH_P_IPV6)));
  if (!fd.is_valid()) {
    PLOG(ERROR) << "socket() failed";
    return base::ScopedFD();
  }
  if (setsockopt(fd.get(), SOL_SOCKET, SO_ATTACH_FILTER, &kNDPacketBpfProgram,
                 sizeof(kNDPacketBpfProgram))) {
    PLOG(ERROR) << "setsockopt(SO_ATTACH_FILTER) failed";
    return base::ScopedFD();
  }
  return fd;
}

bool NDProxy::Init() {
  rtnl_fd_ = base::ScopedFD(
      socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE));
  if (!rtnl_fd_.is_valid()) {
    PLOG(ERROR) << "socket() failed for rtnetlink socket";
    return false;
  }
  sockaddr_nl local = {
      .nl_family = AF_NETLINK,
      .nl_groups = 0,
  };
  if (bind(rtnl_fd_.get(), reinterpret_cast<sockaddr*>(&local), sizeof(local)) <
      0) {
    PLOG(ERROR) << "bind() failed on rtnetlink socket";
    return false;
  }

  dummy_fd_ = base::ScopedFD(socket(AF_INET6, SOCK_DGRAM, 0));
  if (!dummy_fd_.is_valid()) {
    PLOG(ERROR) << "socket() failed for dummy socket";
    return false;
  }
  return true;
}

// static
void NDProxy::ReplaceMacInIcmpOption(uint8_t* icmp6,
                                     size_t icmp6_len,
                                     size_t nd_hdr_len,
                                     uint8_t opt_type,
                                     const MacAddress& target_mac) {
  size_t opt_offset = nd_hdr_len;
  while (opt_offset + sizeof(nd_opt_hdr) <= icmp6_len) {
    nd_opt_hdr* opt = reinterpret_cast<nd_opt_hdr*>(icmp6 + opt_offset);
    // nd_opt_len is in 8 bytes unit.
    size_t opt_len = 8 * (opt->nd_opt_len);
    if (opt_len == 0 || icmp6_len < opt_offset + opt_len) {
      // Invalid packet.
      return;
    }
    if (opt->nd_opt_type == opt_type) {
      if (opt_len < sizeof(nd_opt_hdr) + ETHER_ADDR_LEN) {
        // Option length was inconsistent with the size of a MAC address.
        return;
      }
      memcpy(icmp6 + opt_offset + sizeof(nd_opt_hdr), target_mac.data(),
             ETHER_ADDR_LEN);
    }
    opt_offset += opt_len;
  }
}

// static
ssize_t NDProxy::TranslateNDPacket(const uint8_t* in_packet,
                                   size_t packet_len,
                                   const MacAddress& local_mac_addr,
                                   const in6_addr* new_src_ip,
                                   const in6_addr* new_dst_ip,
                                   uint8_t* out_packet) {
  if (packet_len < sizeof(ip6_hdr) + sizeof(icmp6_hdr)) {
    return kTranslateErrorInsufficientLength;
  }
  if (reinterpret_cast<const ip6_hdr*>(in_packet)->ip6_nxt != IPPROTO_ICMPV6) {
    return kTranslateErrorNotICMPv6Packet;
  }
  if (ntohs(reinterpret_cast<const ip6_hdr*>(in_packet)->ip6_plen) !=
      (packet_len - sizeof(struct ip6_hdr))) {
    return kTranslateErrorMismatchedIp6Length;
  }

  memcpy(out_packet, in_packet, packet_len);
  ip6_hdr* ip6 = reinterpret_cast<ip6_hdr*>(out_packet);
  icmp6_hdr* icmp6 = reinterpret_cast<icmp6_hdr*>(out_packet + sizeof(ip6_hdr));
  const size_t icmp6_len = packet_len - sizeof(ip6_hdr);

  switch (icmp6->icmp6_type) {
    case ND_ROUTER_SOLICIT:
      ReplaceMacInIcmpOption(reinterpret_cast<uint8_t*>(icmp6), icmp6_len,
                             sizeof(nd_router_solicit), ND_OPT_SOURCE_LINKADDR,
                             local_mac_addr);
      break;
    case ND_ROUTER_ADVERT: {
      // RFC 4389 Section 4.1.3.3 - Set Proxy bit
      nd_router_advert* ra = reinterpret_cast<nd_router_advert*>(icmp6);
      if (ra->nd_ra_flags_reserved & 0x04) {
        // According to RFC 4389, an RA packet with 'Proxy' bit set already
        // should not be proxied again, in order to avoid loop. However, we'll
        // need this form of proxy cascading in Crostini (Host->VM->Container)
        // so we are ignoring the check here. Note that we know we are doing RA
        // proxy in only one direction so there should be no loop.
      }
      ra->nd_ra_flags_reserved |= 0x04;

      ReplaceMacInIcmpOption(reinterpret_cast<uint8_t*>(icmp6), icmp6_len,
                             sizeof(nd_router_advert), ND_OPT_SOURCE_LINKADDR,
                             local_mac_addr);
      break;
    }
    case ND_NEIGHBOR_SOLICIT:
      ReplaceMacInIcmpOption(reinterpret_cast<uint8_t*>(icmp6), icmp6_len,
                             sizeof(nd_neighbor_solicit),
                             ND_OPT_SOURCE_LINKADDR, local_mac_addr);
      break;
    case ND_NEIGHBOR_ADVERT:
      ReplaceMacInIcmpOption(reinterpret_cast<uint8_t*>(icmp6), icmp6_len,
                             sizeof(nd_neighbor_advert), ND_OPT_TARGET_LINKADDR,
                             local_mac_addr);
      break;
    default:
      return kTranslateErrorNotNDPacket;
  }

  if (new_src_ip != nullptr) {
    memcpy(&ip6->ip6_src, new_src_ip, sizeof(in6_addr));

    // Turn off onlink flag if we are pretending to be the router.
    nd_opt_prefix_info* prefix_info =
        GetPrefixInfoOption(reinterpret_cast<uint8_t*>(icmp6), icmp6_len);
    if (prefix_info) {
      prefix_info->nd_opt_pi_flags_reserved &= ~ND_OPT_PI_FLAG_ONLINK;
    }
  }
  if (new_dst_ip != nullptr) {
    memcpy(&ip6->ip6_dst, new_dst_ip, sizeof(in6_addr));
  }

  // Recalculate the checksum. We need to clear the old checksum first so
  // checksum calculation does not wrongly take old checksum into account.
  icmp6->icmp6_cksum = 0;
  icmp6->icmp6_cksum =
      Icmpv6Checksum(reinterpret_cast<const uint8_t*>(ip6), packet_len);

  return static_cast<ssize_t>(packet_len);
}

void NDProxy::ReadAndProcessOnePacket(int fd) {
  uint8_t* in_packet = reinterpret_cast<uint8_t*>(in_packet_buffer_);
  uint8_t* out_packet = reinterpret_cast<uint8_t*>(out_packet_buffer_);

  sockaddr_ll recv_ll_addr;
  struct iovec iov_in = {
      .iov_base = in_packet,
      .iov_len = IP_MAXPACKET,
  };
  msghdr hdr = {
      .msg_name = &recv_ll_addr,
      .msg_namelen = sizeof(recv_ll_addr),
      .msg_iov = &iov_in,
      .msg_iovlen = 1,
      .msg_control = nullptr,
      .msg_controllen = 0,
      .msg_flags = 0,
  };

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

  ip6_hdr* ip6 = reinterpret_cast<ip6_hdr*>(in_packet);
  icmp6_hdr* icmp6 = reinterpret_cast<icmp6_hdr*>(in_packet + sizeof(ip6_hdr));

  if (ip6->ip6_nxt != IPPROTO_ICMPV6 || icmp6->icmp6_type < ND_ROUTER_SOLICIT ||
      icmp6->icmp6_type > ND_NEIGHBOR_ADVERT)
    return;

  VLOG_IF(2, (icmp6->icmp6_type == ND_ROUTER_SOLICIT ||
              icmp6->icmp6_type == ND_ROUTER_ADVERT))
      << "Received on interface " << recv_ll_addr.sll_ifindex << ": "
      << Icmp6ToString(in_packet, len);
  VLOG_IF(6, (icmp6->icmp6_type == ND_NEIGHBOR_SOLICIT ||
              icmp6->icmp6_type == ND_NEIGHBOR_ADVERT))
      << "Received on interface " << recv_ll_addr.sll_ifindex << ": "
      << Icmp6ToString(in_packet, len);

  NotifyPacketCallbacks(recv_ll_addr.sll_ifindex, in_packet, len);

  if (downlink_link_local_.find(recv_ll_addr.sll_ifindex) !=
          downlink_link_local_.end() &&
      memcmp(&ip6->ip6_dst, &downlink_link_local_[recv_ll_addr.sll_ifindex],
             sizeof(in6_addr)) == 0) {
    // If destination IP is our link local unicast, no need to proxy the packet.
    return;
  }

  // Translate the NDP frame and send it through proxy interface
  auto map_entry =
      MapForType(icmp6->icmp6_type)->find(recv_ll_addr.sll_ifindex);
  if (map_entry == MapForType(icmp6->icmp6_type)->end())
    return;

  const auto& target_ifs = map_entry->second;
  for (int target_if : target_ifs) {
    MacAddress local_mac;
    if (!GetLocalMac(target_if, &local_mac))
      continue;

    // b/246444885: Overwrite source IP address with host address and set
    // prefix offlink, to prevent internal traffic causing ICMP messaged being
    // sent to upstream caused by internal traffic.
    // b/187918638: On L850 only this is a must instead of an optimization.
    // With those modems we are observing irregular RAs coming from a src IP
    // that either cannot map to a hardware address in the neighbor table, or
    // is mapped to the local MAC address on the cellular interface. Directly
    // proxying these RAs will cause the guest OS to set up a default route to
    // a next hop that is not reachable for them.
    const in6_addr* new_src_ip_p = nullptr;
    in6_addr new_src_ip;
    if (modify_ra_uplinks_.find(recv_ll_addr.sll_ifindex) !=
            modify_ra_uplinks_.end() &&
        icmp6->icmp6_type == ND_ROUTER_ADVERT) {
      if (downlink_link_local_.find(target_if) == downlink_link_local_.end()) {
        continue;
      }
      memcpy(&new_src_ip, &downlink_link_local_[target_if], sizeof(in6_addr));
      new_src_ip_p = &new_src_ip;
    }

    // Always proxy RA to multicast address, so that every guest will accept it
    // therefore saving the total amount of RSs we sent to the network.
    // b/228574659: On L850 only this is a must instead of an optimization.
    const in6_addr* new_dst_ip_p = nullptr;
    if (icmp6->icmp6_type == ND_ROUTER_ADVERT) {
      new_dst_ip_p = &kAllNodesMulticastAddress;
    }

    ssize_t result = TranslateNDPacket(in_packet, len, local_mac, new_src_ip_p,
                                       new_dst_ip_p, out_packet);
    if (result < 0) {
      switch (result) {
        case kTranslateErrorNotICMPv6Packet:
          LOG(DFATAL) << "Attempt to TranslateNDPacket on a non-ICMPv6 packet";
          return;
        case kTranslateErrorNotNDPacket:
          LOG(DFATAL) << "Attempt to TranslateNDPacket on a non-NDP packet, "
                         "icmpv6 type = "
                      << static_cast<int>(icmp6->icmp6_type);
          return;
        case kTranslateErrorInsufficientLength:
          LOG(DFATAL) << "TranslateNDPacket failed: packet length = " << len
                      << " is too small";
          return;
        case kTranslateErrorMismatchedIp6Length:
          LOG(DFATAL) << "TranslateNDPacket failed: expected ip6_plen = "
                      << ntohs(ip6->ip6_plen) << ", received length = "
                      << (len - sizeof(struct ip6_hdr));
          return;
        default:
          LOG(DFATAL) << "Unknown error in TranslateNDPacket";
          return;
      }
    }

    sockaddr_ll send_ll_addr = {
        .sll_family = AF_PACKET,
        .sll_protocol = htons(ETH_P_IPV6),
        .sll_ifindex = target_if,
        .sll_halen = ETHER_ADDR_LEN,
    };

    ip6_hdr* new_ip6 = reinterpret_cast<ip6_hdr*>(out_packet);
    ResolveDestinationMac(new_ip6->ip6_dst, send_ll_addr.sll_addr);
    if (memcmp(send_ll_addr.sll_addr, &kZeroMacAddress, ETHER_ADDR_LEN) == 0) {
      VLOG(1) << "Cannot resolve " << Icmp6TypeName(icmp6->icmp6_type)
              << " packet dest IP " << IPv6AddressToString(new_ip6->ip6_dst)
              << " into MAC address. In: " << recv_ll_addr.sll_ifindex
              << ", out: " << target_if;
      if (IsGuestInterface(target_if) || !kDropUnresolvableUnicastToUpstream) {
        // If we can't resolve the destination IP into MAC from kernel neighbor
        // table, fill destination MAC with all-nodes multicast MAC instead.
        memcpy(send_ll_addr.sll_addr, &kAllNodesMulticastMacAddress,
               ETHER_ADDR_LEN);
      } else {
        // Drop the packet.
        return;
      }
    }

    VLOG_IF(3, (icmp6->icmp6_type == ND_ROUTER_SOLICIT ||
                icmp6->icmp6_type == ND_ROUTER_ADVERT))
        << "Sending to interface " << target_if << ": "
        << Icmp6ToString(out_packet, len);
    VLOG_IF(7, (icmp6->icmp6_type == ND_NEIGHBOR_SOLICIT ||
                icmp6->icmp6_type == ND_NEIGHBOR_ADVERT))
        << "Sending to interface " << target_if << ": "
        << Icmp6ToString(out_packet, len);

    struct iovec iov_out = {
        .iov_base = out_packet,
        .iov_len = static_cast<size_t>(len),
    };
    msghdr hdr = {
        .msg_name = &send_ll_addr,
        .msg_namelen = sizeof(send_ll_addr),
        .msg_iov = &iov_out,
        .msg_iovlen = 1,
        .msg_control = nullptr,
        .msg_controllen = 0,
    };
    if (sendmsg(fd, &hdr, 0) < 0) {
      // Ignore ENETDOWN: this can happen if the interface is not yet configured
      if (if_map_ra_.find(target_if) != if_map_ra_.end() && errno != ENETDOWN) {
        PLOG(WARNING) << "sendmsg() failed on interface " << target_if;
      }
    }
  }
}

// static
nd_opt_prefix_info* NDProxy::GetPrefixInfoOption(uint8_t* icmp6,
                                                 size_t icmp6_len) {
  uint8_t* start = reinterpret_cast<uint8_t*>(icmp6);
  uint8_t* end = start + icmp6_len;
  uint8_t* ptr = start + sizeof(nd_router_advert);
  while (ptr + offsetof(nd_opt_hdr, nd_opt_len) < end) {
    nd_opt_hdr* opt = reinterpret_cast<nd_opt_hdr*>(ptr);
    if (opt->nd_opt_len == 0)
      return nullptr;
    ptr += opt->nd_opt_len << 3;  // nd_opt_len is in 8 bytes
    if (ptr > end)
      return nullptr;
    if (opt->nd_opt_type == ND_OPT_PREFIX_INFORMATION &&
        opt->nd_opt_len << 3 == sizeof(nd_opt_prefix_info)) {
      return reinterpret_cast<nd_opt_prefix_info*>(opt);
    }
  }
  return nullptr;
}

// static
const nd_opt_prefix_info* NDProxy::GetPrefixInfoOption(const uint8_t* icmp6,
                                                       size_t icmp6_len) {
  return NDProxy::GetPrefixInfoOption(const_cast<uint8_t*>(icmp6), icmp6_len);
}

void NDProxy::NotifyPacketCallbacks(int recv_ifindex,
                                    const uint8_t* packet,
                                    size_t len) {
  const ip6_hdr* ip6 = reinterpret_cast<const ip6_hdr*>(packet);
  const icmp6_hdr* icmp6 =
      reinterpret_cast<const icmp6_hdr*>(packet + sizeof(ip6_hdr));

  // GuestDiscovery event is triggered whenever an NA advertising global
  // address or an NS with a global source address is received on a downlink.
  const in6_addr* guest_address = nullptr;
  if ((IsGuestInterface(recv_ifindex) ||
       neighbor_monitor_links_.count(recv_ifindex) > 0) &&
      !guest_discovery_handler_.is_null()) {
    if (icmp6->icmp6_type == ND_NEIGHBOR_ADVERT) {
      const nd_neighbor_advert* na =
          reinterpret_cast<const nd_neighbor_advert*>(icmp6);
      guest_address = &(na->nd_na_target);
    } else if (icmp6->icmp6_type == ND_NEIGHBOR_SOLICIT) {
      guest_address = &(ip6->ip6_src);

      // b/187918638: some cellular modems never send proper NS and NA,
      // there is no chance that we get the guest IP as normally from NA.
      // Instead, we have to monitor DAD NS frames and use it as judgement.
      // Notice that since upstream never reply NA, this DAD never fails.
      // b/266514205: extent this workaround to all technologies as we are
      // observing similar behavior in some wifi APs.
      uint8_t zerobuf[sizeof(in6_addr)] = {0};
      // Empty source IP indicates DAD
      if (memcmp(&ip6->ip6_src, zerobuf, sizeof(in6_addr)) == 0) {
        const nd_neighbor_solicit* ns =
            reinterpret_cast<const nd_neighbor_solicit*>(icmp6);
        guest_address = &(ns->nd_ns_target);
      }
    }
  }

  if (guest_address &&
      ((guest_address->s6_addr[0] & 0xe0) == 0x20 ||   // Global Unicast
       (guest_address->s6_addr[0] & 0xfe) == 0xfc)) {  // Unique Local
    guest_discovery_handler_.Run(recv_ifindex, *guest_address);
    VLOG(2) << "GuestDiscovery on interface " << recv_ifindex << ": "
            << IPv6AddressToString(*guest_address);
  }

  // RouterDiscovery event is triggered whenever an RA is received on a uplink.
  if (icmp6->icmp6_type == ND_ROUTER_ADVERT &&
      IsRouterInterface(recv_ifindex) && !router_discovery_handler_.is_null()) {
    const nd_opt_prefix_info* prefix_info = GetPrefixInfoOption(
        reinterpret_cast<const uint8_t*>(icmp6), len - sizeof(ip6_hdr));
    if (prefix_info != nullptr) {
      router_discovery_handler_.Run(recv_ifindex, prefix_info->nd_opt_pi_prefix,
                                    prefix_info->nd_opt_pi_prefix_len);
      VLOG(2) << "RouterDiscovery on interface " << recv_ifindex << ": "
              << IPv6AddressToString(prefix_info->nd_opt_pi_prefix) << "/"
              << prefix_info->nd_opt_pi_prefix_len;
    }
  }
}

void NDProxy::ResolveDestinationMac(const in6_addr& dest_ipv6,
                                    uint8_t* dest_mac) {
  if (memcmp(&dest_ipv6, &kAllNodesMulticastAddress, sizeof(in6_addr)) == 0) {
    memcpy(dest_mac, &kAllNodesMulticastMacAddress, ETHER_ADDR_LEN);
    return;
  }
  if (memcmp(&dest_ipv6, &kAllRoutersMulticastAddress, sizeof(in6_addr)) == 0) {
    memcpy(dest_mac, &kAllRoutersMulticastMacAddress, ETHER_ADDR_LEN);
    return;
  }
  if (memcmp(&dest_ipv6, &kSolicitedNodeMulticastAddressPrefix,
             sizeof(in6_addr) - kSolicitedGroupSuffixLength) == 0) {
    memcpy(dest_mac, &kSolicitedNodeMulticastMacAddressPrefix, ETHER_ADDR_LEN);
    memcpy(dest_mac + ETHER_ADDR_LEN - kSolicitedGroupSuffixLength,
           &dest_ipv6.s6_addr[sizeof(in6_addr) - kSolicitedGroupSuffixLength],
           kSolicitedGroupSuffixLength);
    return;
  }

  MacAddress neighbor_mac;
  if (GetNeighborMac(dest_ipv6, &neighbor_mac)) {
    memcpy(dest_mac, neighbor_mac.data(), ETHER_ADDR_LEN);
    return;
  }

  memcpy(dest_mac, &kZeroMacAddress, ETHER_ADDR_LEN);
}

bool NDProxy::GetLinkLocalAddress(int ifindex, in6_addr* link_local) {
  DCHECK(link_local != nullptr);
  std::ifstream proc_file("/proc/net/if_inet6");
  std::string line;
  while (std::getline(proc_file, line)) {
    // Line format in /proc/net/if_inet6:
    //   address ifindex prefix_len scope flags ifname
    auto tokens = base::SplitString(line, " \t", base::TRIM_WHITESPACE,
                                    base::SPLIT_WANT_NONEMPTY);
    if (tokens[3] != "20") {
      // We are only looking for link local address (scope value == "20")
      continue;
    }
    int line_if_id;
    if (!base::HexStringToInt(tokens[1], &line_if_id) ||
        line_if_id != ifindex) {
      continue;
    }
    std::vector<uint8_t> line_address;
    if (!base::HexStringToBytes(tokens[0], &line_address) ||
        line_address.size() != sizeof(in6_addr)) {
      continue;
    }
    memcpy(link_local, line_address.data(), sizeof(in6_addr));
    return true;
  }
  return false;
}

bool NDProxy::GetLocalMac(int if_id, MacAddress* mac_addr) {
  ifreq ifr = {
      .ifr_ifindex = if_id,
  };
  if (ioctl(dummy_fd_.get(), SIOCGIFNAME, &ifr) < 0) {
    PLOG(ERROR) << "ioctl() failed to get interface name on interface "
                << if_id;
    return false;
  }
  if (ioctl(dummy_fd_.get(), SIOCGIFHWADDR, &ifr) < 0) {
    PLOG(ERROR) << "ioctl() failed to get MAC address on interface " << if_id;
    return false;
  }
  memcpy(mac_addr->data(), ifr.ifr_addr.sa_data, ETHER_ADDR_LEN);
  return true;
}

bool NDProxy::GetNeighborMac(const in6_addr& ipv6_addr, MacAddress* mac_addr) {
  sockaddr_nl kernel = {
      .nl_family = AF_NETLINK,
      .nl_groups = 0,
  };
  struct nl_req {
    nlmsghdr hdr;
    rtgenmsg gen;
  } req = {
      .hdr =
          {
              .nlmsg_len = NLMSG_LENGTH(sizeof(rtgenmsg)),
              .nlmsg_type = RTM_GETNEIGH,
              .nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP,
              .nlmsg_seq = 1,
          },
      .gen =
          {
              .rtgen_family = AF_INET6,
          },
  };
  iovec io_req = {
      .iov_base = &req,
      .iov_len = req.hdr.nlmsg_len,
  };
  msghdr rtnl_req = {
      .msg_name = &kernel,
      .msg_namelen = sizeof(kernel),
      .msg_iov = &io_req,
      .msg_iovlen = 1,
  };
  if (sendmsg(rtnl_fd_.get(), &rtnl_req, 0) < 0) {
    PLOG(ERROR) << "sendmsg() failed on rtnetlink socket";
    return false;
  }

  static constexpr size_t kRtnlReplyBufferSize = 32768;
  char reply_buffer[kRtnlReplyBufferSize];
  iovec io_reply = {
      .iov_base = reply_buffer,
      .iov_len = kRtnlReplyBufferSize,
  };
  msghdr rtnl_reply = {
      .msg_name = &kernel,
      .msg_namelen = sizeof(kernel),
      .msg_iov = &io_reply,
      .msg_iovlen = 1,
  };

  bool any_entry_matched = false;
  bool done = false;
  while (!done) {
    ssize_t len;
    if ((len = recvmsg(rtnl_fd_.get(), &rtnl_reply, 0)) < 0) {
      PLOG(ERROR) << "recvmsg() failed on rtnetlink socket";
      return false;
    }
    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: {
          // Bitmap - 0x1: Found IP match; 0x2: found MAC address;
          uint8_t current_entry_status = 0x0;
          uint8_t current_mac[ETHER_ADDR_LEN];
          ndmsg* nd_msg = reinterpret_cast<ndmsg*>(NLMSG_DATA(msg_ptr));
          rtattr* rt_attr = reinterpret_cast<rtattr*>(RTM_RTA(nd_msg));
          size_t rt_attr_len = RTM_PAYLOAD(msg_ptr);
          for (; RTA_OK(rt_attr, rt_attr_len);
               rt_attr = RTA_NEXT(rt_attr, rt_attr_len)) {
            if (rt_attr->rta_type == NDA_DST &&
                memcmp(&ipv6_addr, RTA_DATA(rt_attr), sizeof(in6_addr)) == 0) {
              current_entry_status |= 0x1;
            } else if (rt_attr->rta_type == NDA_LLADDR) {
              current_entry_status |= 0x2;
              memcpy(current_mac, RTA_DATA(rt_attr), ETHER_ADDR_LEN);
            }
          }
          if (current_entry_status == 0x3) {
            memcpy(mac_addr->data(), current_mac, ETHER_ADDR_LEN);
            any_entry_matched = true;
          }
          break;
        }
        default: {
          LOG(WARNING) << "received unexpected rtnetlink message type "
                       << msg_ptr->nlmsg_type << ", length "
                       << msg_ptr->nlmsg_len;
          break;
        }
      }
    }
  }
  return any_entry_matched;
}

void NDProxy::RegisterOnGuestIpDiscoveryHandler(
    base::RepeatingCallback<void(int, const in6_addr&)> handler) {
  guest_discovery_handler_ = std::move(handler);
}

void NDProxy::RegisterOnRouterDiscoveryHandler(
    base::RepeatingCallback<void(int, const in6_addr&, int)> handler) {
  router_discovery_handler_ = std::move(handler);
}

NDProxy::interface_mapping* NDProxy::MapForType(uint8_t type) {
  switch (type) {
    case ND_ROUTER_SOLICIT:
      return &if_map_rs_;
    case ND_ROUTER_ADVERT:
      return &if_map_ra_;
    case ND_NEIGHBOR_SOLICIT:
      return &if_map_ns_;
    case ND_NEIGHBOR_ADVERT:
      return &if_map_na_;
    default:
      LOG(DFATAL) << "Attempt to get interface map on illegal icmpv6 type "
                  << static_cast<int>(type);
      return nullptr;
  }
}

void NDProxy::StartRSRAProxy(int if_id_upstream,
                             int if_id_downstream,
                             bool modify_router_address) {
  VLOG(1) << "StartRARSProxy(" << if_id_upstream << ", " << if_id_downstream
          << (modify_router_address ? ", modify_router_address)" : ")");
  if_map_ra_[if_id_upstream].insert(if_id_downstream);
  if_map_rs_[if_id_downstream].insert(if_id_upstream);
  if (modify_router_address) {
    modify_ra_uplinks_.insert(if_id_upstream);
  }
  downlink_link_local_[if_id_downstream] = in6_addr{};
  if (!GetLinkLocalAddress(if_id_downstream,
                           &downlink_link_local_[if_id_downstream])) {
    LOG(WARNING) << "Cannot find a link local address on interface "
                 << if_id_downstream;
  }
}

void NDProxy::StartNSNAProxy(int if_id_na_side, int if_id_ns_side) {
  VLOG(1) << "StartNSNAProxy(" << if_id_na_side << ", " << if_id_ns_side << ")";
  if_map_na_[if_id_na_side].insert(if_id_ns_side);
  if_map_ns_[if_id_ns_side].insert(if_id_na_side);
}

void NDProxy::StopProxy(int if_id1, int if_id2) {
  VLOG(1) << "StopProxy(" << if_id1 << ", " << if_id2 << ")";
  auto remove_pair = [if_id1, if_id2](interface_mapping& mapping) {
    mapping[if_id1].erase(if_id2);
    if (mapping[if_id1].empty()) {
      mapping.erase(if_id1);
    }
    mapping[if_id2].erase(if_id1);
    if (mapping[if_id2].empty()) {
      mapping.erase(if_id2);
    }
  };
  remove_pair(if_map_ra_);
  remove_pair(if_map_rs_);
  remove_pair(if_map_na_);
  remove_pair(if_map_ns_);
  if (!IsRouterInterface(if_id1)) {
    modify_ra_uplinks_.erase(if_id1);
  }
  if (!IsRouterInterface(if_id2)) {
    modify_ra_uplinks_.erase(if_id2);
  }
}

void NDProxy::StartNeighborMonitor(int if_id) {
  neighbor_monitor_links_.insert(if_id);
}

void NDProxy::StopNeighborMonitor(int if_id) {
  neighbor_monitor_links_.erase(if_id);
}

bool NDProxy::IsGuestInterface(int ifindex) {
  return if_map_rs_.find(ifindex) != if_map_rs_.end();
}

bool NDProxy::IsRouterInterface(int ifindex) {
  return if_map_ra_.find(ifindex) != if_map_ra_.end();
}

NDProxyDaemon::NDProxyDaemon(base::ScopedFD control_fd)
    : msg_dispatcher_(std::make_unique<MessageDispatcher<SubprocessMessage>>(
          std::move(control_fd))) {}

NDProxyDaemon::~NDProxyDaemon() {}

int NDProxyDaemon::OnInit() {
  // Prevent the main process from sending us any signals.
  if (setsid() < 0) {
    PLOG(ERROR) << "Failed to created a new session with setsid: exiting";
    return EX_OSERR;
  }

  EnterChildProcessJail();

  // Register control fd callbacks
  if (msg_dispatcher_) {
    msg_dispatcher_->RegisterFailureHandler(base::BindRepeating(
        &NDProxyDaemon::OnParentProcessExit, weak_factory_.GetWeakPtr()));
    msg_dispatcher_->RegisterMessageHandler(base::BindRepeating(
        &NDProxyDaemon::OnControlMessage, weak_factory_.GetWeakPtr()));
  }

  // Initialize NDProxy and register guest IP discovery callback
  if (!proxy_.Init()) {
    PLOG(ERROR) << "Failed to initialize NDProxy internal state";
    return EX_OSERR;
  }
  proxy_.RegisterOnGuestIpDiscoveryHandler(base::BindRepeating(
      &NDProxyDaemon::OnGuestIpDiscovery, weak_factory_.GetWeakPtr()));
  proxy_.RegisterOnRouterDiscoveryHandler(base::BindRepeating(
      &NDProxyDaemon::OnRouterDiscovery, weak_factory_.GetWeakPtr()));

  // Initialize data fd
  fd_ = NDProxy::PreparePacketSocket();
  if (!fd_.is_valid()) {
    return EX_OSERR;
  }

  // Start watching on data fd
  watcher_ = base::FileDescriptorWatcher::WatchReadable(
      fd_.get(), base::BindRepeating(&NDProxyDaemon::OnDataSocketReadReady,
                                     weak_factory_.GetWeakPtr()));
  LOG(INFO) << "Started watching on packet fd...";

  return Daemon::OnInit();
}

void NDProxyDaemon::OnDataSocketReadReady() {
  proxy_.ReadAndProcessOnePacket(fd_.get());
}

void NDProxyDaemon::OnParentProcessExit() {
  LOG(ERROR) << "Quitting because the parent process died";
  Quit();
}

void NDProxyDaemon::OnControlMessage(const SubprocessMessage& root_msg) {
  if (!root_msg.has_control_message() ||
      !root_msg.control_message().has_ndproxy_control()) {
    LOG(ERROR) << "Unexpected message type";
    return;
  }
  const NDProxyControlMessage& msg =
      root_msg.control_message().ndproxy_control();
  VLOG(4) << "Received NDProxyControlMessage: " << msg.type() << ": "
          << msg.if_id_primary() << "<->" << msg.if_id_secondary();
  switch (msg.type()) {
    case NDProxyControlMessage::START_NS_NA: {
      proxy_.StartNSNAProxy(msg.if_id_primary(), msg.if_id_secondary());
      proxy_.StartNSNAProxy(msg.if_id_secondary(), msg.if_id_primary());
      break;
    }
    case NDProxyControlMessage::START_NS_NA_RS_RA: {
      proxy_.StartNSNAProxy(msg.if_id_primary(), msg.if_id_secondary());
      proxy_.StartNSNAProxy(msg.if_id_secondary(), msg.if_id_primary());
      proxy_.StartRSRAProxy(msg.if_id_primary(), msg.if_id_secondary());
      break;
    }
    case NDProxyControlMessage::START_NS_NA_RS_RA_MODIFYING_ROUTER_ADDRESS: {
      // TODO(taoyl): therotically whe should be able to stop proxying NS from
      // downlink to uplink and NA from uplink to downlink as we set prefix to
      // be not ONLINK. However, Android ignores the ONLINK flag and always add
      // a local subnet route when receiving a prefix [1]. Consider addressing
      // this in Android so we can remove the first line below.
      // [1] LinkProperties::ensureDirectlyConnectedRoutes()
      proxy_.StartNSNAProxy(msg.if_id_primary(), msg.if_id_secondary());
      proxy_.StartNSNAProxy(msg.if_id_secondary(), msg.if_id_primary());
      proxy_.StartRSRAProxy(msg.if_id_primary(), msg.if_id_secondary(), true);
      break;
    }
    case NDProxyControlMessage::STOP_PROXY: {
      proxy_.StopProxy(msg.if_id_primary(), msg.if_id_secondary());
      break;
    }
    case NDProxyControlMessage::START_NEIGHBOR_MONITOR: {
      proxy_.StartNeighborMonitor(msg.if_id_primary());
      break;
    }
    case NDProxyControlMessage::STOP_NEIGHBOR_MONITOR: {
      proxy_.StopNeighborMonitor(msg.if_id_primary());
      break;
    }
    case NDProxyControlMessage::UNKNOWN:
    default:
      NOTREACHED();
  }
}

void NDProxyDaemon::OnGuestIpDiscovery(int if_id, const in6_addr& ip6addr) {
  if (!msg_dispatcher_) {
    return;
  }
  NeighborDetectedSignal msg;
  msg.set_if_id(if_id);
  msg.set_ip(&ip6addr, sizeof(in6_addr));
  NDProxySignalMessage nm;
  *nm.mutable_neighbor_detected_signal() = msg;
  FeedbackMessage fm;
  *fm.mutable_ndproxy_signal() = nm;
  SubprocessMessage root_m;
  *root_m.mutable_feedback_message() = fm;
  msg_dispatcher_->SendMessage(root_m);
}

void NDProxyDaemon::OnRouterDiscovery(int if_id,
                                      const in6_addr& prefix_addr,
                                      int prefix_len) {
  if (!msg_dispatcher_) {
    return;
  }
  RouterDetectedSignal msg;
  msg.set_if_id(if_id);
  msg.set_ip(&prefix_addr, sizeof(in6_addr));
  msg.set_prefix_len(prefix_len);
  NDProxySignalMessage nm;
  *nm.mutable_router_detected_signal() = msg;
  FeedbackMessage fm;
  *fm.mutable_ndproxy_signal() = nm;
  SubprocessMessage root_m;
  *root_m.mutable_feedback_message() = fm;
  msg_dispatcher_->SendMessage(root_m);
}

}  // namespace patchpanel
