// 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;

// RFC9293
constexpr uint8_t kTcpProtocol = 0x06;

// 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);
static_assert(kTcpProtocol == IPPROTO_TCP);
#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;
    case IpPacketPayloadType::kTcp:
      payload_protocol = kTcpProtocol;
      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
