// 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/platform/icmp_packet.h"

#include <netinet/ip6.h>

#include <cstdint>

#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h"

namespace quic {
namespace {

constexpr char kReferenceSourceAddress[] = "fe80:1:2:3:4::1";
constexpr char kReferenceDestinationAddress[] = "fe80:4:3:2:1::1";

// clang-format off
constexpr  uint8_t kReferenceICMPMessageBody[] {
    0xd2, 0x61, 0x29, 0x5b, 0x00, 0x00, 0x00, 0x00,
    0x0d, 0x59, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37
};

constexpr uint8_t kReferenceICMPPacket[] = {
    // START IPv6 Header
    // IPv6 with zero TOS and flow label.
    0x60, 0x00, 0x00, 0x00,
    // Payload is 64 bytes
    0x00, 0x40,
    // Next header is 58
    0x3a,
    // Hop limit is 64
    0x40,
    // Source address of fe80:1:2:3:4::1
    0xfe, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03,
    0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
    // Destination address of fe80:4:3:2:1::1
    0xfe, 0x80, 0x00, 0x04, 0x00, 0x03, 0x00, 0x02,
    0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
    // END IPv6 Header
    // START ICMPv6 Header
    // Echo Request, zero code
    0x80, 0x00,
    // Checksum
    0xec, 0x00,
    // Identifier
    0xcb, 0x82,
    // Sequence Number
    0x00, 0x01,
    // END ICMPv6 Header
    // Message body
    0xd2, 0x61, 0x29, 0x5b, 0x00, 0x00, 0x00, 0x00,
    0x0d, 0x59, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37
};
// clang-format on

}  // namespace

TEST(IcmpPacketTest, CreatedPacketMatchesReference) {
  QuicIpAddress src;
  ASSERT_TRUE(src.FromString(kReferenceSourceAddress));
  in6_addr src_addr;
  memcpy(src_addr.s6_addr, src.ToPackedString().data(), sizeof(in6_addr));

  QuicIpAddress dst;
  ASSERT_TRUE(dst.FromString(kReferenceDestinationAddress));
  in6_addr dst_addr;
  memcpy(dst_addr.s6_addr, dst.ToPackedString().data(), sizeof(in6_addr));

  icmp6_hdr icmp_header{};
  icmp_header.icmp6_type = ICMP6_ECHO_REQUEST;
  icmp_header.icmp6_id = 0x82cb;
  icmp_header.icmp6_seq = 0x0100;

  quiche::QuicheStringPiece message_body = quiche::QuicheStringPiece(
      reinterpret_cast<const char*>(kReferenceICMPMessageBody), 56);
  quiche::QuicheStringPiece expected_packet = quiche::QuicheStringPiece(
      reinterpret_cast<const char*>(kReferenceICMPPacket), 104);
  CreateIcmpPacket(src_addr, dst_addr, icmp_header, message_body,
                   [&expected_packet](quiche::QuicheStringPiece packet) {
                     QUIC_LOG(INFO) << quiche::QuicheTextUtils::HexDump(packet);
                     ASSERT_EQ(packet, expected_packet);
                   });
}

TEST(IcmpPacketTest, NonZeroChecksumIsIgnored) {
  QuicIpAddress src;
  ASSERT_TRUE(src.FromString(kReferenceSourceAddress));
  in6_addr src_addr;
  memcpy(src_addr.s6_addr, src.ToPackedString().data(), sizeof(in6_addr));

  QuicIpAddress dst;
  ASSERT_TRUE(dst.FromString(kReferenceDestinationAddress));
  in6_addr dst_addr;
  memcpy(dst_addr.s6_addr, dst.ToPackedString().data(), sizeof(in6_addr));

  icmp6_hdr icmp_header{};
  icmp_header.icmp6_type = ICMP6_ECHO_REQUEST;
  icmp_header.icmp6_id = 0x82cb;
  icmp_header.icmp6_seq = 0x0100;
  // Set the checksum to a bogus value
  icmp_header.icmp6_cksum = 0x1234;

  quiche::QuicheStringPiece message_body = quiche::QuicheStringPiece(
      reinterpret_cast<const char*>(kReferenceICMPMessageBody), 56);
  quiche::QuicheStringPiece expected_packet = quiche::QuicheStringPiece(
      reinterpret_cast<const char*>(kReferenceICMPPacket), 104);
  CreateIcmpPacket(src_addr, dst_addr, icmp_header, message_body,
                   [&expected_packet](quiche::QuicheStringPiece packet) {
                     QUIC_LOG(INFO) << quiche::QuicheTextUtils::HexDump(packet);
                     ASSERT_EQ(packet, expected_packet);
                   });
}

}  // namespace quic
