Winpcap网络开发库入门

      Winpcap是一个强大的网络开发库,可以实现许多功能:获取可用的网络适配器;获取指定适配器信息(比如名称和描述信息);捕获指定网卡的数据封包;发送数据封包;过滤捕获的包以获取特定包等。

     

      首先到http://www.winpcap.org/install/default.htm下载安装winpcap 驱动和DLL组件。

Winpcap网络开发库入门

Winpcap网络开发库入门

      然后到http://www.winpcap.org/devel.htm.下载winpcap开发包,解压到指定目录,这里我解压到C:\WpdPack_4_0_2\WpdPack,可以看到里面包含了:Lib,Include,文档和示例程序。

Winpcap网络开发库入门

Winpcap网络开发库入门

首先创建一个C++控制台程序,设置如下:

1)  “Configuration Properties -> C/C++ -> General”中,在Additional Include Directories加入Include路径(“C:\WpdPack_4_0_2\WpdPack\Include”)

Winpcap网络开发库入门

2)  “Configuration Properties -> Linker -> General” 中,在Additional Library Directories中加入 winpcap 库文件路径 ( “C:\WpdPack_4_0_2\WpdPack\Lib” )

Winpcap网络开发库入门

3)  “Configuration Properties -> Linker -> Input”中, Additional Dependencies 加入用到的两个winpcap 库文件(wpcap.lib and Packet.lib )

Winpcap网络开发库入门

4)  为了使用Winpcap的远程访问,必须在预处理器中加入HAVE_REMOTE

Winpcap网络开发库入门

示例程序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 ;
    
//  设置封包其他部分内容
     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 ;
}

 

参考文章:

1Introduction to the Winpcap Networking Libraries

你可能感兴趣的:(CAP)