// Copyright 2016 The Fuchsia 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 "src/bringup/bin/netsvc/inet6.h"

#include <arpa/inet.h>
#include <lib/zircon-internal/fnv1hash.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <zircon/assert.h>
#include <zircon/syscalls.h>

#include <mutex>
#include <optional>

#include "src/bringup/bin/netsvc/netifc-discover.h"
#include "src/bringup/bin/netsvc/netifc.h"

#define REPORT_BAD_PACKETS 0

#if REPORT_BAD_PACKETS
#define BAD_PACKET(reason) report_bad_packet(NULL, reason)
#define BAD_PACKET_FROM(addr, reason) report_bad_packet(addr, reason)
#else
#define BAD_PACKET(reason)
#define BAD_PACKET_FROM(addr, reason)
#endif

// useful addresses
const ip6_addr_t ip6_ll_all_nodes = {
    .u8 = {0xFF, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
};

namespace {

// Convert MAC Address to IPv6 Unique Local Address.
ip6_addr_t ula6addr_from_mac(const mac_addr_t& mac) {
  return {.u8 = {
              0xFD,
              mac.x[1],
              mac.x[2],
              mac.x[3],
              mac.x[4],
              mac.x[5],
              0,
              0,
              0,
              0,
              0,
              0,
              // We need these down here to keep us matching the snmaddr.
              mac.x[3],
              mac.x[4],
              mac.x[5],
          }};
}

// Convert MAC Address to IPv6 Link Local Address
// aa:bb:cc:dd:ee:ff => FF80::aabb:cc4D:FEdd:eeff
// bit 2 (U/L) of the mac is inverted
ip6_addr_t ll6addr_from_mac(const mac_addr_t& mac) {
  return {.u8 = {
              0xFE,
              0x80,
              0,
              0,
              0,
              0,
              0,
              0,
              // Flip the globally-unique bit from the MAC
              // since the sense of this is backwards in
              // IPv6 Interface Identifiers.
              static_cast<uint8_t>(mac.x[0] ^ 2),
              mac.x[1],
              mac.x[2],
              0xFE,
              0xFE,
              mac.x[3],
              mac.x[4],
              mac.x[5],
          }};
}

// Convert MAC Address to IPv6 Solicit Neighbor Multicast Address
// aa:bb:cc:dd:ee:ff -> FF02::1:FFdd:eeff
ip6_addr_t snmaddr_from_mac(const mac_addr_t& mac) {
  return {.u8 = {
              0xFF,
              0x02,
              0,
              0,
              0,
              0,
              0,
              0,
              0,
              0,
              0,
              0x01,
              0xFF,
              mac.x[3],
              mac.x[4],
              mac.x[5],
          }};
}

// Convert IPv6 Multicast Address to Ethernet Multicast Address
mac_addr_t multicast_from_ip6(const ip6_addr_t& ip6) {
  return {.x = {
              0x33,
              0x33,
              ip6.u8[12],
              ip6.u8[13],
              ip6.u8[14],
              ip6.u8[15],
          }};
}

// cache for the last source addresses we've seen
#define MAC_TBL_BUCKETS 256
#define MAC_TBL_ENTRIES 5
struct ip6_to_mac_t {
  zx_time_t last_used;  // A value of 0 indicates "unused".
  ip6_addr_t ip6;
  mac_addr_t mac;
};

uint8_t mac_cache_hash(const ip6_addr_t& ip) {
  static_assert(MAC_TBL_BUCKETS == 256, "hash algorithms must be updated");
  uint32_t hash = fnv1a32(&ip, sizeof(ip));
  return ((hash >> 8) ^ hash) & 0xff;
}

// ip6 stack configuration.
struct Ip6Stack {
  const mac_addr_t ll_mac_addr;
  const ip6_addr_t ll_ip6_addr;
  const ip6_addr_t ula_ip6_addr;
  const ip6_addr_t snm_ip6_addr;
  const mac_addr_t snm_mac_addr;
  ip6_to_mac_t mac_lookup_tbl[MAC_TBL_BUCKETS][MAC_TBL_ENTRIES] __TA_GUARDED(mac_cache_lock);
  std::mutex mac_cache_lock;

  Ip6Stack(mac_addr_t macaddr, bool quiet)
      : ll_mac_addr(macaddr),
        ll_ip6_addr(ll6addr_from_mac(macaddr)),
        ula_ip6_addr(ula6addr_from_mac(macaddr)),
        snm_ip6_addr(snmaddr_from_mac(macaddr)),
        snm_mac_addr(multicast_from_ip6(snm_ip6_addr)) {
    size_t bucket_ndx;
    size_t entry_ndx;
    for (bucket_ndx = 0; bucket_ndx < MAC_TBL_BUCKETS; bucket_ndx++) {
      for (entry_ndx = 0; entry_ndx < MAC_TBL_ENTRIES; entry_ndx++) {
        mac_lookup_tbl[bucket_ndx][entry_ndx].last_used = 0;
      }
    }

    eth_add_mcast_filter(&snm_mac_addr);

    mac_addr_t all = multicast_from_ip6(ip6_ll_all_nodes);
    eth_add_mcast_filter(&all);

    if (!quiet) {
      printf("macaddr: %02x:%02x:%02x:%02x:%02x:%02x\n", ll_mac_addr.x[0], ll_mac_addr.x[1],
             ll_mac_addr.x[2], ll_mac_addr.x[3], ll_mac_addr.x[4], ll_mac_addr.x[5]);

      char tmp[INET6_ADDRSTRLEN];
      printf("ip6addr (LL) : %s\n", inet_ntop(AF_INET6, &ll_ip6_addr, tmp, sizeof(tmp)));
      printf("ip6addr (ULA): %s\n", inet_ntop(AF_INET6, &ula_ip6_addr, tmp, sizeof(tmp)));
      printf("snmaddr: %s\n", inet_ntop(AF_INET6, &snm_ip6_addr, tmp, sizeof(tmp)));
    }
  }

  // Find the MAC corresponding to a given IP6 address
  std::optional<mac_addr_t> ResolveIp6(const ip6_addr_t& ip) {
    // Multicast addresses are a simple transform
    if (ip.u8[0] == 0xFF) {
      return multicast_from_ip6(ip);
    }

    uint8_t key = mac_cache_hash(ip);

    std::lock_guard lock(mac_cache_lock);
    for (size_t entry_ndx = 0; entry_ndx < MAC_TBL_ENTRIES; entry_ndx++) {
      ip6_to_mac_t* entry = &mac_lookup_tbl[key][entry_ndx];

      if (entry->last_used == 0) {
        // All out of entries
        break;
      }

      if (entry->ip6 == ip) {
        // Match!
        return entry->mac;
      }
    }
    return std::nullopt;
  }

  // If ip is not in cache already, add it. Otherwise, update its last access time.
  void SaveMacCache(const mac_addr_t& mac, const ip6_addr_t& ip) {
    uint8_t key = mac_cache_hash(ip);

    std::lock_guard lock(mac_cache_lock);
    ip6_to_mac_t* oldest_entry = &mac_lookup_tbl[key][0];
    zx_time_t curr_time = zx_clock_get_monotonic();

    for (size_t entry_ndx = 0; entry_ndx < MAC_TBL_ENTRIES; entry_ndx++) {
      ip6_to_mac_t* entry = &mac_lookup_tbl[key][entry_ndx];

      if (entry->last_used == 0) {
        // Unused entry -- fill it
        oldest_entry = entry;
        break;
      }

      if (entry->ip6 == ip) {
        // Match found.
        // Update mac and last seen.
        entry->mac = mac;
        entry->last_used = curr_time;
        return;
      }

      if ((entry_ndx > 0) && (entry->last_used < oldest_entry->last_used)) {
        oldest_entry = entry;
      }
    }

    // No available entry found -- replace oldest.
    *oldest_entry = {
        .last_used = curr_time,
        .ip6 = ip,
        .mac = mac,
    };
  }

  std::optional<std::tuple<uint8_t*, uint16_t>> PrepareIp6Packet(uint8_t* data,
                                                                 const ip6_addr_t& saddr,
                                                                 const ip6_addr_t& daddr,
                                                                 size_t length, uint8_t type) {
    std::optional mac = ResolveIp6(daddr);
    if (!mac.has_value()) {
      printf("%s: Failed to resolve ipv6 addr\n", __func__);
      return std::nullopt;
    }

    mac_addr_t& dmac = mac.value();
    // Ethernet header.
    data = std::copy(std::begin(dmac.x), std::end(dmac.x), data);
    data = std::copy(std::begin(ll_mac_addr.x), std::end(ll_mac_addr.x), data);
    *data++ = (ETH_IP6 >> 8) & 0xFF;
    *data++ = ETH_IP6 & 0xFF;
    // ip6 header.
    const ip6_hdr hdr = {
        .ver_tc_flow = 0x60,  // v=6, tc=0, flow=0
        .length = htons(length),
        .next_header = type,
        .hop_limit = 255,
        .src = saddr,
        .dst = daddr,
    };
    data = std::copy_n(reinterpret_cast<const uint8_t*>(&hdr), sizeof(hdr), data);
    return std::make_tuple(data, ip6_header_checksum(hdr, type));
  }

  static constexpr size_t kIcmp6MaxPayload = ETH_MTU - ETH_HDR_LEN - IP6_HDR_LEN;

  zx_status_t SendIcmp6(const void* data, size_t length, const ip6_addr_t& saddr,
                        const ip6_addr_t& daddr, bool block) {
    if (length > kIcmp6MaxPayload) {
      return ZX_ERR_INVALID_ARGS;
    }

    zx::result status = DeviceBuffer::Get(ETH_MTU, block);
    if (status.is_error()) {
      return status.status_value();
    }
    DeviceBuffer& buffer = status.value();

    std::optional prepared =
        PrepareIp6Packet(buffer.data().data(), saddr, daddr, length, HDR_ICMP6);
    if (!prepared.has_value()) {
      return ZX_ERR_INVALID_ARGS;
    }
    auto [body, checksum] = prepared.value();
    std::copy_n(static_cast<const uint8_t*>(data), length, body);
    checksum = ip6_finalize_checksum(checksum, data, length);
    std::copy_n(reinterpret_cast<const uint8_t*>(&checksum), sizeof(checksum),
                body + offsetof(icmp6_hdr_t, checksum));
    return buffer.Send(ETH_HDR_LEN + IP6_HDR_LEN + length);
  }
};

std::optional<Ip6Stack> g_state;

}  // namespace

void ip6_init(mac_addr_t macaddr, bool quiet) { g_state.emplace(macaddr, quiet); }

#define UDP6_MAX_PAYLOAD (ETH_MTU - ETH_HDR_LEN - IP6_HDR_LEN - UDP_HDR_LEN)

zx_status_t udp6_send(const void* data, size_t dlen, const ip6_addr_t* daddr, uint16_t dport,
                      uint16_t sport, bool block) {
  if (dlen > UDP6_MAX_PAYLOAD)
    return ZX_ERR_INVALID_ARGS;
  size_t length = dlen + UDP_HDR_LEN;
  zx::result status = DeviceBuffer::Get(ETH_MTU, block);
  if (status.is_error()) {
    printf("%s: DeviceBuffer::Get failed: %s\n", __func__, status.status_string());
    return status.status_value();
  }
  DeviceBuffer& buffer = status.value();

  ZX_ASSERT(g_state.has_value());
  Ip6Stack& stack_state = g_state.value();
  const bool ula = (*daddr).u8[0] == stack_state.ula_ip6_addr.u8[0];
  const ip6_addr_t& saddr = ula ? stack_state.ula_ip6_addr : stack_state.ll_ip6_addr;

  std::optional prepared =
      stack_state.PrepareIp6Packet(buffer.data().data(), saddr, *daddr, length, HDR_UDP);
  if (!prepared.has_value()) {
    return ZX_ERR_INVALID_ARGS;
  }
  auto [body, checksum] = prepared.value();
  const udp_hdr_t udp = {
      .src_port = htons(sport),
      .dst_port = htons(dport),
      .length = htons(length),
      .checksum = 0,
  };
  uint8_t* payload = std::copy_n(reinterpret_cast<const uint8_t*>(&udp), sizeof(udp), body);
  std::copy_n(static_cast<const uint8_t*>(data), dlen, payload);
  checksum = ip6_finalize_checksum(checksum, body, sizeof(udp) + dlen);
  // Do not transmit all zeroes checksum, replace with its one's complement.
  //
  // https://datatracker.ietf.org/doc/html/rfc768
  if (checksum == 0) {
    checksum = 0xFFFF;
  }
  std::copy_n(reinterpret_cast<const uint8_t*>(&checksum), sizeof(checksum),
              body + offsetof(udp_hdr_t, checksum));
  zx_status_t ret = buffer.Send(ETH_HDR_LEN + IP6_HDR_LEN + length);
  if (ret != ZX_OK) {
    printf("%s: buffer.Send(%zu) failed: %s\n", __func__, ETH_HDR_LEN + IP6_HDR_LEN + length,
           zx_status_get_string(ret));
  }
  return ret;
}

#if REPORT_BAD_PACKETS
static void report_bad_packet(ip6_addr_t* ip6_addr, const char* msg) {
  if (ip6_addr == NULL) {
    printf("inet6: dropping packet: %s\n", msg);
  } else {
    char addr_str[INET6_ADDRSTRLEN];
    printf("inet6: dropping packet from %s: %s\n",
           inet_ntop(AF_INET6, ip6_addr, addr_str, sizeof(addr_str)), msg);
  }
}
#endif

// This is the cornerstone of SLAAC networking. This will have connected clients
// add an ipv6 address that can talk to our ULA address.
void send_router_advertisement() {
  // This struct is not a generic advert packet, it is specific to sending a
  // single prefix, if you want to do more look at the spec and extend.
  static struct {
    icmp6_hdr_t hdr;
    uint8_t hop_limit;  // 0 means this router has no opinion.
    uint8_t autoconf_flags;
    uint16_t router_lifetime_ms;   // 0 means don't use this router.
    uint32_t reachable_time_ms;    // 0 means this router has no opinion.
    uint32_t retransmit_timer_ms;  // 0 means this router has no opinion.
    uint8_t option_type;           // We are using a prefix option of 3
    uint8_t option_length;         // length is units of 8 bytes (for some reason).
    uint8_t prefix_length;         // valid bits of prefix.
    uint8_t prefix_flags;
    uint32_t prefix_lifetime_s;
    uint32_t prefix_pref_lifetime_s;
    uint32_t reserved;
    uint8_t prefix[16];  // prefix for all devices on this link to communicate.
  } __attribute__((packed)) msg;

  memset(&msg, 0, sizeof(msg));

  msg.hdr.type = ICMP6_NDP_R_ADVERTISE;
  msg.hdr.code = 0;
  msg.hdr.checksum = 0;
  msg.option_type = 3;                      // Prefix option.
  msg.option_length = 4;                    // From spec, length is in 64bit units.
  msg.prefix_length = 64;                   // 64 leading bits of address are all we care about.
  msg.prefix_flags = 0b11000000;            // valid on this link and used for autoconf.
  msg.prefix_lifetime_s = 0xFFFFFFFF;       // valid while this link is up.
  msg.prefix_pref_lifetime_s = 0xFFFFFFFF;  // preferred while this link is up.

  ZX_ASSERT(g_state.has_value());
  Ip6Stack& stack_state = g_state.value();

  // Copy first 8 bytes (64bits) as our prefix, rest will be 0.
  memcpy(msg.prefix, &stack_state.ula_ip6_addr, 8);

  // We need to send this on the link-local address because nothing is talking
  // to the ula address yet.
  zx_status_t status =
      stack_state.SendIcmp6(&msg, sizeof(msg), stack_state.ll_ip6_addr, ip6_ll_all_nodes, false);
  if (status == ZX_ERR_SHOULD_WAIT) {
    printf("inet6: No buffers available, dropping RA\n");
  } else if (status < 0) {
    printf("inet6: Failed to send RA (err = %d)\n", status);
  }
}

void udp6_recv_internal(async_dispatcher_t* dispatcher, ip6_hdr_t* ip, void* _data, size_t len) {
  udp_hdr_t* udp = static_cast<udp_hdr_t*>(_data);
  uint16_t sum, n;

  if (unlikely(len < UDP_HDR_LEN)) {
    BAD_PACKET_FROM(&ip->src, "invalid header in UDP packet");
    return;
  }
  if (unlikely(udp->checksum == 0)) {
    BAD_PACKET_FROM(&ip->src, "missing checksum in UDP packet");
    return;
  }
  if (udp->checksum == 0xFFFF)
    udp->checksum = 0;

  sum = ip6_finalize_checksum(ip6_header_checksum(*ip, HDR_UDP), udp, len);
  if (unlikely(sum != 0)) {
    BAD_PACKET_FROM(&ip->src, "incorrect checksum in UDP packet");
    return;
  }

  n = ntohs(udp->length);
  if (unlikely(n < UDP_HDR_LEN)) {
    BAD_PACKET_FROM(&ip->src, "UDP length too short");
    return;
  }
  if (unlikely(n > len)) {
    BAD_PACKET_FROM(&ip->src, "UDP length too long");
    return;
  }
  len = n - UDP_HDR_LEN;

  udp6_recv(dispatcher, static_cast<uint8_t*>(_data) + UDP_HDR_LEN, len, &ip->dst,
            ntohs(udp->dst_port), &ip->src, ntohs(udp->src_port));
}

void icmp6_recv(ip6_hdr_t* ip, void* _data, size_t len) {
  icmp6_hdr_t* icmp = static_cast<icmp6_hdr_t*>(_data);
  uint16_t sum;

  sum = ip6_finalize_checksum(ip6_header_checksum(*ip, HDR_ICMP6), icmp, len);
  if (unlikely(sum != 0)) {
    BAD_PACKET_FROM(&ip->src, "incorrect checksum in ICMP packet");
    return;
  }

  ZX_ASSERT(g_state.has_value());
  Ip6Stack& stack_state = g_state.value();

  zx_status_t status;
  if (icmp->type == ICMP6_NDP_N_SOLICIT) {
    ndp_n_hdr_t* ndp = static_cast<ndp_n_hdr_t*>(_data);
    struct {
      ndp_n_hdr_t hdr;
      uint8_t opt[8];
    } msg;

    if (unlikely(len < sizeof(ndp_n_hdr_t))) {
      BAD_PACKET_FROM(&ip->src, "bogus NDP message");
      return;
    }
    if (unlikely(ndp->code != 0)) {
      BAD_PACKET_FROM(&ip->src, "bogus NDP code");
      return;
    }

    // Ignore the neighbor solicitation if it is targeting another node, as per
    // RFC 4861 section 7.2.3.
    {
      const ip6_addr_t& ndp_target = *reinterpret_cast<ip6_addr_t*>(ndp->target);
      if (ndp_target != stack_state.ll_ip6_addr && ndp_target != stack_state.ula_ip6_addr) {
        return;
      }
    }

    msg.hdr.type = ICMP6_NDP_N_ADVERTISE;
    msg.hdr.code = 0;
    msg.hdr.checksum = 0;
    msg.hdr.flags = 0x60;  // (S)olicited and (O)verride flags
    memcpy(msg.hdr.target, ndp->target, sizeof(ip6_addr_t));
    msg.opt[0] = NDP_N_TGT_LL_ADDR;
    msg.opt[1] = 1;
    memcpy(msg.opt + 2, &stack_state.ll_mac_addr, ETH_ADDR_LEN);

    // If the target was on the ula network, respond from it.
    // Otherwise respond from the ll address.
    const bool ula = ndp->target[0] == stack_state.ula_ip6_addr.u8[0];
    const ip6_addr_t& saddr = ula ? stack_state.ula_ip6_addr : stack_state.ll_ip6_addr;

    status = stack_state.SendIcmp6(&msg, sizeof(msg), saddr, ip->src, false);
  } else if (icmp->type == ICMP6_ECHO_REQUEST) {
    icmp->checksum = 0;
    icmp->type = ICMP6_ECHO_REPLY;

    // If the target was on the ULA network, respond from it.
    // Otherwise respond from the ll address.
    const bool ula = ip->dst == stack_state.ula_ip6_addr;
    const ip6_addr_t& saddr = ula ? stack_state.ula_ip6_addr : stack_state.ll_ip6_addr;

    status = stack_state.SendIcmp6(_data, len, saddr, ip->src, false);
  } else {
    // Ignore
    return;
  }
  if (status == ZX_ERR_SHOULD_WAIT) {
    printf("inet6: No buffers available, dropping ICMP response\n");
  } else if (status < 0) {
    printf("inet6: Failed to send ICMP response (err = %d)\n", status);
  }
}

void eth_recv(async_dispatcher_t* dispatcher, void* _data, size_t len) {
  uint8_t* data = static_cast<uint8_t*>(_data);
  uint32_t n;

  if (unlikely(len < (ETH_HDR_LEN + IP6_HDR_LEN))) {
    BAD_PACKET("bogus header length");
    return;
  }
  if (data[12] != (ETH_IP6 >> 8))
    return;
  if (data[13] != (ETH_IP6 & 0xFF))
    return;

  // Copy IP header to prevent misaligned access.
  ip6_hdr_t ip;
  std::copy_n(data + ETH_HDR_LEN, IP6_HDR_LEN, reinterpret_cast<uint8_t*>(&ip));
  data += (ETH_HDR_LEN + IP6_HDR_LEN);
  len -= (ETH_HDR_LEN + IP6_HDR_LEN);

  // Require v6.
  if (unlikely((ip.ver_tc_flow & 0xF0) != 0x60)) {
    BAD_PACKET("unknown IP6 version");
    return;
  }

  // Ensure length is in bounds.
  n = ntohs(ip.length);
  if (unlikely(n > len)) {
    BAD_PACKET("IP6 length mismatch");
    return;
  }

  ZX_ASSERT(g_state.has_value());
  Ip6Stack& stack_state = g_state.value();

  // Ignore any trailing data in the ethernet frame.
  len = n;
  // Require that we are the destination.
  if (ip.dst != stack_state.ll_ip6_addr && ip.dst != stack_state.snm_ip6_addr &&
      ip.dst != ip6_ll_all_nodes && ip.dst != stack_state.ula_ip6_addr) {
    return;
  }

  // stash the sender's info to simplify replies
  mac_addr& mac = *reinterpret_cast<mac_addr*>(static_cast<uint8_t*>(_data) + ETH_ADDR_LEN);
  stack_state.SaveMacCache(mac, ip.src);

  switch (ip.next_header) {
    case HDR_ICMP6:
      icmp6_recv(&ip, data, len);
      break;
    case HDR_UDP:
      udp6_recv_internal(dispatcher, &ip, data, len);
      break;
    default:
      // do nothing
      break;
  }
}
