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

#include "quiche/quic/test_tools/test_ip_packets.h"

#include <cstdint>
#include <limits>
#include <string>

#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "quiche/quic/platform/api/quic_socket_address.h"
#include "quiche/common/internet_checksum.h"
#include "quiche/common/platform/api/quiche_logging.h"
#include "quiche/common/quiche_data_writer.h"
#include "quiche/common/quiche_endian.h"
#include "quiche/common/quiche_ip_address.h"
#include "quiche/common/quiche_ip_address_family.h"

#if defined(__linux__)
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netinet/udp.h>
#endif

namespace quic::test {

namespace {

// RFC791, Section 3.1. Size without the optional Options field.
constexpr uint16_t kIpv4HeaderSize = 20;

// RFC8200, Section 3.
constexpr uint16_t kIpv6HeaderSize = 40;

// RFC768.
constexpr uint16_t kUdpHeaderSize = 8;
constexpr uint8_t kUdpProtocol = 0x11;

// For Windows compatibility, avoid dependency on netinet, but when building on
// Linux, check that the constants match.
#if defined(__linux__)
static_assert(kIpv4HeaderSize == sizeof(iphdr));
static_assert(kIpv6HeaderSize == sizeof(ip6_hdr));
static_assert(kUdpHeaderSize == sizeof(udphdr));
static_assert(kUdpProtocol == IPPROTO_UDP);
#endif

std::string CreateIpv4Header(int payload_length,
                             quiche::QuicheIpAddress source_address,
                             quiche::QuicheIpAddress destination_address,
                             uint8_t protocol) {
  QUICHE_CHECK_GT(payload_length, 0);
  QUICHE_CHECK_LE(payload_length,
                  std::numeric_limits<uint16_t>::max() - kIpv4HeaderSize);
  QUICHE_CHECK(source_address.address_family() ==
               quiche::IpAddressFamily::IP_V4);
  QUICHE_CHECK(destination_address.address_family() ==
               quiche::IpAddressFamily::IP_V4);

  std::string header(kIpv4HeaderSize, '\0');
  quiche::QuicheDataWriter header_writer(header.size(), header.data());

  header_writer.WriteUInt8(0x45);  // Version: 4, Header length: 5 words
  header_writer.WriteUInt8(0x00);  // DSCP: 0, ECN: 0
  header_writer.WriteUInt16(kIpv4HeaderSize + payload_length);  // Total length
  header_writer.WriteUInt16(0x0000);  // Identification: 0 (replaced by socket)
  header_writer.WriteUInt16(0x0000);  // Flags: 0, Fragment offset: 0
  header_writer.WriteUInt8(64);       // TTL: 64 hops/seconds
  header_writer.WriteUInt8(protocol);
  header_writer.WriteUInt16(0x0000);  // Checksum (replaced by socket)
  header_writer.WriteStringPiece(source_address.ToPackedString());
  header_writer.WriteStringPiece(destination_address.ToPackedString());
  QUICHE_CHECK_EQ(header_writer.remaining(), 0u);

  return header;
}

std::string CreateIpv6Header(int payload_length,
                             quiche::QuicheIpAddress source_address,
                             quiche::QuicheIpAddress destination_address,
                             uint8_t next_header) {
  QUICHE_CHECK_GT(payload_length, 0);
  QUICHE_CHECK_LE(payload_length, std::numeric_limits<uint16_t>::max());
  QUICHE_CHECK(source_address.address_family() ==
               quiche::IpAddressFamily::IP_V6);
  QUICHE_CHECK(destination_address.address_family() ==
               quiche::IpAddressFamily::IP_V6);

  std::string header(kIpv6HeaderSize, '\0');
  quiche::QuicheDataWriter header_writer(header.size(), header.data());

  // Version: 6
  // Traffic class: 0
  // Flow label: 0 (possibly replaced by socket)
  header_writer.WriteUInt32(0x60000000);

  header_writer.WriteUInt16(payload_length);
  header_writer.WriteUInt8(next_header);
  header_writer.WriteUInt8(64);  // Hop limit: 64
  header_writer.WriteStringPiece(source_address.ToPackedString());
  header_writer.WriteStringPiece(destination_address.ToPackedString());
  QUICHE_CHECK_EQ(header_writer.remaining(), 0u);

  return header;
}

}  // namespace

std::string CreateIpPacket(const quiche::QuicheIpAddress& source_address,
                           const quiche::QuicheIpAddress& destination_address,
                           absl::string_view payload,
                           IpPacketPayloadType payload_type) {
  QUICHE_CHECK(source_address.address_family() ==
               destination_address.address_family());

  uint8_t payload_protocol;
  switch (payload_type) {
    case IpPacketPayloadType::kUdp:
      payload_protocol = kUdpProtocol;
      break;
    default:
      QUICHE_NOTREACHED();
      return "";
  }

  std::string header;
  switch (source_address.address_family()) {
    case quiche::IpAddressFamily::IP_V4:
      header = CreateIpv4Header(payload.size(), source_address,
                                destination_address, payload_protocol);
      break;
    case quiche::IpAddressFamily::IP_V6:
      header = CreateIpv6Header(payload.size(), source_address,
                                destination_address, payload_protocol);
      break;
    default:
      QUICHE_NOTREACHED();
      return "";
  }

  return absl::StrCat(header, payload);
}

std::string CreateUdpPacket(const QuicSocketAddress& source_address,
                            const QuicSocketAddress& destination_address,
                            absl::string_view payload) {
  QUICHE_CHECK(source_address.host().address_family() ==
               destination_address.host().address_family());
  QUICHE_CHECK(!payload.empty());
  QUICHE_CHECK_LE(payload.size(),
                  static_cast<uint16_t>(std::numeric_limits<uint16_t>::max() -
                                        kUdpHeaderSize));

  std::string header(kUdpHeaderSize, '\0');
  quiche::QuicheDataWriter header_writer(header.size(), header.data());

  header_writer.WriteUInt16(source_address.port());
  header_writer.WriteUInt16(destination_address.port());
  header_writer.WriteUInt16(kUdpHeaderSize + payload.size());

  quiche::InternetChecksum checksum;
  switch (source_address.host().address_family()) {
    case quiche::IpAddressFamily::IP_V4: {
      // IP pseudo header information. See RFC768.
      checksum.Update(source_address.host().ToPackedString());
      checksum.Update(destination_address.host().ToPackedString());
      uint8_t protocol[] = {0x00, kUdpProtocol};
      checksum.Update(protocol, sizeof(protocol));
      uint16_t udp_length =
          quiche::QuicheEndian::HostToNet16(kUdpHeaderSize + payload.size());
      checksum.Update(reinterpret_cast<uint8_t*>(&udp_length),
                      sizeof(udp_length));
      break;
    }
    case quiche::IpAddressFamily::IP_V6: {
      // IP pseudo header information. See RFC8200, Section 8.1.
      checksum.Update(source_address.host().ToPackedString());
      checksum.Update(destination_address.host().ToPackedString());
      uint32_t udp_length =
          quiche::QuicheEndian::HostToNet32(kUdpHeaderSize + payload.size());
      checksum.Update(reinterpret_cast<uint8_t*>(&udp_length),
                      sizeof(udp_length));
      uint8_t protocol[] = {0x00, 0x00, 0x00, kUdpProtocol};
      checksum.Update(protocol, sizeof(protocol));
      break;
    }
    default:
      QUICHE_NOTREACHED();
      return "";
  }

  checksum.Update(header.data(), header.size());
  checksum.Update(payload.data(), payload.size());
  uint16_t checksum_val = checksum.Value();

  // Checksum is always written in the same byte order in which it was
  // calculated.
  header_writer.WriteBytes(&checksum_val, sizeof(checksum_val));

  QUICHE_CHECK_EQ(header_writer.remaining(), 0u);

  return absl::StrCat(header, payload);
}

}  // namespace quic::test
