<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="http://commons.oreilly.com/wiki/skins/common/feed.css?97"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://commons.oreilly.com/wiki/index.php?title=Network_Security_Tools/Modifying_and_Hacking_Security_Tools/Writing_Network_Sniffers&amp;action=history&amp;feed=atom</id>
		<title>Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers - Revision history</title>
		<link rel="self" type="application/atom+xml" href="http://commons.oreilly.com/wiki/index.php?title=Network_Security_Tools/Modifying_and_Hacking_Security_Tools/Writing_Network_Sniffers&amp;action=history&amp;feed=atom"/>
		<link rel="alternate" type="text/html" href="http://commons.oreilly.com/wiki/index.php?title=Network_Security_Tools/Modifying_and_Hacking_Security_Tools/Writing_Network_Sniffers&amp;action=history"/>
		<updated>2013-05-18T06:04:40Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.11.0</generator>

	<entry>
		<id>http://commons.oreilly.com/wiki/index.php?title=Network_Security_Tools/Modifying_and_Hacking_Security_Tools/Writing_Network_Sniffers&amp;diff=9252&amp;oldid=prev</id>
		<title>Docbook2Wiki: Initial conversion from Docbook</title>
		<link rel="alternate" type="text/html" href="http://commons.oreilly.com/wiki/index.php?title=Network_Security_Tools/Modifying_and_Hacking_Security_Tools/Writing_Network_Sniffers&amp;diff=9252&amp;oldid=prev"/>
				<updated>2008-03-11T22:54:01Z</updated>
		
		<summary type="html">&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 22:54, 11 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</summary>
		<author><name>Docbook2Wiki</name></author>	</entry>

	<entry>
		<id>http://commons.oreilly.com/wiki/index.php?title=Network_Security_Tools/Modifying_and_Hacking_Security_Tools/Writing_Network_Sniffers&amp;diff=8338&amp;oldid=prev</id>
		<title>Docbook2Wiki: Initial conversion from Docbook</title>
		<link rel="alternate" type="text/html" href="http://commons.oreilly.com/wiki/index.php?title=Network_Security_Tools/Modifying_and_Hacking_Security_Tools/Writing_Network_Sniffers&amp;diff=8338&amp;oldid=prev"/>
				<updated>2008-03-11T21:39:00Z</updated>
		
		<summary type="html">&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Network Security Tools/TOC}}&lt;br /&gt;
An important function of many security tools is to capture network traffic and then either reassemble it or extract information from the network packets flowing across the network. Common examples of such tools include password sniffers such as dsniff (''http://monkey.org/~dugsong/dsniff/'') and Ettercap (''http://ettercap.sourceforge.net/''), and diagnostic, troubleshooting, and monitoring tools such as ntop (''http://www.ntop.org'') and Snort (''http://www.snort.org'').&lt;br /&gt;
&lt;br /&gt;
This chapter provides a quick and practical introduction to packet capture using the commonly available ''libpcap'' library on wired and wireless networks, and is intended to accelerate and simplify the process of creating a packet-capturing tool.&lt;br /&gt;
&lt;br /&gt;
== Introduction to libpcap ==&lt;br /&gt;
&lt;br /&gt;
''libpcap'' is an open source C-language library for capturing network packets. ''libpcap'' is available for a number of different platforms, including most Unix and Unix-like platforms (such as Linux and BSD), as well as for Windows.&lt;br /&gt;
&lt;br /&gt;
Although ''libpcap'' is primarily a packet-capturing tool, it also can create and manipulate packets from saved files, which can then be used in the wide variety of tools that support the ''libpcap'' format.&lt;br /&gt;
&lt;br /&gt;
=== Why Use libpcap? ===&lt;br /&gt;
&lt;br /&gt;
''libpcap'' hides much of the complexity inherent in network packet capture. Packet capture is possible using native network functionality on most platforms; however, the interfaces and semantics required for capturing packets are not for the faint of heart. For example, the following is a fragment of code for packet capture from a tool I wrote for Linux some years ago:&amp;lt;ref&amp;gt;If you're familiar with the &amp;lt;tt&amp;gt;netlink(3)&amp;lt;/tt&amp;gt; interface you know how old this code really is.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 struct sockaddr_nl nl_addr;&lt;br /&gt;
 int fd;&lt;br /&gt;
 int recvlen;&lt;br /&gt;
 unsigned char msgbuf[3000];&lt;br /&gt;
 &lt;br /&gt;
 fd = socket (PF_NETLINK, SOCK_RAW, 0x02)&lt;br /&gt;
 &lt;br /&gt;
 memset (&amp;amp;nl_addr, 0, sizeof (struct sockaddr_nl));&lt;br /&gt;
 nl_addr.nl_family = (sa_family_t) PF_NETLINK;&lt;br /&gt;
 nl_addr.nl_pid = (unsigned int) getpid ( );&lt;br /&gt;
 nl_addr.nl_groups = 0x02;&lt;br /&gt;
 &lt;br /&gt;
 bind (fd, (struct sockaddr *) &amp;amp;nl_addr, sizeof (struct sockaddr_nl)&lt;br /&gt;
 recvlen = recv (fd, msgbuf, MAX_BUFFER_SIZE, 0)&lt;br /&gt;
&lt;br /&gt;
As you can see, this is not the friendliest of code. It uses BSD socket calls to the Linux-only &amp;lt;tt&amp;gt;netlink(3)&amp;lt;/tt&amp;gt; interface to pass packets from the kernel to the user tool.&lt;br /&gt;
&lt;br /&gt;
''libpcap'' hides the complexity of getting packets from the operating system, and it gives the tool developer a consistent interface for developing tools, regardless of the tool's intended operating system. In turn, this makes writing portable code much simpler, and it makes your tools much more useful.&lt;br /&gt;
&lt;br /&gt;
=== Installing libpcap ===&lt;br /&gt;
&lt;br /&gt;
You can obtain the latest version of ''libpcap'' from ''http://www.tcpdump.org''. ''libpcap'' is easy to compile from the source code:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt; tar zxvf libpcap-0.8.3.tar.gz&lt;br /&gt;
 &amp;gt; cd libpcap-0.8.3&lt;br /&gt;
 &amp;gt; ./configure&lt;br /&gt;
 &amp;gt; make&lt;br /&gt;
 &amp;gt; make install&lt;br /&gt;
&lt;br /&gt;
Many Linux distributions also include ''libpcap'' as an optional package that you can install with the distribution, or add afterward. Because ''libpcap'''s functionality changes between versions, you should use the latest version of the libraries available for your distribution or compile the library from source for your own development.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;warning&amp;quot;&amp;gt;&lt;br /&gt;
'''Warning'''&lt;br /&gt;
&lt;br /&gt;
If you are compiling ''libpcap'' from source, make sure you uninstall previous versions of ''libpcap'' to avoid problems with mismatched files. You will need to remove the following files from the libraries directory (commonly ''/usr/lib/'' or ''/usr/local/lib/'' ):&lt;br /&gt;
&lt;br /&gt;
* ''libpcap.a''&lt;br /&gt;
* ''libpcap.so.*.*''&lt;br /&gt;
&lt;br /&gt;
You will also need to remove the following files from the include files directory (commonly ''/usr/include/'' or ''/usr/local/include/'' ):&lt;br /&gt;
&lt;br /&gt;
* ''pcap.h''&lt;br /&gt;
* ''pcap-bpf.h''&lt;br /&gt;
* ''pcap-namedb.h''&lt;br /&gt;
&lt;br /&gt;
You might also have to add the path the ''libpcap'' libraries are installed to into the library search path (commonly ''/etc/ld.so.conf'' for Linux systems).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To develop the examples in this chapter, we'll be using ''libpcap'' Version 0.8.3. Although many of the examples work with earlier versions of ''libpcap'', some functionality might not be available.&lt;br /&gt;
&lt;br /&gt;
== Getting Started with libpcap ==&lt;br /&gt;
&lt;br /&gt;
Now that we have ''libpcap'' installed, we can write our first network packet-capture tool. The example we are going to demonstrate is a simple tool for capturing Address Resolution Protocol (ARP) packets from a local network interface. A slightly more complex tool utilizing ''libpcap'' to capture and process TCP headers (SYNplescan) is discussed in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Packet-Injection Tools|Chapter 11]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;warning&amp;quot;&amp;gt;&lt;br /&gt;
'''Warning'''&lt;br /&gt;
&lt;br /&gt;
Some of the operations we will undertake with ''libpcap'' work only if you are running as the root user. Therefore, tools written that use ''libpcap'' (as per the examples) commonly need to be run by the root user, or be SETUID root. Your tool should be careful of what it does with input and captured packets so that it is not vulnerable to buffer overflows and other security vulnerabilities. A well-written tool should generally drop privileges after functions requiring root privileges have been performed.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Overview of Arpsniff ===&lt;br /&gt;
&lt;br /&gt;
ARP is the protocol used in IP networks to map network protocol addresses (most often, IP addresses) to link layer hardware addresses. When a system on a network needs to communicate with another system on the local subnet (for example, another system on the local TCP/IP subnet), it consults its cache of hardware and protocol addresses (commonly Ethernet Media Access Control, or MAC addresses) to determine if a matching system is known. Otherwise, an ARP exchange is sent to the network device hardware broadcast address, as shown in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#networkst-CHP-10-FIG-1|Figure 10-1]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-10-FIG-1&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 10-1. Overview of an ARP exchange'''&lt;br /&gt;
&lt;br /&gt;
[[Image:Network Security Tools_I_4_tt576.png|Overview of an ARP exchange]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arpsniff is designed to capture both packets in the ARP packet interchanges occurring on the network, and to output the IP addresses of the machines involved. This could be useful for discovering live hosts on the network, or for some other network reconnaissance purpose. For clarity we can separate Arpsniff into five major sections of ''libpcap'' functionality to understand what we are doing at each step:&lt;br /&gt;
&lt;br /&gt;
# Identify the network interface.&lt;br /&gt;
# Open the network interface.&lt;br /&gt;
# Configure packet-capture options.&lt;br /&gt;
# Capture and process packets.&lt;br /&gt;
# Close down gracefully.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;&lt;br /&gt;
'''Tip'''&lt;br /&gt;
&lt;br /&gt;
Note that Arpsniff captures interchanges on the network only if you are not in a switched environment. If you are in a switched environment you might see only one of the packets—i.e., the packet sent to the subnet broadcast address. Several techniques exist for capturing all packets on a switched environment. The Ettercap sniffer uses several of these techniques, including ARP poisoning. Visit ''http://ettercap.sourceforge.net/'' for more information.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Identify the Network Interface ===&lt;br /&gt;
&lt;br /&gt;
To capture packets from a network interface, we need to supply ''libpcap'' with a network interface to use for packet capture. We have a number of different options, including specifying a network interface, asking ''libpcap'' to automatically find an appropriate interface, obtaining a list of the available interfaces, and in recent versions of ''libpcap'', using all available interfaces to capture traffic.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;&lt;br /&gt;
'''Tip'''&lt;br /&gt;
&lt;br /&gt;
''libpcap'' does not support all network interfaces. Most Ethernet cards will work, as will most wireless cards while capturing packets on the network you are associated to. ''libpcap'' generates an error for any network interface supplied to it that it cannot determine how to open.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The easiest way is to let ''libpcap'' choose a suitable interface:&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;pcap.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 char *device;                         /* device to sniff on */&lt;br /&gt;
 char errbuf[PCAP_ERRBUF_SIZE];        /* pcap error messages buffer */&lt;br /&gt;
 &lt;br /&gt;
 device = pcap_lookupdev (errbuf);     /* let pcap find a compatible device */&lt;br /&gt;
 &lt;br /&gt;
 if (device == NULL)                   /* there was an error */&lt;br /&gt;
   {&lt;br /&gt;
     fprintf (stderr, &amp;quot;%s&amp;quot;, errbuf);&lt;br /&gt;
     exit (1);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
To use the ''libpcap'' functions, we are including the ''pcap.h'' header file. This contains the ''libpcap'' function definitions as well as other handy, predefined values, such as &amp;lt;tt&amp;gt;PCAP_ERRBUF_SIZE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The prototype for &amp;lt;tt&amp;gt;pcap_lookupdev&amp;lt;/tt&amp;gt; is as follows:&lt;br /&gt;
&lt;br /&gt;
 char *pcap_lookupdev(char *errbuf)&lt;br /&gt;
&lt;br /&gt;
This function returns the name of an appropriate interface to be used for packet capture. For Linux this is typically &amp;lt;tt&amp;gt;eth0&amp;lt;/tt&amp;gt; or something similar, but this might be different for other operating systems.&lt;br /&gt;
&lt;br /&gt;
The function returns &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt; and the &amp;lt;tt&amp;gt;errbuf&amp;lt;/tt&amp;gt; array is populated with an error message if an error occurs—for example, if no suitable interfaces were located or if the user running the tool did not have sufficient privileges to perform the operation. A number of functions within ''libpcap'' use an &amp;lt;tt&amp;gt;errbuf&amp;lt;/tt&amp;gt; array in this way to return meaningful error messages to the calling tool.&lt;br /&gt;
&lt;br /&gt;
Instead of letting ''libpcap'' choose a suitable interface, you can allow the user to specify one. For some tools it is useful to be able to obtain a list of usable network interfaces:&lt;br /&gt;
&lt;br /&gt;
 pcap_if_t *alldevsp;       /* list of interfaces */&lt;br /&gt;
 &lt;br /&gt;
 if (pcap_findalldevs (&amp;amp;alldevsp, errbuf) &amp;lt; 0)   &lt;br /&gt;
   {&lt;br /&gt;
     fprintf (stderr, &amp;quot;%s&amp;quot;, errbuf);&lt;br /&gt;
     exit (1);&lt;br /&gt;
   }&lt;br /&gt;
 while (alldevsp != NULL)&lt;br /&gt;
   {&lt;br /&gt;
     printf (&amp;quot;%s\n&amp;quot;, alldevsp-&amp;gt;name);&lt;br /&gt;
     alldevsp = alldevsp-&amp;gt;next;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;pcap_findalldevs&amp;lt;/tt&amp;gt; function takes a &amp;lt;tt&amp;gt;pcap_if_t&amp;lt;/tt&amp;gt; pointer and returns a linked list of information about the interfaces found. The &amp;lt;tt&amp;gt;pcap_if_t&amp;lt;/tt&amp;gt; (a type derived from &amp;lt;tt&amp;gt;pcap_if&amp;lt;/tt&amp;gt;) structure contains several pieces of information that might be useful to a tool:&lt;br /&gt;
&lt;br /&gt;
 struct pcap_if&lt;br /&gt;
   {&lt;br /&gt;
     struct pcap_if *next;&lt;br /&gt;
     char *name;             /* interface name */&lt;br /&gt;
     char *description;      /* human-readable description of interface, or NULL */&lt;br /&gt;
     struct pcap_addr *addresses;&lt;br /&gt;
     bpf_u_int32 flags;      /* PCAP_IF_LOOPBACK if a loopback interface */&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
The linked list is populated with the names and descriptions of all the interfaces ''libpcap'' can use, as well as the IP address and netmask of the interfaces, as follows:&lt;br /&gt;
&lt;br /&gt;
 struct pcap_addr&lt;br /&gt;
   {&lt;br /&gt;
     struct pcap_addr *next;&lt;br /&gt;
     struct sockaddr *addr;          /* interface address */&lt;br /&gt;
     struct sockaddr *netmask;       /* netmask for that address */&lt;br /&gt;
     struct sockaddr *broadaddr;     /* broadcast address */&lt;br /&gt;
     struct sockaddr *dstaddr;       /* point-to-point destination or NULL */&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
You could use the information this returns to allow the person using the tool to select an appropriate interface to use, such as the network to which the interface is attached.&lt;br /&gt;
&lt;br /&gt;
=== Open the Network Interface ===&lt;br /&gt;
&lt;br /&gt;
Once we have a network interface supplied by the user, or ''libpcap'' has located an appropriate interface, we can open the interface for packet capture:&lt;br /&gt;
&lt;br /&gt;
 pcap_t *handle;&lt;br /&gt;
 &lt;br /&gt;
 handle = pcap_open_live (device,  /* device to sniff on */&lt;br /&gt;
        BUFSIZ,  /* maximum number of bytes to capture per packet */&lt;br /&gt;
        1, /* promisc - 1 to set card in promiscuous mode, 0 to not */&lt;br /&gt;
        0, /* to_ms - amount of time to perform packet capture in milliseconds */&lt;br /&gt;
           /* 0 = sniff until error */&lt;br /&gt;
        errbuf); /* error message buffer if something goes wrong */&lt;br /&gt;
 &lt;br /&gt;
 if (handle == NULL)   /* there was an error */&lt;br /&gt;
   {&lt;br /&gt;
     fprintf (stderr, &amp;quot;%s&amp;quot;, errbuf);&lt;br /&gt;
     exit (1);&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
 if (strlen (errbuf) &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
       fprintf (stderr, &amp;quot;Warning: %s&amp;quot;, errbuf);  /* a warning was generated */&lt;br /&gt;
       errbuf[0] = 0;    /* reset error buffer */&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;pcap_t&amp;lt;/tt&amp;gt; provides a packet-capture descriptor to the opened session which is used throughout the tool. &amp;lt;tt&amp;gt;pcap_t&amp;lt;/tt&amp;gt; is a ''typedef'' of the &amp;lt;tt&amp;gt;pcap&amp;lt;/tt&amp;gt; structure that is used internally within ''libpcap''; however, the user should never need to know what this structure actually contains.&lt;br /&gt;
&lt;br /&gt;
The prototype for &amp;lt;tt&amp;gt;pcap_open_live&amp;lt;/tt&amp;gt; is as follows:&lt;br /&gt;
&lt;br /&gt;
 pcap_t *pcap_open_live(const char *device, int snaplen, int promisc, &lt;br /&gt;
                        int to_ms, char *errbuf)&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;pcap_open_live&amp;lt;/tt&amp;gt; function is used to open network interfaces for packet capture, and as such it takes several parameters, as shown in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#networkst-CHP-10-TABLE-1|Table 10-1]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-10-TABLE-1&amp;quot;&amp;gt;&lt;br /&gt;
'''Table 10-1. Parameters to pcap_open_live'''&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 device&lt;br /&gt;
| The interface on which to capture traffic. This is either a string such as &amp;lt;tt&amp;gt;eth0&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;any&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt;, and it can be used to capture traffic from all interfaces on recent Linux systems.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 snaplen&lt;br /&gt;
| The maximum number of bytes to capture per packet (snapshot length). If this is less than the length of the packet, the packet is truncated. Note that this has nothing to do with Ethernet SNAP headers.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 promisc&lt;br /&gt;
| Flag to determine whether the interface should be put into promiscuous mode. Promiscuous mode instructs the network interface to capture all traffic on a shared medium network (such as Ethernet), regardless of whether it was intended for the system running the tool. Note that the interface could be in promiscuous mode for some other reason, and it might not be supported for all network interfaces.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 to_ms&lt;br /&gt;
| Timeout in milliseconds before a read operation returns. This is not supported on all platforms. A value of &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; causes the read to wait until an error occurs.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 errbuf&lt;br /&gt;
| Error buffer. If an error or warning occurs, this is populated with a human-readable error message.&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;&lt;br /&gt;
'''Tip'''&lt;br /&gt;
&lt;br /&gt;
Although all options are present for all platforms supported by ''libpcap'', some options will work only if supported by the underlying operating system or device drivers. In particular, promiscuous mode might not work as expected on all devices. A good example is wireless network devices. Most wireless network devices will allow ''libpcap'' to capture wireless traffic in promiscuous mode in Unix-like operating systems, allowing a tool to capture packets on the network to which the user is associated. On Windows, this is not supported by all drivers. To capture all packets, including those not on the network to which a user is associated, special driver support is required. This is covered later in this chapter.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configure Packet-Capture Options ===&lt;br /&gt;
&lt;br /&gt;
Once we have an active packet-capture interface we can determine or set a number of options before we start capturing packets from the interface. For example, we can determine the type of interface that has been opened:&lt;br /&gt;
&lt;br /&gt;
 if (pcap_datalink (handle) != DLT_EN10MB)&lt;br /&gt;
   {&lt;br /&gt;
     fprintf (stderr, &amp;quot;This program only supports Ethernet cards!\n&amp;quot;);&lt;br /&gt;
     exit (1);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;pcap_datalink&amp;lt;/tt&amp;gt; function returns the type of the underlying link layer from the &amp;lt;tt&amp;gt;pcap_t&amp;lt;/tt&amp;gt; handle passed to it.&lt;br /&gt;
&lt;br /&gt;
The prototype for &amp;lt;tt&amp;gt;pcap_datalink&amp;lt;/tt&amp;gt; is as follows:&lt;br /&gt;
&lt;br /&gt;
 int pcap_datalink(pcap_t *p)&lt;br /&gt;
&lt;br /&gt;
This function will generate an error if the selected network interface was not an Ethernet interface (10MB, 100MB, 1000MB, or more). It is wise to check the data link type before trying to manipulate data captured from the network interface, as this determines what format the data is in.&lt;br /&gt;
&lt;br /&gt;
The data link layers that ''libpcap'' can return include network data link types (such as Ethernet), as well as encapsulation types such as the common dial-up Point to Point Protocol (PPP) and OpenBSD pflog. [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#networkst-CHP-10-TABLE-2|Table 10-2]] shows supported link types as of ''libpcap'' Version 0.8.3.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-10-TABLE-2&amp;quot;&amp;gt;&lt;br /&gt;
'''Table 10-2. Link layers supported by libpcap'''&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
! Data link type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| DLT_EN10MB || Ethernet devices, including 10MB, 100MB, 1000MB, and up&lt;br /&gt;
|-&lt;br /&gt;
| DLT_IEEE802_11 || 802.11 wireless devices; can include all the different variants of 802.11, including 802.11, 802.11a, 802.11b, 802.11g, and so on&lt;br /&gt;
|-&lt;br /&gt;
| DLT_NULL || BSD loop-back encapsulation&lt;br /&gt;
|-&lt;br /&gt;
| DLT_IEEE802 || 802.5 token ring devices&lt;br /&gt;
|-&lt;br /&gt;
| DLT_ARCNET || ARCNET devices&lt;br /&gt;
|-&lt;br /&gt;
| DLT_SLIP || Serial Line Internet Protocol (SLIP; predecessor to PPP)&lt;br /&gt;
|-&lt;br /&gt;
| DLT_PPP || PPP&lt;br /&gt;
|-&lt;br /&gt;
| DLT_SLIP_BSDOS || BSD/OS SLIP&lt;br /&gt;
|-&lt;br /&gt;
| DLT_PPP_BSDOS || BSD/OS PPP&lt;br /&gt;
|-&lt;br /&gt;
| DLT_ATM_CLIP || Linux Classical IP (CLIP) over ATM&lt;br /&gt;
|-&lt;br /&gt;
| DLT_FDDI || Fiber Distributed Data Interface (FDDI; data over fiber optic cable)&lt;br /&gt;
|-&lt;br /&gt;
| DLT_ATM_RFC1483 || RFC 1483 encapsulated Asynchronous Transfer Mode (ATM)&lt;br /&gt;
|-&lt;br /&gt;
| DLT_RAW || Raw IP packet&lt;br /&gt;
|-&lt;br /&gt;
| DLT_PPP_SERIAL || PPP in HDLC framing (RFC 1662 or Cisco PPP with HDLC framing)&lt;br /&gt;
|-&lt;br /&gt;
| DLT_PPP_ETHER || PPP over Ethernet (PPPoE); commonly used in DSL networks&lt;br /&gt;
|-&lt;br /&gt;
| DLT_C_HDLC || Cisco PPP with HDLC framing&lt;br /&gt;
|-&lt;br /&gt;
| DLT_FRELAY || Frame relay devices&lt;br /&gt;
|-&lt;br /&gt;
| DLT_LOOP || OpenBSD loop-back encapsulation&lt;br /&gt;
|-&lt;br /&gt;
| DLT_ENC || OpenBSD encapsulated IP&lt;br /&gt;
|-&lt;br /&gt;
| DLT_LINUX_SLL || Linux cooked capture encapsulation&lt;br /&gt;
|-&lt;br /&gt;
| DLT_LTALK || Apple LocalTalk&lt;br /&gt;
|-&lt;br /&gt;
| DLT_PFLOG || OpenBSD pflog firewall log&lt;br /&gt;
|-&lt;br /&gt;
| DLT_PRISM_HEADER || 802.11 Prism monitor mode devices&lt;br /&gt;
|-&lt;br /&gt;
| DLT_IP_OVER_FC || RFC 2625 IP over Fiber Channel&lt;br /&gt;
|-&lt;br /&gt;
| DLT_SUNATM || Sun raw ATM devices&lt;br /&gt;
|-&lt;br /&gt;
| DLT_IEEE802_11_RADIO || BSD wireless with Radiotap header&lt;br /&gt;
|-&lt;br /&gt;
| DLT_APPLE_IP_OVER_IEEE1394 || Apple IP over IEEE-1394 (FireWire)&lt;br /&gt;
|-&lt;br /&gt;
| DLT_IEEE802_11_RADIO_AVS || AVS wireless monitor mode devices&lt;br /&gt;
|-&lt;br /&gt;
| DLT_ARCNET_LINUX || Linux ARCNET devices&lt;br /&gt;
|-&lt;br /&gt;
| DLT_LINUX_IRDA || Linux IRDA devices&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Some platforms and interfaces can have multiple link types available. In this case we need to interrogate the underlying data link layer to see what link types are supported. We can do this using &amp;lt;tt&amp;gt;pcap_list_datalinks&amp;lt;/tt&amp;gt; with the &amp;lt;tt&amp;gt;pcap_t&amp;lt;/tt&amp;gt; handle from the opened session:&lt;br /&gt;
&lt;br /&gt;
 int *dlt_buf;         /* array of supported data link types */&lt;br /&gt;
 int num;              /* number of supported link type */&lt;br /&gt;
 int i;                /* counter for for loop */&lt;br /&gt;
 &lt;br /&gt;
 num = pcap_list_datalinks(handle, &amp;amp;dlt_buf);&lt;br /&gt;
 &lt;br /&gt;
 for (i=0; i&amp;lt;num; i++)&lt;br /&gt;
   {&lt;br /&gt;
     printf(&amp;quot;%d - %s - %s\n&amp;quot;,dlt_buf[i],&lt;br /&gt;
               pcap_datalink_val_to_name(dlt_buf[i]),&lt;br /&gt;
               pcap_datalink_val_to_description(dlt_buf[i]));&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
This example uses three functions to enumerate the data link types, and to display human-readable names and descriptions for them. The prototypes of these functions are as follows:&lt;br /&gt;
&lt;br /&gt;
 int pcap_list_datalinks(pcap_t *p, int **dlt_buf);&lt;br /&gt;
 const char *pcap_datalink_val_to_name(int dlt);&lt;br /&gt;
 const char *pcap_datalink_val_to_description(int dlt);&lt;br /&gt;
&lt;br /&gt;
In most cases, the preceding code displays only one link type and the output usually is something such as the following:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt; ./example&lt;br /&gt;
 &amp;gt; 1 - EN10MB - Ethernet&lt;br /&gt;
&lt;br /&gt;
However, when multiple data link types are supported, something such as the following can be displayed. This was run on FreeBSD 5.2 with an Atheros-based wireless network card:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt; ./example&lt;br /&gt;
 &amp;gt; 127 - IEEE802_11_RADIO - 802.11 plus BSD radio information header&lt;br /&gt;
 &amp;gt; 105 - IEEE802_11 - 802.11&lt;br /&gt;
 &amp;gt; 1 - EN10MB - Ethernet&lt;br /&gt;
&lt;br /&gt;
In this case, in which multiple link types are returned, we can select the desired link type using &amp;lt;tt&amp;gt;pcap_set_datalink&amp;lt;/tt&amp;gt;, which has the following prototype:&lt;br /&gt;
&lt;br /&gt;
 int pcap_set_datalink(pcap_t *p, int dlt);&lt;br /&gt;
&lt;br /&gt;
For example, the following code is required on recent versions of FreeBSD to capture data in Radiotap format from supported wireless cards:&lt;br /&gt;
&lt;br /&gt;
 if (pcap_set_datalink (handle, DLT_IEEE802_11_RADIO) == -1)&lt;br /&gt;
     {&lt;br /&gt;
       pcap_perror (handle, &amp;quot;Error on pcap_set_datalink: &amp;quot;);&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
Now that we have determined that the link type we are capturing on is Ethernet-based, we can assume the interface has an IP address and netmask (as Arpsniff does not work on a non-IP network). We can determine the IP address and netmask as follows:&lt;br /&gt;
&lt;br /&gt;
 bpf_u_int32 netp;     /* ip address of interface */&lt;br /&gt;
 bpf_u_int32 maskp;    /* subnet mask of interface */&lt;br /&gt;
 &lt;br /&gt;
 if (pcap_lookupnet (device, &amp;amp;netp, &amp;amp;maskp, errbuf) == -1)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;%s&amp;quot;, errbuf);&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;pcap_lookupnet&amp;lt;/tt&amp;gt; function has the following prototype:&lt;br /&gt;
&lt;br /&gt;
 int pcap_lookupnet(const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp,&lt;br /&gt;
                           char *errbuf)&lt;br /&gt;
&lt;br /&gt;
This function returns the network address and netmask as an integer value. To convert these to a human-readable format, you can do something such as the following:&lt;br /&gt;
&lt;br /&gt;
 char *net_addr;&lt;br /&gt;
 struct in_addr addr;&lt;br /&gt;
 addr.s_addr = netp;&lt;br /&gt;
 net_addr = inet_ntoa(addr);&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;pcap_lookupnet&amp;lt;/tt&amp;gt; function does not take a &amp;lt;tt&amp;gt;pcap_t&amp;lt;/tt&amp;gt; argument, as it can be run on an interface before it is opened for packet capture. This could be used to locate a particular interface as an alternative to using &amp;lt;tt&amp;gt;pcap_findalldevs&amp;lt;/tt&amp;gt;. You also can use this information when setting a Berkeley Packet Filter (BPF) on the capture, which requires the netmask of the network to be capturing on.&lt;br /&gt;
&lt;br /&gt;
''libpcap'' supports BPF filter programs for filtering incoming packets. BPF is a powerful filtering language based on a programmable state engine running pseudo-Assembly language instructions, as shown in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#networkst-CHP-10-EX-1|Example 10-1]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-10-EX-1&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 10-1. tcpdump -d output for &amp;quot;arp&amp;quot; filter'''&lt;br /&gt;
&lt;br /&gt;
 (000) ldh      [12]&lt;br /&gt;
 (001) jeq      #0x806           jt 2    jf 3&lt;br /&gt;
 (002) ret      #68&lt;br /&gt;
 (003) ret      #0&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''libpcap'' supports BPF at the kernel level for systems that have operating system support for BPF, such as AIX, and in a user-space implementation in the ''libpcap'' library for systems that do not have kernel BPF implementations. On systems that have BPF support at the kernel level, filtering can be done very quickly and efficiently, as the packets the filter drops do not have to be copied from the kernel space to the tool running in user space.&lt;br /&gt;
&lt;br /&gt;
Using ''libpcap'' we can generate a BPF filter from a ''tcpdump'' -style, human-readable filter string using the &amp;lt;tt&amp;gt;pcap_compile&amp;lt;/tt&amp;gt; function, as shown here:&lt;br /&gt;
&lt;br /&gt;
 char *filter = &amp;quot;arp&amp;quot;;   /* filter for BPF (human readable) */&lt;br /&gt;
 struct bpf_program fp;  /* compiled BPF filter */&lt;br /&gt;
 &lt;br /&gt;
 if (pcap_compile (handle, &amp;amp;fp, filter, 0, maskp) == -1)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;%s&amp;quot;, pcap_geterr (handle));&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
The prototype for &amp;lt;tt&amp;gt;pcap_compile&amp;lt;/tt&amp;gt; is as follows:&lt;br /&gt;
&lt;br /&gt;
 int pcap_compile(pcap_t *p, struct bpf_program *fp, char *str, int optimize,&lt;br /&gt;
                       bpf_u_int32 netmask)&lt;br /&gt;
&lt;br /&gt;
This function supports the same human-readable filter syntax used by ''tcpdump''. Read the full syntax from the ''tcpdump'' manpage, or online at ''http://www.tcpdump.org''. [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#networkst-CHP-10-TABLE-3|Table 10-3]] shows some examples of the syntax.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-10-TABLE-3&amp;quot;&amp;gt;&lt;br /&gt;
'''Table 10-3. Example of human-readable filters'''&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
! Filter syntax !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;udp&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;arp&amp;lt;/tt&amp;gt; || Only UDP or ARP packets are passed.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 icmp[icmptype] &amp;amp;#33;= icmp-echo&lt;br /&gt;
| All ICMP packets that are not echo requests/replies.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 host 192.168.0.12&lt;br /&gt;
| All packets to/from 192.168.0.12.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 ip proto 47&lt;br /&gt;
| Only IP protocol 47 (GRE) packets.&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once the human-readable syntax has been compiled into the state machine pseudocode, we can set the filter on the capture session we have initiated as follows:&lt;br /&gt;
&lt;br /&gt;
 if (pcap_setfilter (handle, &amp;amp;fp) == -1)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;%s&amp;quot;, pcap_geterr (handle));&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
Here is the prototype for the &amp;lt;tt&amp;gt;pcap_setfilter&amp;lt;/tt&amp;gt; function:&lt;br /&gt;
&lt;br /&gt;
 int pcap_setfilter(pcap_t *p, struct bpf_program *fp)q&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;pcap_setfilter&amp;lt;/tt&amp;gt; function sets the BPF program in the kernel where BPF support is present or in a user-space implementation if there is no kernel support for BPF.&lt;br /&gt;
&lt;br /&gt;
After we have successfully set the filter on our capture, we can free the memory used for the filter (in this case, a rather trivial amount) as follows:&lt;br /&gt;
&lt;br /&gt;
 pcap_freecode (&amp;amp;fp);&lt;br /&gt;
&lt;br /&gt;
Now we are ready to capture some packets from the interface we have opened, with the BPF filter we have set. For Arpsniff we have set a filter of &amp;lt;tt&amp;gt;arp&amp;lt;/tt&amp;gt;, so we should only have ARP packets passed to us by the filter.&lt;br /&gt;
&lt;br /&gt;
=== Capture and Process Packets ===&lt;br /&gt;
&lt;br /&gt;
''libpcap'' has several options for handling the capture and processing of packets. The three main functions for capturing and processing packets are shown in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#networkst-CHP-10-TABLE-4|Table 10-4]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-10-TABLE-4&amp;quot;&amp;gt;&lt;br /&gt;
'''Table 10-4. libpcap packet-capture functions'''&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
! Function !! Prototype !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 pcap_next_ex&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 int pcap_next_ex &lt;br /&gt;
 (pcap_t *p,&lt;br /&gt;
 struct pcap_pkthdr **pkt_header,&lt;br /&gt;
 const u_char **pkt_data)&lt;br /&gt;
| Reads the next packet from the capture session, returning success or failure. The following values are returned:&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;Packet was read.&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;Timeout expired.&amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt;An error occurred.&amp;lt;tt&amp;gt;-2&amp;lt;/tt&amp;gt;Packets are being read from a saved file, and no more packets are available.If the packet was read, the &amp;lt;tt&amp;gt;pkt_header&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;pkt_data&amp;lt;/tt&amp;gt; pointers are set to the packet header and packet data, respectively.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 pcap_dispatch&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 int pcap_dispatch&lt;br /&gt;
 (pcap_t *p,&lt;br /&gt;
 int cnt,&lt;br /&gt;
 pcap_handler callback,&lt;br /&gt;
 u_char *user)&lt;br /&gt;
| Reads up to &amp;lt;tt&amp;gt;cnt&amp;lt;/tt&amp;gt; packets from the session. A &amp;lt;tt&amp;gt;cnt&amp;lt;/tt&amp;gt; value of &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; reads all packets in the buffer. &amp;lt;tt&amp;gt;pcap_dispatch&amp;lt;/tt&amp;gt; uses a callback function (discussed in a bit) to process packets, and returns the number of packets processed. &amp;lt;tt&amp;gt;pcap_dispatch&amp;lt;/tt&amp;gt; returns when a read timeout occurs on supported platforms.The user value is a user-specified value to be passed to the callback function, and can be &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 pcap_loop&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 int pcap_loop&lt;br /&gt;
 (pcap_t *p,&lt;br /&gt;
 int cnt,&lt;br /&gt;
 pcap_handler callback,&lt;br /&gt;
 u_char *user)&lt;br /&gt;
| Reads &amp;lt;tt&amp;gt;cnt&amp;lt;/tt&amp;gt; packets from the session. &amp;lt;tt&amp;gt;pcap_loop&amp;lt;/tt&amp;gt; uses a callback function to process packets, loops forever until &amp;lt;tt&amp;gt;cnt&amp;lt;/tt&amp;gt; packets are processed (a value of &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; loops forever), and returns the following:&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;&amp;lt;tt&amp;gt;cnt&amp;lt;/tt&amp;gt; packets read.&amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt;An error occurred.&amp;lt;tt&amp;gt;-2&amp;lt;/tt&amp;gt;Loop was terminated by &amp;lt;tt&amp;gt;pcap_breakloop&amp;lt;/tt&amp;gt;.The user value is a user-specified value to be passed to the callback function, and can be &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Also available to the user for simple tasks is the &amp;lt;tt&amp;gt;pcap_next&amp;lt;/tt&amp;gt; function. This is a wrapper to the &amp;lt;tt&amp;gt;pcap_dispatch&amp;lt;/tt&amp;gt; function with a &amp;lt;tt&amp;gt;cnt&amp;lt;/tt&amp;gt; of &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;warning&amp;quot;&amp;gt;&lt;br /&gt;
'''Warning'''&lt;br /&gt;
&lt;br /&gt;
Read timeouts specified in &amp;lt;tt&amp;gt;pcap_open_live&amp;lt;/tt&amp;gt; are not supported consistently across platforms, and as such you can't rely on &amp;lt;tt&amp;gt;pcap_dispatch&amp;lt;/tt&amp;gt; returning after the read timeout on all platforms. For this reason you should not use &amp;lt;tt&amp;gt;pcap_dispatch&amp;lt;/tt&amp;gt; as a polling mechanism.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;pcap_next&amp;lt;/tt&amp;gt; has the following prototype:&lt;br /&gt;
&lt;br /&gt;
 const u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)&lt;br /&gt;
&lt;br /&gt;
As the &amp;lt;tt&amp;gt;pcap_next&amp;lt;/tt&amp;gt; function doesn't support error messages, you should use &amp;lt;tt&amp;gt;pcap_next_ex&amp;lt;/tt&amp;gt; instead if capturing single packets.&lt;br /&gt;
&lt;br /&gt;
For Arpsniff we are going to use &amp;lt;tt&amp;gt;pcap_loop&amp;lt;/tt&amp;gt; as follows:&lt;br /&gt;
&lt;br /&gt;
 if ((r = pcap_loop (handle, -1, process_packet, NULL)) &amp;lt; 0)&lt;br /&gt;
   {&lt;br /&gt;
     if (r == -1)    /* pcap error */&lt;br /&gt;
       {&lt;br /&gt;
         fprintf (stderr, &amp;quot;%s&amp;quot;, pcap_geterr (handle));&lt;br /&gt;
         exit (1);&lt;br /&gt;
        }&lt;br /&gt;
     /* otherwise return should be -2, meaning pcap_breakloop has been called */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;process_packet&amp;lt;/tt&amp;gt; parameter passed to &amp;lt;tt&amp;gt;pcap_loop&amp;lt;/tt&amp;gt; is the name of the function we have written to handle the packet in whichever way we want when it has been captured. Both &amp;lt;tt&amp;gt;pcap_dispatch&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;pcap_loop&amp;lt;/tt&amp;gt; use a callback function with the same parameters as follows:&lt;br /&gt;
&lt;br /&gt;
 void process_packet (u_char *user, const struct pcap_pkthdr *header,&lt;br /&gt;
                       const u_char *packet)&lt;br /&gt;
&lt;br /&gt;
The callback function does not return anything, as &amp;lt;tt&amp;gt;pcap_loop&amp;lt;/tt&amp;gt; would not know what to do with the returned value. As parameters, &amp;lt;tt&amp;gt;pcap_loop&amp;lt;/tt&amp;gt; passes in a header with information about the packet, as well as a pointer to the body of the packet itself. The &amp;lt;tt&amp;gt;user&amp;lt;/tt&amp;gt; value is the value specified in &amp;lt;tt&amp;gt;pcap_loop&amp;lt;/tt&amp;gt; and is not commonly used.&lt;br /&gt;
&lt;br /&gt;
Now we can write the main functionality of the tool within the callback function, and we can run this every time a packet matching the filter is run.&lt;br /&gt;
&lt;br /&gt;
=== Close Down ===&lt;br /&gt;
&lt;br /&gt;
Once we are finished capturing packets, we should gracefully close down the connection before we exit the tool. Two functions can come in handy in this case.&lt;br /&gt;
&lt;br /&gt;
Arpsniff uses a trivial signal handler to intercept the Ctrl-C break sequence. Because the tool is in an endless loop, due to the &amp;lt;tt&amp;gt;pcap_loop&amp;lt;/tt&amp;gt; function, the signal handler calls the &amp;lt;tt&amp;gt;pcap_breakloop&amp;lt;/tt&amp;gt; function. This function, which is available only in recent versions of ''libpcap'', is designed for use in signal handlers or similar tools, and allows the packet- capture loop to be interrupted smoothly and the tool to exit gracefully. &amp;lt;tt&amp;gt;pcap_breakloop&amp;lt;/tt&amp;gt; takes only one argument and has the following prototype:&lt;br /&gt;
&lt;br /&gt;
 void pcap_breakloop(pcap_t *)&lt;br /&gt;
&lt;br /&gt;
Now that we have exited the packet-capture loop, we can close the packet-capture handler and associated resources using the &amp;lt;tt&amp;gt;pcap_close&amp;lt;/tt&amp;gt; function, which has the following prototype:&lt;br /&gt;
&lt;br /&gt;
 void pcap_close(pcap_t *p)&lt;br /&gt;
&lt;br /&gt;
=== Arpsniff ===&lt;br /&gt;
&lt;br /&gt;
Example 10-2 shows the complete code for the Arpsniff tool we have been discussing. You should be able to compile this on most Linux distributions as follows:&lt;br /&gt;
&lt;br /&gt;
                   '''gcc -o arpsniff arpsniff.c -lpcap'''&lt;br /&gt;
                &lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;-lpcap&amp;lt;/tt&amp;gt; option instructs &amp;lt;tt&amp;gt;gcc&amp;lt;/tt&amp;gt; to link the final binary tool against the ''pcap'' library.&lt;br /&gt;
&lt;br /&gt;
Note that this has been developed on Gentoo Linux on x86, and with the removal of the &amp;lt;tt&amp;gt;pcap_breakloop&amp;lt;/tt&amp;gt; call on Red Hat Enterprise Linux on x86. Although it should work on other Linux variants, it might not work on other Unix-like systems without a little tweaking.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-10-EX-2&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 10-2. Arpsniff source code'''&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;signal.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;net/if.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;pcap.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;netinet/if_ether.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 /* ugly shortcut -- Ethernet packet headers are 14 bytes */&lt;br /&gt;
 #define ETH_HEADER_SIZE 14&lt;br /&gt;
 &lt;br /&gt;
 /* for the sake of clarity we'll use globals for a few things */&lt;br /&gt;
 char *device;       /* device to sniff on */&lt;br /&gt;
 int verbose = 0;    /* verbose output about device */&lt;br /&gt;
 pcap_t *handle;     /* handle for the opened pcap session */&lt;br /&gt;
 &lt;br /&gt;
 /* gracefully handle a Control C */&lt;br /&gt;
 void&lt;br /&gt;
 ctrl_c ( )&lt;br /&gt;
 {&lt;br /&gt;
   printf (&amp;quot;Exiting\n&amp;quot;);&lt;br /&gt;
   pcap_breakloop (handle);  /* tell pcap_loop or pcap_dispatch to stop capturing */&lt;br /&gt;
   pcap_close(handle);&lt;br /&gt;
   exit (0);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 /* usage */&lt;br /&gt;
 void&lt;br /&gt;
 usage (char *name)&lt;br /&gt;
 {&lt;br /&gt;
   printf (&amp;quot;%s - simple ARP sniffer\n&amp;quot;, name);&lt;br /&gt;
   printf (&amp;quot;Usage: %s [-i interface] [-l] [-v]\n&amp;quot;, name);&lt;br /&gt;
   printf (&amp;quot;    -i    interface to sniff on\n&amp;quot;);&lt;br /&gt;
   printf (&amp;quot;    -l    list available interfaces\n&amp;quot;);&lt;br /&gt;
   printf (&amp;quot;    -v    print verbose info\n\n&amp;quot;);&lt;br /&gt;
   exit (1);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 /* callback function to process a packet when captured */&lt;br /&gt;
 void&lt;br /&gt;
 process_packet (u_char *user, const struct pcap_pkthdr *header,&lt;br /&gt;
     const u_char * packet)&lt;br /&gt;
 {&lt;br /&gt;
   struct ether_header *eth_header;  /* in ethernet.h included by if_eth.h */&lt;br /&gt;
   struct ether_arp *arp_packet; /* from if_eth.h */&lt;br /&gt;
 &lt;br /&gt;
   eth_header = (struct ether_header *) packet;&lt;br /&gt;
   arp_packet = (struct ether_arp *) (packet + ETH_HEADER_SIZE);&lt;br /&gt;
 &lt;br /&gt;
   if (ntohs (eth_header-&amp;gt;ether_type) == ETHERTYPE_ARP)  /* if it is an ARP packet */&lt;br /&gt;
     {&lt;br /&gt;
       printf (&amp;quot;Source: %d.%d.%d.%d\t\tDestination: %d.%d.%d.%d\n&amp;quot;,&lt;br /&gt;
         arp_packet-&amp;gt;arp_spa[0],&lt;br /&gt;
         arp_packet-&amp;gt;arp_spa[1],&lt;br /&gt;
         arp_packet-&amp;gt;arp_spa[2],&lt;br /&gt;
         arp_packet-&amp;gt;arp_spa[3],&lt;br /&gt;
         arp_packet-&amp;gt;arp_tpa[0],&lt;br /&gt;
         arp_packet-&amp;gt;arp_tpa[1],&lt;br /&gt;
         arp_packet-&amp;gt;arp_tpa[2],&lt;br /&gt;
         arp_packet-&amp;gt;arp_tpa[3]);&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int&lt;br /&gt;
 main (int argc, char *argv[])&lt;br /&gt;
 {&lt;br /&gt;
   char o;     /* for option processing */&lt;br /&gt;
   char errbuf[PCAP_ERRBUF_SIZE];  /* pcap error messages buffer */&lt;br /&gt;
   struct pcap_pkthdr header;  /* packet header from pcap */&lt;br /&gt;
   const u_char *packet;   /* packet */&lt;br /&gt;
   bpf_u_int32 netp;   /* ip address of interface */&lt;br /&gt;
   bpf_u_int32 maskp;    /* subnet mask of interface */&lt;br /&gt;
   char *filter = &amp;quot;arp&amp;quot;;   /* filter for BPF (human readable) */&lt;br /&gt;
   struct bpf_program fp;  /* compiled BPF filter */&lt;br /&gt;
   int r;      /* generic return value */&lt;br /&gt;
   pcap_if_t *alldevsp;    /* list of interfaces */&lt;br /&gt;
 &lt;br /&gt;
   while ((o = getopt (argc, argv, &amp;quot;i:vl&amp;quot;)) &amp;gt; 0)&lt;br /&gt;
     {&lt;br /&gt;
       switch (o)&lt;br /&gt;
   {&lt;br /&gt;
   case 'i':&lt;br /&gt;
     device = optarg;&lt;br /&gt;
     break;&lt;br /&gt;
   case 'l':&lt;br /&gt;
     if (pcap_findalldevs (&amp;amp;alldevsp, errbuf) &amp;lt; 0)&lt;br /&gt;
       {&lt;br /&gt;
         fprintf (stderr, &amp;quot;%s&amp;quot;, errbuf);&lt;br /&gt;
         exit (1);&lt;br /&gt;
       }&lt;br /&gt;
     while (alldevsp != NULL)&lt;br /&gt;
       {&lt;br /&gt;
         printf (&amp;quot;%s\n&amp;quot;, alldevsp-&amp;gt;name);&lt;br /&gt;
         alldevsp = alldevsp-&amp;gt;next;&lt;br /&gt;
       }&lt;br /&gt;
     exit (0);&lt;br /&gt;
   case 'v':&lt;br /&gt;
     verbose = 1;&lt;br /&gt;
     break;&lt;br /&gt;
   default:&lt;br /&gt;
     usage (argv[0]);&lt;br /&gt;
     break;&lt;br /&gt;
   }&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   /* setup signal handler so Control-C will gracefully exit */&lt;br /&gt;
   signal (SIGINT, ctrl_c);&lt;br /&gt;
 &lt;br /&gt;
   /* find device for sniffing if needed */&lt;br /&gt;
   if (device == NULL)   /* if user hasn't specified a device */&lt;br /&gt;
     {&lt;br /&gt;
       device = pcap_lookupdev (errbuf); /* let pcap find a compatible device */&lt;br /&gt;
       if (device == NULL) /* there was an error */&lt;br /&gt;
   {&lt;br /&gt;
     fprintf (stderr, &amp;quot;%s&amp;quot;, errbuf);&lt;br /&gt;
     exit (1);&lt;br /&gt;
   }&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   /* set errbuf to 0 length string to check for warnings */&lt;br /&gt;
   errbuf[0] = 0;&lt;br /&gt;
 &lt;br /&gt;
   /* open device for sniffing */&lt;br /&gt;
   handle = pcap_open_live (device,  /* device to sniff on */&lt;br /&gt;
          BUFSIZ,  /* maximum number of bytes to capture per packet */&lt;br /&gt;
                   /* BUFSIZE is defined in pcap.h */&lt;br /&gt;
          1, /* promisc - 1 to set card in promiscuous mode, 0 to not */&lt;br /&gt;
          0, /* to_ms - amount of time to perform packet capture in milliseconds */&lt;br /&gt;
             /* 0 = sniff until error */&lt;br /&gt;
          errbuf); /* error message buffer if something goes wrong */&lt;br /&gt;
 &lt;br /&gt;
   if (handle == NULL)   /* there was an error */&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;%s&amp;quot;, errbuf);&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   if (strlen (errbuf) &amp;gt; 0)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;Warning: %s&amp;quot;, errbuf);  /* a warning was generated */&lt;br /&gt;
       errbuf[0] = 0;    /* re-set error buffer */&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   if (verbose)&lt;br /&gt;
     {&lt;br /&gt;
       printf (&amp;quot;Using device: %s\n&amp;quot;, device);&lt;br /&gt;
       /* printf (&amp;quot;Using libpcap version %s&amp;quot;, pcap_lib_version); */&lt;br /&gt;
     }&lt;br /&gt;
   /* find out the datalink type of the connection */&lt;br /&gt;
   if (pcap_datalink (handle) != DLT_EN10MB)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;This program only supports Ethernet cards!\n&amp;quot;);&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   /* get the IP subnet mask of the device, so we set a filter on it */&lt;br /&gt;
   if (pcap_lookupnet (device, &amp;amp;netp, &amp;amp;maskp, errbuf) == -1)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;%s&amp;quot;, errbuf);&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   /* compile the filter, so we can capture only stuff we are interested in */&lt;br /&gt;
   if (pcap_compile (handle, &amp;amp;fp, filter, 0, maskp) == -1)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;%s&amp;quot;, pcap_geterr (handle));&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   /* set the filter for the device we have opened */&lt;br /&gt;
   if (pcap_setfilter (handle, &amp;amp;fp) == -1)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;%s&amp;quot;, pcap_geterr (handle));&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   /* we'll be nice and free the memory used for the compiled filter */&lt;br /&gt;
   pcap_freecode (&amp;amp;fp);&lt;br /&gt;
 &lt;br /&gt;
   if ((r = pcap_loop (handle, -1, process_packet, NULL)) &amp;lt; 0)&lt;br /&gt;
     {&lt;br /&gt;
       if (r == -1)    /* pcap error */&lt;br /&gt;
   {&lt;br /&gt;
     fprintf (stderr, &amp;quot;%s&amp;quot;, pcap_geterr (handle));&lt;br /&gt;
     exit (1);&lt;br /&gt;
   }&lt;br /&gt;
       /* otherwise return should be -2, meaning pcap_breakloop has been called */&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   /* close our devices */&lt;br /&gt;
   pcap_close (handle);&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example 10-3 shows a sample run of the Arpsniff tool, capturing the IP address ranges in use on this network by capturing ARP packets.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-10-EX-3&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 10-3. Sample run of the Arpsniff tool'''&lt;br /&gt;
&lt;br /&gt;
 clarkju@home$ sudo arpsniff&lt;br /&gt;
 Source: 192.168.0.123   Destination: 192.168.0.1&lt;br /&gt;
 Source: 192.168.0.1     Destination: 192.168.0.123&lt;br /&gt;
 Source: 192.168.0.123   Destination: 192.168.0.101&lt;br /&gt;
 Source: 192.168.0.101   Destination: 192.168.0.123&lt;br /&gt;
 Source: 192.168.0.123   Destination: 192.168.0.138&lt;br /&gt;
 Source: 192.168.0.138   Destination: 192.168.0.123&lt;br /&gt;
 Source: 192.168.0.138   Destination: 192.168.0.123&lt;br /&gt;
 Source: 192.168.0.123   Destination: 192.168.0.138&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== libpcap and 802.11 Wireless Networks ==&lt;br /&gt;
&lt;br /&gt;
As shown in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#networkst-CHP-10-TABLE-2|Table 10-2]], ''libpcap'' supports packet capture from a wide variety of link types, including several link types related to 802.11 wireless networks.&lt;br /&gt;
&lt;br /&gt;
The Arpsniff tool we just demonstrated was designed to work only on Ethernet networks (or more specifically, Ethernet II networks). We check the link type of the network interface because we receive different types of packet frames from the interface depending on the link type reported. For example, Arpsniff is expecting to receive an Ethernet II frame, containing an ARP packet. In this case, we know the Ethernet II frame has a header consisting of 14 bytes, as shown in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#networkst-CHP-10-FIG-2|Figure 10-2]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-10-FIG-2&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 10-2. Ethernet II header format'''&lt;br /&gt;
&lt;br /&gt;
[[Image:Network Security Tools_I_4_tt620.png|Ethernet II header format]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Had Arpsniff been capturing packets from an 802.11 wireless network, however, something such as the 802.11 packet header shown in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#networkst-CHP-10-FIG-3|Figure 10-3]] would have been present.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-10-FIG-3&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 10-3. Header format'''&lt;br /&gt;
&lt;br /&gt;
[[Image:Network Security Tools_I_4_tt621.png|Header format]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to expecting the correct packet framing for the data link type we are using, there is one other major obstacle to successful packet capture from wireless networks, and that is ''monitor mode''.&lt;br /&gt;
&lt;br /&gt;
=== 802.11 Monitor Mode ===&lt;br /&gt;
&lt;br /&gt;
In 802.11 wireless networks you are generally interested in capturing all information on a particular frequency or channel, regardless of the network the traffic belongs to. Unfortunately, putting an 802.11 wireless card into promiscuous mode does not allow you to capture all packets on a channel; rather, it allows you to capture only the packets on the network you are attached to on that channel. To capture all packets on a channel, you need to put the card into a special mode known as ''monitor'' or ''rfmon'' mode.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;&lt;br /&gt;
'''Tip'''&lt;br /&gt;
&lt;br /&gt;
Monitor mode is the mode for monitoring traffic, usually on a particular channel. A lot of wireless hardware is capable of entering monitor mode, but the ability to set the wireless hardware into monitor mode depends on support within the wireless driver. As such, you can force many cards into monitor mode in Linux, but in Windows you will probably need to write your own wireless network card driver.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Table 10-5 shows some ways to make common 802.11 wireless cards enter monitor mode. A good reference for cards capable of entering monitor mode is available from the web site for the Kismet tool, located at ''http://www.kismetwireless.net''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-10-TABLE-5&amp;quot;&amp;gt;&lt;br /&gt;
'''Table 10-5. Example commands to enter monitor mode'''&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
! Driver/card !! Operating system !! Command&lt;br /&gt;
|-&lt;br /&gt;
| Cisco Aironet || Linux || &amp;lt;tt&amp;gt;'''&amp;lt;nowiki&amp;gt;Echo &amp;quot;mode: y&amp;quot; &amp;gt; '/proc/driver/aironet/&amp;lt;device&amp;gt;/Config'&amp;lt;/nowiki&amp;gt;'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| HostAP || Linux || &amp;lt;tt&amp;gt;'''iwconfig &amp;lt;device&amp;gt; mode monitor'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Orinoco (patched) || Linux || &amp;lt;tt&amp;gt;'''iwpriv &amp;lt;device&amp;gt; monitor 1 &amp;lt;channel&amp;gt;'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Madwifi || Linux || &amp;lt;tt&amp;gt;'''iwconfig &amp;lt;device&amp;gt; mode monitor'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Wlan-ng || Linux || &amp;lt;tt&amp;gt;'''wlanctl-ng &amp;lt;device&amp;gt; lnxreq_wlansniff channel=&amp;lt;channel&amp;gt; enable=true'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Radiotap || FreeBSD || &amp;lt;tt&amp;gt;'''ifconfig &amp;lt;device&amp;gt; monitor up'''&amp;lt;/tt&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Another complication when capturing packets from a wireless card in monitor mode is that there is less consistency in packet-framing format. In addition to the 802.11 packet header shown in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#networkst-CHP-10-FIG-3|Figure 10-3]], many wireless drivers return custom headers detailing a number of pieces of information about the captured packet, such as signal strength and noise values. The two most common of these are the Prism header and the AVS header.&lt;br /&gt;
&lt;br /&gt;
The Prism monitor mode header was originally developed as part of the linux-wlan-ng project (''http://www.linux-wlan.com/''), and was designed for use when developing drivers for the Prism II 802.11b card for Linux. Now this format is supported on a wide variety of drivers, and it is supported by ''libpcap'' as the &amp;lt;tt&amp;gt;DLT_PRISM_HEADER&amp;lt;/tt&amp;gt; link type. The Prism monitor mode header is of the following format:&lt;br /&gt;
&lt;br /&gt;
 struct prism_value&lt;br /&gt;
 {&lt;br /&gt;
   uint32 did;&lt;br /&gt;
   uint16 status;&lt;br /&gt;
   uint16 len;&lt;br /&gt;
   uint32 data;&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 struct prism_header&lt;br /&gt;
 {&lt;br /&gt;
   uint32 msgcode;&lt;br /&gt;
   uint32 msglen;&lt;br /&gt;
   u8char devname[16];&lt;br /&gt;
   struct prism_value hosttime;&lt;br /&gt;
   struct prism_value mactime;&lt;br /&gt;
   struct prism_value channel;&lt;br /&gt;
   struct prism_value rssi;&lt;br /&gt;
   struct prism_value sq;&lt;br /&gt;
   struct prism_value signal;&lt;br /&gt;
   struct prism_value noise;&lt;br /&gt;
   struct prism_value rate;&lt;br /&gt;
   struct prism_value istx;&lt;br /&gt;
   struct prism_value frmlen;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
The AVS capture header is a newer development designed to replace the Prism monitor mode header. In addition to providing additional information, the AVS capture header can capture information about 802.11a and 802.11g packet-capture sources. The ''doc/capturefrm.txt'' file in the ''linux wlan-ng'' driver package is available from ''ftp://ftp.linux-wlan.org/pub/linux-wlan-ng/''.&lt;br /&gt;
&lt;br /&gt;
''libpcap'' supports this format as &amp;lt;tt&amp;gt;DLT_IEEE802_11_RADIO_AVS&amp;lt;/tt&amp;gt;. The AVS capture header is 64 bytes in length, and the format is as follows:&lt;br /&gt;
&lt;br /&gt;
 struct AVS_header&lt;br /&gt;
 {&lt;br /&gt;
   uint32 version;&lt;br /&gt;
   uint32 length;&lt;br /&gt;
   uint64 mactime;&lt;br /&gt;
   uint64 hosttime;&lt;br /&gt;
   uint32 phytype;&lt;br /&gt;
   uint32 channel;&lt;br /&gt;
   uint32 datarate;&lt;br /&gt;
   uint32 antenna;&lt;br /&gt;
   uint32 priority;&lt;br /&gt;
   uint32 ssi_type;&lt;br /&gt;
   int32 ssi_signal;&lt;br /&gt;
   int32 ssi_noise;&lt;br /&gt;
   uint32 preamble;&lt;br /&gt;
   uint32 encoding;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Most recent wireless drivers that are capable of entering monitor mode support either a Prism monitor mode header or the AVS capture header, or both. Where possible you should use the AVS capture format, as this is better documented (i.e., it ''is'' documented, period) and is designed to be extensible to support newer technologies.&lt;br /&gt;
&lt;br /&gt;
=== Adapting Arpsniff to 802.11 ===&lt;br /&gt;
&lt;br /&gt;
To adapt Arpsniff to capture information from a wireless packet-capture source, we need to make a few changes to the application logic. We assume the wireless device used in this example supports the AVS wireless capture format.&lt;br /&gt;
&lt;br /&gt;
First of all, we need to specify the sizes of some of the additional frames captured:&lt;br /&gt;
&lt;br /&gt;
 /* ugly shortcuts - Defining our header types */&lt;br /&gt;
 #define ETH_HEADER_SIZE 14&lt;br /&gt;
 #define AVS_HEADER_SIZE 64                 /* AVS capture header size */&lt;br /&gt;
 #define DATA_80211_FRAME_SIZE 24           /* header for 802.11 data packet */&lt;br /&gt;
 #define LLC_HEADER_SIZE 8                  /* LLC frame for encapsulation */&lt;br /&gt;
&lt;br /&gt;
We are specifying additional header sizes because of the additional headers our ARP packet has when capturing from a wireless source due to RFC 1042 IP encapsulation, as shown in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#networkst-CHP-10-FIG-4|Figure 10-4]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-10-FIG-4&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 10-4. ARP packet format on 802.11 from an AVS capture source'''&lt;br /&gt;
&lt;br /&gt;
[[Image:Network Security Tools_I_4_tt625.png|ARP packet format on 802.11 from an AVS capture source]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To determine the type of packet embedded in the 802.11 packet, we need to have a definition for the LLC header so that we can extract the &amp;lt;tt&amp;gt;ether_type&amp;lt;/tt&amp;gt; value:&lt;br /&gt;
&lt;br /&gt;
 /* SNAP LLC header format */&lt;br /&gt;
 struct snap_header           &lt;br /&gt;
 {&lt;br /&gt;
   u_int8_t dsap; &lt;br /&gt;
   u_int8_t ssap;&lt;br /&gt;
   u_int8_t ctl;&lt;br /&gt;
   u_int16_t org; &lt;br /&gt;
   u_int8_t org2;&lt;br /&gt;
   u_int16_t ether_type;          /* ethernet type */              &lt;br /&gt;
 } _ _attribute_ _ ((_ _packed_  _));&lt;br /&gt;
&lt;br /&gt;
Now we can alter the &amp;lt;tt&amp;gt;process_packet&amp;lt;/tt&amp;gt; function to work with a captured 802.11 packet from an AVS wireless source:&lt;br /&gt;
&lt;br /&gt;
 /* callback function to process a packet when captured */&lt;br /&gt;
 void&lt;br /&gt;
 process_packet (u_char * args, const struct pcap_pkthdr *header,&lt;br /&gt;
     const u_char * packet)&lt;br /&gt;
 {&lt;br /&gt;
   struct ether_header *eth_header;  /* in ethernet.h included by if_eth.h */&lt;br /&gt;
   struct snap_header *llc_header;   /* RFC 1042 encapsulation header */&lt;br /&gt;
   struct ether_arp *arp_packet;     /* from if_eth.h */&lt;br /&gt;
 &lt;br /&gt;
   if (wired)     /* global flag - wired or wireless? */&lt;br /&gt;
   {&lt;br /&gt;
     eth_header = (struct ether_header *) packet;&lt;br /&gt;
     arp_packet = (struct ether_arp *) (packet + ETH_HEADER_SIZE);&lt;br /&gt;
     if (ntohs (eth_header-&amp;gt;ether_type) != ETHERTYPE_ARP) return;&lt;br /&gt;
   } else {      /* wireless */&lt;br /&gt;
     llc_header = (struct snap_header *) &lt;br /&gt;
           (packet + AVS_HEADER_SIZE + DATA_80211_FRAME_SIZE);&lt;br /&gt;
     arp_packet = (struct ether_arp *) &lt;br /&gt;
           (packet + AVS_HEADER_SIZE + DATA_80211_FRAME_SIZE + LLC_HEADER_SIZE);&lt;br /&gt;
     if (ntohs (llc_header-&amp;gt;ether_type) != ETHERTYPE_ARP) return;&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
   printf (&amp;quot;Source: %d.%d.%d.%d\t\tDestination: %d.%d.%d.%d\n&amp;quot;,&lt;br /&gt;
     arp_packet-&amp;gt;arp_spa[0],&lt;br /&gt;
     arp_packet-&amp;gt;arp_spa[1],&lt;br /&gt;
     arp_packet-&amp;gt;arp_spa[2],&lt;br /&gt;
     arp_packet-&amp;gt;arp_spa[3],&lt;br /&gt;
     arp_packet-&amp;gt;arp_tpa[0],&lt;br /&gt;
     arp_packet-&amp;gt;arp_tpa[1],&lt;br /&gt;
     arp_packet-&amp;gt;arp_tpa[2],&lt;br /&gt;
     arp_packet-&amp;gt;arp_tpa[3]);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
You might have noticed that we have introduced a global flag called &amp;lt;tt&amp;gt;wired&amp;lt;/tt&amp;gt; which we are going to use to determine a packet's framing type. We will set this further down in Arpsniff when we check the link type using &amp;lt;tt&amp;gt;pcap_datalink&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
   /* find out the datalink type of the connection */&lt;br /&gt;
   if (pcap_datalink (handle) == DLT_EN10MB)&lt;br /&gt;
   {&lt;br /&gt;
     wired = 1;     /* ethernet link */&lt;br /&gt;
   } else {&lt;br /&gt;
     if (pcap_datalink (handle) == DLT_IEEE802_11_RADIO_AVS)&lt;br /&gt;
     {&lt;br /&gt;
       wired = 0;  /* wireless */&lt;br /&gt;
     } else {&lt;br /&gt;
       fprintf (stderr, &amp;quot;I don't support this interface type!\n&amp;quot;);&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Once we have made the preceding changes, Arpsniff is ready to capture ARP packets from a wireless network interface in monitor mode. The full source code for the updated version of Arpsniff is included in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#networkst-CHP-10-EX-4|Example 10-4]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-10-EX-4&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 10-4. Arpsniff2 source code'''&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;signal.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;net/if.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;pcap.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;netinet/if_ether.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 /* ugly shortcut -- Ethernet packet headers are 14 bytes */&lt;br /&gt;
 #define ETH_HEADER_SIZE 14&lt;br /&gt;
 #define AVS_HEADER_SIZE 64                 /* AVS capture header size */&lt;br /&gt;
 #define DATA_80211_FRAME_SIZE 24           /* header for 802.11 data packet */&lt;br /&gt;
 #define LLC_HEADER_SIZE 8                  /* LLC frame for encapsulation */&lt;br /&gt;
 &lt;br /&gt;
 /* SNAP LLC header format */&lt;br /&gt;
 struct snap_header           &lt;br /&gt;
 {&lt;br /&gt;
   u_int8_t dsap; &lt;br /&gt;
   u_int8_t ssap;&lt;br /&gt;
   u_int8_t ctl;&lt;br /&gt;
   u_int16_t org; &lt;br /&gt;
   u_int8_t org2;&lt;br /&gt;
   u_int16_t ether_type;          /* ethernet type */              &lt;br /&gt;
 } __attribute__ ((__packed_  _));&lt;br /&gt;
 &lt;br /&gt;
 /* for the sake of clarity we'll use globals for a few things */&lt;br /&gt;
 char *device;     /* device to sniff on */&lt;br /&gt;
 int verbose = 0;    /* verbose output about device */&lt;br /&gt;
 pcap_t *handle;     /* handle for the opened pcap session */&lt;br /&gt;
 int wired=0;        /* flag for wired/wireless */&lt;br /&gt;
 &lt;br /&gt;
 /* gracefully handle a Control C */&lt;br /&gt;
 void&lt;br /&gt;
 ctrl_c ( )&lt;br /&gt;
 {&lt;br /&gt;
   printf (&amp;quot;Exiting\n&amp;quot;);&lt;br /&gt;
   pcap_breakloop (handle);  /* tell pcap_loop or pcap_dispatch to stop capturing */&lt;br /&gt;
   pcap_close(handle);&lt;br /&gt;
   exit (0);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 /* usage */&lt;br /&gt;
 void&lt;br /&gt;
 usage (char *name)&lt;br /&gt;
 {&lt;br /&gt;
   printf (&amp;quot;%s - simple ARP sniffer\n&amp;quot;, name);&lt;br /&gt;
   printf (&amp;quot;Usage: %s [-i interface] [-l] [-v]\n&amp;quot;, name);&lt;br /&gt;
   printf (&amp;quot;    -i    interface to sniff on\n&amp;quot;);&lt;br /&gt;
   printf (&amp;quot;    -l    list available interfaces\n&amp;quot;);&lt;br /&gt;
   printf (&amp;quot;    -v    print verbose info\n\n&amp;quot;);&lt;br /&gt;
   exit (1);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 /* callback function to process a packet when captured */&lt;br /&gt;
 void&lt;br /&gt;
 process_packet (u_char * args, const struct pcap_pkthdr *header,&lt;br /&gt;
     const u_char * packet)&lt;br /&gt;
 {&lt;br /&gt;
   struct ether_header *eth_header;  /* in ethernet.h included by if_eth.h */&lt;br /&gt;
   struct snap_header *llc_header;   /* RFC 1042 encapsulation header */&lt;br /&gt;
   struct ether_arp *arp_packet;     /* from if_eth.h */&lt;br /&gt;
 &lt;br /&gt;
   if (wired)     /* global flag - wired or wireless? */&lt;br /&gt;
   {&lt;br /&gt;
     eth_header = (struct ether_header *) packet;&lt;br /&gt;
     arp_packet = (struct ether_arp *) (packet + ETH_HEADER_SIZE);&lt;br /&gt;
     if (ntohs (eth_header-&amp;gt;ether_type) != ETHERTYPE_ARP) return;&lt;br /&gt;
   } else {      /* wireless */&lt;br /&gt;
     llc_header = (struct snap_header *) &lt;br /&gt;
           (packet + AVS_HEADER_SIZE + DATA_80211_FRAME_SIZE);&lt;br /&gt;
     arp_packet = (struct ether_arp *) &lt;br /&gt;
           (packet + AVS_HEADER_SIZE + DATA_80211_FRAME_SIZE + LLC_HEADER_SIZE);&lt;br /&gt;
     if (ntohs (llc_header-&amp;gt;ether_type) != ETHERTYPE_ARP) return;&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
   printf (&amp;quot;Source: %d.%d.%d.%d\t\tDestination: %d.%d.%d.%d\n&amp;quot;,&lt;br /&gt;
     arp_packet-&amp;gt;arp_spa[0],&lt;br /&gt;
     arp_packet-&amp;gt;arp_spa[1],&lt;br /&gt;
     arp_packet-&amp;gt;arp_spa[2],&lt;br /&gt;
     arp_packet-&amp;gt;arp_spa[3],&lt;br /&gt;
     arp_packet-&amp;gt;arp_tpa[0],&lt;br /&gt;
     arp_packet-&amp;gt;arp_tpa[1],&lt;br /&gt;
     arp_packet-&amp;gt;arp_tpa[2],&lt;br /&gt;
     arp_packet-&amp;gt;arp_tpa[3]);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int&lt;br /&gt;
 main (int argc, char *argv[])&lt;br /&gt;
 {&lt;br /&gt;
   char o;     /* for option processing */&lt;br /&gt;
   char errbuf[PCAP_ERRBUF_SIZE];  /* pcap error messages buffer */&lt;br /&gt;
   struct pcap_pkthdr header;  /* packet header from pcap */&lt;br /&gt;
   const u_char *packet;   /* packet */&lt;br /&gt;
   bpf_u_int32 netp;   /* ip address of interface */&lt;br /&gt;
   bpf_u_int32 maskp;    /* subnet mask of interface */&lt;br /&gt;
   char *filter = &amp;quot;arp&amp;quot;;   /* filter for BPF (human readable) */&lt;br /&gt;
   struct bpf_program fp;  /* compiled BPF filter */&lt;br /&gt;
   int r;      /* generic return value */&lt;br /&gt;
   pcap_if_t *alldevsp;    /* list of interfaces */&lt;br /&gt;
 &lt;br /&gt;
   while ((o = getopt (argc, argv, &amp;quot;i:vl&amp;quot;)) &amp;gt; 0)&lt;br /&gt;
     {&lt;br /&gt;
       switch (o)&lt;br /&gt;
   {&lt;br /&gt;
   case 'i':&lt;br /&gt;
     device = optarg;&lt;br /&gt;
     break;&lt;br /&gt;
   case 'l':&lt;br /&gt;
     if (pcap_findalldevs (&amp;amp;alldevsp, errbuf) &amp;lt; 0)&lt;br /&gt;
       {&lt;br /&gt;
         fprintf (stderr, &amp;quot;%s&amp;quot;, errbuf);&lt;br /&gt;
         exit (1);&lt;br /&gt;
       }&lt;br /&gt;
     while (alldevsp != NULL)&lt;br /&gt;
       {&lt;br /&gt;
         printf (&amp;quot;%s\n&amp;quot;, alldevsp-&amp;gt;name);&lt;br /&gt;
         alldevsp = alldevsp-&amp;gt;next;&lt;br /&gt;
       }&lt;br /&gt;
     exit (0);&lt;br /&gt;
   case 'v':&lt;br /&gt;
     verbose = 1;&lt;br /&gt;
     break;&lt;br /&gt;
   default:&lt;br /&gt;
     usage (argv[0]);&lt;br /&gt;
     break;&lt;br /&gt;
   }&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   /* setup signal handler so Control-C will gracefully exit */&lt;br /&gt;
   signal (SIGINT, ctrl_c);&lt;br /&gt;
 &lt;br /&gt;
   /* find device for sniffing if needed */&lt;br /&gt;
   if (device == NULL)   /* if user hasn't specified a device */&lt;br /&gt;
     {&lt;br /&gt;
       device = pcap_lookupdev (errbuf); /* let pcap find a compatible device */&lt;br /&gt;
       if (device == NULL) /* there was an error */&lt;br /&gt;
   {&lt;br /&gt;
     fprintf (stderr, &amp;quot;%s&amp;quot;, errbuf);&lt;br /&gt;
     exit (1);&lt;br /&gt;
   }&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   /* set errbuf to 0 length string to check for warnings */&lt;br /&gt;
   errbuf[0] = 0;&lt;br /&gt;
 &lt;br /&gt;
   /* open device for sniffing */&lt;br /&gt;
   handle = pcap_open_live (device,  /* device to sniff on */&lt;br /&gt;
          BUFSIZ,  /* maximum number of bytes to capture per packet */&lt;br /&gt;
                   /* BUFSIZE is defined in pcap.h */&lt;br /&gt;
          1, /* promisc - 1 to set card in promiscuous mode, 0 to not */&lt;br /&gt;
          0, /* to_ms - amount of time to perform packet capture in milliseconds */&lt;br /&gt;
             /* 0 = sniff until error */&lt;br /&gt;
          errbuf); /* error message buffer if something goes wrong */&lt;br /&gt;
 &lt;br /&gt;
   if (handle == NULL)   /* there was an error */&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;%s&amp;quot;, errbuf);&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   if (strlen (errbuf) &amp;gt; 0)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;Warning: %s&amp;quot;, errbuf);  /* a warning was generated */&lt;br /&gt;
       errbuf[0] = 0;    /* re-set error buffer */&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   if (verbose)&lt;br /&gt;
     {&lt;br /&gt;
       printf (&amp;quot;Using device: %s\n&amp;quot;, device);&lt;br /&gt;
       /* printf (&amp;quot;Using libpcap version %s&amp;quot;, pcap_lib_version); */&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
  /* find out the datalink type of the connection */&lt;br /&gt;
   if (pcap_datalink (handle) == DLT_EN10MB)&lt;br /&gt;
   {&lt;br /&gt;
     wired = 1;     /* ethernet link */&lt;br /&gt;
   } else {&lt;br /&gt;
     if (pcap_datalink (handle) == DLT_IEEE802_11_RADIO_AVS)&lt;br /&gt;
     {&lt;br /&gt;
       wired = 0;  /* wireless */&lt;br /&gt;
     } else {&lt;br /&gt;
       fprintf (stderr, &amp;quot;I don't support this interface type!\n&amp;quot;);&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
   /* get the IP subnet mask of the device, so we set a filter on it */&lt;br /&gt;
   if (pcap_lookupnet (device, &amp;amp;netp, &amp;amp;maskp, errbuf) == -1)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;%s&amp;quot;, errbuf);&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   /* compile the filter, so we can capture only stuff we are interested in */&lt;br /&gt;
   if (pcap_compile (handle, &amp;amp;fp, filter, 0, maskp) == -1)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;%s&amp;quot;, pcap_geterr (handle));&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   /* set the filter for the device we have opened */&lt;br /&gt;
   if (pcap_setfilter (handle, &amp;amp;fp) == -1)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;%s&amp;quot;, pcap_geterr (handle));&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   /* we'll be nice and free the memory used for the compiled filter */&lt;br /&gt;
   pcap_freecode (&amp;amp;fp);&lt;br /&gt;
 &lt;br /&gt;
   if ((r = pcap_loop (handle, -1, process_packet, NULL)) &amp;lt; 0)&lt;br /&gt;
     {&lt;br /&gt;
       if (r == -1)    /* pcap error */&lt;br /&gt;
   {&lt;br /&gt;
     fprintf (stderr, &amp;quot;%s&amp;quot;, pcap_geterr (handle));&lt;br /&gt;
     exit (1);&lt;br /&gt;
   }&lt;br /&gt;
       /* otherwise return should be -2, meaning pcap_breakloop has been called */&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   /* close our devices */&lt;br /&gt;
   pcap_close (handle);&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;warning&amp;quot;&amp;gt;&lt;br /&gt;
'''Warning'''&lt;br /&gt;
&lt;br /&gt;
If the wireless network is using encryption, we are not going to be able to intercept all traffic in a readable format. Unfortunately, we cannot be in monitor mode and have the wireless card decrypting data for us, so any data requiring decryption should be captured while not in monitor mode, or else the tool will have to implement decryption for the captured data.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== libpcap and Perl ==&lt;br /&gt;
&lt;br /&gt;
The ''libpcap'' examples we have demonstrated so far have been in C, as the ''libpcap'' library is a C library. However, many interfaces and wrappers to ''libpcap'' exist for higher-level languages, such as Perl and Python. Using a high-level language has a number of advantages for developers not familiar with C, and for developers looking to quickly throw together a tool that works, without necessarily requiring it to be robust, scalable, or even stable. A tool written in Perl or Python is generally a lot smaller than an equivalent tool written in C.&lt;br /&gt;
&lt;br /&gt;
Using a high-level language can also have some disadvantages, in that less commonly used functionality and new functionality within ''libpcap'' might not be supported properly, or even at all. Also, high-level languages are not a realistic option for tools requiring high throughput of packet processing, so you would not want to write a network IDS in a high-level language.&lt;br /&gt;
&lt;br /&gt;
For the Perl scripting language, the package for ''libpcap'' is called &amp;lt;tt&amp;gt;Net::Pcap&amp;lt;/tt&amp;gt; . If a &amp;lt;tt&amp;gt;Net::Pcap&amp;lt;/tt&amp;gt; package is not available for your Linux distribution, you should be able to install &amp;lt;tt&amp;gt;Net::Pcap&amp;lt;/tt&amp;gt; as follows:&lt;br /&gt;
&lt;br /&gt;
                '''perl -MCPAN -e 'install Net::Pcap''''&lt;br /&gt;
&lt;br /&gt;
This downloads the source code for the package and automatically builds the package in most cases. If you are using Windows, your install process might be different. The functions in &amp;lt;tt&amp;gt;Net::Pcap&amp;lt;/tt&amp;gt; are very similar to the C functions, as are the parameters passed to the functions. Documentation of these functions is available on the module's home page, at ''http://search.cpan.org/~kcarnut/Net-Pcap-0.05/Pcap.pm''.&lt;br /&gt;
&lt;br /&gt;
=== Arpsniff in Perl ===&lt;br /&gt;
&lt;br /&gt;
The following is a quick demonstration of &amp;lt;tt&amp;gt;Net::Pcap&amp;lt;/tt&amp;gt; functionality and a quick reimplementation of the major functionality of the Arpsniff tool in Perl. Note that this tool also uses the &amp;lt;tt&amp;gt;NetPacket::Ethernet&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;NetPacket::ARP&amp;lt;/tt&amp;gt; packages to easily decompose the packets it captures:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#!/usr/bin/env perl&lt;br /&gt;
&lt;br /&gt;
use Net::Pcap;&lt;br /&gt;
use NetPacket::Ethernet;&lt;br /&gt;
use NetPacket::ARP;&lt;br /&gt;
&lt;br /&gt;
my $errbuf;&lt;br /&gt;
&lt;br /&gt;
# find a network device&lt;br /&gt;
$device = Net::Pcap::lookupdev(\$errbuf);&lt;br /&gt;
if (defined $errbuf) {die &amp;quot;Unable to find device: &amp;quot;, $errbuf;}&lt;br /&gt;
&lt;br /&gt;
# open device&lt;br /&gt;
$handle = Net::Pcap::open_live($device, 2000, 1, 0, \$errbuf);&lt;br /&gt;
if (!defined $handle) {die &amp;quot;Unable to open &amp;quot;,$device, &amp;quot; - &amp;quot;, $errbuf;}&lt;br /&gt;
&lt;br /&gt;
# find netmask so we can set a filter on the interface&lt;br /&gt;
Net::Pcap::lookupnet(\$device, \$netp, \$maskp, \$errbuf) &lt;br /&gt;
    || die &amp;quot;Can't find network info&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
# set filter on interface&lt;br /&gt;
$filter = &amp;quot;arp&amp;quot;;&lt;br /&gt;
Net::Pcap::compile($handle, \$fp, $filter, 0, $maskp) &lt;br /&gt;
    &amp;amp;&amp;amp; die &amp;quot;Unable to compile BPF&amp;quot;;&lt;br /&gt;
Net::Pcap::setfilter($handle, $fp) &amp;amp;&amp;amp; die &amp;quot;Unable to set filter&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
# start sniffing&lt;br /&gt;
Net::Pcap::loop($handle, -1, \&amp;amp;process_packet, '') &lt;br /&gt;
    || die &amp;quot;Unable to start sniffing&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
# close&lt;br /&gt;
Net::Pcap::close($handle);&lt;br /&gt;
&lt;br /&gt;
sub process_packet&lt;br /&gt;
{&lt;br /&gt;
  my ($user, $header, $packet) = @_;&lt;br /&gt;
&lt;br /&gt;
  my $eth_data = NetPacket::Ethernet::strip($packet);&lt;br /&gt;
    &lt;br /&gt;
  my $arp = NetPacket::ARP-&amp;gt;decode($eth_data);&lt;br /&gt;
&lt;br /&gt;
  # convert hex number to IP dotted - from rob_au at perlmonks&lt;br /&gt;
  my $spa = join '.', map { hex } ($arp-&amp;gt;{'spa'} =~ /([[:xdigit:]]{2})/g);&lt;br /&gt;
  my $tpa = join '.', map { hex } ($arp-&amp;gt;{'tpa'} =~ /([[:xdigit:]]{2})/g);&lt;br /&gt;
&lt;br /&gt;
  print &amp;quot;Source: &amp;quot;,$spa,&amp;quot;\tDestination: &amp;quot;,$tpa, &amp;quot;\n&amp;quot;;&lt;br /&gt;
}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== libpcap Library Reference ==&lt;br /&gt;
&lt;br /&gt;
Although the Arpsniff tool demonstrates a majority of the functionality that most tools require, the ''libpcap'' library has a lot of functionality we have not yet explored. This section provides a high-level reference, by functionality type, to all the functionality present in ''libpcap''.&lt;br /&gt;
&lt;br /&gt;
=== Lookup Functions ===&lt;br /&gt;
&lt;br /&gt;
The following functions are used to provide information about available interfaces.&lt;br /&gt;
&lt;br /&gt;
====''pcap_lookupdev''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;char *pcap_lookupdev(char *errbuf)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_lookupdev&amp;lt;/tt&amp;gt; finds the first usable interface (active and supported by ''libpcap'') for use with &amp;lt;tt&amp;gt;pcap_open_live&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;pcap_lookup_net&amp;lt;/tt&amp;gt; returned by the operating system. The function returns a string containing the device's name if successful. If not successful, the function returns &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;errbuf&amp;lt;/tt&amp;gt; contains a human-readable error message. &amp;lt;tt&amp;gt;pcap_lookupdev&amp;lt;/tt&amp;gt; is not recommended in situations where multiple network interfaces are in use. Note that if the calling user does not have appropriate privileges, this function might not return a device even though usable devices are present. You can find an example of using &amp;lt;tt&amp;gt;pcap_lookupdev&amp;lt;/tt&amp;gt; in the [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#Identify the Network Interface|Section 10.2.2]] section earlier in this chapter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_findalldevs''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;int pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_findalldevs&amp;lt;/tt&amp;gt; finds all usable (active and supported by ''libpcap'') interfaces for use with &amp;lt;tt&amp;gt;pcap_open_live&amp;lt;/tt&amp;gt;. If successful, the function returns &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;alldevsp&amp;lt;/tt&amp;gt; points to a linked list of &amp;lt;tt&amp;gt;pcap_if_t&amp;lt;/tt&amp;gt; structures with interface details. If not successful, the function returns &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;errbuf&amp;lt;/tt&amp;gt; is populated with a human-readable error message. You can find an example of utilizing the information returned by &amp;lt;tt&amp;gt;pcap_findalldevs&amp;lt;/tt&amp;gt; in the [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#Identify the Network Interface|Section 10.2.2]] section earlier in this chapter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_lookupnet''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;int pcap_lookupnet(const char *device, bpf_u_int32 *netp, bpf_u_int32&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;*maskp, char *errbuf)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_lookupnet&amp;lt;/tt&amp;gt; returns the network address and network mask of the device supplied in the device parameter. The function returns &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; if successful and &amp;lt;tt&amp;gt;netp&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;maskp&amp;lt;/tt&amp;gt; point to the network interface address and netmask, respectively. If an error occurs, &amp;lt;tt&amp;gt;pcap_lookupnet&amp;lt;/tt&amp;gt; returns &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;errbuf&amp;lt;/tt&amp;gt; is populated with a human-readable error message. You can find an example of using the &amp;lt;tt&amp;gt;pcap_lookupnet&amp;lt;/tt&amp;gt; function in the [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#Configure Packet-Capture Options|Section 10.2.4]] section earlier in this chapter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_freealldevs''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;void pcap_freealldevs(pcap_if_t *alldevs)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_freealldevs&amp;lt;/tt&amp;gt; frees a linked list of interface information returned by the &amp;lt;tt&amp;gt;pcap_findalldevs&amp;lt;/tt&amp;gt; function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Packet-Capture Functions ===&lt;br /&gt;
&lt;br /&gt;
The following are functions for capturing packets and manipulating live capture sources.&lt;br /&gt;
&lt;br /&gt;
====''pcap_open_live''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;pcap_t *pcap_open_live(const char *device, int snaplen, int promisc, int&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;to_ms, char *errbuf)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_open_live&amp;lt;/tt&amp;gt; is used to open a live packet-capturing session from the network interface &amp;lt;tt&amp;gt;device&amp;lt;/tt&amp;gt; (for example, &amp;lt;tt&amp;gt;eth0&amp;lt;/tt&amp;gt; on Linux, or &amp;lt;tt&amp;gt;le0&amp;lt;/tt&amp;gt; on a Sun Sparc). &amp;lt;tt&amp;gt;device&amp;lt;/tt&amp;gt; can be &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;any&amp;lt;/tt&amp;gt; on recent Linux systems, in which case all interfaces are used for packet capture. &amp;lt;tt&amp;gt;snaplen&amp;lt;/tt&amp;gt; specifies the length in bytes to be captured. If you want to capture the entire packet, set this to more than the packet size, including headers for the link type you are capturing from (65,535 should be sufficient). &amp;lt;tt&amp;gt;promisc&amp;lt;/tt&amp;gt; should be &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; if the interface should be put into promiscuous mode or &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; otherwise. When a network interface is in promiscuous mode, and promiscuous mode is supported by the underlying data link layer, it captures all traffic on the network, regardless of whether it is intended for the host running the packet capture. This does not have any effect if the device is set to &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;any&amp;lt;/tt&amp;gt;. The parameter &amp;lt;tt&amp;gt;to_ms&amp;lt;/tt&amp;gt; specifies a read timeout in milliseconds for when read operations should not necessarily return immediately when a packet is seen, therefore allowing us to capture multiple packets in one read operation. &amp;lt;tt&amp;gt;to_ms&amp;lt;/tt&amp;gt; is not supported on all platforms (for unsupported systems, this value is ignored), and is useful mostly if you're going to use &amp;lt;tt&amp;gt;pcap_dispatch&amp;lt;/tt&amp;gt; in nonblocking mode. A value of &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; causes ''libpcap'' to wait until packets arrive. &amp;lt;tt&amp;gt;pcap_open_live&amp;lt;/tt&amp;gt; returns &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt; is the open fails, and &amp;lt;tt&amp;gt;errbuf&amp;lt;/tt&amp;gt; is set to a human-readable error message. &amp;lt;tt&amp;gt;errbuf&amp;lt;/tt&amp;gt; should be of at least &amp;lt;tt&amp;gt;PCAP_ERRBUF_SIZE&amp;lt;/tt&amp;gt; size. &amp;lt;tt&amp;gt;pcap_open_live&amp;lt;/tt&amp;gt; can also return a warning message in &amp;lt;tt&amp;gt;errbuf&amp;lt;/tt&amp;gt; on a successful call. &amp;lt;tt&amp;gt;errbuf&amp;lt;/tt&amp;gt; should be checked after the successful call to determine if &amp;lt;tt&amp;gt;errbuf&amp;lt;/tt&amp;gt; is still a zero length string, and any warnings should be returned to the user. You can find an example of using the &amp;lt;tt&amp;gt;pcap_open_live&amp;lt;/tt&amp;gt; function in the [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#Open the Network Interface|Section 10.2.3]] section earlier in this chapter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_next''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;const u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_next&amp;lt;/tt&amp;gt; reads the next packet available on the buffer. This is a wrapper to &amp;lt;tt&amp;gt;pcap_dispatch&amp;lt;/tt&amp;gt; called with a &amp;lt;tt&amp;gt;cnt&amp;lt;/tt&amp;gt; of &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;. If successful, &amp;lt;tt&amp;gt;pcap_next&amp;lt;/tt&amp;gt; returns a pointer to the captured packet. If the read was not successful for any reason, no packet was available due to a timeout, or no packets passed a filter, &amp;lt;tt&amp;gt;pcap_next&amp;lt;/tt&amp;gt; returns &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt;. No packet header information is returned for this function. Because no error messages are returned by &amp;lt;tt&amp;gt;pcap_next&amp;lt;/tt&amp;gt;, it is more suited to simple uses and for reading from dump files. Use &amp;lt;tt&amp;gt;pcap_next_ex&amp;lt;/tt&amp;gt; if you need error handling.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_next_ex''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;pcap_next_ex(pcap_t&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;*p&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;struct&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;pcap_pkthdr&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;**pkt_header&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;u_char&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;**pkt_data)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_next_ex&amp;lt;/tt&amp;gt; returns the next packet available on the buffer. If successful, the function returns &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;pkt_header&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;pkt_data&amp;lt;/tt&amp;gt; point to the captured packet's ''libpcap'' capture information header and the packet, respectively. If not successful, the function returns &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; if the timeout expired, &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; if an error occurred reading the packet, or &amp;lt;tt&amp;gt;-2&amp;lt;/tt&amp;gt; if the packet is being read from a saved file and there are no more packets to read.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_loop''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_loop&amp;lt;/tt&amp;gt; enters a loop for processing &amp;lt;tt&amp;gt;cnt&amp;lt;/tt&amp;gt; packets from the opened capture (live or saved file). Unlike &amp;lt;tt&amp;gt;pcap_dispatch&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;pcap_loop&amp;lt;/tt&amp;gt; does not observe read timeouts. If &amp;lt;tt&amp;gt;cnt&amp;lt;/tt&amp;gt; is set to a negative number, the loop continues forever. The function specified by &amp;lt;tt&amp;gt;callback&amp;lt;/tt&amp;gt; is the name of a function of the prototype &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;callback&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;(u_char&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;*user&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;struct&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;pcap_pkthdr&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;*header&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;u_char*&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;packet)&amp;lt;/tt&amp;gt;. This function is called for each packet captured. The &amp;lt;tt&amp;gt;user&amp;lt;/tt&amp;gt; parameter is a user-specifiable value that is passed to the callback function when it is invoked, and can be &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt;. The function &amp;lt;tt&amp;gt;pcap_loop&amp;lt;/tt&amp;gt; returns &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;cnt&amp;lt;/tt&amp;gt; packets were successfully read, &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; on an error, and &amp;lt;tt&amp;gt;-2&amp;lt;/tt&amp;gt; if a call to &amp;lt;tt&amp;gt;pcap_breakloop&amp;lt;/tt&amp;gt; occurred before packets have been captured. If an error has occurred, you can use &amp;lt;tt&amp;gt;pcap_perror( )&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;pcap_geterr( )&amp;lt;/tt&amp;gt; to obtain the error message. You can find an example of using the &amp;lt;tt&amp;gt;pcap_loop&amp;lt;/tt&amp;gt; function in the [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#Capture and Process Packets|Section 10.2.5]] section earlier in this chapter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_dispatch''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;int pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;*user)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_dispatch&amp;lt;/tt&amp;gt; captures and processes packets while observing read timeouts specified in &amp;lt;tt&amp;gt;pcap_open_live&amp;lt;/tt&amp;gt;. The &amp;lt;tt&amp;gt;cnt&amp;lt;/tt&amp;gt; parameter specifies the maximum number of packets that are to be processed. When reading from a live capture, &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; up to &amp;lt;tt&amp;gt;cnt&amp;lt;/tt&amp;gt; packets can be processed depending on the status of the buffer. A &amp;lt;tt&amp;gt;cnt&amp;lt;/tt&amp;gt; value of &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; processes all packets in the buffer or the entire file, if used on a saved file. The function specified by &amp;lt;tt&amp;gt;callback&amp;lt;/tt&amp;gt; is the name of a function of the prototype &amp;lt;tt&amp;gt;void callback (u_char *user, const struct pcap_pkthdr *header, const u_char* packet)&amp;lt;/tt&amp;gt;. This function is called for each packet. The &amp;lt;tt&amp;gt;user&amp;lt;/tt&amp;gt; parameter is a user-specifiable value that is passed to the callback function when it is invoked, and can be &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt;. The function returns the number of packets processed if successful. &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; is returned if no packets were read (due to a read timeout, or if in nonblocking mode and no packets were available to be read), &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; if an error occurred, or &amp;lt;tt&amp;gt;-2&amp;lt;/tt&amp;gt; if a call to &amp;lt;tt&amp;gt;pcap_breakloop&amp;lt;/tt&amp;gt; was made before any packets were captured. If an error has occurred, you can use &amp;lt;tt&amp;gt;pcap_perror( )&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;pcap_geterr( )&amp;lt;/tt&amp;gt; to obtain the error message. Note that because of the way &amp;lt;tt&amp;gt;pcap_dispatch&amp;lt;/tt&amp;gt; behaves with different platforms, it might not necessarily return immediately after a read timeout.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_setnonblock''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;int pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_setnonblock&amp;lt;/tt&amp;gt; allows you to set the status of a live capture as blocking or nonblocking. The &amp;lt;tt&amp;gt;nonblock&amp;lt;/tt&amp;gt; parameter should be &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; to set the status to nonblocking and &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; to set the status to blocking (default). &amp;lt;tt&amp;gt;pcap_setnonblock&amp;lt;/tt&amp;gt; is intended for use with &amp;lt;tt&amp;gt;pcap_dispatch&amp;lt;/tt&amp;gt;, and when the live capture is set to nonblocking, &amp;lt;tt&amp;gt;pcap_dispatch&amp;lt;/tt&amp;gt; returns immediately if no packets are available for processing, without observing any read timeouts. If the live capture is set to block, the capture waits for packets to arrive. &amp;lt;tt&amp;gt;pcap_setnonblock&amp;lt;/tt&amp;gt; returns &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; on success and &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; on an error with a human-readable error message returned in &amp;lt;tt&amp;gt;errbuf&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_getnonblock''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;int pcap_getnonblock(pcap_t *p, char *errbuf)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_getnonblock&amp;lt;/tt&amp;gt; returns the current blocking status of &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (nonblocking) or &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (blocking; the default). If an error occurs, the function returns &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; with the &amp;lt;tt&amp;gt;errbuf&amp;lt;/tt&amp;gt; containing a human-readable error message. &amp;lt;tt&amp;gt;pcap_getnonblock&amp;lt;/tt&amp;gt; always returns &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; on saved files.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_set_datalink''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;int pcap_set_datalink(pcap_t *p, int dlt)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_set_datalink&amp;lt;/tt&amp;gt; sets the data link type on the underlying data link layer to the value in &amp;lt;tt&amp;gt;dlt&amp;lt;/tt&amp;gt; (refer to [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#networkst-CHP-10-TABLE-2|Table 10-2]] for example data link types) where the underlying data link layer supports multiple link types. Support for multiple link types is not available on all link types or platforms. You can obtain a list of all possible data link types supported for an interface using &amp;lt;tt&amp;gt;pcap_list_datalinks&amp;lt;/tt&amp;gt;. The function returns &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; on success and &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; on failure.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_compile''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;int pcap_compile(pcap_t *p, struct bpf_program *fp, char *str, intoptimize, bpf_u_int32 netmask)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_compile&amp;lt;/tt&amp;gt; is used to compile the &amp;lt;tt&amp;gt;tcpdump&amp;lt;/tt&amp;gt; format filter string &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; into a BPF filter &amp;lt;tt&amp;gt;fp&amp;lt;/tt&amp;gt;. &amp;lt;tt&amp;gt;optimize&amp;lt;/tt&amp;gt; controls whether the resulting code is optimized (value &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;) or not (value &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;). &amp;lt;tt&amp;gt;netmask&amp;lt;/tt&amp;gt; is the IPv4 netmask of the network interface being used for capture. This value can be obtained using &amp;lt;tt&amp;gt;pcap_lookupnet&amp;lt;/tt&amp;gt;, or it can be &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;, in which case some tests for IPv4 broadcast addresses will not work correctly. &amp;lt;tt&amp;gt;pcap_compile&amp;lt;/tt&amp;gt; returns &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; on success, &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; on error. You can find an example of using &amp;lt;tt&amp;gt;pcap_compile&amp;lt;/tt&amp;gt; in the [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#Configure Packet-Capture Options|Section 10.2.4]] section earlier in this chapter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_compile_nopcap''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;pcap_compile_nopcap(int snaplen, int linktype, struct bpf_program&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;*fp,char *str, int optimize, bpf_u_int32 netmask)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_compile_nopcap&amp;lt;/tt&amp;gt; is a wrapper to &amp;lt;tt&amp;gt;pcap_compile&amp;lt;/tt&amp;gt; that allows us to compile BPF filters without a &amp;lt;tt&amp;gt;pcap_t&amp;lt;/tt&amp;gt; structure. &amp;lt;tt&amp;gt;snaplen&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;linktype&amp;lt;/tt&amp;gt; specify the capture length and the link type (as per [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#networkst-CHP-10-TABLE-2|Table 10-2]]) and are used as arguments to &amp;lt;tt&amp;gt;pcap_open_dead&amp;lt;/tt&amp;gt;. &amp;lt;tt&amp;gt;pcap_compile_nopcap&amp;lt;/tt&amp;gt; returns &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; on success and &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; on error.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_setfilter''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;int pcap_setfilter(pcap_t *p, struct bpf_program *fp)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_setfilter&amp;lt;/tt&amp;gt; is used to set a compiled BPF filter on a capture session. &amp;lt;tt&amp;gt;fp&amp;lt;/tt&amp;gt; contains the compiled BPF program as generated by &amp;lt;tt&amp;gt;pcap_compile&amp;lt;/tt&amp;gt;. &amp;lt;tt&amp;gt;pcap_setfilter&amp;lt;/tt&amp;gt; returns &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; on success and &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; on error. You can find an example of using &amp;lt;tt&amp;gt;pcap_setfilter&amp;lt;/tt&amp;gt; in the [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#Configure Packet-Capture Options|Section 10.2.4]] section earlier in this chapter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_freecode''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;void pcap_freecode(struct bpf_program *fp)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_freecode&amp;lt;/tt&amp;gt; is used to free the memory used by a compiled BPF filter. You can find an example of using &amp;lt;tt&amp;gt;pcap_freecode&amp;lt;/tt&amp;gt; in the [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#Configure Packet-Capture Options|Section 10.2.4]] section earlier in this chapter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_breakloop''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;void pcap_breakloop(pcap_t *)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_breakloop&amp;lt;/tt&amp;gt; is used to signal &amp;lt;tt&amp;gt;pcap_dispatch&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;pcap_loop&amp;lt;/tt&amp;gt; (and &amp;lt;tt&amp;gt;pcap_next&amp;lt;/tt&amp;gt; on some platforms) to exit. A flag is set that is checked within many of the functions, and therefore &amp;lt;tt&amp;gt;pcap_dispatch&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;pcap_loop&amp;lt;/tt&amp;gt; might not exit immediately but can capture up to one more packet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_fileno''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;int pcap_fileno(pcap_t *p)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_fileno&amp;lt;/tt&amp;gt; returns the file descriptor for the capture session. This returns the handle for when a live capture is in progress and &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; if the session is using a saved file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_close''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;void pcap_close(pcap_t *p)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_close&amp;lt;/tt&amp;gt; closes the open session and any associated file handles.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_open_dead''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;pcap_t *pcap_open_dead(int linktype, int snaplen)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_open_dead&amp;lt;/tt&amp;gt; is used to create a &amp;lt;tt&amp;gt;pcap_t&amp;lt;/tt&amp;gt; handle, without opening a live capture or saved file. This is commonly used for compiling BPF code. &amp;lt;tt&amp;gt;linktype&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;snaplen&amp;lt;/tt&amp;gt; specify the link type as per [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#networkst-CHP-10-TABLE-2|Table 10-2]] and the capture length.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Save and Dump File Functions ===&lt;br /&gt;
&lt;br /&gt;
The following functions are for saving and reading packets from files on disk.&lt;br /&gt;
&lt;br /&gt;
====''pcap_open_offline''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;pcap_t *pcap_open_offline(const char *fname, char *errbuf)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_open_offline&amp;lt;/tt&amp;gt; is used to open a ''libpcap''-format saved file as a packet source. The &amp;lt;tt&amp;gt;fname&amp;lt;/tt&amp;gt; string holds a filename appropriate for the underlying platform, and can be &amp;quot;&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;&amp;quot; to denote &amp;lt;tt&amp;gt;STDIN&amp;lt;/tt&amp;gt;. On success a &amp;lt;tt&amp;gt;pcap_t&amp;lt;/tt&amp;gt; handle is returned that can be used to return packets using any of the ''libpcap'' functions for capturing packets (such as &amp;lt;tt&amp;gt;pcap_next_ex&amp;lt;/tt&amp;gt;). On error, the function returns &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;errbuf&amp;lt;/tt&amp;gt; is populated with an appropriate human-readable error message.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_dump_open''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;pcap_dumper_t *pcap_dump_open(pcap_t *p, const char *fname)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_dump_open&amp;lt;/tt&amp;gt; is used to open a file for saving packets to a disk file. The &amp;lt;tt&amp;gt;fname&amp;lt;/tt&amp;gt; string holds an appropriate filename for the underlying platform, or can be &amp;quot;&amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;&amp;quot; to denote &amp;lt;tt&amp;gt;STDOUT&amp;lt;/tt&amp;gt;. &amp;lt;tt&amp;gt;pcap_dump_open&amp;lt;/tt&amp;gt; returns a &amp;lt;tt&amp;gt;pcap_dumper_t&amp;lt;/tt&amp;gt; handle on success that can used for calling &amp;lt;tt&amp;gt;pcap_dump&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt; on error.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_dump''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;void pcap_dump(u_char *user, struct pcap_pkthdr *h, u_char *sp)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_dump&amp;lt;/tt&amp;gt; writes a packet with the ''libpcap'' packet header &amp;lt;tt&amp;gt;h&amp;lt;/tt&amp;gt;, and the packet body &amp;lt;tt&amp;gt;sp&amp;lt;/tt&amp;gt;, to the saved file opened with &amp;lt;tt&amp;gt;pcap_dump_open&amp;lt;/tt&amp;gt;. If called directly, the &amp;lt;tt&amp;gt;user&amp;lt;/tt&amp;gt; value should be the &amp;lt;tt&amp;gt;pcap_dumper_t&amp;lt;/tt&amp;gt; handle opened by &amp;lt;tt&amp;gt;pcap_dump_open&amp;lt;/tt&amp;gt;. &amp;lt;tt&amp;gt;pcap_dump&amp;lt;/tt&amp;gt; can also be called from &amp;lt;tt&amp;gt;pcap_loop&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;pcap_dispatch&amp;lt;/tt&amp;gt; to dump captured packets directly to a file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_dump_close''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;void pcap_dump_close(pcap_dumper_t *p)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_dump_close&amp;lt;/tt&amp;gt; closes the saved file associated with the &amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; handle.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_dump_flush''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;int pcap_dump_flush(pcap_dumper_t *p)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_dump_flush&amp;lt;/tt&amp;gt; is used to flush the file output buffer to disk therefore writing any packets output on dump session &amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; using &amp;lt;tt&amp;gt;pcap_dump&amp;lt;/tt&amp;gt;, but not yet written to disk. &amp;lt;tt&amp;gt;pcap_dump_flush&amp;lt;/tt&amp;gt; returns &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; on success, or &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; on error.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_major_version''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;int pcap_major_version(pcap_t *p)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_major_version&amp;lt;/tt&amp;gt; returns the major version of the ''libpcap'' library used to write a saved file opened with &amp;lt;tt&amp;gt;pcap_open_offline&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_minor_version''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;int pcap_minor_version(pcap_t *p)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_minor_version&amp;lt;/tt&amp;gt; returns the minor version of the ''libpcap'' library used to write a saved file opened with &amp;lt;tt&amp;gt;pcap_open_offline&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_file''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;FILE *pcap_file(pcap_t *p)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_file&amp;lt;/tt&amp;gt; returns the file handle to a saved file opened with &amp;lt;tt&amp;gt;pcap_open_offline&amp;lt;/tt&amp;gt;. &amp;lt;tt&amp;gt;pcap_file&amp;lt;/tt&amp;gt; returns the handle on success, or &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt; if the &amp;lt;tt&amp;gt;pcap_t&amp;lt;/tt&amp;gt; handle &amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; relates to a live capture opened with &amp;lt;tt&amp;gt;pcap_open_live&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_is_swapped''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;int pcap_is_swapped(pcap_t *p)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_is_swapped&amp;lt;/tt&amp;gt; returns &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; if the saved file referred to by &amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; is in a different byte order than the byte order used in the underlying platform, or &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; if it is the same. If the saved file is in a different byte order, most platforms provide the &amp;lt;tt&amp;gt;ntohs( )&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;ntohl()&amp;lt;/tt&amp;gt; functions for converting network order to host order (i.e., big endian to little endian) and/or &amp;lt;tt&amp;gt;htons()&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;htonl( )&amp;lt;/tt&amp;gt; for converting host order to network order (i.e., little endian to big endian).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Status Functions ===&lt;br /&gt;
&lt;br /&gt;
These functions are used to interrogate interfaces for information.&lt;br /&gt;
&lt;br /&gt;
====''pcap_datalink''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;int pcap_datalink(pcap_t *p)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_datalink&amp;lt;/tt&amp;gt; returns the type of the underlying data link layer of a session. This can be compared to the predefined list of values included in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#networkst-CHP-10-TABLE-2|Table 10-2]], or converted to a human-readable string using &amp;lt;tt&amp;gt;pcap_datalink_val_to_name&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;pcap_datalink_val_to_description&amp;lt;/tt&amp;gt;. You can find an example of using &amp;lt;tt&amp;gt;pcap_datalink&amp;lt;/tt&amp;gt; in the [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#Configure Packet-Capture Options|Section 10.2.4]] section earlier in this chapter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_list_datalinks''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;int pcap_list_datalinks(pcap_t *p, int **dlt_buf);&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_list_datalinks&amp;lt;/tt&amp;gt; lists all data link types supported by a capture device. Where multiple types are supported, a particular data link type can be selected with &amp;lt;tt&amp;gt;pcap_set_datalink&amp;lt;/tt&amp;gt;. &amp;lt;tt&amp;gt;pcap_list_datalinks&amp;lt;/tt&amp;gt; returns the number of supported data links on success, with &amp;lt;tt&amp;gt;dlt_buf&amp;lt;/tt&amp;gt; pointing to an array of data link type values. The function returns &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; on error. The data link type values can be converted to human-readable link types (such as the values in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#networkst-CHP-10-TABLE-2|Table 10-2]]) using the &amp;lt;tt&amp;gt;pcap_datalink_val_to_name&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;pcap_datalink_val_to_description&amp;lt;/tt&amp;gt; functions. You can find an example of using &amp;lt;tt&amp;gt;pcap_list_datalinks&amp;lt;/tt&amp;gt; in the [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#Configure Packet-Capture Options|Section 10.2.4]] section earlier in this chapter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_snapshot''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;int pcap_snapshot(pcap_t *p)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_snapshot&amp;lt;/tt&amp;gt; returns the number of bytes captured per packet (snapshot length) of the opened session. This is the value specified at the &amp;lt;tt&amp;gt;pcap_open_live&amp;lt;/tt&amp;gt; call to open the interface.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_stats''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;int pcap_stats(pcap_t *p, struct pcap_stat *ps)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_stats&amp;lt;/tt&amp;gt; is used to return capture statistics for all packets captured since the start of the capture. &amp;lt;tt&amp;gt;pcap_stats&amp;lt;/tt&amp;gt; is relevant only for live captures because statistics are not stored in saved files. The &amp;lt;tt&amp;gt;pcap_stat&amp;lt;/tt&amp;gt; structure returned contains the members &amp;lt;tt&amp;gt;ps_recv&amp;lt;/tt&amp;gt; (number of packets received), &amp;lt;tt&amp;gt;ps_drop&amp;lt;/tt&amp;gt; (number of packets dropped), &amp;lt;tt&amp;gt;ps_ifdrop&amp;lt;/tt&amp;gt; (number of packets dropped by the interface; this is not supported on all platforms), and, on Windows platforms, &amp;lt;tt&amp;gt;bs_capt&amp;lt;/tt&amp;gt; (number of packets reaching the application). Exactly what is measured for packets received and dropped depends on the platform. For example, when using BPF filters, some platforms count all packets received, while others count only the packets passing the filter. &amp;lt;tt&amp;gt;pcap_stats&amp;lt;/tt&amp;gt; returns &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; on error or when statistics are not supported and it returns &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; on success.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_lib_version''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;const char *pcap_lib_version(void)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_lib_version&amp;lt;/tt&amp;gt; returns a string containing the description of the ''libpcap'' version in use. For ''libpcap'' version 0.8.3 this is something such as &amp;lt;tt&amp;gt;libpcap version 0.8.3&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_datalink_name_to_val''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;int pcap_datalink_name_to_val(const char *name);&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_datalink_name_to_val&amp;lt;/tt&amp;gt; returns the numeric value of a data link type when supplied as a string. The string &amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt; is a data link type, minus the &amp;lt;tt&amp;gt;DLT_&amp;lt;/tt&amp;gt;, as described in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#networkst-CHP-10-TABLE-2|Table 10-2]]. The numeric value is returned on success, or &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; on error.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_datalink_val_to_name''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;const char *pcap_datalink_val_to_name(int dlt);&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_datalink_val_to_name&amp;lt;/tt&amp;gt; returns the data link name as per [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#networkst-CHP-10-TABLE-2|Table 10-2]] when supplied with the numeric value in &amp;lt;tt&amp;gt;dlt&amp;lt;/tt&amp;gt;. This returns the name on success, or &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt; on error. You can find an example of using &amp;lt;tt&amp;gt;pcap_datalink_val_to_name&amp;lt;/tt&amp;gt; in the [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#Configure Packet-Capture Options|Section 10.2.4]] section earlier in this chapter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_datalink_val_to_description''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;const char *pcap_datalink_val_to_description(int dlt)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_datalink_val_to_description&amp;lt;/tt&amp;gt; returns a short text description when supplied with the numeric value in &amp;lt;tt&amp;gt;dlt&amp;lt;/tt&amp;gt;. This description is contained in the array &amp;lt;tt&amp;gt;dlt_choices&amp;lt;/tt&amp;gt; in ''pcap.c'' of the ''libpcap'' source code. This returns the name on success, or &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt; on error. You can find an example of using &amp;lt;tt&amp;gt;pcap_datalink_val_to_description&amp;lt;/tt&amp;gt; in the [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers#Configure Packet-Capture Options|Section 10.2.4]] section earlier in this chapter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Error-Handling Functions ===&lt;br /&gt;
&lt;br /&gt;
''libpcap'' supplies three functions for determining and reporting errors, as shown in the following.&lt;br /&gt;
&lt;br /&gt;
====''pcap_geterr''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;char *pcap_geterr(pcap_t *p)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_geterr&amp;lt;/tt&amp;gt; returns the error text for the last ''libpcap'' error that has occurred. This requires that the &amp;lt;tt&amp;gt;pcap_t&amp;lt;/tt&amp;gt; handle &amp;lt;tt&amp;gt;p&amp;lt;/tt&amp;gt; has not been closed using &amp;lt;tt&amp;gt;pcap_close&amp;lt;/tt&amp;gt;. &amp;lt;tt&amp;gt;pcap_geterr&amp;lt;/tt&amp;gt; is used to obtain human-readable error messages for all ''libpcap'' functions that do not supply this ability through the use of an &amp;lt;tt&amp;gt;errbuf&amp;lt;/tt&amp;gt; parameter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_strerror''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;char *pcap_strerror(int error)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_strerror&amp;lt;/tt&amp;gt; is an implementation of &amp;lt;tt&amp;gt;strerror(1)&amp;lt;/tt&amp;gt; for platforms that do not have their own implementation. &amp;lt;tt&amp;gt;pcap_strerror&amp;lt;/tt&amp;gt; returns an operating system error message for a given error code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====''pcap_perror''====&lt;br /&gt;
&lt;br /&gt;
Prototype: &amp;lt;tt&amp;gt;void pcap_perror(pcap_t *p, char *prefix)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Synopsis=====&lt;br /&gt;
&lt;br /&gt;
Purpose: &amp;lt;tt&amp;gt;pcap_perror&amp;lt;/tt&amp;gt; prints the last ''libpcap'' error message to &amp;lt;tt&amp;gt;STDERR&amp;lt;/tt&amp;gt; in human-readable format, prefixed by the string &amp;lt;tt&amp;gt;prefix&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Docbook2Wiki</name></author>	</entry>

	</feed>