// Copyright (c) 2019 The Chromium 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 "net/third_party/quiche/src/quic/qbone/qbone_packet_processor.h"

#include <cstring>

#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_endian.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
#include "net/third_party/quiche/src/quic/qbone/platform/icmp_packet.h"
#include "net/third_party/quiche/src/quic/qbone/platform/internet_checksum.h"
#include "net/third_party/quiche/src/quic/qbone/platform/tcp_packet.h"

namespace {

constexpr size_t kIPv6AddressSize = 16;
constexpr size_t kIPv6MinPacketSize = 1280;
constexpr size_t kIcmpTtl = 64;
constexpr size_t kICMPv6DestinationUnreachableDueToSourcePolicy = 5;

}  // namespace

namespace quic {

const QuicIpAddress QbonePacketProcessor::kInvalidIpAddress =
    QuicIpAddress::Any6();

QbonePacketProcessor::QbonePacketProcessor(QuicIpAddress self_ip,
                                           QuicIpAddress client_ip,
                                           size_t client_ip_subnet_length,
                                           OutputInterface* output,
                                           StatsInterface* stats)
    : client_ip_(client_ip),
      output_(output),
      stats_(stats),
      filter_(new Filter) {
  memcpy(self_ip_.s6_addr, self_ip.ToPackedString().data(), kIPv6AddressSize);
  DCHECK_LE(client_ip_subnet_length, kIPv6AddressSize * 8);
  client_ip_subnet_length_ = client_ip_subnet_length;

  DCHECK(IpAddressFamily::IP_V6 == self_ip.address_family());
  DCHECK(IpAddressFamily::IP_V6 == client_ip.address_family());
  DCHECK(self_ip != kInvalidIpAddress);
}

QbonePacketProcessor::OutputInterface::~OutputInterface() {}
QbonePacketProcessor::StatsInterface::~StatsInterface() {}
QbonePacketProcessor::Filter::~Filter() {}

QbonePacketProcessor::ProcessingResult
QbonePacketProcessor::Filter::FilterPacket(Direction direction,
                                           QuicStringPiece full_packet,
                                           QuicStringPiece payload,
                                           icmp6_hdr* icmp_header,
                                           OutputInterface* output) {
  return ProcessingResult::OK;
}

void QbonePacketProcessor::ProcessPacket(string* packet, Direction direction) {
  if (QUIC_PREDICT_FALSE(!IsValid())) {
    QUIC_BUG << "QuicPacketProcessor is invoked in an invalid state.";
    stats_->OnPacketDroppedSilently(direction);
    return;
  }

  uint8_t transport_protocol;
  char* transport_data;
  icmp6_hdr icmp_header;
  memset(&icmp_header, 0, sizeof(icmp_header));
  ProcessingResult result = ProcessIPv6HeaderAndFilter(
      packet, direction, &transport_protocol, &transport_data, &icmp_header);

  switch (result) {
    case ProcessingResult::OK:
      switch (direction) {
        case Direction::FROM_CLIENT:
          output_->SendPacketToNetwork(*packet);
          break;
        case Direction::FROM_NETWORK:
          output_->SendPacketToClient(*packet);
          break;
      }
      stats_->OnPacketForwarded(direction);
      break;
    case ProcessingResult::SILENT_DROP:
      stats_->OnPacketDroppedSilently(direction);
      break;
    case ProcessingResult::DEFER:
      stats_->OnPacketDeferred(direction);
      break;
    case ProcessingResult::ICMP:
      SendIcmpResponse(&icmp_header, *packet, direction);
      stats_->OnPacketDroppedWithIcmp(direction);
      break;
    case ProcessingResult::ICMP_AND_TCP_RESET:
      SendIcmpResponse(&icmp_header, *packet, direction);
      stats_->OnPacketDroppedWithIcmp(direction);
      SendTcpReset(*packet, direction);
      stats_->OnPacketDroppedWithTcpReset(direction);
      break;
  }
}

QbonePacketProcessor::ProcessingResult
QbonePacketProcessor::ProcessIPv6HeaderAndFilter(string* packet,
                                                 Direction direction,
                                                 uint8_t* transport_protocol,
                                                 char** transport_data,
                                                 icmp6_hdr* icmp_header) {
  ProcessingResult result = ProcessIPv6Header(
      packet, direction, transport_protocol, transport_data, icmp_header);

  if (result == ProcessingResult::OK) {
    char* packet_data = &*packet->begin();
    size_t header_size = *transport_data - packet_data;
    // Sanity-check the bounds.
    if (packet_data >= *transport_data || header_size > packet->size() ||
        header_size < kIPv6HeaderSize) {
      QUIC_BUG << "Invalid pointers encountered in "
                  "QbonePacketProcessor::ProcessPacket.  Dropping the packet";
      return ProcessingResult::SILENT_DROP;
    }

    result = filter_->FilterPacket(
        direction, *packet,
        QuicStringPiece(*transport_data, packet->size() - header_size),
        icmp_header, output_);
  }

  // Do not send ICMP error messages in response to ICMP errors.
  if (result == ProcessingResult::ICMP) {
    const uint8_t* header = reinterpret_cast<const uint8_t*>(packet->data());

    constexpr size_t kIPv6NextHeaderOffset = 6;
    constexpr size_t kIcmpMessageTypeOffset = kIPv6HeaderSize + 0;
    constexpr size_t kIcmpMessageTypeMaxError = 127;
    if (
        // Check size.
        packet->size() >= (kIPv6HeaderSize + kICMPv6HeaderSize) &&
        // Check that the packet is in fact ICMP.
        header[kIPv6NextHeaderOffset] == IPPROTO_ICMPV6 &&
        // Check that ICMP message type is an error.
        header[kIcmpMessageTypeOffset] < kIcmpMessageTypeMaxError) {
      result = ProcessingResult::SILENT_DROP;
    }
  }

  return result;
}

QbonePacketProcessor::ProcessingResult QbonePacketProcessor::ProcessIPv6Header(
    string* packet,
    Direction direction,
    uint8_t* transport_protocol,
    char** transport_data,
    icmp6_hdr* icmp_header) {
  // Check if the packet is big enough to have IPv6 header.
  if (packet->size() < kIPv6HeaderSize) {
    QUIC_DVLOG(1) << "Dropped malformed packet: IPv6 header too short";
    return ProcessingResult::SILENT_DROP;
  }

  // Check version field.
  ip6_hdr* header = reinterpret_cast<ip6_hdr*>(&*packet->begin());
  if (header->ip6_vfc >> 4 != 6) {
    QUIC_DVLOG(1) << "Dropped malformed packet: IP version is not IPv6";
    return ProcessingResult::SILENT_DROP;
  }

  // Check payload size.
  const size_t declared_payload_size =
      QuicEndian::NetToHost16(header->ip6_plen);
  const size_t actual_payload_size = packet->size() - kIPv6HeaderSize;
  if (declared_payload_size != actual_payload_size) {
    QUIC_DVLOG(1)
        << "Dropped malformed packet: incorrect packet length specified";
    return ProcessingResult::SILENT_DROP;
  }

  // Check that the address of the client is in the packet.
  QuicIpAddress address_to_check;
  uint8_t address_reject_code;
  bool ip_parse_result;
  switch (direction) {
    case Direction::FROM_CLIENT:
      // Expect the source IP to match the client.
      ip_parse_result = address_to_check.FromPackedString(
          reinterpret_cast<const char*>(&header->ip6_src),
          sizeof(header->ip6_src));
      address_reject_code = kICMPv6DestinationUnreachableDueToSourcePolicy;
      break;
    case Direction::FROM_NETWORK:
      // Expect the destination IP to match the client.
      ip_parse_result = address_to_check.FromPackedString(
          reinterpret_cast<const char*>(&header->ip6_dst),
          sizeof(header->ip6_src));
      address_reject_code = ICMP6_DST_UNREACH_NOROUTE;
      break;
  }
  DCHECK(ip_parse_result);
  if (!client_ip_.InSameSubnet(address_to_check, client_ip_subnet_length_)) {
    QUIC_DVLOG(1)
        << "Dropped packet: source/destination address is not client's";
    icmp_header->icmp6_type = ICMP6_DST_UNREACH;
    icmp_header->icmp6_code = address_reject_code;
    return ProcessingResult::ICMP;
  }

  // Check and decrement TTL.
  if (header->ip6_hops <= 1) {
    icmp_header->icmp6_type = ICMP6_TIME_EXCEEDED;
    icmp_header->icmp6_code = ICMP6_TIME_EXCEED_TRANSIT;
    return ProcessingResult::ICMP;
  }
  header->ip6_hops--;

  // Check and extract IP headers.
  switch (header->ip6_nxt) {
    case IPPROTO_TCP:
    case IPPROTO_UDP:
    case IPPROTO_ICMPV6:
      *transport_protocol = header->ip6_nxt;
      *transport_data = (&*packet->begin()) + kIPv6HeaderSize;
      break;
    default:
      icmp_header->icmp6_type = ICMP6_PARAM_PROB;
      icmp_header->icmp6_code = ICMP6_PARAMPROB_NEXTHEADER;
      return ProcessingResult::ICMP;
  }

  return ProcessingResult::OK;
}

void QbonePacketProcessor::SendIcmpResponse(icmp6_hdr* icmp_header,
                                            QuicStringPiece original_packet,
                                            Direction original_direction) {
  in6_addr dst;
  // TODO(b/70339814): ensure this is actually a unicast address.
  memcpy(dst.s6_addr, &original_packet[8], kIPv6AddressSize);

  CreateIcmpPacket(self_ip_, dst, *icmp_header, original_packet,
                   [this, original_direction](QuicStringPiece packet) {
                     SendResponse(original_direction, packet);
                   });
}

void QbonePacketProcessor::SendTcpReset(QuicStringPiece original_packet,
                                        Direction original_direction) {
  CreateTcpResetPacket(original_packet,
                       [this, original_direction](QuicStringPiece packet) {
                         SendResponse(original_direction, packet);
                       });
}

void QbonePacketProcessor::SendResponse(Direction original_direction,
                                        QuicStringPiece packet) {
  switch (original_direction) {
    case Direction::FROM_CLIENT:
      output_->SendPacketToClient(packet);
      break;
    case Direction::FROM_NETWORK:
      output_->SendPacketToNetwork(packet);
      break;
  }
}

}  // namespace quic
