Winpcap網絡開發庫入門,分類: C/C++/VC++

     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;
}
複製代碼

 

參考文章:

1,Introduction to the Winpcap Networking Libraries

作者:洞庭散人

出處:http://phinecos.cnblogs.com/    

本博客遵從Creative Commons Attribution 3.0 License,若用於非商業目的,您可以自由轉載,但請保留原作者信息和文章鏈接URL。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章