Winpcap网络开发库入门

      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  获取适配器列表

#include <pcap.h>
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 打开指定适配器并捕获数据包

#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 ];//错误信息缓冲区
    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 发送数据封包

#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 ];//错误信息缓冲区
    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;
    
// 设置封包其他部分内容
    forint 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;
}

 

参考文章:

1Introduction to the Winpcap Networking Libraries

posted on 2008-10-20 16:03  Phinecos(洞庭散人)  阅读(24549)  评论(6编辑  收藏  举报

导航