The Packet Capture library (libpcap) is an API that provides a high level interface to packet capture systems. It was originally written for UNIX where it is used by TcpDump and of other network tools as the low-level part of the capture process. The Win32 version of the library is fully compatible with the UNIX one, and can run indifferently in Windows 95, 98, NT, 2000 .
- pcap_setbuff: this function is used by the capture application to set the dimension of the buffer in the driver. It exploits the possibility of the capture driver to change the size of the drivers buffer whenever it is needed. This possibility is not present in UNIX, where the buffer is statically allocated by BPF and cannot be changed. Since the dimension of the drivers buffer is a important parameter for the capture, a function to set or modify it without using directly the calls of PACKET.DLL is very useful.
- pcap_setmode: this function can be used to put an adapter in statistics mode. It was added to allow the use of statistics mode of the BPF packet capture driver from libpcap. For more informations about statistics mode, see the chapter on the driver.
As we said, the Win32 of libpcap is a superset of the UNIX one and is fully compatible with it. The only differences are statistics mode and the pcap_setbuff function. For this reason, we provide the HTML version of the UNIX manual of libpcap, modified to include the new function introduced in the Win32 version.
WinDump and libpcap are written using the C language, and the original code was written to be easily portable to the various UNIX versions. Windows, though does not offer all the calls of the POSIX systems, offers some API calls very similar to them. The memory model is comparable (32 bit in Windows and in most UNIX) and the dimension of the integers is similar. The Win32 version of the pcap library is based on the packet capture driver. We developed this driver following the structure and the behavior of BPF for UNIX. This made the porting process quite easy and linear.
During the porting process some problems were encountered with the include files. In fact not all the include files needed to compile the pcap library are present in Windows. Only sometimes it is possible to find the corresponding of a UNIX structure in a Win32 include file, but some structures do not exist in Windows. This problem was solved taking the missing definitions from FreeBSD, a public domain UNIX-like operating system. Since the source code of the entire FreeBSD project is available under the Berkeley license, we were able to obtain the needed include sections from it. The include files containing these definitions are put in the Win32-Include directory.
libpcap also needs some UNIX network functions that are not present in Win32 (for example getnetent, getnetbyname, etc.). These functions, were taken from libraries provided with public-domain C compilers for Free-BSD. For example GNU C for Linux has a library called libc whose source code is available and from which we took some functions.
The code for the communication with the network adapter had to be rewritten in order to use the NDIS packet capture driver. According to the libpcap source code structure, the code to interact with the hardware is contained a set of files that are called pcap-XXX.c (there is usually an equivalent pcap-XXX.h), where XXX indicates a particular operating system or a particular capture system. Examples of these files are pcap-nit.c, pcap-bpf.c, pcap-linux.c. The functions in these files are used to:
We created a file named pcap-win32.c, that implements these functions for the Win32 operating systems family, using the functions of the PACKET.DLL API to interact with the capture driver. This file has the following functions:
Function |
Description |
pcap_open_live | This function is used to open an adapter and initialize it to capture packets. First, this function opens the adapter with the PacketOpenAdapter function of PACKET.DLL. If no errors occurred, and if the promisc input parameter is TRUE, the adapter is set in promiscuous mode with a call to PacketSetHwFilter. Then the type of network is determined with a call to PacketGetNetType. The type of network is saved to be used lately with libpcap's pcap_datalink function. Then pcap_open_live allocates a buffer to receive the packets from the driver. Notice that this buffer is allocated once by pcap_open_live, and then is used by all the pcap_read calls. It is allocated only a time to optimize the capture performances. The size of this buffer is 256 KB and is fixed: changing it requires the recompilation of libpcap. Notice that this buffer in libpcap for UNIX must have the same size of the BPF's packet buffer. In Windows, the size of the two buffers can be different, because the copy mechanism of the packet capture driver is independent from the size of the application's buffer. This feature is very useful when the driver's buffer is very big (allocating a corresponding application buffer's wouldn't be possible). At this point a PACKET structure is allocated and initialized. It will be used to read the data from the driver. In previous versions of libpcap for Windows, a PACKET structure was allocated and initialized for every read on the driver. To improve the capture speed, from version 2.01 there is only one global PACKET structure, that is used for all the read calls of libpcap. Finally, pcap_open_live uses the PacketSetBuff function of PACKET.DLL to allocate a 1 MB packet buffer in the capture driver. The user will be able to change the size of this buffer with the pcap_setbuff libpcap's function. |
pcap_read | This function reads a group of packets from the packet capture driver and invokes the user's callback function for each of them. The function starts performing a PacketReceivePacket to fill the libpcap's packet buffer with data coming from the driver. At this point pcap_read loops through the packets, invoking for each of them the user defined callback function received as an input parameter. |
pcap_setbuff | This function sets a new buffer in the packet capture driver calling the PacketSetBuff procedure of PACKET.DLL. This function is not present in the UNIX versions of libpcap. |
pcap_setfilter | This function sets a new packet filter in the capture driver. The filter is received in a bpf_program structure, and is passed to the driver calling the PacketSetBpf procedure of PACKET.DLL. |
pcap_stats | This function get the capture statistics from the packet capture driver (number of packets received and number of packets dropped by the driver) calling the PacketGetStats procedure of PACKET.DLL. |
pcap_setmode | Sets the working mode of an adapter. This function can be used to put an instance of the driver in statistics mode, and is present only in the Win32 version of libpcap. |
The use of packet.dll makes possible to have only a version of libpcap that works in Windows 95 and Windows NT. Pcap-win32.c is not very different from the equivalent file for the UNIX systems (like FREEBSD or Digital UNIX) that have BPF in the kernel. This is due to the similar behavior of the BPF and our capture driver.
As for the rest of the libpcap's source code, we isolated all our changes to the original sources (above all different include files or minor changes) through the use of #ifdef and #ifndef like in the following example
#ifdef WIN32 /* source code for Windows */ #endif |
In this way, the code of libpcap for Windows is compatible with the code for UNIX, and can be compiled in the UNIX environment in order to generate the correct libpcap binary file.
The pcap library was written to be used from C programs. The reason is that the original version of libpcap was for the UNIX family of operating systems, where C is the most used language. In Windows, C++ (with the MFC class library) is the most used programming language. For this reason we made some efforts to allow a programmer to easily use the libpcap functions from C++. A new include file, called Pcap-c++.h, was created. It exports the functions of libpcap in the C++ calling convention, and must be included in a C++ file instead of the standard pcap.h file.
From version 2.02, libpcap for windows offers the possibility to exploit statistics mode of the packet capture driver. Statistics mode, is a particular working mode of the BPF capture driver that can be used to perform real time statistics on the network's traffic in an easy way and with the minimum impact on the system. When in statistics mode, the driver does not capture anything, but limits itself to count the number of packets and the amount of bytes that satisfy the user-defined BPF filter. This is very useful when a user needs to perform statistics on the network's traffic, but does not need the data of every packet. Statistics mode allows to obtain statistics values with a VERY low impact on the system compared to the standard capture mode, because minimizes the number of bytes copied and context switches. The counters are encapsulated in a bpf_hdr structure before being passed to the application, so interaction with libpcap is quite immediate.
An application that wants to use statistics mode should perform the following operations:
At this point, the capture callback function is invoked every time the timeout defined with pcap_open_live expires. This function receives in the third input parameter a pointer to a buffer containing two 64 bit counters. The first holds the number of packets satisfying the filter received in the last interval, the second the amount of bytes satisfying the filter. The second parameter of the callback function is a standard bpf_hdr structure, with a valid timestamp. Next table shows the data received from the packet driver.
HEADER |
struct timeval bh_tstamp |
UINT bh_caplen=16 |
UINT bh_datalen=16 |
USHORT bh_hdrlen=18 |
DATA |
LARGE_INTEGER PacketsAccepted |
LARGE_INTEGER BytesAccepted |
The NetMeter example in the developer's pack shows how to use statistics mode from libpcap.