// 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_logging.h"
#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
