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

// Fuchsia's libpcap module.
//
// As per doc/README.capture-module,
//
//   The module should be a C source file, with a name of the form
//   pcap-{MOD}.c, where {MOD} is a name appropriate for your device; for
//   example, the support for DAG cards is in pcap-dag.c, and the support for
//   capturing USB traffic on Linux is pcap-usb-linux.c.
//
//   Your module is assumed to support one or more named devices.  The names
//   should be relatively short names, containing only lower-case
//   alphanumeric characters, consisting of a prefix that ends with an
//   alphabetic character and, if there can be more than one device instance,
//   possibly followed by a numerical device ID, such as "mydevice" or
//   "mydevice0"/"mydevice1"/....  If you have more than one type of device
//   that you can support, you can have more than one prefix, each of which
//   can be followed by a numerical device ID.
//
//   The two exported functions that your module must provide are routines to
//   provide a list of device instances and a program to initialize a
//   created-but-not-activated pcap_t for an instance of one of your devices.
//
// See pcap_platform_finddevs and pcap_create_interface for more details.

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <errno.h>
#include <lib/fit/defer.h>
#include <net/if.h>
#include <netinet/if_ether.h>
#include <poll.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/eventfd.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <zircon/assert.h>

#include <iterator>
#include <limits>
#include <mutex>

#include <netpacket/packet.h>

#include "pcap-fuchsia.h"
#include "pcap-int.h"
#include "pcap/sll.h"

namespace {

int loopback_ifindex() {
  static std::once_flag once_flag;
  static int loopback_ifindex;

  std::call_once(once_flag, [&]() {
    constexpr char kLoopbackDeviceName[] = "lo";

    loopback_ifindex = if_nametoindex(kLoopbackDeviceName);
    if (loopback_ifindex < 0) {
      ZX_PANIC("failed to get interface index for loopback (%s): %s", kLoopbackDeviceName,
               strerror(errno));
    }
  });

  return loopback_ifindex;
}

constexpr char kAnyDeviceDescription[] = "A device that captures on all interfaces";
constexpr char kAnyDeviceName[] = "any";
constexpr int kAnyDeviceIndex = std::numeric_limits<int>::lowest();

pcap_fuchsia *fuchsia_handle(pcap_t *handle) { return static_cast<pcap_fuchsia *>(handle->priv); }

void pcap_cleanup_fuchsia(pcap_t *handle) {
  pcap_fuchsia *const handlep = fuchsia_handle(handle);

  if (handlep->poll_breakloop_fd != 0) {
    close(handlep->poll_breakloop_fd);
    handlep->poll_breakloop_fd = 0;
  }

  pcap_cleanup_live_common(handle);
}

void pcap_setnonblock_fuchsia(pcap_t *handle, bool nonblock) {
  pcap_fuchsia *const handlep = fuchsia_handle(handle);

  if (nonblock) {
    handlep->poll_timeout = 0;
  } else {
    handlep->poll_timeout = handle->opt.timeout;
  }
}

// Returns false iff the packet should be dropped.
bool pcap_check_direction_fuchsia(pcap_direction_t direction, const sockaddr_ll *sll) {
  if (sll->sll_pkttype == PACKET_OUTGOING) {
    switch (direction) {
      case PCAP_D_INOUT:
        // If we are interested in both input and output packets and this packet
        // is outgoing on loopback, drop it in favour of the incoming looped-back
        // packet so clients don't see the same packet twice.
        return sll->sll_ifindex != loopback_ifindex();
      case PCAP_D_IN:
        // We are only interested in incoming packets.
        return false;
      case PCAP_D_OUT:
        return true;
      default:
        ZX_PANIC("unhandled direction value = %d", direction);
    }
  }

  if (direction == PCAP_D_OUT) {
    // We are only interested in outgoing packets.
    return false;
  }

  return true;
}

// Activate a device.
//
// As per doc/README.capture-module,
//
//   Your activate routine takes, as an argument, a pointer to the pcap_t
//   being activated, and returns an int.
//
//   The perameters set for the device in the pcap_create() call, and after
//   that call(), are mostly in the opt member of the pcap_t:
//
//   	device
//   		the name of the device
//
//   	timeout
//   		the buffering timeout, in milliseconds
//
//   	buffer_size
//   		the buffer size to use
//
//   	promisc
//   		1 if promiscuous mode is to be used, 0 otherwise
//
//   	rfmon
//   		1 if monitor mode is to be used, 0 otherwise
//
//   	immediate
//   		1 if the device should be in immediate mode, 0 otherwise
//
//   	nonblock
//   		1 if the device should be in non-blocking mode, 0
//   		otherwise
//
//   	tstamp_type
//   		the type of time stamp to supply
//
//   	tstamp_precision
//   		the time stamp precision to supply
//
//   The snapshot member of the pcap_t structure will contain the snapshot
//   length to be used.
//
//   Your routine should attempt to set up the device for capturing.  If it
//   fails, it must return an error indication which is one of the PCAP_ERROR
//   values.  For PCAP_ERROR, it must also set the errbuf member of the
//   pcap_t to an error string.  For PCAP_ERROR_NO_SUCH_DEVICE and
//   PCAP_ERROR_PERM_DENIED, it may set it to an error string providing
//   additional information that may be useful for debugging, or may just
//   leave it as a null string.
//
//   If it succeeds, it must set certain function pointers in the pcap_t
//   structure:
//
//   	read_op
//   		called whenever packets are to be read
//
//   	inject_op
//   		called whenever packets are to be injected
//
//   	setfilter_op
//   		called whenever pcap_setfilter() is called
//
//   	setdirection_op
//   		called whenever pcap_setdirection() is called
//
//   	set_datalink_op
//   		called whnever pcap_set_datalink() is called
//
//   	getnonblock_op
//   		called whenever pcap_getnonblock() is called
//
//   	setnonblock_op
//   		called whenever pcap_setnonblock() is called
//
//   	stats_op
//   		called whenever pcap_stats() is called
//
//   	cleanup_op
//   		called if the activate routine fails or pcap_close() is
//   		called
//
//   and must also set the linktype member to the DLT_ value for the device.
//
//   On UN*Xes, if the device supports waiting for packets to arrive with
//   select()/poll()/epoll()/kqueues etc., it should set the selectable_fd
//   member of the structure to the descriptor you would use with those
//   calls.  If it does not, then, if that's because the device polls for
//   packets rather than receiving interrupts or other signals when packets
//   arrive, it should have a struct timeval in the private data structure,
//   set the value of that struct timeval to the poll timeout, and set the
//   required_select_timeout member of the pcap_t to point to the struct
//   timeval.
int pcap_activate_fuchsia(pcap_t *handle) {
  pcap_fuchsia *const handlep = fuchsia_handle(handle);

  // Cancelled on success.
  auto on_error_defer_cleanup = fit::defer([&] { pcap_cleanup_fuchsia(handle); });

  if (handle->opt.rfmon) {
    return PCAP_ERROR_RFMON_NOTSUP;
  }

  if (strcmp(handle->opt.device, kAnyDeviceName) == 0) {
    handlep->ifindex = kAnyDeviceIndex;
  } else {
    handlep->ifindex = if_nametoindex(handle->opt.device);
    if (handlep->ifindex < 0) {
      if (errno == ENXIO) {
        return PCAP_ERROR_NO_SUCH_DEVICE;
      }
      pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, errno, "if_nametoindex");
      return PCAP_ERROR;
    }
  }

  if (handle->opt.promisc) {
    if (handlep->ifindex == loopback_ifindex()) {
      fprintf(stderr, "Loopback does not have a promiscuous mode; ignoring...\n");
    } else if (handlep->ifindex == kAnyDeviceIndex) {
      fprintf(stderr, "The any device does not have a promiscuous mode; ignoring...\n");
    } else {
      // TODO(https://fxbug.dev/88038): Put the device in promiscuous mode.
      pcap_strlcpy(handle->errbuf, "promiscuous mode not supported", PCAP_ERRBUF_SIZE);
      return PCAP_WARNING_PROMISC_NOTSUP;
    }
  }

  // Open a packet socket.
  //
  // TODO(https://fxbug.dev/88035): Only open a SOCK_DGRAM packet socket if this
  // is the any device so that we can parse the link headers of the device we
  // are bound to.
  handle->linktype = DLT_LINUX_SLL2;
  fprintf(stderr, "Only cooked (SOCK_DGRAM) packet sockets supported on Fuchsia\n");
  // Always start the socket in non-blocking mode - we block with poll.
  handle->fd = socket(AF_PACKET, SOCK_DGRAM | SOCK_NONBLOCK, 0);
  if (handle->fd < 0) {
    pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, errno, "socket");
    if (errno == EPERM || errno == EACCES) {
      // No access to packet sockets.
      return PCAP_ERROR_PERM_DENIED;
    }
    return PCAP_ERROR;
  }
  handle->selectable_fd = handle->fd;

  // Bind the packet socket to the device and start receiving packets.
  const sockaddr_ll sll = {
      .sll_family = AF_PACKET,
      .sll_protocol = htons(ETH_P_ALL),
      .sll_ifindex = (handlep->ifindex == kAnyDeviceIndex) ? 0 : handlep->ifindex,
  };
  if (bind(handle->fd, reinterpret_cast<const sockaddr *>(&sll), sizeof(sll)) != 0) {
    pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, errno, "bind");

    switch (errno) {
      case ENETDOWN:
        return PCAP_ERROR_IFACE_NOT_UP;
      case ENODEV:
        return PCAP_ERROR_NO_SUCH_DEVICE;
      default:
        return PCAP_ERROR;
    }
  }

  pcap_setnonblock_fuchsia(handle, handle->opt.nonblock != 0);

  // Allocate a buffer to hold a single packet.
  if (handle->snapshot <= 0 || handle->snapshot > MAXIMUM_SNAPLEN) {
    handle->snapshot = MAXIMUM_SNAPLEN;
  }
  handle->buffer = malloc(handle->snapshot);
  if (handle->buffer == NULL) {
    pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, errno,
                              "can't allocate packet buffer");
    return PCAP_ERROR;
  }
  handle->bufsize = handle->snapshot;

  // Attempts to read packets from the device.
  //
  // As per doc/README.capture-module,
  //
  //   The read_op routine is called when pcap_dispatch(), pcap_loop(),
  //   pcap_next(), or pcap_next_ex() is called.  It is passed the same
  //   arguments as pcap_dispatch() is called.
  //
  //   The routine should first check if the break_loop member of the pcap_t is
  //   non-zero and, if so, set that member to zero and return
  //   PCAP_ERROR_BREAK.
  //
  //   Then, if the pcap_t is in blocking mode (as opposed to non-blocking
  //   mode), and there are no packets immediately available to be passed to
  //   the callback, it should block waiting for packets to arrive, using the
  //   buffering timeout, first, and read packets from the device if necessary.
  //
  //   Then it should loop through the available packets, calling the callback
  //   routine for each packet:
  //
  //   	If the PACKET_COUNT_IS_UNLIMITED() macro evaluates to true when
  //   	passed the packet count argument, the loop should continue until
  //   	there are no more packets immediately available or the
  //   	break_loop member of the pcap_t is non-zero.  If the break_loop
  //   	member is fount to be non-zero, it should set that member to
  //   	zero and return PCAP_ERROR_BREAK.
  //
  //   	If it doesn't evaluat to true, then the loop should also
  //   	terminate if the specified number of packets have been delivered
  //   	to the callback.
  //
  //   Note that there is *NO* requirement that the packet header or data
  //   provided to the callback remain available, or valid, after the callback
  //   routine returns; if the callback needs to save the data for other code
  //   to use, it must make a copy of that data.  This means that the module is
  //   free to, for example, overwrite the buffer into which it read the
  //   packet, or release back to the kernel a packet in a memory-mapped
  //   buffer shared between the kernel and userland, after the callback
  //   returns.
  //
  //   If an error occurs when reading packets from the device, it must set the
  //   errbuf member of the pcap_t to an error string and return PCAP_ERROR.
  //
  //   If no error occurs, it must return the number of packets that were
  //   supplied to the callback routine.
  handle->read_op = [](pcap_t *handle, int max_packets, pcap_handler callback,
                       u_char *user) -> int {
    pcap_fuchsia *const handlep = fuchsia_handle(handle);

    // Wait for a packet to be available.
    for (;;) {
      pollfd pfds[] = {
          // Wait for a packet.
          {
              .fd = handle->fd,
              .events = POLLIN,
          },
          // Wait for a signal to break out of the poll.
          {
              .fd = handlep->poll_breakloop_fd,
              .events = POLLIN,
          },
      };

      int n = poll(pfds, std::size(pfds), handlep->poll_timeout);
      if (n == 0) {
        // We timed-out.
        break;
      }
      const pollfd &socket_fd = pfds[0];
      const pollfd &break_fd = pfds[1];

      if (n < 0) {
        if (errno != EINTR) {
          pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, errno, "poll error");
          return PCAP_ERROR;
        }

        // poll returned because a signal occured before a requested event.
        continue;
      }

      if (socket_fd.revents == POLLIN) {
        // A packet is avalable.
        break;
      }

      if (socket_fd.revents != 0) {
        if (socket_fd.revents & POLLNVAL) {
          pcap_strlcpy(handle->errbuf, "invalid polling request on packet socket",
                       PCAP_ERRBUF_SIZE);
          return PCAP_ERROR;
        }

        if (socket_fd.revents & (POLLHUP | POLLRDHUP)) {
          pcap_strlcpy(handle->errbuf, "hangup on packet socket", PCAP_ERRBUF_SIZE);
          return PCAP_ERROR;
        }

        if (socket_fd.revents & POLLERR) {
          int err;
          socklen_t errlen = sizeof(err);
          if (getsockopt(handle->fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) {
            err = errno;
          }

          pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, err,
                                    "error on packet socket");
          return PCAP_ERROR;
        }
      }

      // Were we signalled to break the loop?
      if (break_fd.revents & POLLIN) {
        uint64_t value;
        ssize_t nread = read(handlep->poll_breakloop_fd, &value, sizeof(value));
        if (nread < 0) {
          pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, errno,
                                    "error reading from breakloop FD");
          return PCAP_ERROR;
        }

        if (nread != 0 && (size_t)nread < sizeof(value)) {
          snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
                   "short read from event FD: expected %zu, got %zd", sizeof(value), nread);
          return PCAP_ERROR;
        }

        if (handle->break_loop) {
          handle->break_loop = 0;
          return PCAP_ERROR_BREAK;
        }

        // We were signalled to break the loop but the break_loop flag was not
        // set. We continue to try again.
        continue;
      }
    }

    int processed = 0;
    while (handle->break_loop == 0 &&
           ((processed < max_packets) || PACKET_COUNT_IS_UNLIMITED(max_packets))) {
      sockaddr_ll src_addr;
      socklen_t src_addr_len = sizeof(src_addr);
      uint8_t *buffer = static_cast<uint8_t *>(handle->buffer);
      size_t bufsize = handle->bufsize;

      // reserve the first sizeof(sll2_header) bytes in the packet buffer
      // for the SLL2 header.
      if (bufsize < sizeof(sll2_header)) {
        snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
                 "bufsize shorter than expected; got %zu, want atleast %zu", bufsize,
                 sizeof(sll2_header));
        return PCAP_ERROR;
      }
      ssize_t nread =
          recvfrom(handle->fd, buffer + sizeof(sll2_header), bufsize - sizeof(sll2_header), 0,
                   reinterpret_cast<sockaddr *>(&src_addr), &src_addr_len);
      if (nread < 0) {
        if (errno == EAGAIN) {
          // Nothing else to read for now.
          break;
        }
        pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, errno,
                                  "error reading packet socket");
        return PCAP_ERROR;
      }
      if (src_addr_len != sizeof(src_addr)) {
        snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "invalid address length = %d, want = %lu",
                 src_addr_len, sizeof(src_addr));
        return PCAP_ERROR;
      }
      if (nread == 0) {
        // No more to read.
        break;
      }

      if (!pcap_check_direction_fuchsia(handle->direction, &src_addr)) {
        // We are not interested in this packet's direction.
        continue;
      }

      pcap_pkthdr pcap_header = {
          .caplen = static_cast<bpf_u_int32>(nread + sizeof(sll2_header)),
          .len = static_cast<bpf_u_int32>(nread + sizeof(sll2_header)),
      };

      if (gettimeofday(&pcap_header.ts, NULL) != 0) {
        pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, errno, "gettimeofday");
        return PCAP_ERROR;
      }

      sll2_header sll2 = {
          .sll2_protocol = src_addr.sll_protocol,
          .sll2_reserved_mbz = 0,
          .sll2_if_index = htonl(src_addr.sll_ifindex),
          .sll2_hatype = src_addr.sll_hatype,
          .sll2_pkttype = src_addr.sll_pkttype,
          .sll2_halen = src_addr.sll_halen,
      };
      memcpy(buffer, &sll2, offsetof(sll2_header, sll2_addr));
      memcpy(buffer + offsetof(sll2_header, sll2_addr), src_addr.sll_addr,
             sizeof(src_addr.sll_addr));

      if ((handle->fcode.bf_insns == NULL) ||
          pcap_filter(handle->fcode.bf_insns, buffer, pcap_header.len, pcap_header.caplen)) {
        handlep->stat.ps_recv++;
        processed++;

        callback(user, &pcap_header, buffer);
      }
    }

    if (handle->break_loop) {
      handle->break_loop = 0;
      return PCAP_ERROR_BREAK;
    }

    return processed;
  };

  // Attempts to inject a packet to the device.
  //
  // As per doc/README.capture-module,
  //
  //   The inject routine is passed a pointer to the pcap_t, a buffer
  //   containing the contents of the packet to inject, and the number of bytes
  //   in the packet.  If the device doesn't support packet injection, the
  //   routine must set the errbuf member of the pcap_t to a message indicating
  //   that packet injection isn't supported and return PCAP_ERROR.  Otherwise,
  //   it should attempt to inject the packet; if the attempt fails, it must
  //   set the errbuf member of the pcap_t to an error message and return
  //   PCAP_ERROR.  Otherwise, it should return the number of bytes injected.
  handle->inject_op = [](pcap_t *handle, const void *buf, int size) -> int {
    pcap_strlcpy(handle->errbuf, "injecting packets isn't supported on Fuchsia", PCAP_ERRBUF_SIZE);
    return PCAP_ERROR;
  };

  // Sets a filter for packets.
  //
  // As per doc/README.capture-module,
  //
  //   The setfilter routine is passed a pointer to the pcap_t and a pointer
  //   to a struct bpf_program containing a BPF program to be used as a filter.
  //   If the mechanism used by your module can perform filtering with a BPF
  //   program, it would attempt to set that filter to the specified program.
  //
  //   If that failed because the program was too large, or used BPF features
  //   not supported by that mechanism, the module should fall back on
  //   filtering in userland by saving a copy of the filter with a call to
  //   install_bpf_program(), setting a flag in the private data instructure
  //   indicating that filtering is being done by the module and, in the read
  //   routine's main loop, checking the flag and, if it's set, calling
  //   pcap_filter(), passing it the fcode.bf_insns member of the pcap_t, the
  //   raw packet data, the on-the-wire length of the packet, and the captured
  //   length of the packet, and only passing the packet to the callback
  //   routine, and counting it, if pcap_filter() returns a non-zero value.
  //   (If the flag is not set, all packets should be passed to the callback
  //   routine and counted, as the filtering is being done by the mechanism
  //   used by the module.)  If install_bpf_program() returns a negative value,
  //   the routine should return PCAP_ERROR.
  //
  //   If the attempt to set the filter failed for any other reason, the
  //   routine must set the errbuf member of the pcap_t to an error message and
  //   return PCAP_ERROR.
  //
  //   If the attempt to set the filter succeeded, or it failed because the
  //   mechanism used by the module rejected it and the call to
  //   install_bpf_program() succeeded, the routine should return 0.
  //
  //   If the mechanism the module uses doesn't support filtering, the pointer
  //   to the setfilter routine can just be set to point to
  //   install_bpf_program; the module does not need a routine of its own to
  //   handle that.
  handle->setfilter_op = install_bpf_program;

  // Sets the direction to filter for.
  //
  // As per doc/README.capture-module,
  //
  //   The setdirection routine is passed a pointer to the pcap_t and a
  //   pcap_direction_t indicating which packet directions should be accepted.
  //   If the module can't arrange to handle only incoming packets or only
  //   outgoing packets, it can set the pointer to the setdirection routine to
  //   NULL, and calls to pcap_setdirection() will fail with an error message
  //   indicating that setting the direction isn't supported.
  handle->setdirection_op = [](pcap_t *handle, pcap_direction_t d) -> int {
    handle->direction = d;
    return 0;
  };

  handle->set_datalink_op = [](pcap_t *handle, int dlt) -> int {
    pcap_strlcpy(handle->errbuf, "setting the datalink isn't support on Fuchsia", PCAP_ERRBUF_SIZE);
    return PCAP_ERROR;
  };

  handle->setnonblock_op = [](pcap_t *handle, int nonblock) -> int {
    pcap_setnonblock_fuchsia(handle, nonblock != 0);
    return 0;
  };

  handle->getnonblock_op = [](pcap_t *handle) -> int {
    pcap_fuchsia *const handlep = fuchsia_handle(handle);
    return handlep->poll_timeout == 0;
  };

  handle->cleanup_op = pcap_cleanup_fuchsia;

  handle->stats_op = [](pcap_t *handle, pcap_stat *stat) -> int {
    pcap_fuchsia *const handlep = fuchsia_handle(handle);
    *stat = handlep->stat;
    return 0;
  };

  handle->breakloop_op = [](pcap_t *handle) {
    pcap_breakloop_common(handle);
    pcap_fuchsia *const handlep = fuchsia_handle(handle);

    uint64_t value = 1;
    ssize_t n = write(handlep->poll_breakloop_fd, &value, sizeof(value));
    if (n < 0) {
      ZX_PANIC("failed to write to breaklook fd; %s\n", strerror(errno));
    }
    if (n != sizeof(value)) {
      ZX_PANIC("short write to event FD; expected %zu, got %zd\n", sizeof(value), n);
    }
  };

  // Cancel the deferred cleanup as we did not encounter an error.
  on_error_defer_cleanup.cancel();
  return 0;
}

}  // namespace

// Initializes a created but not yet activated instance of a device.
//
// As per doc/README.capture-module,
//
//   The "initialize the pcap_t" routine takes, as arguments:
//
//   	a pointer to a device name;
//
//   	a pointer to an error message buffer;
//
//   	a pointer to an int.
//
//   It returns a pointer to a pcap_t.
//
//   Your module will probably need, for each pcap_t for an opened device, a
//   private data structure to maintain its own information about the opened
//   device.  These should be allocated per opened instance, not per device;
//   if, for example, mydevice0 can be captured on by more than one program
//   at the same time, there will be more than one pcap_t opened for
//   mydevice0, and so there will be separate private data structures for
//   each pcap_t.  If you need to maintain per-device, rather than per-opened
//   instance information, you will have to maintain that yourself.
//
//   The routine should first check the device to see whether it looks like a
//   device that this module would handle; for example, it should begin with
//   one of the device name prefixes for your module and, if your devices
//   have instance numbers, be followed by a number.  If it is not one of
//   those devices, you must set the integer pointed to by the third
//   argument to 0, to indicate that this is *not* one of the devices for
//   your module, and return NULL.
//
//   If it *is* one of those devices, it should call pcap_create_common,
//   passing to it the error message buffer as the first argument and the
//   size of the per-opened instance data structure as the second argument.
//   If it fails, it will return NULL; you must return NULL in this case.
//
//   If it succeeds, the pcap_t pointed to by the return value has been
//   partially initialized, but you will need to complete the process.  It
//   has a "priv" member, which is a void * that points to the private data
//   structure attached to it; that structure has been initialized to zeroes.
//
//   What you need to set are some function pointers to your routines to
//   handle certain operations:
//
//   	activate_op
//   		the routine called when pcap_activate() is done on the
//   		pcap_t
//
//   	can_set_rfmon_op
//   		the routine called when pcap_can_set_rfmon() is done on
//   		the pcap_t - if your device doesn't support 802.11
//   		monitor mode, you can leave this as initialized by
//   		pcap_create_common(), as that routine will return "no,
//   		monitor mode isn't supported".
//
//   Once you've set the activate_op and, if necessary, the can_set_rfmon_op,
//   you must return the pcap_t * that was returned to you.
pcap_t *pcap_create_interface(const char *device _U_, char *ebuf) {
  pcap_t *const handle = pcap_create_common_fuchsia(ebuf);
  if (handle == NULL) {
    return NULL;
  }

  handle->activate_op = pcap_activate_fuchsia;

  pcap_fuchsia *const handlep = fuchsia_handle(handle);
  handlep->poll_breakloop_fd = eventfd(0, EFD_NONBLOCK);

  return handle;
}

// Returns a list of device instances
//
// As per doc/README.capture-module,
//
//   The "list of device instances" routine takes, as arguments:
//
//   	a pointer to a pcap_if_list_t;
//
//   	a pointer to an error message buffer.
//
//   The error message buffer may be assumed to be PCAP_ERRBUF_SIZE bytes
//   large, but must not be assumed to be larger.  By convention, the routine
//   typically has a name containing "findalldevs".
//
//   The routine should attempt to determine what device instances are
//   available and add them to the list pointed to by the first argument;
//   this may be impossible for some modules, but, for those modules, it may
//   be difficult to capture on the devices using Wirehshark (although it
//   should be possible to capture on them using tcpdump, TShark, or other
//   programs that take a device name on the command line), so we recommend
//   that your routine provide the list of devices if possible.  If it
//   cannot, it should just immediately return 0.
//
//   The routine should add devices to the list by calling the add_dev()
//   routine in libpcap, declared in the pcap-int.h header.  It takes, as
//   arguments:
//
//   	the pointer to the pcap_if_list_t passed as an argument to the
//   	routine;
//
//   	the device name, as described above;
//
//   	a 32-bit word of flags, as provided by pcap_findalldevs();
//
//   	a text description of the device, or NULL if there is no
//   	description;
//
//   	the error message buffer pointer provided to the routine.
//
//   add_dev() will, if it succeeds, return a pointer to a pcap_if_t that was
//   added to the list of devices.  If it fails, it will return NULL; in this
//   case, the error message buffer has been filled in with an error string,
//   and your routine must return -1 to indicate the error.
//
//   If your routine succeeds, it must return 0.  If it fails, it must fill
//   in the error message buffer with an error string and return -1.
int pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf) {
  // Get the list of regular devices.
  int res = pcap_findalldevs_interfaces(
      devlistp, errbuf, [](const char *name) -> int { return 1; } /* can_be_bound */,
      [](const char *name, bpf_u_int32 *flags,
         char *errbuf) { /* get_if_flags */
                         if (*flags & PCAP_IF_LOOPBACK) {
                           *flags |= PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE;
                         }

                         // TODO(https://fxbug.dev/88036): Set PCAP_IF_WIRELESS
                         // and/or PCAP_IF_CONNECTION_STATUS_* if needed.

                         return 0;
      });
  if (res != 0) {
    return -1;
  }

  // Add the any device used to capture on all devices.
  if (add_dev(devlistp, kAnyDeviceName,
              PCAP_IF_UP | PCAP_IF_RUNNING | PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE,
              kAnyDeviceDescription, errbuf) == NULL) {
    return -1;
  }

  return 0;
}
