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

#ifndef SRC_FIRMWARE_GIGABOOT_CPP_NETWORK_H_
#define SRC_FIRMWARE_GIGABOOT_CPP_NETWORK_H_

#include <arpa/inet.h>
#include <lib/fit/result.h>
#include <lib/stdcompat/span.h>

#include <array>
#include <cstdint>
#include <numeric>

#include <efi/protocol/managed-network.h>
#include <phys/efi/protocol.h>

#include "utils.h"

namespace gigaboot {

constexpr uint8_t kUdpHdr = 0x11;

// Ethernet MTU: 2 ethernet addresses, ethertype, ipv6 header, udp header, payload
constexpr size_t kEthMTU = 1502;

constexpr size_t kMacAddrLen = 6;
using MacAddr = std::array<uint8_t, kMacAddrLen>;

constexpr size_t kIp6AddrLen = 16;
using Ip6Addr = std::array<uint8_t, kIp6AddrLen>;

// Given a multicast IPv6 address, generate the destination multicast MAC address for
// link-local transmission.
// Defined in RFC 2464.
constexpr MacAddr MulticastMacFromIp6(Ip6Addr const& addr) {
  return MacAddr{
      0x33, 0x33, addr[12], addr[13], addr[14], addr[15],
  };
}

// IPv6 Stateless Address Auto-configuration (SLAAC) allows the definition of
// link-local, deterministic IP addresses without input from other network elements.
// The address must use have the prefix fe80::/64, but the precise generation mechanism
// is deferred to the implementation.
constexpr Ip6Addr LocalIp6AddrFromMac(MacAddr mac_addr) {
  return Ip6Addr{
      0xFE,        0x80,        0,
      0,           0,           0,
      0,           0,           static_cast<uint8_t>(mac_addr[0] ^ 2),
      mac_addr[1], mac_addr[2], 0xFF,
      0xFE,        mac_addr[3], mac_addr[4],
      mac_addr[5],
  };
}

// Calculate the 1s complement checksum on a payload.
uint16_t CalculateChecksum(cpp20::span<const uint8_t> data, uint64_t start);

class Ip6Header {
 public:
  Ip6Header(uint16_t len, uint8_t next_hdr, const Ip6Addr& src, const Ip6Addr& dst);

  // The first four octets of an IPv6 header contain three fields:
  // version (4 bits), always 0b0110, or 6.
  // traffic class (8 bits), used for differentiated services and congestion control.
  // flow label (20 bits), identifies a flow of packets, used for QoS.
  //
  // These fields are combined into a single 32 bit number for simplified serialization.
  // Both traffic class and flow label can be 0.
  uint32_t vtcf;
  uint16_t length;
  uint8_t next_header;
  uint8_t hop_limit;
  Ip6Addr source;
  Ip6Addr dest;
};
static_assert(sizeof(Ip6Header) == 40);

struct UdpHeader {
  uint16_t src_port;
  uint16_t dst_port;
  uint16_t length;
  uint16_t checksum;
};
static_assert(sizeof(UdpHeader) == 8);

class EthernetAgent {
 public:
  // Create and return an EthernetAgent, or an error if construction fails.
  // The EthernetAgent manages transmission and configuration of a single interface
  // via the ManagedNetworkProtocol.
  //
  // Construction may fail for any of the following reasons:
  // *) There are no interfaces
  // *) No interface has connected media
  // *) Failure to determine configuration for an interface
  // *) Failure to configure an interface
  static fit::result<efi_status, EthernetAgent> Create();

  // No default ctor or copy.
  // The whole point of an agent is that it is the sole owner of a managed protocol.
  EthernetAgent() = delete;
  EthernetAgent(const EthernetAgent&) = delete;
  EthernetAgent& operator=(const EthernetAgent&) = delete;

  // We do want move because of the factory function.
  EthernetAgent(EthernetAgent&&) = default;
  EthernetAgent& operator=(EthernetAgent&&) = default;

  constexpr MacAddr Addr() const { return mac_addr_; }

  // Transmit an IPv6 packet.
  //
  // Note: the only reason that this method specifically transmits an IPv6 packet is
  //       because it sets the ethertype to be that of IPv6. All v6 header data
  //       must be set in the payload by the caller.
  //
  // Parameters:
  // dst: the MAC address of the destination.
  //      The address can be unicast, multicast, or broadcast.
  //
  // data: the IPv6 packet to transmit. This must include the v6 header,
  //       any higher protocol headers, and any payload data.
  //
  // callback: a UEFI event to be signaled once the data has been transmitted.
  //           It must be created with a priority of TPL_CALLBACK and must be of type
  //           EVT_NOTIFY_SIGNAL.
  //           The event callback with associated context can be used to e.g. set a timer,
  //           update a counter, or clean up a resource.
  //
  //           See the documentation for EFI_BOOT_SERVICES.CreateEvent for more details
  //           on creating and using signalled events.
  //
  // token: (output) a transmission token that, after transmission is complete,
  //        contains the return status of transmission.
  //        The UEFI spec states that the completion token's status is updated after the
  //        operation completes, and that the operation is asynchronous.
  //        The token is provided by the caller because the caller is better equipped
  //        to guarantee that the token is not mutated until transmission is complete
  //        and `callback` has been signalled.
  //
  // The transmission data is copied into a buffer before being sent to the
  // simple network protocol, so it is safe to overwrite that as soon
  // as SendV6Frame returns.
  fit::result<efi_status> SendV6LocalFrame(MacAddr dst, cpp20::span<const uint8_t> data,
                                           efi_event callback,
                                           efi_managed_network_sync_completion_token* token);

 private:
  explicit EthernetAgent(EfiProtocolPtr<efi_managed_network_protocol> net_proto,
                         const MacAddr& mac_addr)
      : net_proto_(std::move(net_proto)), mac_addr_(mac_addr) {}

  EfiProtocolPtr<efi_managed_network_protocol> net_proto_;
  MacAddr mac_addr_;
};

}  // namespace gigaboot

#endif  // SRC_FIRMWARE_GIGABOOT_CPP_NETWORK_H_
