Introduction to the Winpcap Networking Libraries

本文介绍了WinPcap库的基本安装配置方法,并通过几个简单的示例演示了如何使用该库来获取网络适配器列表、捕获和发送网络数据包。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Note: This is an unedited contribution. If this article is inappropriate, needs attention or copies someone else's work without reference then please Report This Article

Motivation

The first question you should ask yourself before starting to write an article is why do you need to write it. In my case, I have decided to write this introductory article because I saw that many people are interested in networking and they want to use the winpcap library for programming.

Winpcap is a powerful set of libraries, which can be used for a various list of tasks, very important in network programming: obtain all available network adapters; obtain information about an adapter, like the name and the description of the adapter; capture network packets using one of the network interface cards of the computer; send network packets across the network; filter the captured packets, to obtain only the desired ones.

Introduction

The most important thing to do before using this library is to install it correctly. That’s why I have decided to give a helping hand to all people who want to install and use winpcap library. Remember this is not a winpcap tutorial. This presents the quickest way to install and start using winpcap. Thus, let’s start by presenting how to install winpcap.

Installing and configuring winpcap

First of all, we must install the winpcap driver and DLL components. The latest version is 4.0.2. We can get it from the following location: http://www.winpcap.org/install/default.htm.

Sample Image - maximum width is 600 pixels

After downloading and running the executable file, following the instructions given by the wizard, the winpcap components are installed on your computer.

Sample Image - maximum width is 600 pixels

The next step is to download the winpcap developer’s pack. This can be obtained from the following location: http://www.winpcap.org/devel.htm.

Sample Image - maximum width is 600 pixels

This is a ZIP file that contains the resources needed to create winpcap networking applications: libraries, include files, documentation and example applications. You must download the ZIP file and uncompress it to the desired folder. For example, I placed the developer’s pack in “C:/WpdPack_4_0_2/WpdPack”.

Sample Image - maximum width is 600 pixels

Now, we are finally ready to start using winpcap’s power to develop strong, networking applications. For the sake of the example, I will use Visual Studio 2005 in the following examples.

Let’s see how to link a C++ program with winpcap libraries.

First, we create a simple C++ console application project, named winpcapTest. Then, go to Project -> winpcapTest Properties… and do the following:

Under “Configuration Properties -> C/C++ -> General” tab, add the winpcap include path ( “C:/WpdPack_4_0_2/WpdPack/Include” ) to Additional Include Directories:

Sample Image - maximum width is 600 pixels

Under “Configuration Properties -> Linker -> General” tab, add the winpcap library path ( “C:/WpdPack_4_0_2/WpdPack/Lib” ) to Additional Library Directories:

Sample Image - maximum width is 600 pixels

Under “Configuration Properties -> Linker -> Input” tab, add the two main winpcap libraries ( wpcap.lib and Packet.lib ) to Additional Dependencies:

Sample Image - maximum width is 600 pixels

That’s all there is to it. Now, we are ready to test the winpcap networking library.

In what follows we will present some simple examples of applications that use the winpcap libraries. For more detailed tutorials see the winpcap documentation materials.

Using winpcap

To use the libraries, we must simply include the winpcap header ( #include <pcap.h> ) at the beginning of every source file that uses the libraries. Also, usually we intend to use winpcap remote capabilities. In this case, we must add HAVE_REMOTE to the preprocessor definitions. To do this, under “Project -> winpcapTest Properties… -> Configuration Properties -> C/C++ -> Preprocessor” tab, add the HAVE_REMOTE definition to Preprocessor Definitions:

Sample Image - maximum width is 600 pixels

Obtaining the adapter list

Typically, the first thing we do when we use a winpcap based application is to obtain the list of attached network adapters. We do this with pcap_findalldevs_ex() function, which returns a linked list of pcap_if structures. Every pcap_if structure contains detailed information about a network adapter. In particular, name and description contain the name and a detailed description of the corresponding device.

In the following code, we obtain the network adapters and we print it on the screen. If no adapters are found, we print an error.

Collapse
#include <pcap.h>

int _tmain(int argc, _TCHAR* argv[])
{
pcap_if_t * allAdapters;
pcap_if_t * adapter;
char errorBuffer[ PCAP_ERRBUF_SIZE ];

// retrieve the adapters from the computer
if( pcap_findalldevs_ex( PCAP_SRC_IF_STRING, NULL,
&allAdapters, errorBuffer ) == -1 )
{
fprintf( stderr, "Error in pcap_findalldevs_ex function: %s/n", errorBuffer );
return -1;
}

// if there are no adapters, print an error
if( allAdapters == NULL )
{
printf( "/nNo adapters found! Make sure WinPcap is installed./n" );
return 0;
}

// print the list of adapters along with basic information about an adapter
int crtAdapter = 0;
for( adapter = allAdapters; adapter != NULL; adapter = adapter->next)
{
printf( "/n%d.%s ", ++crtAdapter, adapter->name );
printf( "-- %s/n", adapter->description );
}

printf( "/n" );

// free the adapter list
pcap_freealldevs( allAdapters );

system( "PAUSE" );
return 0;
}

In the code above, we see that pcap_findalldevs_ex() function has an errorBuffer parameter. If an error is encountered, the description of the error will be stored in this parameter. At the end, to avoid memory leaks, we must free the adapter list, since we don’t need it anymore.

If we compile the above program on an XP machine, we get the following adapters:

  1. rpcap:///Device/NPF_GenericDialupAdapter -- Network adapter 'Adapter for gener ic dialup and VPN capture' on local host
  2. rpcap:///Device/NPF_{E5C91E92-0E7F-4286-BDC3-4A6547E099C1} -- Network adapter 'VIA Rhine II Fast Ethernet Adapter (Microsoft's Packe t Scheduler) ' on local host

Opening an adapter and capturing the packets

Once we have learned how to obtain the list of attached adapters, it is time to see how to open a specified adapter and capture some packets. We use function pcap_open() to open an adapter. Three of the parameters passed to pcap_open() are named snaplen, flags and to_ms.

snaplen specifies the length of the packet to capture. For instance, on Windows OS, the adapter can be configured to capture only a specified part of every network packet. To enable the application to always receive the entire contents of a packet, we give this parameter value 65536.

flags specify all flags passed to the adapter. The most important flag is the one that specifies if the adapter will be in promiscuous mode. If not in promiscuous mode, the adapter captures only the packets destined to it. The other packets are ignored. In promiscuous mode, the adapter captures all network packets (destined to it or not).

to_ms specifies the read timeout, in milliseconds. This means that, after to_ms milliseconds, the capture session will exit on the adapter. Setting this value to 0 means that we do not want a timeout.

The following program opens a capture session on an adapter and prints some information about each captured network packet.

Collapse
#include <pcap.h>

int _tmain(int argc, _TCHAR* argv[])
{
pcap_if_t * allAdapters;
pcap_if_t * adapter;
pcap_t * adapterHandle;
struct pcap_pkthdr * packetHeader;
const u_char * packetData;
char errorBuffer[ PCAP_ERRBUF_SIZE ];

// retrieve the adapters from the computer
if( pcap_findalldevs_ex( PCAP_SRC_IF_STRING, NULL,
&allAdapters, errorBuffer ) == -1 )
{
fprintf( stderr, "Error in pcap_findalldevs_ex function: %s/n", errorBuffer );
return -1;
}

// if there are no adapters, print an error
if( allAdapters == NULL )
{
printf( "/nNo adapters found! Make sure WinPcap is installed./n" );
return 0;
}

// print the list of adapters along with basic information about an adapter
int crtAdapter = 0;
for( adapter = allAdapters; adapter != NULL; adapter = adapter->next)
{
printf( "/n%d.%s ", ++crtAdapter, adapter->name );
printf( "-- %s/n", adapter->description );
}

printf( "/n" );

int adapterNumber;

printf( "Enter the adapter number between 1 and %d:", crtAdapter );
scanf_s( "%d", &adapterNumber );

if( adapterNumber < 1 || adapterNumber > crtAdapter )
{
printf( "/nAdapter number out of range./n" );

// Free the adapter list
pcap_freealldevs( allAdapters );

return -1;
}

// parse the list until we reach the desired adapter
adapter = allAdapters;
for( crtAdapter = 0; crtAdapter < adapterNumber - 1; crtAdapter++ )
adapter = adapter->next;

// open the adapter
adapterHandle = pcap_open( adapter->name, // name of the adapter
65536, // portion of the packet to capture
// 65536 guarantees that the whole
// packet will be captured
PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode
1000, // read timeout - 1 millisecond
NULL, // authentication on the remote machine
errorBuffer // error buffer
);

if( adapterHandle == NULL )
{
fprintf( stderr, "/nUnable to open the adapter/n", adapter->name );

// Free the adapter list
pcap_freealldevs( allAdapters );

return -1;
}

printf( "/nCapture session started on adapter %s.../n", adapter->name );

// free the adapter list
pcap_freealldevs( allAdapters );


// this is the most important part of the application
// here we start receiving packet traffic
int retValue;
while( ( retValue = pcap_next_ex( adapterHandle,
&packetHeader,
&packetData ) ) >= 0 )
{
// timeout elapsed if we reach this point
if( retValue == 0 )
continue;

// we print some information about the captured packet
// we print only the length of the packet here
printf( "length of packet: %d/n", packetHeader->len );
}

// if we get here, there was an error reading the packets
if( retValue == -1 )
{
printf( "Error reading the packets: %s/n", pcap_geterr( adapterHandle ) );
return -1;
}


system( "PAUSE" );
return 0;
}

Some explanations are in order about the above program.

First of all, we see that the pcap_open() function, after opening the adapter, returns a handle to an adapter handle (pcap_t structure), which we will use intensively in the capture session.

For capturing a packet, we use the pcap_next_ex() function. This function receives as parameters the adapter handle created with the call to pcap_open() function, a pointer to pcap_pkthdr structure, which holds some information about the packet header and a pointer to a buffer in which we will store the whole packet data (including the packet header).

Sending packets over the network

Another useful feature of the winpcap libraries is the ability to send packets over the network.

To send a packet, we use pcap_sendpacket() function. This function receives as parameters a buffer containing the data to send, the length of the buffer and the adapter handle. An important thing to notice here is that, in order to send meaningful packets on the network, we must correctly create the packet data (with respect to the internet protocol headers).

In what follows, we create a simple program, that sends a packet over the network.

Collapse
#include <pcap.h>

int _tmain(int argc, _TCHAR* argv[])
{
pcap_if_t * allAdapters;
pcap_if_t * adapter;
pcap_t * adapterHandle;
u_char packet[ 20 ];
char errorBuffer[ PCAP_ERRBUF_SIZE ];

// retrieve the adapters from the computer
if( pcap_findalldevs_ex( PCAP_SRC_IF_STRING, NULL,
&allAdapters, errorBuffer ) == -1 )
{
fprintf( stderr, "Error in pcap_findalldevs_ex function: %s/n", errorBuffer );
return -1;
}

// if there are no adapters, print an error
if( allAdapters == NULL )
{
printf( "/nNo adapters found! Make sure WinPcap is installed./n" );
return 0;
}

// print the list of adapters along with basic information about an adapter
int crtAdapter = 0;
for( adapter = allAdapters; adapter != NULL; adapter = adapter->next)
{
printf( "/n%d.%s ", ++crtAdapter, adapter->name );
printf( "-- %s/n", adapter->description );
}

printf( "/n" );

int adapterNumber;

printf( "Enter the adapter number between 1 and %d:", crtAdapter );
scanf_s( "%d", &adapterNumber );

if( adapterNumber < 1 || adapterNumber > crtAdapter )
{
printf( "/nAdapter number out of range./n" );

// Free the adapter list
pcap_freealldevs( allAdapters );

return -1;
}

// parse the list until we reach the desired adapter
adapter = allAdapters;
for( crtAdapter = 0; crtAdapter < adapterNumber - 1; crtAdapter++ )
adapter = adapter->next;

// open the adapter
adapterHandle = pcap_open( adapter->name, // name of the adapter
65536, // portion of the packet to capture
// 65536 guarantees that the whole
// packet will be captured
PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode
1000, // read timeout - 1 millisecond
NULL, // authentication on the remote machine
errorBuffer // error buffer
);

if( adapterHandle == NULL )
{
fprintf( stderr, "/nUnable to open the adapter/n", adapter->name );

// Free the adapter list
pcap_freealldevs( allAdapters );

return -1;
}

// free the adapter list
pcap_freealldevs( allAdapters );


// this is the most important part of the application
// here we send the packet

// first we create the packet

// set mac destination address to 01 : 01 : 01 : 01 : 01 : 01
packet[0] = 0x01;
packet[1] = 0x01;
packet[2] = 0x01;
packet[3] = 0x01;
packet[4] = 0x01;
packet[5] = 0x01;

// set mac source address to 02 : 02 : 02 : 02 : 02 : 02
packet[6] = 0x02;
packet[7] = 0x02;
packet[8] = 0x02;
packet[9] = 0x02;
packet[10] = 0x02;
packet[11] = 0x02;

// set the rest of the packet
for( int index = 12; index < 20; index++ )
{
packet[index] = 0xC4;
}

// send the packet
if( pcap_sendpacket( adapterHandle, // the adapter handle
packet, // the packet
20 // the length of the packet
) != 0 )
{
fprintf( stderr,"/nError sending the packet: /n", pcap_geterr( adapterHandle ) );
return -1;
}


system( "PAUSE" );
return 0;
}

Conclusion

In this article we saw what winpcap libraries are, how they can be installed and, most important, some basic applications that use them. Check the documentation tutorials to explore the real power of winpcap.

History

  • 18th October, 2008: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

cristitomi



Occupation: Software Developer (Senior)
Location: Romania Romania


From: http://www.codeproject.com/KB/IP/winpcap_basic.aspx
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值