<sect1 id="npcap-api">
  <title>The Npcap API</title>
  <sect1info>
    <abstract>
      <para>The Npcap Application Programming Interface (<acronym>API</acronym>) consists of the
        libpcap API and a few non-portable extensions: <code>pcap_setbuff</code>, 
          <code>pcap_setuserbuffer</code>,
          <code>pcap_setmintocopy</code>,
          <code>pcap_getevent</code>,
          <code>pcap_setmode</code>,
          <code>pcap_oid_get_request</code> and <code>pcap_oid_set_request</code>,
          functions for batch-sending packets with <code>pcap_send_queue</code>,
          and <code>pcap_stats_ex</code>.
        </para>
    </abstract>
  </sect1info>

  <para>The Npcap API is exported by <filename>wpcap.dll</filename> and is the
	  Windows port of <ulink url="https://www.tcpdump.org/">libpcap</ulink>.
	  The API and functions are described in
          <ulink url="wpcap/pcap.html">the pcap(1) man page</ulink>.
          This port varies from the standard Unix libpcap API in just a few ways.
          First, the <literal>pcap_get_selectable_fd()</literal> and
          <literal>pcap_get_required_select_timeout()</literal>
          functions are not defined or exported. Second, as described in
          <xref linkend="npcap-api-extensions"/>, Npcap extends the libpcap API with
          a set of non-portable functions. Lastly, Npcap includes functions from the
          remote capture API of libpcap, which is described in
          <xref linkend="npcap-api-remote"/>.
  </para>

  <sect2 id="npcap-api-extensions">
    <title>Extensions to libpcap for Windows</title>
    <para>
      There are a few extensions to libpcap that exist only on Windows.
      Software that uses these extensions will not be portable to non-Windows
      systems. The following is a brief list of these extensions and their purpose.
    </para>
    <variablelist>
      <varlistentry>
        <term>
          <code>pcap_setbuff</code>
        </term>
        <listitem>
          <para>
            Sets the size of the kernel buffer associated with an adapter.
          </para>
          <code>int pcap_setbuff(pcap_t *p, int dim);</code>
          <para><literal>dim</literal> specifies the size of the buffer in
            bytes. The return value is 0 when the call succeeds, -1 otherwise.
            If an old buffer was already created with a previous call to
            <literal>pcap_setbuff()</literal>, it is deleted and its content is
            discarded. <ulink
              url="wpcap/pcap_open_live.html">pcap_open_live()</ulink> creates
            a 1 MByte buffer by default.
          </para>
	  <para>
            <emphasis>Portability note:</emphasis> libpcap provides the <ulink
              url="wpcap/pcap_set_buffer_size.html">pcap_set_buffer_size()</ulink>
            function for setting the kernel buffer size.  This removes the need
            to use the non-portable <literal>pcap_setbuff()</literal> for this
            purpose.
          </para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>
          <code>pcap_setmode</code>
        </term>
        <listitem>
          <para>Sets the working mode of the interface.</para>
          <code>int pcap_setmode(pcap_t *p, int mode);</code>
          <para>
            Valid values for mode are <literal>MODE_CAPT</literal> (default
            capture mode) and <literal>MODE_STAT</literal> (statistical mode).
            See <xref linkend="npcap-tutorial-statistics" /> for details about
            statistical mode.
          </para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>
          <code>pcap_setmintocopy</code>
        </term>
        <listitem>
          <para>
            Sets the minumum amount of data received by the kernel in a single call.
          </para>
          <code>int pcap_setmintocopy(pcap_t *p, int size);</code>

          <para>
            This function changes the minimum amount of data in the
            kernel buffer that causes a read from the application to return
            (unless the timeout expires). If the value of
            <literal>size</literal> is large, the kernel is forced to wait the
            arrival of several packets before
            copying the data to the user. This guarantees a low number of
            system calls, i.e. low processor usage, and is a good setting for
            applications like packet-sniffers and protocol analyzers. Vice
            versa, in presence of a small value for this variable, the kernel
            will copy the packets as soon as the application is ready to
            receive them. This is useful for real time applications that need
            the best responsiveness from the kernel. <ulink
              url="wpcap/pcap_open_live.html">pcap_open_live()</ulink> sets a
            default <literal>size</literal> value of 16000 bytes.
          </para>
          <para>
            <emphasis>Portability note:</emphasis> libpcap provides the <ulink
              url="wpcap/pcap_set_immediate_mode.html">pcap_set_immediate_mode()</ulink>
            function for applications that need to receive packets as soon as
            they arrive. This removes the need to use the non-portable
            <literal>pcap_setmintocopy()</literal> for this purpose.
          </para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>
          <code>pcap_getevent</code>
        </term>
        <listitem>
          <para>Returns the handle of the event associated with the interface.</para>
          <code>HANDLE pcap_getevent(pcap_t *p);</code>

          <para> This event can be passed to functions like
            <literal>WaitForSingleObject()</literal> or
            <literal>WaitForMultipleObjects()</literal> to wait until the
            driver's buffer contains some data without performing a read.
          </para>

          <para>
            <emphasis>Portability note:</emphasis> This function is the Windows
            alternative to <ulink
              url="wpcap/pcap_get_selectable_fd.html">pcap_get_selectable_fd()</ulink>,
            which is only available on UNIX-like systems.
	  </para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>
          <code>pcap_oid_get_request</code> and <code>pcap_oid_set_request</code>
        </term>
        <listitem>
          <para>Send an OID request to the underlying NDIS drivers</para>
          <code>int pcap_oid_get_request(pcap_t *, bpf_u_int32, void *, size_t *);</code>
          <code>int pcap_oid_set_request(pcap_t *, bpf_u_int32, const void *, size_t *);</code>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>
          Queuing sent packets with <code>pcap_send_queue</code>
        </term>
        <listitem>
          <para>
            Npcap has the ability to queue multiple raw packets for
            transmission on the network in a single call. This is more
            efficient than issuing a series of
            <literal>pcap_sendpacket()</literal>, because the packets are
            buffered in the kernel driver, so the number of context switches is
            reduced.
          </para>
          <code>pcap_send_queue* pcap_sendqueue_alloc(u_int memsize);</code>
          <code>void pcap_sendqueue_destroy(pcap_send_queue* queue);</code>
          <para>Allocate a send queue as a buffer of <literal>memsize</literal>
            bytes. The <literal>pcap_send_queue</literal> allocated can be
            freed with <literal>pcap_sendqueue_destroy()</literal>.</para>
          <code>int pcap_sendqueue_queue(pcap_send_queue* queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data);</code>
          <para>
            <literal>pcap_sendqueue_queue()</literal> adds a packet at the end
            of the send queue pointed by the <literal>queue</literal>
            parameter.  <literal>pkt_header</literal> points to a
            <literal>pcap_pkthdr</literal> structure with the timestamp and the
            length of the packet, <literal>pkt_data</literal> points to a
            buffer with the data of the packet.
          </para>

          <para>
            The <literal>pcap_pkthdr</literal> structure is the same used by
            Npcap and libpcap to store the packets in a file, therefore sending
            a capture file is straightforward. 'Raw packet' means that the
            sending application will have to include the protocol headers,
            since every packet is sent to the network 'as is'. The CRC of the
            packets needs not to be calculated, because it will be
            transparently added by the network interface.
          </para>
          <code>u_int pcap_sendqueue_transmit(pcap_t *p, pcap_send_queue* queue, int sync);</code>
          <para>
            This function transmits the content of a queue to the wire.
            <literal>p</literal> is a pointer to the adapter on which the
            packets will be sent, <literal>queue</literal> points to a
            <literal>pcap_send_queue</literal> structure containing the packets
            to send), <literal>sync</literal> determines if the send operation
            must be synchronized: if it is non-zero, the packets are sent
            respecting the timestamps, otherwise they are sent as fast as
            possible.
          </para>

          <para>
            The return value is the amount of bytes actually sent. If it is
            smaller than the <literal>size</literal> parameter, an error
            occurred during the send.  The error can be caused by a
            driver/adapter problem or by an inconsistent/bogus send queue.
          </para>

          <para>
            <emphasis>Performance note:</emphasis> When <literal>sync</literal>
            is set to <literal>TRUE</literal>, the packets are synchronized in
            the kernel with a high precision timestamp.  This requires a
            non-negligible amount of CPU, but allows normally to send the
            packets with a precision of some microseconds (depending on the
            accuracy of the performance counter of the machine). Such a
            precision cannot be reached sending the packets with
            <literal>pcap_sendpacket()</literal>.
          </para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>
          <code>pcap_stats_ex</code>
        </term>
        <listitem>
          <code>struct pcap_stat *pcap_stats_ex(pcap_t *p, int *pcap_stat_size);</code>
          <para>
            <literal>pcap_stats_ex()</literal> extends the
            <literal>pcap_stats()</literal> allowing to return more statistical
            parameters than the old call.  One of the advantages of
            this new call is that the <literal>pcap_stat</literal> structure is
            not allocated by the user; instead, it is returned back by the
            system. This allow to extend the <literal>pcap_stat</literal>
            structure without affecting backward compatibility on older
            applications. These will simply check at the values of the members
            at the beginning of the structure, while only newest applications
            are able to read new statistical values, which are appended in
            tail.
          </para>

          <para>
            To be sure not to read a piece of memory which has not been allocated
            by the system, the variable <literal>pcap_stat_size</literal> will
            return back the size of the structure <literal>pcap_stat</literal>
            allocated by the system.
          </para>

          <para>
            <literal>p</literal>: pointer to the <literal>pcap_t</literal>
            currently in use. <literal>pcap_stat_size</literal>: pointer to an
            integer that will contain (when the function returns back) the size
            of the structure <literal>pcap_stat</literal> as it has been
            allocated by the system.
          </para>

          <para>
            The function returns a pointer to a pcap_stat structure, that will
            contain the statistics related to the current device. The return
            value is <literal>NULL</literal> in case of errors, and the error
            text can be obtained with <literal>pcap_perror()</literal> or
            <literal>pcap_geterr()</literal>.
          </para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>
          <code>pcap_setuserbuffer</code>
        </term>
        <listitem>
          <para>Sets the size of the buffer that accepts packets from the kernel driver.</para>
          <code>int pcap_setuserbuffer(pcap_t *p, int size);</code>

          <para>
            The size of the packet buffer is a parameter that can sensibly
            influence the performance of the capture process, since this buffer
            will contain the packets received from the the Npcap driver. The
            driver is able to return several packets using a single read call,
            and the number of packets transferable to the application in a call
            is limited only by the size of this buffer.  Therefore setting a
            larger buffer siz can noticeably decrease the number of system
            calls, reducing the impact of the capture process on the processor.
          </para>
        </listitem>
      </varlistentry>

    </variablelist>
  </sect2>

  <sect2 id="npcap-api-remote">
    <title>The libpcap remote capture API</title>
    <para>
      WinPcap introduced several additional functions to the libpcap API in
      order to support remote capture. While the upstream libpcap project has
      absorbed these functions, they have not yet published documentation on
      them. Here is a brief overview.
    </para>
    <variablelist>
      <varlistentry>
        <term>
          <code>pcap_open</code>
        </term>
        <listitem>
          <para>
            Opens a remote or local capture handle.
          </para>
	  <code>pcap_t* pcap_open(const char * source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf);</code>
          <para>
            This routine can open a savefile, a local device, or a device on
            a remote machine running an RPCAP server.
          </para>
          <variablelist>
            <varlistentry>
              <term><code>source</code></term>
              <listitem>
                <para>
                  Zero-terminated string containing the source name to open.
                  The source name must be in one of the following formats:
                </para>
                <itemizedlist>
                  <listitem><para><literal>file://path/to/file.pcap</literal></para></listitem>
                  <listitem><para>
                      <literal>rpcap://devicename</literal> (or the equivalent,
                      <literal>devicename</literal>)
                  </para></listitem>
                  <listitem><para><literal>rpcap://host/devicename</literal></para></listitem>
                  <listitem><para><literal>rpcap://host:port/devicename</literal></para></listitem>
                </itemizedlist>
                <para>
                  Adapter names returned by <literal>pcap_findalldevs_ex()</literal>
                  are already in this format. For convenience, compatible source
                  strings can be built with the helper function,
                  <literal>int pcap_createsrcstr(char *source, int type, const char *host, const char *port, const char *name, char *errbuf)</literal>,
                  where <literal>type</literal> is one of
                  <literal>PCAP_SRC_FILE</literal>,
                  <literal>PCAP_SRC_IFLOCAL</literal>, or
                  <literal>PCAP_SRC_IFREMOTE</literal>,
                  and <literal>source</literal> is a user-allocated buffer of
                  at least <literal>PCAP_BUF_SIZE</literal> bytes.
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term><code>snaplen</code></term>
              <listitem>
                <para>
                  See the documentation for
                  <ulink url="wpcap/pcap_open_live.html">pcap_open_live()</ulink>.
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term><code>flags</code></term>
              <listitem>
                <para>
                  Keeps several flags that can be needed for capturing packets.
                  The allowed flags are defined in the pcap_open() flags .
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term><code>read_timeout></code></term>
              <listitem>
                <para>
                  See the documentation for
                  <ulink url="wpcap/pcap_open_live.html">pcap_open_live()</ulink>.
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term><code>auth</code></term>
              <listitem>
                <para>
                  A pointer to a 'struct pcap_rmtauth' that keeps the
                  information required to authenticate the user on a remote
                  machine. In case this is not a remote capture, this pointer
                  can be set to NULL.
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term><code>errbuf</code></term>
              <listitem>
                <para>
                <para>
                  See the documentation for
                  <ulink url="wpcap/pcap_open_live.html">pcap_open_live()</ulink>.
                </para>
              </listitem>
            </varlistentry>
          </variablelist>
 
          <para>
            <emphasis>Portability notes:</emphasis> For opening a savefile, the
            <ulink url="wpcap/pcap_open_offline.html">pcap_open_offline</ulink>
            routines can be used, and will work just as well; code using them
            will work on more platforms than code using <literal>pcap_open()</literal>
            to open savefiles.
          </para>
 
          <para>
            For opening a local device,
            <ulink url="wpcap/pcap_open_live.html">pcap_open_live()</ulink>
            can be used; it supports most of the capabilities than
            <literal>pcap_open()</literal> supports, and code using it will work
            on more platforms than code using <literal>pcap_open()</literal>.
            <ulink url="wpcap/pcap_create.html">pcap_create()</ulink> and
            <ulink url="wpcap/pcap_activate.html">pcap_activate()</literal>
            can also be used; they support all capabilities that
            <literal>pcap_open()</literal> supports, except for the Windows-only
            <literal>PCAP_OPENFLAG_NOCAPTURE_LOCAL</literal>,
            and they support additional capabilities.
          </para>
 
          <para>
            For opening a remote capture, <literal>pcap_open()</literal> is
            currently the only API available.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term>
          <code>pcap_findalldevs_ex</code>
        </term>
        <listitem>
          <para>
            Lists local and remote capture sources.
          </para>
          <code>int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf);</code>
          <variablelist>
            <varlistentry>
              <term><code>source</code></term>
              <listitem>
                <para>
                  Zero-terminated string containing the source name to list.
                  The source name must be in one of the following formats:
                </para>
                <itemizedlist>
                  <listitem><para>
                      <literal>file://path/to/directory</literal>
                      - lists capture files in a directory
                  </para></listitem>
                  <listitem><para>
                      <literal>rpcap://</literal> - lists local adapters
                  </para></listitem>
                  <listitem><para>
                      <literal>rpcap://host[:port]</literal>
                        - lists remote adapters
                  </para></listitem>
                </itemizedlist>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term><code>auth</code></term>
              <listitem>
                <para>See <literal>pcap_open()</literal>.</para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term><code>alldevs</code></term>
              <listitem>
                <para>
                  See <ulink href="wpcap/pcap_findalldevs.html">pcap_findalldevs()</ulink>.
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term><code>errbuf</code></term>
              <listitem>
                <para>
                  See <ulink href="wpcap/pcap_findalldevs.html">pcap_findalldevs()</ulink>.
                </para>
              </listitem>
            </varlistentry>
          </variablelist>
          <para>
            As with <literal> pcap_findalldevs()</literal>, the buffer returned in
            <literal>alldevs</literal> must be freed using
            <ulink href="wpcap/pcap_freealldevs.html">pcap_freealldevs()</ulink>.
          </para>
        </listitem>
      </varlistentry>
    </variablelist>
  </sect2>
</sect1>
