前言:
winpcap(windows packet capture)是windows平台下一个免费,公共的网络访问系统。开发winpcap这个项目的目的在于为win32应用程序提供访问网络底层的能力。它用于windows系统下的直接的网络编程。进行过网络方面学习的都知道,wireshark软件是基于winpcap的,winpcap可直接开发基于网络底层协议的应用程序,例如arp,以后会写一篇arp的开发、应用和防御
功能需求:
1、截取主机A发送给主机B的消息
2、获取消息保存到文件
3、将消息下发到主机B
4、截取接收主机B消息
5、获取消息保存到文件
6、将消息转发到主机A
程序设计
1、由于winpcap是基于网卡的数据获取,所以先获取正确的网卡
2、打开选择的网卡设备
设计一个获取主机A消息的线程和一个获取主机B消息的线程。
相关接口介绍
1、int pcap_findalldevs(pcap_if_t **, char *);//获取所有网络设备,保存于pcap_if_t 指向的内存空间
2、void pcap_freealldevs(pcap_if_t *); // 清空所有网络设备
3、pcap_t *pcap_open(const char *source, // 获取的设备名
int snaplen, //要捕捉的数据包的部分
int flags, // 模式
int read_timeout,// 超时时间
struct pcap_rmtauth *auth, // 远程机器验证
char *errbuf);// 错误缓冲池
4、void pcap_close(pcap_t *);//关闭设备
5、int pcap_compile(//编译过滤规则
pcap_t *,
const char *,
int,
bpf_u_int32);
6、int pcap_setfilter(pcap_t *, struct bpf_program *);// 设置过滤规则
7、int pcap_next_ex(// 从interface或离线记录文件获取一个报文
pcap_t *,
struct pcap_pkthdr **, // 报文头,包含mac地址
const u_char **);//报文内容
程序设计
main.cpp
#include "pcap.h"
#include "vector"
using namespace std;
int main()
{
vector<string> vecDevName;
vecDevName.clear();
pcap_if_t *alldevs;
char errbuf[PCAP_ERRBUF_SIZE];
/*查询网卡设备*/
if(pcap_findalldevs(&alldevs, errbuf) == -1)
{
/* At this point, we don't need any more the device list. Free it */
pcap_freealldevs(alldevs);
return -1;
}
while (alldevs->next != NULL)
{
printf("%s:%s \n", alldevs->name, alldevs->description);
vecDevName.push_back(alldevs->name);
alldevs = alldevs->next;
}
// 打开网络设备
pcap_t *adhandle;
/* Open the device */
/* 打开设备 */
if ( (adhandle= pcap_open(vecDevName[0].c_str(), // 设备名
65536, // 要捕捉的数据包的部分
// 65535保证能捕获到不同数据链路层上的每个数据包的全部内容
PCAP_OPENFLAG_PROMISCUOUS, // 混杂模式
1000, // 读取超时时间
NULL, // 远程机器验证
errbuf // 错误缓冲池
) ) == NULL)
{
// fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
return -1;
}
// 编译过滤规则
bpf_u_int32 NetMask=0xffffff;
struct bpf_program fcode;
char szFilter[256];
sprintf(szFilter, "ip host 192.168.1.254");
//compile the filter
if(pcap_compile(adhandle, &fcode, szFilter, 1, NetMask) < 0)
{
//strTip.Format("Error compiling filter: wrong syntax:%s", szFilter);
pcap_close(adhandle);
return -3;
}
// 设置过滤规则
if(pcap_setfilter(adhandle, &fcode) < 0)
{
pcap_close(adhandle);
return -4;
}
int res;
struct pcap_pkthdr *header;
const u_char *pkt_data;
time_t local_tv_sec;
struct tm *ltime;
char timestr[16];
while((res = pcap_next_ex( adhandle, &header, &pkt_data)) >= 0)
{
if(res == 0)
continue;
/* 将时间戳转换成可识别的格式 */
local_tv_sec = header->ts.tv_sec;
ltime=localtime(&local_tv_sec);
strftime( timestr, sizeof timestr, "%H:%M:%S", ltime);
printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len);
}
return 0;
}