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

#include "netdump_types.h"
#include "src/lib/fxl/logging.h"

#define INSUFF_LEN(a, b)                                                 \
  if ((a) < (b)) {                                                       \
    FX_LOGS(ERROR) << "Insufficient length " << (a) << ", need " << (b); \
    return false;                                                        \
  }

namespace netemul {

namespace testing {

bool NetDumpParser::Parse(const uint8_t* data, size_t len) {
  interfaces_.clear();
  packets_.clear();

  INSUFF_LEN(len, sizeof(pcap_shb_t));

  pcap_shb_t shb;
  memcpy(&shb, data, sizeof(shb));
  data += sizeof(shb);
  len -= sizeof(shb);
  // expect the first block to be a section block
  if (shb.magic != kSectionHeaderByteOrderMagic || shb.blk_tot_len != sizeof(shb) ||
      shb.blk_tot_len2 != sizeof(shb) || shb.type != kSectionHeaderBlockType) {
    FX_LOGS(ERROR) << "Invalid section header block";
    return false;
  }
  // now read all the rest of the blocks:

  while (len > 0) {
    struct {
      uint32_t type;
      uint32_t len;
    } __attribute__((packed)) block_header{};

    INSUFF_LEN(len, sizeof(block_header));

    memcpy(&block_header, data, sizeof(block_header));

    INSUFF_LEN(len, block_header.len);

    // at the end of every block, we repeat the size:
    uint32_t len2;
    memcpy(&len2, data + block_header.len - sizeof(len2), sizeof(len2));
    // end-of-block length doesn't match:
    if (len2 != block_header.len) {
      FX_LOGS(ERROR) << "Block header and footer don't match lengths";
      return false;
    }

    if (block_header.type == kInterfaceDescriptionBlockType) {
      pcap_idb_t idb;

      INSUFF_LEN(len, sizeof(idb));

      memcpy(&idb, data, sizeof(idb));
      // only link type we know:
      if (idb.linktype != kLinkTypeEthernet) {
        FX_LOGS(ERROR) << "Unrecognized link type: " << idb.linktype;
        return false;
      }

      auto options = data + sizeof(idb);
      // length of options is the rest of the block,
      // removing the header and the end of block length
      uint32_t options_len = idb.blk_tot_len - sizeof(idb) - sizeof(uint32_t);

      while (options_len > 0) {
        option_tlv_t option_tlv;
        INSUFF_LEN(options_len, sizeof(option_tlv));

        memcpy(&option_tlv, options, sizeof(option_tlv));
        auto padded_len = PAD(static_cast<uint32_t>(option_tlv.len));

        INSUFF_LEN(options_len, padded_len);

        if (option_tlv.type == kOptionInterfaceName) {
          interfaces_.emplace_back(options + sizeof(option_tlv_t),
                                   options + sizeof(option_tlv_t) + option_tlv.len);
        } else {
          // we don't recognize any other types of options.
          FX_LOGS(ERROR) << "Unrecognized interface definition option: " << option_tlv.type;
          return false;
        }

        padded_len += sizeof(option_tlv);
        options_len -= padded_len;
        options += padded_len;
      }

    } else if (block_header.type == kEnhancedPacketBlockType) {
      INSUFF_LEN(len, sizeof(enhanced_pkt_t));

      enhanced_pkt_t pkt;
      memcpy(&pkt, data, sizeof(pkt));

      if (
          // we always put capture and orig len on the same value:
          pkt.captured_len != pkt.orig_len
          // check that the reported size matches the external block
          // information:
          || PAD(pkt.captured_len) + sizeof(enhanced_pkt_t) + sizeof(uint32_t) != block_header.len
          // check that the interface is actually specified in interfaces:
          || pkt.interface_id >= interfaces_.size()) {
        FX_LOGS(ERROR) << "Invalid enhanced packet block";
        return false;
      }
      packets_.push_back(ParsedPacket{data + sizeof(pkt), pkt.captured_len, pkt.interface_id});
    } else {
      FX_LOGS(ERROR) << "Unrecognized block type: " << block_header.type;
      return false;
    }
    data += len2;
    len -= len2;
  }

  return true;
}

}  // namespace testing

}  // namespace netemul
