Winpcap网络开发库入门

Posted wuyuan2011woaini

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Winpcap网络开发库入门相关的知识,希望对你有一定的参考价值。

原文链接地址:http://www.cnblogs.com/phinecos/archive/2008/10/20/1315176.html

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

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

image

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

截图20160331141259

 

首先创建一个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;

    // 设置封包其他部分内容

    for( int index = 12; index < 20; index++ )

    {

        packet[index] = 0xC4;

    }

    //发送数据封包

    if( pcap_sendpacket( adapterHandle, // the adapter handle

             packet, // the packet
// 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

2.中文手册:http://www.ferrisxu.com/WinPcap/html/index.html

以上是关于Winpcap网络开发库入门的主要内容,如果未能解决你的问题,请参考以下文章

winpcap抓包原理

捕获网络数据包并进行分析的开源库-WinPcap

mac 开发FFmpeg入门

WinPcap

WinPcap

winpcap获取设备列表