您的位置:首页 > 理论基础 > 计算机网络

Winpcap网络开发库入门,分类: C/C++/VC++

2015-10-22 15:47 489 查看
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;

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

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;

}

参考文章:

1,Introduction to the Winpcap Networking Libraries

作者:洞庭散人

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

本博客遵从Creative Commons Attribution 3.0 License,若用于非商业目的,您可以自由转载,但请保留原作者信息和文章链接URL。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: