// Copyright 2019 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.

#include "netdump.h"

#include <iomanip>
#include <lib/zx/clock.h>

#include "netdump_types.h"

namespace netemul {

// Classes below implement the PCAP Next Generation (pcapng) format.
// The specification can be found at:
// https://github.com/pcapng/pcapng

#define ENHANCED_PKT_MIN_SIZE (sizeof(enhanced_pkt_t) + sizeof(uint32_t))
#define IDB_MIN_SIZE (sizeof(pcap_idb_t) + sizeof(uint32_t))
#define OPTION_LEN(len) (sizeof(option_tlv_t) + PAD(len))

void NetworkDump::Write(const void* data, size_t len) {
  out_->write(reinterpret_cast<const char*>(data), len);
}

void NetworkDump::WriteOption(uint16_t type, const void* data, uint16_t len) {
  option_tlv_t opt = {type, len};
  Write(&opt, sizeof(opt));
  Write(data, len);
  auto padded_len = static_cast<size_t>(PAD(len));
  if (padded_len > len) {
    auto padding = padded_len - len;
    // pcap padding is a round up aligned to 32 bits.
    // if padding is not in interval [0,3] something went
    // terribly wrong.
    ZX_DEBUG_ASSERT(padding <= 3);
    static const uint32_t zero = 0;
    Write(&zero, padding);
  }
}

void NetworkDump::WriteHeaders() {
  pcap_shb_t shb;
  shb.type = kSectionHeaderBlockType;
  shb.blk_tot_len = sizeof(pcap_shb_t);
  shb.magic = kSectionHeaderByteOrderMagic;
  shb.major = 1;
  shb.minor = 0;
  shb.section_len = 0xFFFFFFFFFFFFFFFF;
  shb.blk_tot_len2 = sizeof(pcap_shb_t);
  Write(&shb, sizeof(shb));
}

uint32_t NetworkDump::AddInterface(const std::string& name) {
  pcap_idb_t idb;
  idb.type = kInterfaceDescriptionBlockType;
  idb.blk_tot_len = IDB_MIN_SIZE + OPTION_LEN(name.length());
  ;
  idb.linktype = kLinkTypeEthernet;
  idb.reserved = 0;
  // We can't use a zero here, but tcpdump also rejects 2^32 - 1. Try 2^16 - 1.
  // See http://seclists.org/tcpdump/2012/q2/8.
  idb.snaplen = 0xFFFF;
  Write(&idb, sizeof(idb));
  // write interface name, option = 0x0002
  WriteOption(kOptionInterfaceName, name.c_str(), static_cast<uint16_t>(name.length()));
  Write(&idb.blk_tot_len, sizeof(idb.blk_tot_len));
  return interface_counter_++;
}

void NetworkDump::WritePacket(const void* data, size_t len, uint32_t interface) {
  size_t padded_len = PAD(len);
  auto ts_usec = static_cast<uint64_t>(zx::clock::get_monotonic().get() / ZX_USEC(1));
  ts_usec = ((ts_usec & 0xFFFFFFFF) << 32) | (ts_usec >> 32);
  enhanced_pkt_t pkt = {
      kEnhancedPacketBlockType,                                   // type
      static_cast<uint32_t>(ENHANCED_PKT_MIN_SIZE + padded_len),  // blk_tot_len
      interface,                                                  // interface id
      ts_usec,                                                    // timestamp
      static_cast<uint32_t>(len),                                 // orig_len
      static_cast<uint32_t>(len),                                 // captured_len
  };

  Write(&pkt, sizeof(pkt));
  Write(data, len);
  if (padded_len > len) {
    size_t padding = padded_len - len;
    // pcap padding is a round up aligned to 32 bits.
    // if padding is not in interval [0,3] something went
    // terribly wrong.
    ZX_DEBUG_ASSERT(padding <= 3);
    static const uint32_t zero = 0;
    Write(&zero, padding);
  }
  Write(&pkt.blk_tot_len, sizeof(pkt.blk_tot_len));
  packet_count_++;
}

void InMemoryDump::DumpHex(std::ostream* out) const {
  auto str = mem_.str();
  const auto* buff = reinterpret_cast<const uint8_t*>(str.c_str());
  auto len = str.length();
  constexpr int cols = 50;
  int col = cols;
  while (len--) {
    *out << std::setw(2) << std::hex << std::setfill('0') << (int)*buff++;
    col--;
    if (col == 0) {
      col = cols;
      *out << std::endl;
    }
  }
  if (col != cols) {
    *out << std::endl;
  }
}

std::vector<uint8_t> InMemoryDump::CopyBytes() const {
  auto str = mem_.str();
  const auto* b = reinterpret_cast<const uint8_t*>(str.c_str());
  return std::vector<uint8_t>(b, b + str.length());
}

}  // namespace netemul
