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

#include <netinet/ip6.h>

#include <algorithm>

#include "absl/strings/string_view.h"
#include "quiche/quic/core/internet_checksum.h"
#include "quiche/common/quiche_callbacks.h"
#include "quiche/common/quiche_endian.h"

namespace quic {
namespace {

constexpr size_t kIPv6AddressSize = sizeof(in6_addr);
constexpr size_t kIPv6HeaderSize = sizeof(ip6_hdr);
constexpr size_t kICMPv6HeaderSize = sizeof(icmp6_hdr);
constexpr size_t kIPv6MinPacketSize = 1280;

// Hop limit set to 255 to satisfy:
// https://datatracker.ietf.org/doc/html/rfc4861#section-11.2
constexpr size_t kIcmpTtl = 255;
constexpr size_t kICMPv6BodyMaxSize =
    kIPv6MinPacketSize - kIPv6HeaderSize - kICMPv6HeaderSize;

struct ICMPv6Packet {
  ip6_hdr ip_header;
  icmp6_hdr icmp_header;
  uint8_t body[kICMPv6BodyMaxSize];
};

// pseudo header as described in RFC 2460 Section 8.1 (excluding addresses)
struct IPv6PseudoHeader {
  uint32_t payload_size{};
  uint8_t zeros[3] = {0, 0, 0};
  uint8_t next_header = IPPROTO_ICMPV6;
};

}  // namespace

void CreateIcmpPacket(in6_addr src, in6_addr dst, const icmp6_hdr& icmp_header,
                      absl::string_view body,
                      quiche::UnretainedCallback<void(absl::string_view)> cb) {
  const size_t body_size = std::min(body.size(), kICMPv6BodyMaxSize);
  const size_t payload_size = kICMPv6HeaderSize + body_size;

  ICMPv6Packet icmp_packet{};
  // Set version to 6.
  icmp_packet.ip_header.ip6_vfc = 0x6 << 4;
  // Set the payload size, protocol and TTL.
  icmp_packet.ip_header.ip6_plen =
      quiche::QuicheEndian::HostToNet16(payload_size);
  icmp_packet.ip_header.ip6_nxt = IPPROTO_ICMPV6;
  icmp_packet.ip_header.ip6_hops = kIcmpTtl;
  // Set the source address to the specified self IP.
  icmp_packet.ip_header.ip6_src = src;
  icmp_packet.ip_header.ip6_dst = dst;

  icmp_packet.icmp_header = icmp_header;
  // Per RFC 4443 Section 2.3, set checksum field to 0 prior to computing it
  icmp_packet.icmp_header.icmp6_cksum = 0;

  IPv6PseudoHeader pseudo_header{};
  pseudo_header.payload_size = quiche::QuicheEndian::HostToNet32(payload_size);

  InternetChecksum checksum;
  // Pseudoheader.
  checksum.Update(icmp_packet.ip_header.ip6_src.s6_addr, kIPv6AddressSize);
  checksum.Update(icmp_packet.ip_header.ip6_dst.s6_addr, kIPv6AddressSize);
  checksum.Update(reinterpret_cast<char*>(&pseudo_header),
                  sizeof(pseudo_header));
  // ICMP header.
  checksum.Update(reinterpret_cast<const char*>(&icmp_packet.icmp_header),
                  sizeof(icmp_packet.icmp_header));
  // Body.
  checksum.Update(body.data(), body_size);
  icmp_packet.icmp_header.icmp6_cksum = checksum.Value();

  memcpy(icmp_packet.body, body.data(), body_size);

  const char* packet = reinterpret_cast<char*>(&icmp_packet);
  const size_t packet_size = offsetof(ICMPv6Packet, body) + body_size;

  cb(absl::string_view(packet, packet_size));
}

}  // namespace quic
