Winpcap是一个强大的网络开发库,可以实现许多功能:获取可用的网络适配器;获取指定适配器信息(比如名称和描述信息);捕获指定网卡的数据封包;发送数据封包;过滤捕获的包以获取特定包等。
首先到http://www.winpcap.org/install/default.htm下载安装winpcap 驱动和DLL组件。
然后到http://www.winpcap.org/devel.htm.下载winpcap开发包,解压到指定目录,这里我解压到C:/WpdPack_4_0_2/WpdPack,可以看到里面包含了:Lib,Include,文档和示例程序。
首先创建一个C++控制台程序,设置如下:
1) 在“Configuration Properties -> C/C++ -> General”中,在Additional Include Directories加入Include路径(“C:/WpdPack_4_0_2/WpdPack/Include”)。
2) 在 “Configuration Properties -> Linker -> General” 中,在Additional Library Directories中加入 winpcap 库文件路径 ( “C:/WpdPack_4_0_2/WpdPack/Lib” ) 。
3) 在“Configuration Properties -> Linker -> Input”中, Additional Dependencies 加入用到的两个winpcap 库文件(wpcap.lib and Packet.lib ) 。
4) 为了使用Winpcap的远程访问,必须在预处理器中加入HAVE_REMOTE
示例程序1 获取适配器列表
int _tmain( int argc, _TCHAR * argv[])
{
pcap_if_t * allAdapters; // 适配器列表
pcap_if_t * adapter;
char errorBuffer[ PCAP_ERRBUF_SIZE ]; // 错误信息缓冲区
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 ( allAdapters == NULL )
{ // 不存在人任何适配器
printf( " /nNo adapters found! Make sure WinPcap is installed./n " );
return 0 ;
}
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 " );
pcap_freealldevs( allAdapters ); // 释放适配器列表
system( " PAUSE " );
return 0 ;
}
示例程序2 打开指定适配器并捕获数据包
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 ]; // 错误信息缓冲区
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 ( allAdapters == NULL )
{ // 不存在任何适配器
printf( " /nNo adapters found! Make sure WinPcap is installed./n " );
return 0 ;
}
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 " );
// 释放适配器列表
pcap_freealldevs( allAdapters );
return - 1 ;
}
adapter = allAdapters;
for ( crtAdapter = 0 ; crtAdapter < adapterNumber - 1 ; crtAdapter ++ )
adapter = adapter -> next;
// 打开指定适配器
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 );
// 释放适配器列表
pcap_freealldevs( allAdapters );
return - 1 ;
}
printf( " /nCapture session started on adapter %s/n " , adapter -> name );
pcap_freealldevs( allAdapters ); // 释放适配器列表
// 开始捕获数据包
int retValue;
while ( ( retValue = pcap_next_ex( adapterHandle,
& packetHeader,
& packetData ) ) >= 0 )
{
// timeout elapsed if we reach this point
if ( retValue == 0 )
continue ;
// 打印捕获数据包的信息
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 ;
}
示例程序3 发送数据封包
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 ]; // 错误信息缓冲区
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 ( allAdapters == NULL )
{ // 不存在人任何适配器
printf( " /nNo adapters found! Make sure WinPcap is installed./n " );
return 0 ;
}
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 " );
// 释放适配器列表
pcap_freealldevs( allAdapters );
return - 1 ;
}
adapter = allAdapters;
for ( crtAdapter = 0 ; crtAdapter < adapterNumber - 1 ; crtAdapter ++ )
adapter = adapter -> next;
// 打开指定适配器
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 );
// 释放适配器列表
pcap_freealldevs( allAdapters );
return - 1 ;
}
pcap_freealldevs( allAdapters ); // 释放适配器列表
// 创建数据封包
// 设置目标的MAC地址为01 : 01 : 01 : 01 : 01 : 01
packet[ 0 ] = 0x01 ;
packet[ 1 ] = 0x01 ;
packet[ 2 ] = 0x01 ;
packet[ 3 ] = 0x01 ;
packet[ 4 ] = 0x01 ;
packet[ 5 ] = 0x01 ;
// 设置源的MAC地址为02 : 02 : 02 : 02 : 02 : 02
packet[ 6 ] = 0x02 ;
packet[ 7 ] = 0x02 ;
packet[ 8 ] = 0x02 ;
packet[ 9 ] = 0x02 ;
packet[ 10 ] = 0x02 ;
packet[ 11 ] = 0x02 ;
// 设置封包其他部分内容
for ( int index = 12 ; index < 20 ; index ++ )
{
packet[index] = 0xC4 ;
}
// 发送数据封包
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 ;
}
参考文章: