// Copyright 2017 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 <arpa/inet.h>
#include <fcntl.h>
#include <fuchsia/hardware/ethernet/c/fidl.h>
#include <inttypes.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/zx/channel.h>
#include <lib/zx/clock.h>
#include <lib/zx/fifo.h>
#include <lib/zx/vmo.h>
#include <limits.h>
#include <netinet/if_ether.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <stdlib.h>
#include <unistd.h>
#include <zircon/assert.h>
#include <zircon/boot/netboot.h>
#include <zircon/device/ethernet.h>
#include <zircon/process.h>
#include <zircon/processargs.h>
#include <zircon/syscalls.h>

#include <cstdint>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>

#include <pretty/hexdump.h>

#include "filter_builder_impl.h"

static constexpr size_t BUFSIZE = 2048;
static constexpr size_t STRBUFSIZE = 256;
static constexpr int64_t DEFAULT_TIMEOUT_SECONDS = 60;

namespace netdump {

enum class PrintFormat {
  LOG,
  HEXDUMP,
  PCAPNG,
};

class NetdumpOptions {
 public:
  std::string device;
  PrintFormat print_format = PrintFormat::LOG;
  bool link_level = false;
  bool promisc = false;
  std::optional<uint64_t> packet_count = std::nullopt;
  size_t verbose_level = 0;
  int dumpfile_fd = -1;
  zx::time timeout_deadline = zx::time::infinite();
  Tokenizer tokenizer{};
  parser::Parser parser{tokenizer};
  FilterPtr filter = nullptr;
  FilterPtr highlight_filter = nullptr;
};

typedef struct {
  uint32_t type;
  uint32_t blk_tot_len;
  uint32_t magic;
  uint16_t major;
  uint16_t minor;
  uint64_t section_len;
  // TODO(smklein): Add options here
  uint32_t blk_tot_len2;
} __attribute__((packed)) pcap_shb_t;

typedef struct {
  uint32_t type;
  uint32_t blk_tot_len;
  uint16_t linktype;
  uint16_t reserved;
  uint32_t snaplen;
  uint32_t blk_tot_len2;
} __attribute__((packed)) pcap_idb_t;

typedef struct {
  uint32_t type;
  uint32_t blk_tot_len;
  uint32_t pkt_len;
} __attribute__((packed)) simple_pkt_t;

// Statistics tracking netdump operations
struct Stats {
  // Packet counts
  uint64_t pkts_filtered_in;
  uint64_t pkts_filtered_out;
  uint64_t pkts_len_small;    // Too small to be parsed.
  uint64_t pkts_eth_rx_fail;  // ETH_FIFO_RX_OK flag unset

  // Byte counts
  uint64_t bytes_filtered_in;
  uint64_t bytes_filtered_out;
  uint64_t bytes_len_small;
  uint64_t bytes_eth_rx_fail;

  // File dump statistics
  uint64_t pkts_write_ok;
  uint64_t pkts_write_fail;

  // Extend below.
};

static constexpr size_t SIMPLE_PKT_MIN_SIZE = sizeof(simple_pkt_t) + sizeof(uint32_t);

static std::string mac_to_string(const uint8_t mac[ETH_ALEN]) {
  std::stringstream stream;
  stream.flags(std::ios::hex);
  stream.fill('0');
  // clang-format off
  // Cast is required to make `stream` not interpret input as a char.
  stream << std::setw(2) << static_cast<uint16_t>(mac[0]) << ":"
         << std::setw(2) << static_cast<uint16_t>(mac[1]) << ":"
         << std::setw(2) << static_cast<uint16_t>(mac[2]) << ":"
         << std::setw(2) << static_cast<uint16_t>(mac[3]) << ":"
         << std::setw(2) << static_cast<uint16_t>(mac[4]) << ":"
         << std::setw(2) << static_cast<uint16_t>(mac[5]);
  // clang-format on
  return stream.str();
}

static std::string ethtype_to_string(uint16_t ethtype) {
  switch (ethtype) {
    case ETH_P_IP:
      return "IPv4";
    case ETH_P_ARP:
      return "ARP";
    case ETH_P_IPV6:
      return "IPv6";
    case ETH_P_8021Q:
      return "802.1Q";
    default:
      return "Unknown";
  }
}

static std::string protocol_to_string(uint8_t protocol) {
  switch (protocol) {
    case IPPROTO_HOPOPTS:
      return "HOPOPTS";
    case IPPROTO_TCP:
      return "TCP";
    case IPPROTO_UDP:
      return "UDP";
    case IPPROTO_ICMP:
      return "ICMP";
    case IPPROTO_ROUTING:
      return "ROUTING";
    case IPPROTO_FRAGMENT:
      return "FRAGMENT";
    case IPPROTO_ICMPV6:
      return "ICMPV6";
    case IPPROTO_NONE:
      return "NONE";
    default:
      return "Transport Unknown";
  }
}

static std::string port_to_string(uint16_t port) {
  switch (port) {
    case 7:
      return "Echo";
    case 20:
      return "FTP xfer";
    case 21:
      return "FTP ctl";
    case 22:
      return "SSH";
    case 23:
      return "Telnet";
    case 53:
      return "DNS";
    case 69:
      return "TFTP";
    case 80:
      return "HTTP";
    case 115:
      return "SFTP";
    case 123:
      return "NTP";
    case 194:
      return "IRC";
    case 443:
      return "HTTPS";
    case DEBUGLOG_PORT:
      return "Netboot Debug";
    case DEBUGLOG_ACK_PORT:
      return "Netboot Debug ack";
    default:
      return "";
  }
}

static inline std::string port_string_by_verbosity(uint16_t port, size_t verbosity) {
  std::string port_name = port_to_string(port);
  std::stringstream stream;
  stream << port;
  if (verbosity && !port_name.empty()) {
    stream << " (" << port_name << ")";
  }
  return stream.str();
}

// Test if the packet should be highlit.
inline bool to_highlight(const Packet& packet, const NetdumpOptions& options) {
  return (options.highlight_filter != nullptr && options.highlight_filter->match(packet));
}

// Write link level information to `stream` and return the ethtype.
uint16_t parse_l2_packet(const Packet& packet, const NetdumpOptions& options,
                         std::stringstream* stream) {
  ZX_ASSERT(stream != nullptr);
  uint16_t ethtype = ntohs(packet.eth->h_proto);
  if (options.link_level) {
    *stream << mac_to_string(packet.eth->h_source) << " > " << mac_to_string(packet.eth->h_dest)
            << ", ethertype " << ethtype_to_string(ethtype) << " (0x" << std::hex << ethtype
            << std::dec << "), ";
  }
  return ethtype;
}

// Write L3 information to `stream` and return the transport protocol number if L3 protocol is IP.
uint8_t parse_l3_packet(uint16_t ethtype, const Packet& packet, const NetdumpOptions& options,
                        std::stringstream* stream) {
  ZX_ASSERT(stream != nullptr);
  const struct iphdr* ip = packet.ip;
  char buf[STRBUFSIZE];
  switch (ip->version) {
    case 4: {
      *stream << "IP4 " << inet_ntop(AF_INET, &ip->saddr, buf, sizeof(buf)) << " > "
              << inet_ntop(AF_INET, &ip->daddr, buf, sizeof(buf)) << ": "
              << protocol_to_string(ip->protocol) << ", "
              << "length " << ntohs(ip->tot_len) << ", ";
      return ip->protocol;
    }
    case 6: {
      const struct ip6_hdr* ipv6 = packet.ipv6;
      *stream << "IP6 " << inet_ntop(AF_INET6, &ipv6->ip6_src.s6_addr, buf, sizeof(buf)) << " > "
              << inet_ntop(AF_INET6, &ipv6->ip6_dst.s6_addr, buf, sizeof(buf)) << ": "
              << protocol_to_string(ipv6->ip6_nxt) << ", "
              << "length " << ntohs(ipv6->ip6_plen) << ", ";
      return ipv6->ip6_nxt;
    }
    default: {
      ZX_DEBUG_ASSERT_MSG(false, "Ethtype recognized but IP headers malformed.");
      return 0;
    }
  }
}

void parse_l4_packet(uint8_t transport_protocol, const Packet& packet,
                     const NetdumpOptions& options, std::stringstream* stream) {
  ZX_ASSERT(stream != nullptr);
  switch (transport_protocol) {
    case IPPROTO_TCP: {
      const struct tcphdr* tcp = packet.tcp;
      *stream << "Ports: " << port_string_by_verbosity(ntohs(tcp->source), options.verbose_level)
              << " > " << port_string_by_verbosity(ntohs(tcp->dest), options.verbose_level);
      return;
    }
    case IPPROTO_UDP: {
      const struct udphdr* udp = packet.udp;
      *stream << "Ports: " << port_string_by_verbosity(ntohs(udp->uh_sport), options.verbose_level)
              << " > " << port_string_by_verbosity(ntohs(udp->uh_dport), options.verbose_level);
      return;
    }
    default: {
      ZX_DEBUG_ASSERT_MSG(false, "Transport protocol recognized but headers malformed.");
      return;
    }
  }
}

void parse_packet(const Packet& packet, const NetdumpOptions& options) {
  std::stringstream stream;
  auto is_highlit = to_highlight(packet, options);
  if (is_highlit) {
    stream << parser::ANSI_HIGHLIGHT;
  }
  uint16_t ethtype = parse_l2_packet(packet, options, &stream);
  if (packet.ip != nullptr) {
    uint8_t transport_protocol = parse_l3_packet(ethtype, packet, options, &stream);
    if (packet.transport != nullptr) {
      parse_l4_packet(transport_protocol, packet, options, &stream);
    } else {
      stream << "L4 headers incomplete or unhandled";  // Protocol is displayed in L3 parsing.
    }
  } else {
    stream << "L3 headers incomplete or unhandled";  // Ethtype is displayed in L2 parsing.
  }

  if (is_highlit) {
    std::cout << stream.str() << parser::ANSI_RESET << std::endl;
  } else {
    std::cout << stream.str() << std::endl;
  }
}

inline bool filter_packet(const NetdumpOptions& options, Packet* packet) {
  if (options.filter == nullptr) {
    return true;
  }
  return options.filter->match(*packet);
}

int write_shb(int fd) {
  if (fd == -1) {
    return 0;
  }
  pcap_shb_t shb = {
      .type = 0x0A0D0D0A,
      .blk_tot_len = sizeof(pcap_shb_t),
      .magic = 0x1A2B3C4D,
      .major = 1,
      .minor = 0,
      .section_len = 0xFFFFFFFFFFFFFFFF,
      .blk_tot_len2 = sizeof(pcap_shb_t),
  };

  if (write(fd, &shb, sizeof(shb)) != sizeof(shb)) {
    std::cerr << "Couldn't write PCAP Section Header block" << std::endl;
    return -1;
  }
  return 0;
}

int write_idb(int fd) {
  if (fd == -1) {
    return 0;
  }
  pcap_idb_t idb = {
      .type = 0x00000001,
      .blk_tot_len = sizeof(pcap_idb_t),
      .linktype = 1,
      .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.
      .snaplen = 0xFFFF,
      .blk_tot_len2 = sizeof(pcap_idb_t),
  };

  if (write(fd, &idb, sizeof(idb)) != sizeof(idb)) {
    std::cerr << "Couldn't write PCAP Interface Description block" << std::endl;
    return -1;
  }

  return 0;
}

inline size_t roundup(size_t a, size_t b) { return ((a) + ((b)-1)) & ~((b)-1); }

int write_packet(int fd, void* data, size_t len) {
  if (fd == -1) {
    return 0;
  }

  size_t padded_len = roundup(len, 4);
  simple_pkt_t pkt = {
      .type = 0x00000003,
      .blk_tot_len = static_cast<uint32_t>(SIMPLE_PKT_MIN_SIZE + padded_len),
      .pkt_len = static_cast<uint32_t>(len),
  };

  // TODO(tkilbourn): rewrite this to offload writing to another thread, and also deal with
  // partial writes
  if (write(fd, &pkt, sizeof(pkt)) != sizeof(pkt)) {
    std::cerr << "Couldn't write packet header" << std::endl;
    return -1;
  }
  if (write(fd, data, len) != static_cast<ssize_t>(len)) {
    std::cerr << "Couldn't write packet" << std::endl;
    return -1;
  }
  if (padded_len > len) {
    size_t padding = padded_len - len;
    ZX_DEBUG_ASSERT(padding <= 3);
    static const uint32_t zero = 0;
    if (write(fd, &zero, padding) != static_cast<ssize_t>(padding)) {
      std::cerr << "Couldn't write padding" << std::endl;
      return -1;
    }
  }
  if (write(fd, &pkt.blk_tot_len, sizeof(pkt.blk_tot_len)) != sizeof(pkt.blk_tot_len)) {
    std::cerr << "Couldn't write packet footer" << std::endl;
    return -1;
  }

  return 0;
}

void handle_rx(const zx::fifo& rx_fifo, char* iobuf, unsigned count, const NetdumpOptions& options,
               Stats* stats) {
  if (stats == nullptr) {
    std::cerr << "Couldn't track statistics. Bail out" << std::endl;
    return;
  }

  if (!count) {
    std::cerr << "Expected non-zero count value. Bail out" << std::endl;
    return;
  }

  eth_fifo_entry_t entries[count];

  bool dumpfile_write_error =
      write_shb(options.dumpfile_fd) < 0 || write_idb(options.dumpfile_fd) < 0;
  bool livedump_write_error = (options.print_format == PrintFormat::PCAPNG) &&
                              (write_shb(STDOUT_FILENO) < 0 || write_idb(STDOUT_FILENO) < 0);
  if (dumpfile_write_error || livedump_write_error) {
    return;
  }

  Packet packet{};
  uint64_t packets_remaining =
      (options.packet_count == std::nullopt ? std::numeric_limits<uint64_t>::max()
                                            : *options.packet_count);
  for (; packets_remaining > 0;) {
    size_t n;
    zx_status_t status;
    if ((status = rx_fifo.read(sizeof(entries[0]), entries, countof(entries), &n)) < 0) {
      if (status == ZX_ERR_SHOULD_WAIT) {
        rx_fifo.wait_one(ZX_FIFO_READABLE | ZX_FIFO_PEER_CLOSED, options.timeout_deadline, nullptr);
        if (zx::clock::get_monotonic() >= options.timeout_deadline) {
          return;
        }
        continue;
      }
      std::cerr << "netdump: failed to read rx packets: " << status << std::endl;
      return;
    }

    eth_fifo_entry_t* e = entries;
    for (size_t i = 0; i < n; ++i, ++e) {
      if (e->flags & ETH_FIFO_RX_OK) {
        void* buffer = iobuf + e->offset;
        uint16_t length = e->length;

        bool do_write = true;  // Whether the packet is included for write-out to dumpfile.
        packet.populate(buffer, length);
        if (packet.eth == nullptr) {
          stats->pkts_len_small++;
          stats->bytes_len_small += length;
          // Not setting `do_write` to false in order to record small frames.
          switch (options.print_format) {
            case PrintFormat::LOG:
              [[fallthrough]];
            case PrintFormat::HEXDUMP:
              if (options.verbose_level == 2 || options.print_format == PrintFormat::HEXDUMP) {
                hexdump8_very_ex(buffer, length, 0, hexdump_stdio_printf, stdout);
              }
              break;
            case PrintFormat::PCAPNG:
              if (write_packet(STDOUT_FILENO, buffer, length) < 0) {
                stats->pkts_write_fail += (n - i);
                return;
              }
              stats->pkts_write_ok++;
              break;
            default:
              ZX_ASSERT_MSG(false, "Unknown print format.");
              break;
          }

        } else {
          // pkts_eth_rx_ok++
          // bytes_eth_rx_ok += length
          if (filter_packet(options, &packet)) {
            stats->pkts_filtered_in++;
            stats->bytes_filtered_in += length;
            switch (options.print_format) {
              case PrintFormat::LOG:
                parse_packet(packet, options);
                break;
              case PrintFormat::HEXDUMP:
                std::cout << "---" << std::endl;
                hexdump8_very_ex(buffer, length, 0, hexdump_stdio_printf, stdout);
                break;
              case PrintFormat::PCAPNG:
                if (write_packet(STDOUT_FILENO, buffer, length) < 0) {
                  stats->pkts_write_fail += (n - i);
                  return;
                }
                stats->pkts_write_ok++;
                break;
              default:
                ZX_ASSERT_MSG(false, "Unknown print format.");
                break;
            }
            --packets_remaining;
          } else {
            stats->pkts_filtered_out++;
            stats->bytes_filtered_out += length;
            do_write = false;
          }
        }

        if (do_write && options.dumpfile_fd != -1) {
          auto write_status = write_packet(options.dumpfile_fd, buffer, length);
          if (write_status < 0) {
            stats->pkts_write_fail += (n - i);
            return;
          }
          stats->pkts_write_ok++;
        }

        if (packets_remaining == 0 || zx::clock::get_monotonic() >= options.timeout_deadline) {
          // Normal end condition
          return;
        }
      } else {
        stats->pkts_eth_rx_fail++;
      }

      e->length = BUFSIZE;
      e->flags = 0;
      if ((status = rx_fifo.write(sizeof(*e), e, 1, nullptr)) < 0) {
        std::cerr << "netdump: failed to queue rx packet: " << status << std::endl;
        break;
      }
    }
  }
}

int usage() {
  // clang-format off
  std::cerr << "usage: netdump [ <option>* ] <network-device>" << std::endl
            << " -t {sec}      : Exit after sec seconds, default " << DEFAULT_TIMEOUT_SECONDS
            << std::endl
            << " -w file       : Write packet output to file in pcapng format" << std::endl
            << " -c count      : Exit after receiving count packets" << std::endl
            << " -e            : Print link-level header information" << std::endl
            << " -f filter     : Capture only packets specified by filter" << std::endl
            << " -i filter     : Highlight packets specified by filter" << std::endl
            << " -p            : Use promiscuous mode" << std::endl
            << " -v            : Print verbose output" << std::endl
            << " -vv           : Print extra verbose output" << std::endl
            << " --pcapdump    : Print packet output in pcapng format, "
            << "can be combined with -w" << std::endl
            << " --hexdump     : Print packet output in hexdump format" << std::endl
            << " --help-filter : Show filter syntax usage" << std::endl
            << " --help        : Show this help message" << std::endl
            << "Filter syntax usage:" << std::endl;
  // clang-format on
  parser::parser_syntax(&std::cerr);
  return -1;
}

using StringIterator = std::vector<const std::string>::iterator;

int parse_args(StringIterator begin, StringIterator end, NetdumpOptions* options) {
  if (begin >= end) {
    return usage();
  }
  --end;
  std::string last = *end;

  for (; begin < end; ++begin) {
    std::string arg = *begin;
    if (arg == "-c") {
      ++begin;
      if (begin == end) {
        return usage();
      }
      size_t num_end;
      int64_t packet_count = stoll(*begin, &num_end, 10);
      if (packet_count < 0 || num_end < begin->length()) {
        return usage();
      }
      options->packet_count = std::optional(static_cast<uint64_t>(packet_count));
    } else if (arg == "-e") {
      options->link_level = true;
    } else if (arg == "-f" || arg == "-i") {
      ++begin;
      if (begin == end) {
        return usage();
      }
      parser::FilterTreeBuilder builder(options->tokenizer);
      auto parsed = options->parser.parse(*begin, &builder);
      if (auto error = std::get_if<parser::ParseError>(&parsed)) {
        std::cerr << *error << "Use '--help-filter' to see the filter syntax." << std::endl;
        return -1;
      }
      if (arg == "-f") {
        options->filter = std::move(std::get<FilterPtr>(parsed));
      } else {
        options->highlight_filter = std::move(std::get<FilterPtr>(parsed));
      }
    } else if (arg == "-p") {
      options->promisc = true;
    } else if (arg == "-w") {
      ++begin;
      if (begin == end || options->dumpfile_fd != -1) {
        return usage();
      }
      options->dumpfile_fd = open(begin->c_str(), O_WRONLY | O_CREAT);
      if (options->dumpfile_fd < 0) {
        std::cerr << "Error: Could not output to file: " << *begin << std::endl;
        return usage();
      }
    } else if (arg == "-v") {
      options->verbose_level = 1;
    } else if (!arg.compare(0, sizeof("-vv"), "-vv")) {
      // Since this is the max verbosity, adding extra 'v's does nothing.
      options->verbose_level = 2;
    } else if (arg == "--hexdump") {
      options->print_format = PrintFormat::HEXDUMP;
    } else if (arg == "--pcapdump") {
      options->print_format = PrintFormat::PCAPNG;
    } else if (arg == "-t") {
      int64_t timeout_seconds = DEFAULT_TIMEOUT_SECONDS;
      if (begin < end - 1) {
        size_t num_end;
        int64_t input = stoll(begin[1], &num_end, 10);
        if (num_end == begin[1].length()) {
          // Valid number.
          if (input < 0) {
            return usage();
          }
          timeout_seconds = input;
          ++begin;
        }
      }
      options->timeout_deadline = zx::clock::get_monotonic() + zx::sec(timeout_seconds);
    } else {
      return usage();
    }
  }

  if (last == "--help-filter") {
    parser::parser_syntax(&std::cerr);
    return -1;
  }
  if (last == "--help") {
    return usage();
  }

  options->device = last;
  return 0;
}

}  // namespace netdump

void show_stats(const netdump::Stats& stats) {
  // TODO(porce): Integration test with the emulated network.
  auto pkts_len_ok = stats.pkts_filtered_in + stats.pkts_filtered_out;
  auto pkts_eth_rx_ok = pkts_len_ok + stats.pkts_len_small;
  auto pkts_seen = pkts_eth_rx_ok + stats.pkts_eth_rx_fail;

  auto bytes_len_ok = stats.bytes_filtered_in + stats.bytes_filtered_out;
  auto bytes_eth_rx_ok = bytes_len_ok + stats.bytes_len_small;
  auto bytes_seen = bytes_eth_rx_ok + stats.bytes_eth_rx_fail;

  // Use stderr for auxiliary info not to disturb PCAPNG live streaming.
  fprintf(stderr, "\n --\nPacket capture statistics\n");

  fprintf(stderr, "  pkts_seen           : %" PRIu64 "\n", pkts_seen);
  fprintf(stderr, "  pkts_filtered_in    : %" PRIu64 "\n", stats.pkts_filtered_in);
  fprintf(stderr, "  pkts_filtered_out   : %" PRIu64 "\n", stats.pkts_filtered_out);
  fprintf(stderr, "  pkts_eth_rx_fail    : %" PRIu64 "\n", stats.pkts_eth_rx_fail);
  fprintf(stderr, "  pkts_len_small      : %" PRIu64 "\n", stats.pkts_len_small);

  fprintf(stderr, "  bytes_seen          : %" PRIu64 "\n", bytes_seen);
  fprintf(stderr, "  bytes_filtered_in   : %" PRIu64 "\n", stats.bytes_filtered_in);
  fprintf(stderr, "  bytes_filtered_out  : %" PRIu64 "\n", stats.bytes_filtered_out);
  fprintf(stderr, "  bytes_eth_rx_fail   : %" PRIu64 "\n", stats.bytes_eth_rx_fail);
  fprintf(stderr, "  bytes_len_small     : %" PRIu64 "\n", stats.bytes_len_small);

  fprintf(stderr, "  pkts_write_ok       : %" PRIu64 "\n", stats.pkts_write_ok);
  fprintf(stderr, "  pkts_write_fail     : %" PRIu64 "\n", stats.pkts_write_fail);

  fprintf(stderr, "\n");
}

int main(int argc, const char** argv) {
  netdump::NetdumpOptions options;
  std::vector<std::string> args(argv + 1, argv + argc);
  if (parse_args(args.begin(), args.end(), &options)) {
    return -1;
  }

  int fd;
  if ((fd = open(options.device.c_str(), O_RDWR)) < 0) {
    std::cerr << "netdump: cannot open '" << options.device << "'" << std::endl;
    return -1;
  }

  zx::channel svc;
  zx_status_t status = fdio_get_service_handle(fd, svc.reset_and_get_address());
  if (status != ZX_OK) {
    std::cerr << "netdump: failed to get service handle" << std::endl;
    return -1;
  }

  fuchsia_hardware_ethernet_Fifos fifos;
  zx_status_t call_status = ZX_OK;
  status = fuchsia_hardware_ethernet_DeviceGetFifos(svc.get(), &call_status, &fifos);
  if (status != ZX_OK || call_status != ZX_OK) {
    std::cerr << "netdump: failed to get fifos: " << status << ", " << call_status << std::endl;
    return -1;
  }
  zx::fifo rx_fifo = zx::fifo(fifos.rx);

  unsigned count = fifos.rx_depth / 2;
  zx::vmo iovmo;
  // Allocate shareable ethernet buffer data heap with no options. Non-resizable by default.
  if ((status = zx::vmo::create(count * BUFSIZE, 0, &iovmo)) < 0) {
    return -1;
  }

  char* iobuf;
  if ((status = zx_vmar_map(zx_vmar_root_self(), ZX_VM_PERM_READ | ZX_VM_PERM_WRITE, 0, iovmo.get(),
                            0, count * BUFSIZE, reinterpret_cast<uintptr_t*>(&iobuf))) < 0) {
    return -1;
  }

  status = fuchsia_hardware_ethernet_DeviceSetIOBuffer(svc.get(), iovmo.get(), &call_status);
  if (status != ZX_OK || call_status != ZX_OK) {
    std::cerr << "netdump: failed to set iobuf: " << status << ", " << call_status << std::endl;
    return -1;
  }

  status = fuchsia_hardware_ethernet_DeviceSetClientName(svc.get(), "netdump", 7, &call_status);
  if (status != ZX_OK || call_status != ZX_OK) {
    std::cerr << "netdump: failed to set client name: " << status << ", " << call_status
              << std::endl;
  }

  if (options.promisc) {
    status = fuchsia_hardware_ethernet_DeviceSetPromiscuousMode(svc.get(), true, &call_status);
    if (status != ZX_OK || call_status != ZX_OK) {
      std::cerr << "netdump: failed to set promisc mode: " << status << ", " << call_status
                << std::endl;
    }
  }

  // assign data chunks to ethbufs
  for (unsigned n = 0; n < count; ++n) {
    eth_fifo_entry_t entry = {
        .offset = static_cast<uint32_t>(n * BUFSIZE),
        .length = BUFSIZE,
        .flags = 0,
        .cookie = 0,
    };
    if ((status = zx_fifo_write(fifos.rx, sizeof(entry), &entry, 1, nullptr)) < 0) {
      std::cerr << "netdump: failed to queue rx packet: " << status << std::endl;
      return -1;
    }
  }

  status = fuchsia_hardware_ethernet_DeviceStart(svc.get(), &call_status);
  if (status != ZX_OK || call_status != ZX_OK) {
    std::cerr << "netdump: failed to start network interface" << std::endl;
    return -1;
  }

  status = fuchsia_hardware_ethernet_DeviceListenStart(svc.get(), &call_status);
  if (status != ZX_OK || call_status != ZX_OK) {
    std::cerr << "netdump: failed to start listening" << std::endl;
    return -1;
  }

  zx_handle_t directory_request = zx_take_startup_handle(PA_DIRECTORY_REQUEST);
  if (directory_request != ZX_HANDLE_INVALID) {
    // We don't serve anything, we can close the directory request immediately.
    // This is used in integration tests as a signal that netdump is running and attached to the
    // device; if one day netdump needs to serve anything the integration tests need to be updated.
    zx_handle_close(directory_request);
  }
  netdump::Stats stats = {};
  handle_rx(rx_fifo, iobuf, count, options, &stats);

  if (options.dumpfile_fd != -1) {
    close(options.dumpfile_fd);
  }

  if (options.print_format == netdump::PrintFormat::LOG ||
      options.print_format == netdump::PrintFormat::HEXDUMP) {
    show_stats(stats);
  }

  return 0;
}
