<sect1 id="npcap-tutorial">
  <title>Npcap Development Tutorial</title>
  <sect1info>
    <abstract>
      <para>A step-by-step guide to writing software that uses Npcap to list
        network adapters, capture packets, and send network traffic.</para>
    </abstract>
  </sect1info>

  <para>This section shows how to use the features of the Npcap API. It is
    organized as a tutorial, subdivided into a set of lessons that will
    introduce the reader, in a step-by-step fashion, to program development
    using Npcap, from the basic functions (obtaining the adapter list,
    starting a capture, etc.) to the most advanced ones (handling send queues
    and gathering statistics about network traffic).</para>

  <!-- REVISE
  <para>Several code snippets, as well as simple but complete programs are
    provided as a reference: all of the source code contains links to the rest
    of the manual, making it is possible to click on functions and data
    structures to jump to the corresponding documentation.</para>
-->

  <para>The samples are written in plain C, so a basic knowledge of C
    programming is required. Also, since this is a tutorial about a library
    dealing with "raw" networking packets, good knowledge of networks and
    network protocols is assumed.</para>

  <para>The code in this section is copied from the <xref
      linkend="npcap-examples">Examples directory</xref> in the source
    distribution and the SDK. The code is released under a BSD-3-clause license and
    copyright: NetGroup, Politecnico di Torino (Italy); CACE Technologies,
    Davis (California); and Insecure.com, LLC. Full text of the code license
    can be found in each source file.</para>

  <sect2 id="npcap-tutorial-devlist">
    <title>Obtaining the device list</title>
    <para>Typically, the first thing that a Npcap-based application does is
      get a list of attached network adapters. Both libpcap and Npcap provide
      the <ulink url="wpcap/pcap_findalldevs.html">pcap_findalldevs_ex()</ulink> function for this purpose:
      this function returns a linked list of <literal>pcap_if</literal> structures, each of which contains
      comprehensive information about an attached adapter. In particular, the
      fields <literal>name</literal> and <literal>description</literal> contain the name and a
      human readable description, respectively, of the corresponding
      device.</para>

    <para>The following code retrieves the adapter list and shows it on the
      screen, printing an error if no adapters are found.</para>

    <programlisting language="C"><!-- inline --><![CDATA[
#include "pcap.h"

main()
{
  pcap_if_t *alldevs;
  pcap_if_t *d;
  int i=0;
  char errbuf[PCAP_ERRBUF_SIZE];
  
  /* Retrieve the device list from the local machine */
  if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING,
    NULL /* auth is not needed */,
    &alldevs, errbuf) == -1)
  {
    fprintf(stderr,
      "Error in pcap_findalldevs_ex: %s\n",
      errbuf);
    exit(1);
  }
  
  /* Print the list */
  for(d= alldevs; d != NULL; d= d->next)
  {
    printf("%d. %s", ++i, d->name);
    if (d->description)
      printf(" (%s)\n", d->description);
    else
      printf(" (No description available)\n");
  }
  
  if (i == 0)
  {
    printf("\nNo interfaces found! Make sure Npcap is installed.\n");
    return;
  }

  /* We don't need any more the device list. Free it */
  pcap_freealldevs(alldevs);
}
]]></programlisting>

    <para>Some comments about this code.</para>

    <para>First of all, <ulink
        url="./wpcap/pcap_findalldevs.html">pcap_findalldevs_ex()</ulink>, like
      other libpcap functions, has an <literal>errbuf</literal> parameter. This
      parameter points to a string filled by libpcap with a description of the
      error if something goes wrong.</para>

    <para>Second, remember that not all the OSes supported by libpcap provide a
      description of the network interfaces, therefore if we want to write a
      portable application, we must consider the case in which
      <literal>description</literal> is null: we print the string "No
      description available" in that situation.</para>

    <para>Note finally that we free the list with <ulink
        url="wpcap/pcap_findalldevs.html">pcap_freealldevs()</ulink> once when
      we have finished with it.</para>

    <para>Assuming we have compiled the program, let's try to run it. On a
      particular Windows workstation, the result we optained is</para>

    <screen>
1. \Device\NPF_{4E273621-5161-46C8-895A-48D0E52A0B83} (Realtek RTL8029(AS) Ethernet Adapter)
2. \Device\NPF_{5D24AE04-C486-4A96-83FB-8B5EC6C7F430} (3Com EtherLink PCI)</screen>
    
    <para>As you can see, the name of the network adapters (that will be passed
      to libpcap when opening the devices) under Windows are quite unreadable,
      so the parenthetical descriptions can be very helpful.</para>
  </sect2>

  <sect2 id="npcap-tutorial-devdetails">
    <title>Obtaining advanced information about installed devices</title>

    <para>Lesson 1 (<xref linkend="npcap-tutorial-devlist" />) demonstrated how
      to get basic information (i.e. device name and description) about
      available adapters. Actually, Npcap provides also other advanced
      information. In particular, every <literal>pcap_if</literal> structure
      returned by <ulink
        url="wpcap/pcap_findalldevs.html">pcap_findalldevs_ex()</ulink>
      contains also a list of <literal>pcap_addr</literal> structures,
      with:</para>

    <itemizedlist>
      <listitem>a list of addresses for that interface.</listitem>
      <listitem>a list of netmasks (each of which corresponds to an entry in
        the addresses list).</listitem>
      <listitem>a list of broadcast addresses (each of which corresponds to an
        entry in the addresses list).</listitem>
      <listitem>a list of destination addresses (each of which corresponds to
        an entry in the addresses list).</listitem>
    </itemizedlist>

    <para>Additionally, <literal>pcap_findalldevs_ex()</literal> can also
      return remote adapters and a list of pcap files that are located in a
      given local folder.</para>

    <para>The following sample provides an ifprint() function that prints the
      complete contents of a <literal>pcap_if</literal> structure. It is
      invoked by the program for every entry returned by
      <literal>pcap_findalldevs_ex()</literal>.</para>

    <programlisting language="C"><!-- Examples/iflist/iflist.c --><![CDATA[
/* Print all the available information on the given interface */
void ifprint(pcap_if_t *d)
{
  pcap_addr_t *a;
  char ip6str[128];

  /* Name */
  printf("%s\n",d->name);

  /* Description */
  if (d->description)
    printf("\tDescription: %s\n",d->description);

  /* Loopback Address*/
  printf("\tLoopback: %s\n",(d->flags & PCAP_IF_LOOPBACK)?"yes":"no");

  /* IP addresses */
  for(a=d->addresses;a;a=a->next) {
    printf("\tAddress Family: #%d\n",a->addr->sa_family);
  
    switch(a->addr->sa_family)
    {
      case AF_INET:
        printf("\tAddress Family Name: AF_INET\n");
        if (a->addr)
          printf("\tAddress: %s\n",iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr));
        if (a->netmask)
          printf("\tNetmask: %s\n",iptos(((struct sockaddr_in *)a->netmask)->sin_addr.s_addr));
        if (a->broadaddr)
          printf("\tBroadcast Address: %s\n",iptos(((struct sockaddr_in *)a->broadaddr)->sin_addr.s_addr));
        if (a->dstaddr)
          printf("\tDestination Address: %s\n",iptos(((struct sockaddr_in *)a->dstaddr)->sin_addr.s_addr));
        break;

      case AF_INET6:
        printf("\tAddress Family Name: AF_INET6\n");
        if (a->addr)
          printf("\tAddress: %s\n", ip6tos(a->addr, ip6str, sizeof(ip6str)));
       break;

      default:
        printf("\tAddress Family Name: Unknown\n");
        break;
    }
  }
  printf("\n");
}
]]></programlisting>

  </sect2>

  <sect2 id="npcap-tutorial-openadapter">
    <title>Opening an adapter and capturing the packets</title>

    <para>Now that we've seen how to obtain an adapter to play with, let's
      start the real job, opening an adapter and capturing some traffic. In
      this lesson we'll write a program that prints some information about each
      packet flowing through the adapter.</para>

    <para>The function that opens a capture device is <ulink
        url="wpcap/pcap_open.html">pcap_open()</ulink>. The parameters,
      <literal>snaplen</literal>, <literal>flags</literal> and
      <literal>to_ms</literal> deserve some explanation.</para>

    <para><literal>snaplen</literal> specifies the portion of the packet to capture. On
      some OSes (like xBSD and Win32), the packet driver can be configured to
      capture only the initial part of any packet: this decreases the amount of
      data to copy to the application and therefore improves the efficiency of
      the capture. In this case we use the value 65536 which is higher than the
      greatest MTU that we could encounter. In this manner we ensure that the
      application will always receive the whole packet.</para>

    <para><literal>flags:</literal> the most important flag is the one that
      indicates if the adapter will be put in promiscuous mode. In normal
      operation, an adapter only captures packets from the network that are
      destined to it; the packets exchanged by other hosts are therefore
      ignored. Instead, when the adapter is in promiscuous mode it captures all
      packets whether they are destined to it or not. This means that on shared
      media (like non-switched Ethernet), Npcap will be able to capture the
      packets of other hosts. Promiscuous mode is the default for most capture
      applications, so we enable it in the following example.</para>

    <para><literal>to_ms</literal> specifies the read timeout, in milliseconds.
      A read on the adapter (for example, with <ulink
        url="wpcap/pcap_loop.html">pcap_dispatch()</ulink> or <ulink
        url="wpcap/pcap_next_ex.html">pcap_next_ex()</ulink>) will always
      return after <literal>to_ms</literal> milliseconds, even if no packets
      are available from the network. <literal>to_ms</literal> also defines the
      interval between statistical reports if the adapter is in statistical
      mode (see the lesson "\ref wpcap_tut9" for information about statistical
      mode). Setting <literal>to_ms</literal> to 0 means no timeout, a read on
      the adapter never returns if no packets arrive. A -1 timeout on the other
      side causes a read on the adapter to always return immediately.</para>

    <programlisting language="C"><!-- Examples/misc/basic_dump.c --><![CDATA[
#include <pcap.h>
#include "misc.h" /* LoadNpcapDlls */

/* prototype of the packet handler */
void packet_handler(
  u_char *param,
  const struct pcap_pkthdr *header,
  const u_char *pkt_data);

int main()
{
  pcap_if_t *alldevs;
  pcap_if_t *d;
  int inum;
  int i=0;
  pcap_t *adhandle;
  char errbuf[PCAP_ERRBUF_SIZE];
  
  /* Load Npcap and its functions. */
  if (!LoadNpcapDlls())
  {
    fprintf(stderr, "Couldn't load Npcap\n");
    exit(1);
  }

  /* Retrieve the device list on the local machine */
  if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING,
    NULL, &alldevs, errbuf) == -1)
  {
    fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
    exit(1);
  }
  
  /* Print the list */
  for(d=alldevs; d; d=d->next)
  {
    printf("%d. %s", ++i, d->name);
    if (d->description)
      printf(" (%s)\n", d->description);
    else
      printf(" (No description available)\n");
  }
  
  if(i==0)
  {
    printf("\nNo interfaces found! Make sure Npcap is installed.\n");
    return -1;
  }
  
  printf("Enter the interface number (1-%d):",i);
  scanf_s("%d", &inum);
  
  if(inum < 1 || inum > i)
  {
    printf("\nInterface number out of range.\n");
    /* Free the device list */
    pcap_freealldevs(alldevs);
    return -1;
  }
  
  /* Jump to the selected adapter */
  for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
  
  /* Open the device */
  if ( (adhandle= pcap_open(d->name, // name of the device
          65536, // portion of the packet to capture
                 // 65536 guarantees that the whole packet will
                 // be captured on all the link layers
          PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode
          1000, // read timeout
          NULL, // authentication on the remote machine
          errbuf // error buffer
          ) ) == NULL)
  {
    fprintf(stderr,
      "\nUnable to open the adapter. %s is not supported by Npcap\n",
      d->name);
    /* Free the device list */
    pcap_freealldevs(alldevs);
    return -1;
  }
  
  printf("\nlistening on %s...\n", d->description);
  
  /* At this point, we don't need any more the device list. Free it */
  pcap_freealldevs(alldevs);
  
  /* start the capture */
  pcap_loop(adhandle, 0, packet_handler, NULL);
  
  return 0;
}


/* Callback function invoked by libpcap for every incoming packet */
void packet_handler(u_char *param,
  const struct pcap_pkthdr *header,
  const u_char *pkt_data)
{
  struct tm ltime;
  char timestr[16];
  time_t local_tv_sec;

  /*
   * unused variables
   */
  (VOID)(param);
  (VOID)(pkt_data);

  /* convert the timestamp to readable format */
  local_tv_sec = header->ts.tv_sec;
  localtime_s(&ltime, &local_tv_sec);
  strftime( timestr, sizeof timestr, "%H:%M:%S", &ltime);
  
  printf("%s,%.6d len:%d\n",
    timestr, header->ts.tv_usec, header->len);
}
]]></programlisting>

    <para>Once the adapter is opened, the capture can be started with <ulink
        url="wpcap/pcap_loop.html">pcap_dispatch()</ulink> or <ulink
        url="wpcap/pcap_loop.html">pcap_loop()</ulink>. These two functions are
      very similar, the difference is that <literal>pcap_dispatch()</literal>
      returns (although not guaranteed) when the timeout expires while
      <literal>pcap_loop()</literal> doesn't return until
      <literal>cnt</literal> packets have been captured, so it can block for an
      arbitrary period on an under-utilized network.
      <literal>pcap_loop()</literal> is enough for the purpose of this sample,
      while <literal>pcap_dispatch()</literal> is normally used in a more
      complex program.</para>

    <para>Both of these functions have a <literal>callback</literal> parameter,
      <literal>packet_handler</literal>, pointing to a function that will
      receive the packets. This function is invoked by libpcap for every new
      packet coming from the network and receives a generic status
      (corresponding to the <literal>user</literal> parameter of <ulink
        url="wpcap/pcap_loop.html">pcap_loop()</ulink> and <ulink
        url="wpcap/pcap_loop.html">pcap_dispatch()</ulink>), a header with some
      information on the packet like the timestamp and the length and the
      actual data of the packet including all the protocol headers. Note that
      the frame CRC is normally not present, because it is removed by the
      network adapter after frame validation. Note also that most adapters
      discard packets with wrong CRCs, therefore Npcap is normally not able
      to capture them.</para>

    <para>The above example extracts the timestamp and the length of every
      packet from the <literal>pcap_pkthdr</literal> header and prints them on
      the screen.</para>

    <para>Please note that there may be a drawback using <ulink
        url="wpcap/pcap_loop.html">pcap_loop()</ulink> mainly related to the
      fact that the handler is called by the packet capture driver; therefore
      the user application does not have direct control over it. Another
      approach (and to have more readable programs) is to use the <ulink
        url="wpcap/pcap_next_ex.html">pcap_next_ex()</ulink> function, which is
      presented in the next example (<xref linkend="npcap-tutorial-pcap-next-ex"
        />).</para>
  </sect2>

  <sect2 id="npcap-tutorial-pcap-next-ex">
    <title>Capturing the packets without the callback</title>

    <para>The example program in this lesson behaves exactly like the previous
      program (<xref linkend="npcap-tutorial-openadapter" />), but it uses
      <ulink url="wpcap/pcap_next_ex.html">pcap_next_ex()</ulink> instead of
      <ulink url="wpcap/pcap_loop.html">pcap_loop()</ulink>.</para>

    <para>The callback-based capture mechanism of <ulink
        url="wpcap/pcap_loop.html">pcap_loop()</ulink> is elegant and it could
      be a good choice in some situations. However, handling a callback is
      sometimes not practical&#x2014;it often makes the program more complex
      especially in situations with multithreaded applications or C++
      classes.</para>

    <para>In these cases, <ulink
        url="wpcap/pcap_next_ex.html">pcap_next_ex()</ulink> retrievs a packet
      with a direct call&#x2014;using <literal>pcap_next_ex()</literal>,
      packets are received only when the programmer wants them.</para>

    <para>The parameters of this function are the same as a capture callback.
      It takes an adapter descriptor and a couple of pointers that will be
      initialized and returned to the user (one to a
      <literal>pcap_pkthdr</literal> structure and another to a buffer with the
      packet data).</para>

    <para>In the following program, we recycle the callback code of the
      previous lesson's example and move it inside main() right after the call
      to <ulink url="wpcap/pcap_next_ex.html">pcap_next_ex()</ulink>.</para>

    <programlisting language="C"><!-- Examples/misc/basic_dump_ex.c --><![CDATA[
/* Open the device */
if ( (adhandle= pcap_open(d->name, // name of the device
      65536, // portion of the packet to capture. 
             // 65536 guarantees that the whole packet will
             // be captured on all the link layers
      PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode
      1000, // read timeout
      NULL, // authentication on the remote machine
      errbuf // error buffer
  ) ) == NULL)
{
  fprintf(stderr,
    "\nUnable to open the adapter. %s is not supported by Npcap\n",
    d->name);
  /* Free the device list */
  pcap_freealldevs(alldevs);
  return -1;
}

printf("\nlistening on %s...\n", d->description);

/* At this point, we don't need any more the device list. Free it */
pcap_freealldevs(alldevs);

/* Retrieve the packets */
while((res = pcap_next_ex( adhandle, &header, &pkt_data)) >= 0){

  if(res == 0)
    /* Timeout elapsed */
    continue;

  /* convert the timestamp to readable format */
  local_tv_sec = header->ts.tv_sec;
  localtime_s(&ltime, &local_tv_sec);
  strftime( timestr, sizeof timestr, "%H:%M:%S", &ltime);

  printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len);
}

if(res == -1){
  printf("Error reading the packets: %s\n", pcap_geterr(adhandle));
  return -1;
}
]]></programlisting>

    <para>Why do we use <ulink
        url="wpcap/pcap_next_ex.html">pcap_next_ex()</ulink> instead of the old
      <ulink url="wpcap/pcap_loop.html">pcap_next()</ulink>? Because
      <literal>pcap_next()</literal> has some drawbacks. First of all, it is
      inefficient because it hides the callback method but still relies on
      <literal>pcap_dispatch()</literal>. Second, it is not able to detect EOF,
      so it's not very useful when gathering packets from a file.</para>

    <para>Notice also that <literal>pcap_next_ex()</literal> returns different
      values for success, timeout elapsed, error and EOF conditions.</para>
  </sect2>

  <sect2 id="npcap-tutorial-filtering">
    <title>Filtering the traffic</title>

    <para>One of the most powerful features offered by Npcap (and by libpcap as
      well) is the filtering engine. It provides a very efficient way to
      receive subsets of the network traffic, and is (usually) integrated with
      the capture mechanism provided by Npcap. The functions used to filter
      packets are <ulink url="wpcap/pcap_compile.html">pcap_compile()</ulink>
      and <ulink
        url="wpcap/pcap_setfilter.html">pcap_setfilter()</ulink>.</para>

    <para><ulink url="wpcap/pcap_compile.html">pcap_compile()</ulink> takes a
      string containing a high-level Boolean (filter) expression and produces a
      low-level byte code that can be interpreted by the fileter engine in the
      packet driver. The syntax of the boolean expression can be found in the
      <ulink url="wpcap/pcap-filter.html">Filtering expression syntax</ulink>
      section of this documentation.</para>

    <para><ulink url="wpcap/pcap_setfilter.html">pcap_setfilter()</ulink>
      associates a filter with a capture session in the kernel driver. Once
      <literal>pcap_setfilter()</literal> is called, the associated filter will
      be applied to all the packets coming from the network, and all the
      conformant packets (i.e., packets for which the Boolean expression
      evaluates to true) will be actually copied to the application.</para>

    <para>The following code shows how to compile and set a filter. Note that
      we must retrieve the netmask from the <literal>pcap_if</literal>
      structure that describes the adapter, because some filters created by
      <literal>pcap_compile()</literal> require it.</para>

    <para>The filter passed to <literal>pcap_compile()</literal> in this code
      snippet is "ip and tcp", which means to "keep only the packets that are
      both IPv4 and TCP and deliver them to the application".</para>

    <!-- TODO: PCAP_NETMASK_UNKNOWN? -->
    <programlisting language="C"><!-- inline --><![CDATA[
if (d->addresses != NULL)
  /* Retrieve the mask of the first address of the interface */
  netmask=((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr;
else
  /* If the interface is without an address
   * we suppose to be in a C class network */
  netmask=0xffffff; 


//compile the filter
if (pcap_compile(adhandle, &fcode, "ip and tcp", 1, netmask) < 0)
{
  fprintf(stderr,
    "\nUnable to compile the packet filter. Check the syntax.\n");
  /* Free the device list */
  pcap_freealldevs(alldevs);
  return -1;
}

//set the filter
if (pcap_setfilter(adhandle, &fcode) < 0)
{
  fprintf(stderr,"\nError setting the filter.\n");
  /* Free the device list */
  pcap_freealldevs(alldevs);
  return -1;
}
]]></programlisting>

    <para>If you want to see some code that uses the filtering functions shown
      in this lesson, look at the example presented in the next Lesson, <xref
        linkend="npcap-tutorial-interpreting" />.</para>

  </sect2>

  <sect2 id="npcap-tutorial-interpreting">
    <title>Interpreting the packets</title>

    <para>Now that we are able to capture and filter network traffic, we want
      to put our knowledge to work with a simple "real world"
      application.</para>
   
    <para>In this lesson we will take code from the previous lessons and use
      these pieces to build a more useful program. the main purpose of the
      current program is to show how the protocol headers of a captured packet
      can be parsed and interpreted. The resulting application, called UDPdump,
      prints a summary of the UDP traffic on our network.</para>

    <para>We have chosen to parse and display the UDP protocol because it is
      more accessible than other protocols such as TCP and consequently is an
      excellent initial example. Let's look at the code:</para>

    <programlisting language="C"><!-- Examples/UDPdump/udpdump.c --><![CDATA[
#include <pcap.h>
#include <Winsock2.h>
#include <tchar.h>
BOOL LoadNpcapDlls()
{
  _TCHAR npcap_dir[512];
  UINT len;
  len = GetSystemDirectory(npcap_dir, 480);
  if (!len) {
    fprintf(stderr, "Error in GetSystemDirectory: %x", GetLastError());
    return FALSE;
  }
  _tcscat_s(npcap_dir, 512, _T("\\Npcap"));
  if (SetDllDirectory(npcap_dir) == 0) {
    fprintf(stderr, "Error in SetDllDirectory: %x", GetLastError());
    return FALSE;
  }
  return TRUE;
}


/* 4 bytes IP address */
typedef struct ip_address{
  u_char byte1;
  u_char byte2;
  u_char byte3;
  u_char byte4;
}ip_address;

/* IPv4 header */
typedef struct ip_header{
  u_char  ver_ihl; // Version (4 bits) + IP header length (4 bits)
  u_char  tos;     // Type of service 
  u_short tlen;    // Total length 
  u_short identification; // Identification
  u_short flags_fo; // Flags (3 bits) + Fragment offset (13 bits)
  u_char  ttl;      // Time to live
  u_char  proto;    // Protocol
  u_short crc;      // Header checksum
  ip_address  saddr; // Source address
  ip_address  daddr; // Destination address
  u_int  op_pad;     // Option + Padding
}ip_header;

/* UDP header*/
typedef struct udp_header{
  u_short sport; // Source port
  u_short dport; // Destination port
  u_short len;   // Datagram length
  u_short crc;   // Checksum
}udp_header;

/* prototype of the packet handler */
void packet_handler(u_char *param,
  const struct pcap_pkthdr *header,
  const u_char *pkt_data);


int main()
{
  pcap_if_t *alldevs;
  pcap_if_t *d;
  int inum;
  int i=0;
  pcap_t *adhandle;
  char errbuf[PCAP_ERRBUF_SIZE];
  u_int netmask;
  char packet_filter[] = "ip and udp";
  struct bpf_program fcode;

  /* Load Npcap and its functions. */
  if (!LoadNpcapDlls())
  {
    fprintf(stderr, "Couldn't load Npcap\n");
    exit(1);
  }

  /* Retrieve the device list */
  if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING,
     NULL, &alldevs, errbuf) == -1)
  {
    fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
    exit(1);
  }
  
  /* Print the list */
  for(d=alldevs; d; d=d->next)
  {
    printf("%d. %s", ++i, d->name);
    if (d->description)
      printf(" (%s)\n", d->description);
    else
      printf(" (No description available)\n");
  }

  if(i==0)
  {
    printf("\nNo interfaces found! Make sure Npcap is installed.\n");
    return -1;
  }
  
  printf("Enter the interface number (1-%d):",i);
  scanf_s("%d", &inum);
  
  if(inum < 1 || inum > i)
  {
    printf("\nInterface number out of range.\n");
    /* Free the device list */
    pcap_freealldevs(alldevs);
    return -1;
  }

  /* Jump to the selected adapter */
  for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
  
  /* Open the adapter */
  if ( (adhandle= pcap_open(d->name, // name of the device
               65536, // portion of the packet to capture. 
                      // 65536 grants that the whole packet
                      // will be captured on all the MACs.
               PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode
               1000, // read timeout
               NULL, // remote authentication
               errbuf // error buffer
               ) ) == NULL)
  {
    fprintf(stderr,
      "\nUnable to open the adapter. %s is not supported by Npcap\n",
      d->name);
    /* Free the device list */
    pcap_freealldevs(alldevs);
    return -1;
  }
  
  /* Check the link layer. We support only Ethernet for simplicity. */
  if(pcap_datalink(adhandle) != DLT_EN10MB)
  {
    fprintf(stderr,"\nThis program works only on Ethernet networks.\n");
    /* Free the device list */
    pcap_freealldevs(alldevs);
    return -1;
  }
  
  if(d->addresses != NULL)
    /* Retrieve the mask of the first address of the interface */
    netmask=((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr;
  else
    /* If the interface is without addresses
     * we suppose to be in a C class network */
    netmask=0xffffff; 


  //compile the filter
  if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) <0 )
  {
    fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n");
    /* Free the device list */
    pcap_freealldevs(alldevs);
    return -1;
  }
  
  //set the filter
  if (pcap_setfilter(adhandle, &fcode)<0)
  {
    fprintf(stderr,"\nError setting the filter.\n");
    /* Free the device list */
    pcap_freealldevs(alldevs);
    return -1;
  }
  
  printf("\nlistening on %s...\n", d->description);
  
  /* At this point, we don't need any more the device list. Free it */
  pcap_freealldevs(alldevs);
  
  /* start the capture */
  pcap_loop(adhandle, 0, packet_handler, NULL);
  
  return 0;
}

/* Callback function invoked by libpcap for every incoming packet */
void packet_handler(u_char *param,
  const struct pcap_pkthdr *header,
  const u_char *pkt_data)
{
  struct tm ltime;
  char timestr[16];
  ip_header *ih;
  udp_header *uh;
  u_int ip_len;
  u_short sport,dport;
  time_t local_tv_sec;

  /*
   * Unused variable
   */
  (VOID)(param);

  /* convert the timestamp to readable format */
  local_tv_sec = header->ts.tv_sec;
  localtime_s(&ltime, &local_tv_sec);
  strftime( timestr, sizeof timestr, "%H:%M:%S", &ltime);

  /* print timestamp and length of the packet */
  printf("%s.%.6d len:%d ", timestr, header->ts.tv_usec, header->len);

  /* retireve the position of the ip header */
  ih = (ip_header *) (pkt_data +
    14); //length of ethernet header

  /* retireve the position of the udp header */
  ip_len = (ih->ver_ihl & 0xf) * 4;
  uh = (udp_header *) ((u_char*)ih + ip_len);

  /* convert from network byte order to host byte order */
  sport = ntohs( uh->sport );
  dport = ntohs( uh->dport );

  /* print ip addresses and udp ports */
  printf("%d.%d.%d.%d.%d -> %d.%d.%d.%d.%d\n",
    ih->saddr.byte1,
    ih->saddr.byte2,
    ih->saddr.byte3,
    ih->saddr.byte4,
    sport,
    ih->daddr.byte1,
    ih->daddr.byte2,
    ih->daddr.byte3,
    ih->daddr.byte4,
    dport);
}
]]></programlisting>

    <para>First of all, we set the filter to "ip and udp". In this way we are
      sure that packet_handler() will receive only UDP packets over IPv4: this
      simplifies the parsing and increases the efficiency of the
      program.</para>

    <para>We have also created a couple of structs that describe the IP and UDP
      headers. These structs are used by packet_handler() to properly locate
      the various header fields.</para>

    <para>packet_handler(), although limited to a single protocol dissector
      (UDP over IPv4), shows how complex "sniffers" like tcpdump/WinDump decode
      the network traffic. Since we aren't interested in the MAC header, we
      skip it. For simplicity and before starting the capture, we check the MAC
      layer with <ulink url="wpcap/pcap_datalink.html">pcap_datalink()</ulink>
      to make sure that we are dealing with an Ethernet network. This way we
      can be sure that the MAC header is exactly 14 bytes.</para>

    <para>The IP header is located just after the MAC header. We will extract
      the IP source and destination addresses from the IP header.</para>

    <para>Reaching the UDP header is a bit more complicated, because the IP
      header doesn't have a fixed length. Therefore, we use the IP header's
      length field to know its size. Once we know the location of the UDP
      header, we extract the source and destination ports.</para>

    <para>The extracted values are printed on the screen, and the result is
      something like:</para>
    <screen>
\Device\Packet_{A7FD048A-5D4B-478E-B3C1-34401AC3B72F} (Xircom t 10/100 Adapter)
Enter the interface number (1-2):1
 listening on Xircom CardBus Ethernet 10/100 Adapter...
16:13:15.312784 len:87 130.192.31.67.2682 -&gt; 130.192.3.21.53
16:13:15.314796 len:137 130.192.3.21.53 -&gt; 130.192.31.67.2682
16:13:15.322101 len:78 130.192.31.67.2683 -&gt; 130.192.3.21.53</screen>
    <para>Each of the final 3 lines represents a different packet.</para>
  </sect2>

  <sect2 id="npcap-tutorial-offline">
    <title>Handling offline dump files</title>

    <para>In this lession we are going to learn how to handle packet capture to
      a file (dump to file). Npcap offers a wide range of functions to save
      the network traffic to a file and to read the content of
      dumps&#x2014;this lesson will teach how to use all of these
      functions.</para>

    <para>The format for dump files is the libpcap one. This format contains
      the data of the captured packets in binary form and is a standard used by
      many network tools including WinDump, Wireshark and Snort.</para>

    <sect3 id="npcap-tutorial-offline-saving">
      <title>Saving packets to a dump file</title>

      <para>First of all, let's see how to write packets in libpcap
        format.</para>

      <para>The following example captures the packets from the selected
        interface and saves them on a file whose name is provided by the
        user.</para>
      <programlisting language="C"><!-- Examples/misc/savedump.c --><![CDATA[
#include <pcap.h>
#include "misc.h" /* LoadNpcapDlls */

/* prototype of the packet handler */
void packet_handler(u_char *param,
  const struct pcap_pkthdr *header,
  const u_char *pkt_data);

int main(int argc, char **argv)
{
  pcap_if_t *alldevs;
  pcap_if_t *d;
  int inum;
  int i=0;
  pcap_t *adhandle;
  char errbuf[PCAP_ERRBUF_SIZE];
  pcap_dumper_t *dumpfile;

  /* Load Npcap and its functions. */
  if (!LoadNpcapDlls())
  {
    fprintf(stderr, "Couldn't load Npcap\n");
    exit(1);
  }

  /* Check command line */
  if(argc != 2)
  {
    printf("usage: %s filename", argv[0]);
    return -1;
  }
    
  /* Retrieve the device list on the local machine */
  if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING,
    NULL, &alldevs, errbuf) == -1)
  {
    fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
    exit(1);
  }
    
  /* Print the list */
  for(d=alldevs; d; d=d->next)
  {
    printf("%d. %s", ++i, d->name);
    if (d->description)
      printf(" (%s)\n", d->description);
    else
      printf(" (No description available)\n");
  }

  if(i==0)
  {
    printf("\nNo interfaces found! Make sure Npcap is installed.\n");
    return -1;
  }
  
  printf("Enter the interface number (1-%d):",i);
  scanf_s("%d", &inum);
  
  if(inum < 1 || inum > i)
  {
    printf("\nInterface number out of range.\n");
    /* Free the device list */
    pcap_freealldevs(alldevs);
    return -1;
  }
  
  /* Jump to the selected adapter */
  for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
    
    
  /* Open the device */
  if ( (adhandle= pcap_open(d->name, // name of the device
                65536, // portion of the packet to capture
                       // 65536 guarantees that the whole packet
                       // will be captured on all the link layers
                PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode
                1000, // read timeout
                NULL, // authentication on the remote machine
                errbuf // error buffer
                ) ) == NULL)
  {
    fprintf(stderr,
      "\nUnable to open the adapter. %s is not supported by Npcap\n",
      d->name);
    /* Free the device list */
    pcap_freealldevs(alldevs);
    return -1;
  }

  /* Open the dump file */
  dumpfile = pcap_dump_open(adhandle, argv[1]);

  if(dumpfile==NULL)
  {
    fprintf(stderr,"\nError opening output file\n");
    return -1;
  }

  printf("\nlistening on %s... Press Ctrl+C to stop...\n", d->description);

  /* At this point, we no longer need the device list. Free it */
  pcap_freealldevs(alldevs);
  
  /* start the capture */
  pcap_loop(adhandle, 0, packet_handler, (unsigned char *)dumpfile);

  return 0;
}

/* Callback function invoked by libpcap for every incoming packet */
void packet_handler(u_char *dumpfile,
  const struct pcap_pkthdr *header,
  const u_char *pkt_data)
{
  /* save the packet on the dump file */
  pcap_dump(dumpfile, header, pkt_data);
}
]]></programlisting>

      <para>As you can see, the structure of the program is very similar to the
        ones we have seen in the previous lessons. The differences
        are:</para>

      <itemizedlist>
        <listitem>a call to <ulink
            url="wpcap/pcap_dump_open.html">pcap_dump_open()</ulink> is issued
          once the interface is opened. This call opens a dump file and
          associates it with the interface.</listitem>

        <listitem>the packets are written to this file with a <ulink
            url="wpcap/pcap_dump.html">pcap_dump()</ulink> from the
          packet_handler() callback. The parameters of
          <literal>pcap_dump()</literal> are in 1-1 correspondence with the
          parameters of <ulink
            url="wpcap/pcap_loop.html">pcap_handler()</ulink>.</listitem>
      </itemizedlist>
    </sect3>

    <sect3 id="npcap-tutorial-offline-reading">
      <title>Reading packets from a dump file</title>

      <para>Now that we have a dump file available, we can try to read its
        content. The following code opens a Npcap/libpcap dump file and
        displays every packet contained in the file. The file is opened with
        <ulink url="wpcap/pcap_open_offline.html">pcap_open_offline()</ulink>,
        then the usual <ulink url="wpcap/pcap_loop.html">pcap_loop()</ulink> is
        used to sequence through the packets. As you can see, reading packets
        from an offline capture is nearly identical to receiving them from a
        physical interface.</para>

      <para>This example introduces another function:
        <literal>pcap_createsrcstr()</literal>. This function is required to
        create a source string that begins with a marker used to tell Npcap the
        type of the source, e.g. "rpcap://" if we are going to open an adapter,
        or "file://" if we are going to open a file. This step is not required
        when <literal>pcap_findalldevs_ex()</literal> is used (the returned
        values already contain these strings). However, it is required in this
        example because the name of the file is read from the user
        input.</para>

      <programlisting language="C"><!-- Examples/misc/readfile.c --><![CDATA[
#include <stdio.h>
#include <pcap.h>
#include "misc.h" /* LoadNpcapDlls */

#define LINE_LEN 16

void dispatcher_handler(u_char *,
  const struct pcap_pkthdr *,
  const u_char *);

int main(int argc, char **argv)
{
  pcap_t *fp;
  char errbuf[PCAP_ERRBUF_SIZE];
  char source[PCAP_BUF_SIZE];

  /* Load Npcap and its functions. */
  if (!LoadNpcapDlls())
  {
    fprintf(stderr, "Couldn't load Npcap\n");
    exit(1);
  }

  if(argc != 2){

    printf("usage: %s filename", argv[0]);
    return -1;

  }

  /* Create the source string according to the new Npcap syntax */
  if ( pcap_createsrcstr(  source, // variable that will keep the source string
              PCAP_SRC_FILE,  // we want to open a file
              NULL,      // remote host
              NULL,      // port on the remote host
              argv[1],    // name of the file we want to open
              errbuf      // error buffer
              ) != 0)
  {
    fprintf(stderr,"\nError creating a source string\n");
    return -1;
  }
  
  /* Open the capture file */
  if ( (fp= pcap_open(source, // name of the device
            65536, // portion of the packet to capture
                   // 65536 guarantees that the whole packet
                   // will be captured on all the link layers
             PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode
             1000, // read timeout
             NULL, // authentication on the remote machine
             errbuf // error buffer
             ) ) == NULL)
  {
    fprintf(stderr,"\nUnable to open the file %s.\n", source);
    return -1;
  }

  // read and dispatch packets until EOF is reached
  pcap_loop(fp, 0, dispatcher_handler, NULL);

  return 0;
}


void dispatcher_handler(u_char *temp1, 
  const struct pcap_pkthdr *header,
  const u_char *pkt_data)
{
  u_int i=0;

  /*
   * Unused variable
   */
  (VOID)temp1;

  /* print pkt timestamp and pkt len */
  printf("%ld:%ld (%ld)\n", header->ts.tv_sec, header->ts.tv_usec, header->len);      
  
  /* Print the packet */
  for (i=1; (i < header->caplen + 1 ) ; i++)
  {
    printf("%.2x ", pkt_data[i-1]);
    if ( (i % LINE_LEN) == 0) printf("\n");
  }
  
  printf("\n\n");    
  
}
]]></programlisting>

      <para>The following example has the same purpose of the last one, but
        <ulink url="wpcap/pcap_next_ex.html">pcap_next_ex()</ulink> is used
        instead of the <ulink url="wpcap/pcap_loop.html">pcap_loop()</ulink>
        callback method.</para>

      <programlisting language="C"><!-- Examples/misc/readfile_ex.c --><![CDATA[
#include <stdio.h>
#include <pcap.h>
#include "misc.h" /* LoadNpcapDlls */

#define LINE_LEN 16

int main(int argc, char **argv)
{
  pcap_t *fp;
  char errbuf[PCAP_ERRBUF_SIZE];
  char source[PCAP_BUF_SIZE];
  struct pcap_pkthdr *header;
  const u_char *pkt_data;
  u_int i=0;
  int res;

  /* Load Npcap and its functions. */
  if (!LoadNpcapDlls())
  {
    fprintf(stderr, "Couldn't load Npcap\n");
    exit(1);
  }

  if(argc != 2)
  {
    printf("usage: %s filename", argv[0]);
    return -1;
  }
  
  /* Create the source string according to the new Npcap syntax */
  if ( pcap_createsrcstr(  source, // variable that will keep the source string
              PCAP_SRC_FILE,  // we want to open a file
              NULL,      // remote host
              NULL,      // port on the remote host
              argv[1],    // name of the file we want to open
              errbuf      // error buffer
              ) != 0)
  {
    fprintf(stderr,"\nError creating a source string\n");
    return -1;
  }
  
  /* Open the capture file */
  if ( (fp= pcap_open(source, // name of the device
            65536, // portion of the packet to capture
                   // 65536 guarantees that the whole packet
                   // will be captured on all the link layers
             PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode
             1000, // read timeout
             NULL, // authentication on the remote machine
             errbuf // error buffer
             ) ) == NULL)
  {
    fprintf(stderr,"\nUnable to open the file %s.\n", source);
    return -1;
  }
  
  /* Retrieve the packets from the file */
  while((res = pcap_next_ex( fp, &header, &pkt_data)) >= 0)
  {
    /* print pkt timestamp and pkt len */
    printf("%ld:%ld (%ld)\n", header->ts.tv_sec, header->ts.tv_usec, header->len);      
    
    /* Print the packet */
    for (i=1; (i < header->caplen + 1 ) ; i++)
    {
      printf("%.2x ", pkt_data[i-1]);
      if ( (i % LINE_LEN) == 0) printf("\n");
    }
    
    printf("\n\n");    
  }
  
  
  if (res == -1)
  {
    printf("Error reading the packets: %s\n", pcap_geterr(fp));
  }
  
  return 0;
}
]]></programlisting>

    </sect3>

  </sect2>

  <sect2 id="npcap-tutorial-sending">
    <title>Sending Packets</title>
    <para>Although the name <emphasis>Npcap</emphasis> indicates clearly that the purpose
      of the library is packet capture, other useful features for raw
      networking are provided. Among them, the user can find a complete set of
      functions to send packets.</para>

    <sect3>
      <title>Sending a single packet with <literal>pcap_sendpacket()</literal></title>

      <para>The simplest way to send a packet is shown in the following code
        snippet. After opening an adapter, <ulink
          url="wpcap/pcap_inject.html">pcap_sendpacket()</ulink> is called to
        send a hand-crafted packet. <literal>pcap_sendpacket()</literal> takes
        as arguments a buffer containing the data to send, the length of the
        buffer and the adapter that will send it. Notice that the buffer is
        sent to the net as is, without any manipulation. This means that the
        application has to create the correct protocol headers in order to send
        something meaningful.</para>

      <programlisting language="C"><!-- Examples/misc/sendpack.c --><![CDATA[
#include <stdlib.h>
#include <stdio.h>

#include <pcap.h>
#include "misc.h" /* LoadNpcapDlls */

void main(int argc, char **argv)
{
  pcap_t *fp;
  char errbuf[PCAP_ERRBUF_SIZE];
  u_char packet[100];
  int i;

  /* Load Npcap and its functions. */
  if (!LoadNpcapDlls())
  {
    fprintf(stderr, "Couldn't load Npcap\n");
    exit(1);
  }

  /* Check the validity of the command line */
  if (argc != 2)
  {
    printf("usage: %s interface (e.g. 'rpcap://eth0')", argv[0]);
    return;
  }
    
  /* Open the output device */
  if ( (fp= pcap_open(argv[1], // name of the device
            100, // portion of the packet to capture
            PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode
            1000, // read timeout
            NULL, // authentication on the remote machine
            errbuf // error buffer
            ) ) == NULL)
  {
    fprintf(stderr,
      "\nUnable to open the adapter. %s is not supported by Npcap\n",
      argv[1]);
    return;
  }

  /* Supposing to be on ethernet, set mac destination to 1:1:1:1:1:1 */
  packet[0]=1;
  packet[1]=1;
  packet[2]=1;
  packet[3]=1;
  packet[4]=1;
  packet[5]=1;
  
  /* set mac source to 2:2:2:2:2:2 */
  packet[6]=2;
  packet[7]=2;
  packet[8]=2;
  packet[9]=2;
  packet[10]=2;
  packet[11]=2;
  
  /* Fill the rest of the packet */
  for(i=12;i<100;i++)
  {
    packet[i]=(u_char)i;
  }

  /* Send down the packet */
  if (pcap_sendpacket(fp, packet, 100 /* size */) != 0)
  {
    fprintf(stderr,"\nError sending the packet: %s\n", pcap_geterr(fp));
    return;
  }

  return;
}
]]></programlisting>

    </sect3>

    <sect3>
      <title>Send queues</title>

      <para>While <ulink url="wpcap/pcap_inject.html">pcap_sendpacket()</ulink>
        offers a simple and immediate way to send a single packet,
        <emphasis>send queues</emphasis> provide an advanced, powerful and
        optimized mechanism to send a collection of packets. A send queue is a
        container for a variable number of packets that will be sent to the
        network. It has a size, that represents the maximum amount of bytes it
        can store.</para>

      <para>A send queue is created calling the
        <literal>pcap_sendqueue_alloc()</literal> function, specifying the size
        of the new send queue.</para>

      <para>Once the send queue is created,
        <literal>pcap_sendqueue_queue()</literal> can be used to add a packet
        to the send queue. This function takes a <literal>pcap_pkthdr</literal>
        with the timestamp and the length and a buffer with the data of the
        packet. These parameters are the same as those received by <ulink
          url="wpcap/pcap_next_ex.html">pcap_next_ex()</ulink> and
        <literal>pcap_handler()</literal>, therefore queuing a packet that was
        just captured or read from a file is a matter of passing these
        parameters to <literal>pcap_sendqueue_queue()</literal>.</para>

      <para>To transmit a send queue, Npcap provides the
        <literal>pcap_sendqueue_transmit()</literal> function. Note the third
        parameter: if nonzero, the send will be
        <emphasis>synchronized</emphasis>, i.e. the relative timestamps of the
        packets will be respected. This operation requires a remarkable amount
        of CPU, because the synchronization takes place in the kernel driver
        using "busy wait" loops. Although this operation is quite CPU
        intensive, it often results in very high precision packet transmissions
        (often around few microseconds or less).</para>

      <para>Note that transmitting a send queue with
        <literal>pcap_sendqueue_transmit()</literal> is much more efficient
        than performing a series of <ulink
          url="wpcap/pcap_inject.html">pcap_sendpacket()</ulink>, because the
        send queue is buffered at kernel level drastically decreasing the
        number of context switches.</para>

      <para>When a queue is no longer needed, it can be deleted with
        <literal>pcap_sendqueue_destroy()</literal> that frees all the buffers
        associated with the send queue.</para>

      <para>The next program shows how to use send queues. It opens a capture
        file with <ulink
          url="wpcap/pcap_open_offline.html">pcap_open_offline()</ulink>, then
        it moves the packets from the file to a properly allocated send queue.
        At his point it transmits the queue, synchronizing it if requested by
        the user.</para>

      <para>Note that the link-layer of the dumpfile is compared with the one
        of the interface that will send the packets using <ulink
          url="wpcap/pcap_datalink.html">pcap_datalink()</ulink>, and a warning
        is printed if they are different&#x2014;it is important that the
        capture-file link-layer be the same as the adapter's link layer for
        otherwise the transmission is pointless.</para>

      <programlisting language="C"><!-- Examples/sendcap/sendcap.c --><![CDATA[
#include <stdlib.h>
#include <stdio.h>

#include <pcap.h>

#ifdef _WIN32
#include <tchar.h>
BOOL LoadNpcapDlls()
{
  TCHAR npcap_dir[512];
  UINT len;
  len = GetSystemDirectory(npcap_dir, 480);
  if (!len) {
    fprintf(stderr, "Error in GetSystemDirectory: %x", GetLastError());
    return FALSE;
  }
  _tcscat_s(npcap_dir, 512, TEXT("\\Npcap"));
  if (SetDllDirectory(npcap_dir) == 0) {
    fprintf(stderr, "Error in SetDllDirectory: %x", GetLastError());
    return FALSE;
  }
  return TRUE;
}
#endif

void usage();

void main(int argc, char **argv)
{
  pcap_t *indesc,*outdesc;
  char errbuf[PCAP_ERRBUF_SIZE];
  char source[PCAP_BUF_SIZE];
  FILE *capfile;
  int caplen, sync;
  u_int res;
  pcap_send_queue *squeue;
  struct pcap_pkthdr *pktheader;
  u_char *pktdata;
  float cpu_time;
  u_int npacks = 0;
  errno_t fopen_error;

#ifdef _WIN32
  /* Load Npcap and its functions. */
  if (!LoadNpcapDlls())
  {
    fprintf(stderr, "Couldn't load Npcap\n");
    exit(1);
  }
#endif

  /* Check the validity of the command line */
  if (argc <= 2 || argc >= 5)
  {
    usage();
    return;
  }
    
  /* Retrieve the length of the capture file */
  fopen_error = fopen_s(&capfile, argv[1],"rb");
  if(fopen_error != 0){
    printf("Error opening the file, errno %d.\n", fopen_error);
    return;
  }
  
  fseek(capfile , 0, SEEK_END);
  caplen= ftell(capfile)- sizeof(struct pcap_file_header);
  fclose(capfile);
      
  /* Chek if the timestamps must be respected */
  if(argc == 4 && argv[3][0] == 's')
    sync = TRUE;
  else
    sync = FALSE;

  /* Open the capture */
  /* Create the source string according to the new WinPcap syntax */
  if ( pcap_createsrcstr(
              source, // variable that will keep the source string
              PCAP_SRC_FILE,  // we want to open a file
              NULL,      // remote host
              NULL,      // port on the remote host
              argv[1],    // name of the file we want to open
              errbuf      // error buffer
              ) != 0)
  {
    fprintf(stderr,"\nError creating a source string\n");
    return;
  }
  
  /* Open the capture file */
  if ( (indesc= pcap_open(source, 65536, PCAP_OPENFLAG_PROMISCUOUS,
                          1000, NULL, errbuf) ) == NULL)
  {
    fprintf(stderr,"\nUnable to open the file %s.\n", source);
    return;
  }

  /* Open the output adapter */
  if ( (outdesc= pcap_open(argv[2], 100, PCAP_OPENFLAG_PROMISCUOUS,
                           1000, NULL, errbuf) ) == NULL)
  {
    fprintf(stderr,"\nUnable to open adapter %s.\n", source);
    return;
  }

  /* Check the MAC type */
  if (pcap_datalink(indesc) != pcap_datalink(outdesc))
  {
    printf("Warning: the datalink of the capture differs"
           " from the one of the selected interface.\n");
    printf("Press a key to continue, or CTRL+C to stop.\n");
    getchar();
  }

  /* Allocate a send queue */
  squeue = pcap_sendqueue_alloc(caplen);

  /* Fill the queue with the packets from the file */
  while ((res = pcap_next_ex( indesc, &pktheader, &pktdata)) == 1)
  {
    if (pcap_sendqueue_queue(squeue, pktheader, pktdata) == -1)
    {
      printf("Warning: packet buffer too small, not all the packets will be sent.\n");
      break;
    }

    npacks++;
  }

  if (res == -1)
  {
    printf("Corrupted input file.\n");
    pcap_sendqueue_destroy(squeue);
    return;
  }

  /* Transmit the queue */
  
  cpu_time = (float)clock ();

  if ((res = pcap_sendqueue_transmit(outdesc, squeue, sync)) < squeue->len)
  {
    printf("An error occurred sending the packets: %s."
           " Only %d bytes were sent\n", pcap_geterr(outdesc), res);
  }
  
  cpu_time = (clock() - cpu_time)/CLK_TCK;
  
  printf ("\n\nElapsed time: %5.3f\n", cpu_time);
  printf ("\nTotal packets generated = %d", npacks);
  printf ("\nAverage packets per second = %d", (int)((double)npacks/cpu_time));
  printf ("\n");

  /* free the send queue */
  pcap_sendqueue_destroy(squeue);

  /* Close the input file */
  pcap_close(indesc);

  /* 
   * close the output adapter 
   * IMPORTANT: remember to close the adapter, otherwise there will be no
   * guarantee that all the packets will be sent!
   */
  pcap_close(outdesc);

  return;
}


void usage()
{
  
  printf("\nSendcap, sends a libpcap/tcpdump capture file to the net."
         " Copyright (C) 2002 Loris Degioanni.\n");
  printf("\nUsage:\n");
  printf("\t sendcap file_name adapter [s]\n");
  printf("\nParameters:\n");
  printf("\nfile_name: the name of the dump file that will be sent to the network\n");
  printf("\nadapter: the device to use. Use \"WinDump -D\" for a list of valid devices\n");
  printf("\ns: if present, forces the packets to be sent synchronously,"
         " i.e. respecting the timestamps in the dump file.\n\n");

  exit(0);
}
]]></programlisting>
    </sect3>
  </sect2>

  <sect2 id="npcap-tutorial-statistics">
    <title>Gathering Statistics on the network traffic</title>

    <para>This lesson shows another advanced feature of Npcap: the ability to
      collect statistics about network traffic. The statistical engine makes
      use of the kernel-level packet filter to efficiently classify the
      incoming packet.</para>

    <para>In order to use this feature, the programmer must open an adapter and
      put it in <emphasis>statistical mode</emphasis>. This can be done with
      <literal>pcap_setmode()</literal>. In particular,
      <literal>MODE_STAT</literal> must be used as the <literal>mode</literal>
      argument of this function.</para>

    <para>With statistical mode, making an application that monitors the TCP
      traffic load is a matter of few lines of code. The following sample shows
      how to do it.</para>

    <programlisting language="C"><!-- Examples/tcptop/tcptop.c --><![CDATA[
#include <stdlib.h>
#include <stdio.h>

#include <pcap.h>

#include <tchar.h>
BOOL LoadNpcapDlls()
{
  _TCHAR npcap_dir[512];
  UINT len;
  len = GetSystemDirectory(npcap_dir, 480);
  if (!len) {
    fprintf(stderr, "Error in GetSystemDirectory: %x", GetLastError());
    return FALSE;
  }
  _tcscat_s(npcap_dir, 512, _T("\\Npcap"));
  if (SetDllDirectory(npcap_dir) == 0) {
    fprintf(stderr, "Error in SetDllDirectory: %x", GetLastError());
    return FALSE;
  }
  return TRUE;
}

void usage();

void dispatcher_handler(u_char *, const struct pcap_pkthdr *, const u_char *);


void main(int argc, char **argv)
{
  pcap_t *fp;
  char errbuf[PCAP_ERRBUF_SIZE];
  struct timeval st_ts;
  u_int netmask;
  struct bpf_program fcode;
  
  /* Load Npcap and its functions. */
  if (!LoadNpcapDlls())
  {
    fprintf(stderr, "Couldn't load Npcap\n");
    exit(1);
  }

  /* Check the validity of the command line */
  if (argc != 2)
  {
    usage();
    return;
  }
    
  /* Open the output adapter */
  if ( (fp= pcap_open(argv[1], 100, PCAP_OPENFLAG_PROMISCUOUS,
                      1000, NULL, errbuf) ) == NULL)
  {
    fprintf(stderr,"\nUnable to open adapter %s.\n", errbuf);
    return;
  }

  /* Don't care about netmask, it won't be used for this filter */
  netmask=0xffffff; 

  //compile the filter
  if (pcap_compile(fp, &fcode, "tcp", 1, netmask) <0 )
  {
    fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n");
    /* Free the device list */
    return;
  }
    
  //set the filter
  if (pcap_setfilter(fp, &fcode)<0)
  {
    fprintf(stderr,"\nError setting the filter.\n");
    pcap_close(fp);
    /* Free the device list */
    return;
  }

  /* Put the interface in statstics mode */
  if (pcap_setmode(fp, MODE_STAT)<0)
  {
    fprintf(stderr,"\nError setting the mode.\n");
    pcap_close(fp);
    /* Free the device list */
    return;
  }


  printf("TCP traffic summary:\n");

  /* Start the main loop */
  pcap_loop(fp, 0, dispatcher_handler, (PUCHAR)&st_ts);

  pcap_close(fp);
  return;
}

void dispatcher_handler(u_char *state,
  const struct pcap_pkthdr *header,
  const u_char *pkt_data)
{
  struct timeval *old_ts = (struct timeval *)state;
  u_int delay;
  LARGE_INTEGER Bps,Pps;
  struct tm ltime;
  char timestr[16];
  time_t local_tv_sec;

  /* Calculate the delay in microseconds from the last sample. This value
   * is obtained from the timestamp that the associated with the sample. */
  delay = (header->ts.tv_sec - old_ts->tv_sec) * 1000000
    - old_ts->tv_usec + header->ts.tv_usec;
  /* Get the number of Bits per second */
  Bps.QuadPart=(((*(LONGLONG*)(pkt_data + 8)) * 8 * 1000000) / (delay));
  /*                                            ^      ^
                                                  |      |
                                                  |      | 
                                                  |      |
                         converts bytes in bits --       |
                                                         |
                    delay is expressed in microseconds --
  */

  /* Get the number of Packets per second */
  Pps.QuadPart=(((*(LONGLONG*)(pkt_data)) * 1000000) / (delay));

  /* Convert the timestamp to readable format */
  local_tv_sec = header->ts.tv_sec;
  localtime_s(&ltime, &local_tv_sec);
  strftime( timestr, sizeof timestr, "%H:%M:%S", &ltime);

  /* Print timestamp*/
  printf("%s ", timestr);

  /* Print the samples */
  printf("BPS=%I64u ", Bps.QuadPart);
  printf("PPS=%I64u\n", Pps.QuadPart);

  //store current timestamp
  old_ts->tv_sec=header->ts.tv_sec;
  old_ts->tv_usec=header->ts.tv_usec;
}


void usage()
{
  printf("\nShows the TCP traffic load, in bits per second and packets per second."
         "\nCopyright (C) 2002 Loris Degioanni.\n");
  printf("\nUsage:\n");
  printf("\t tcptop adapter\n");
  printf("\t You can use \"WinDump -D\" if you don't know the name of your adapters.\n");

  exit(0);
}
]]></programlisting>

    <para>Before enabling statistical mode, the user has the option to set a
      filter that defines the subset of network traffic that will be monitored.
      See the <ulink url="wpcap/pcap-filter.html">Filtering expression
        syntax</ulink> documentation for details. If no filter has been set,
      all of the traffic will be monitored.</para>

    <para>Once
      <itemizedlist>
        <listitem>the filter is set</listitem>
        <listitem><literal>pcap_setmode()</literal> is called</listitem>
        <listitem>callback invocation is enabled with <ulink
            url="wpcap/pcap_loop.html">pcap_loop()</ulink></listitem>
      </itemizedlist>
      the interface descriptor starts to work in statistical mode. Notice the
      fourth parameter (<literal>to_ms</literal>) of <ulink
        url="wpcap/pcap_open.html">pcap_open()</ulink>: it defines the interval
      among the statistical samples. The callback function receives the samples
      calculated by the driver every <literal>to_ms</literal> milliseconds.
      These samples are encapsulated in the second and third parameters of the
      callback function.
      <!-- <img src="stats_wpcap.gif" alt="stats_wpcap.gif"/> -->
      Two 64-bit counters are provided: the number of packets and the amount of
      bytes received during the last interval.</para>

    <para>In the example, the adapter is opened with a timeout of 1000 ms. This
      means that dispatcher_handler() is called once per second. At this point
      a filter that keeps only tcp packets is compiled and set. Then
      <literal>pcap_setmode()</literal> and <literal>pcap_loop()</literal> are
      called. Note that a struct timeval pointer is passed to
      <literal>pcap_loop()</literal> as the <literal>user</literal> parameter.
      This structure will be used to store a timestamp in order to calculate
      the interval between two samples.  dispatcher_handler()uses this interval
      to obtain the bits per second and the packets per second and then prints
      these values on the screen.</para>

    <para>Note finally that this example is by far more efficient than a
      program that captures the packets in the traditional way and calculates
      statistics at user-level. Statistical mode requires the minumum amount of
      data copies and context switches and therefore the CPU is optimized.
      Moreover, a very small amount of memory is required.</para>
  </sect2>
</sect1>

