zoukankan      html  css  js  c++  java
  • 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_2WpdPack,可以看到里面包含了:Lib,Include,文档和示例程序。

    截图20160331141259

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

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

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

    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
    ", errorBuffer );
    
            return -1;
    
        }
    
        if( allAdapters == NULL )
    
        {//不存在人任何适配器
    
            printf( "
    No adapters found! Make sure WinPcap is installed.
    " );
    
            return 0;
    
        }
    
        int crtAdapter = 0;
    
        for( adapter = allAdapters; adapter != NULL; adapter = adapter->next)
    
        {//遍历输入适配器信息(名称和描述信息)
    
            printf( "
    %d.%s ", ++crtAdapter, adapter->name );
    
            printf( "-- %s
    ", adapter->description );
    
        }
    
        printf( "
    " );
    
        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
    ", errorBuffer );
    
            return -1;
    
        }
    
        if( allAdapters == NULL )
    
        {//不存在任何适配器
    
            printf( "
    No adapters found! Make sure WinPcap is installed.
    " );
    
            return 0;
    
        }
    
        int crtAdapter = 0;
    
        for( adapter = allAdapters; adapter != NULL; adapter = adapter->next)
    
        {//遍历输入适配器信息(名称和描述信息)
    
            printf( "
    %d.%s ", ++crtAdapter, adapter->name ); 
    
            printf( "-- %s
    ", adapter->description );
    
        }
    
        printf( "
    " );
    
        //选择要捕获数据包的适配器
    
        int adapterNumber;
    
        printf( "Enter the adapter number between 1 and %d:", crtAdapter );
    
        scanf_s( "%d", &adapterNumber );
    
        if( adapterNumber < 1 || adapterNumber > crtAdapter )
    
        {
    
            printf( "
    Adapter number out of range.
    " );
    
            // 释放适配器列表
    
            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, "
    Unable to open the adapter
    ", adapter->name );
    
            // 释放适配器列表
    
            pcap_freealldevs( allAdapters );
    
            return -1;
    
        }
    
        printf( "
    Capture session started on  adapter %s
    ", 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
    ", packetHeader->len );
    
        }
    
        // if we get here, there was an error reading the packets
    
        if( retValue == -1 )
    
        {
    
            printf( "Error reading the packets: %s
    ", 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
    ", errorBuffer );
    
            return -1;
    
        }
    
        if( allAdapters == NULL )
    
        {//不存在人任何适配器
    
            printf( "
    No adapters found! Make sure WinPcap is installed.
    " );
    
            return 0;
    
        }
    
        int crtAdapter = 0;
    
        for( adapter = allAdapters; adapter != NULL; adapter = adapter->next)
    
        {//遍历输入适配器信息(名称和描述信息)
    
            printf( "
    %d.%s ", ++crtAdapter, adapter->name ); 
    
            printf( "-- %s
    ", adapter->description );
    
        }
    
        printf( "
    " );
    
        //选择适配器
    
        int adapterNumber;
    
        printf( "Enter the adapter number between 1 and %d:", crtAdapter );
    
        scanf_s( "%d", &adapterNumber );
    
        if( adapterNumber < 1 || adapterNumber > crtAdapter )
    
        {
    
            printf( "
    Adapter number out of range.
    " );
    
            // 释放适配器列表
    
            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, "
    Unable to open the adapter
    ", 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,"
    Error sending the packet: 
    ", 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

  • 相关阅读:
    进制转换内容总结
    【Linux】Tomcat安装及端口配置
    【Linux】 JDK安装及配置 (linux-tar.gz版)
    判断集合元素唯一
    linux服务器上部署项目,同时运行两个或多个tomcat
    阿里服务器CentOS报错base ls command not found
    java接受安卓及ios App上传的图片,并保存到阿里OSS
    java-随机生成用户名(中文版及英文版)
    java-将评论内容过滤特殊表情emoj符号,保存到mysql中
    jdbc连接阿里云服务器上的MySQL数据库 及 数据库IP限制
  • 原文地址:https://www.cnblogs.com/wuyuan2011woaini/p/5341207.html
Copyright © 2011-2022 走看看