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