一 VC中的配置:
先去http://www.winpcap.org/install/bin/WinPcap_4_0.exe下载安装WinPcap安装包。
再到 http://www.winpcap.org/install/bin/WpdPack_4_0.zip下载WinPcap的开发包,解压。
1.在VC 6.0中[工具]->[选择]->[目录]分别把解压包里的inlude和library加进去。
2.在VC 6.0中[工程]->[Link]中加wpcap.lib Packet.lib或在源文件中加入
#pragma comment(lib, "wpcap.lib")
#pragma comment(lib, "Packet.lib")。
3.若要在程序中使用套接字,还须加#pragma comment(lib, "wsock32.lib")。
二 列举网卡及对应的网络地址和子网掩码
#include "pcap.h"
#pragma comment(lib, "wpcap.lib")
#pragma comment(lib, "Packet.lib")
#pragma comment(lib, "wsock32.lib")
void main()
...{
pcap_if_t *alldevs; //网络接口结点指针
pcap_if_t *d;
struct in_addr net_ip_address;//网络地址
u_int32_t net_ip;//某种格式的网络地址
char *net_ip_string;//可输出格式的网络地址
struct in_addr net_mask_address;//子网掩码
u_int32_t net_mask;//某种格式的子网掩码
char *net_mask_string;//可输出格式的子网掩码
int i=0;
char errbuf[PCAP_ERRBUF_SIZE];
/**//* 取得列表 */
if (pcap_findalldevs(&alldevs, errbuf) == -1)
...{
fprintf(stderr,"Error in pcap_findalldevs: %s ", errbuf);
exit(1);
}
/**//* 输出列表 */
for(d=alldevs;d;d=d->next)
...{
printf("%s ",d->name);//网卡名字
pcap_lookupnet(d->name,&net_ip,&net_mask,errbuf);
//获取网络地址和子网掩码
net_ip_address.s_addr = net_ip;
net_ip_string = inet_ntoa(net_ip_address); //格式转化
printf("网络地址:%s ", net_ip_string);
net_mask_address.s_addr = net_mask;
net_mask_string = inet_ntoa(net_mask_address); //格式转化
printf("网络掩码:%s ", net_mask_string);
}
pcap_freealldevs(alldevs); //释放接口结点链表
}
#pragma comment(lib, "wpcap.lib")
#pragma comment(lib, "Packet.lib")
#pragma comment(lib, "wsock32.lib")
void main()
...{
pcap_if_t *alldevs; //网络接口结点指针
pcap_if_t *d;
struct in_addr net_ip_address;//网络地址
u_int32_t net_ip;//某种格式的网络地址
char *net_ip_string;//可输出格式的网络地址
struct in_addr net_mask_address;//子网掩码
u_int32_t net_mask;//某种格式的子网掩码
char *net_mask_string;//可输出格式的子网掩码
int i=0;
char errbuf[PCAP_ERRBUF_SIZE];
/**//* 取得列表 */
if (pcap_findalldevs(&alldevs, errbuf) == -1)
...{
fprintf(stderr,"Error in pcap_findalldevs: %s ", errbuf);
exit(1);
}
/**//* 输出列表 */
for(d=alldevs;d;d=d->next)
...{
printf("%s ",d->name);//网卡名字
pcap_lookupnet(d->name,&net_ip,&net_mask,errbuf);
//获取网络地址和子网掩码
net_ip_address.s_addr = net_ip;
net_ip_string = inet_ntoa(net_ip_address); //格式转化
printf("网络地址:%s ", net_ip_string);
net_mask_address.s_addr = net_mask;
net_mask_string = inet_ntoa(net_mask_address); //格式转化
printf("网络掩码:%s ", net_mask_string);
}
pcap_freealldevs(alldevs); //释放接口结点链表
}
运行结果如图:
注:网络地址不是IP地址,故是10.10.138.0
三 捕获一个网络数据包
#include <pcap.h>
#pragma comment(lib, "wpcap.lib")
#pragma comment(lib, "Packet.lib")
#pragma comment(lib, "wsock32.lib")
/**//*
-----------------------------------------------------------------------------------------------------------------------
WinPcap头文件 ;
以下是以太网协议格式
-----------------------------------------------------------------------------------------------------------------------
*/
struct ether_header
...{
u_int8_t ether_dhost[6];
/**//* 以太网目的地址 */
u_int8_t ether_shost[6];
/**//* 源以太网地址 */
u_int16_t ether_type;
/**//* 以太网类型 */
};
void main()
...{
pcap_if_t *alldevs;
char error_content[PCAP_ERRBUF_SIZE];
/**//* 存储错误信息 */
pcap_t *pcap_handle;
/**//* winpcap句柄 */
const u_char *packet_content;
/**//* 数据包内容 */
u_char *mac_string;
/**//* 以太网地址 */
u_short ethernet_type;
/**//* 以太网类型 */
bpf_u_int32 net_mask;
/**//* 掩码地址 */
bpf_u_int32 net_ip;
/**//* 网络地址 */
char *net_interface;
/**//* 网络接口 */
struct pcap_pkthdr protocol_header;
/**//* 数据包头部信息 */
struct ether_header *ethernet_protocol;
/**//* 以太网协议变量 */
struct bpf_program bpf_filter;
/**//* BPF过滤规则 */
char bpf_filter_string[] = "ip";
/**//* 过滤规则字符串 */
// net_interface = pcap_lookupdev(error_content); //因为第一个是moden的网卡,所以不用这个
if (pcap_findalldevs(&alldevs,error_content) == -1)
...{
fprintf(stderr,"Error in pcap_findalldevs: %s ",error_content);
exit(1);
}
net_interface=alldevs->next->name;//得到第二个网卡(以太网卡)的名字
/**//* 获得网络接口 */
pcap_lookupnet(net_interface, &net_ip, &net_mask, error_content);
/**//* 获得网络地址和网络掩码 */
pcap_handle = pcap_open_live(net_interface, BUFSIZ, 1, 0, error_content);
/**//* 打开网路接口 */
pcap_compile(pcap_handle, &bpf_filter, bpf_filter_string, 0, net_ip);
/**//* 编译过滤规则 */
pcap_setfilter(pcap_handle, &bpf_filter);
/**//* 设置过滤规则 */
if (pcap_datalink(pcap_handle) != DLT_EN10MB)
return ;
packet_content = pcap_next(pcap_handle, &protocol_header);
/**//* 捕获一个数据包,数据包内容返回给packet_content */
printf("--------------------*****----------------------- ");
printf("捕获到一个网络数据包 ");
printf("捕获时间: ");
printf("%s", ctime((const time_t*) &protocol_header.ts.tv_sec));
printf("数据包长度: ");
printf("%d ", protocol_header.len);
ethernet_protocol = (struct ether_header*)packet_content;
/**//* 获得数据包内容 */
printf("以太网类型: ");
ethernet_type = ntohs(ethernet_protocol->ether_type);
#pragma comment(lib, "wpcap.lib")
#pragma comment(lib, "Packet.lib")
#pragma comment(lib, "wsock32.lib")
/**//*
-----------------------------------------------------------------------------------------------------------------------
WinPcap头文件 ;
以下是以太网协议格式
-----------------------------------------------------------------------------------------------------------------------
*/
struct ether_header
...{
u_int8_t ether_dhost[6];
/**//* 以太网目的地址 */
u_int8_t ether_shost[6];
/**//* 源以太网地址 */
u_int16_t ether_type;
/**//* 以太网类型 */
};
void main()
...{
pcap_if_t *alldevs;
char error_content[PCAP_ERRBUF_SIZE];
/**//* 存储错误信息 */
pcap_t *pcap_handle;
/**//* winpcap句柄 */
const u_char *packet_content;
/**//* 数据包内容 */
u_char *mac_string;
/**//* 以太网地址 */
u_short ethernet_type;
/**//* 以太网类型 */
bpf_u_int32 net_mask;
/**//* 掩码地址 */
bpf_u_int32 net_ip;
/**//* 网络地址 */
char *net_interface;
/**//* 网络接口 */
struct pcap_pkthdr protocol_header;
/**//* 数据包头部信息 */
struct ether_header *ethernet_protocol;
/**//* 以太网协议变量 */
struct bpf_program bpf_filter;
/**//* BPF过滤规则 */
char bpf_filter_string[] = "ip";
/**//* 过滤规则字符串 */
// net_interface = pcap_lookupdev(error_content); //因为第一个是moden的网卡,所以不用这个
if (pcap_findalldevs(&alldevs,error_content) == -1)
...{
fprintf(stderr,"Error in pcap_findalldevs: %s ",error_content);
exit(1);
}
net_interface=alldevs->next->name;//得到第二个网卡(以太网卡)的名字
/**//* 获得网络接口 */
pcap_lookupnet(net_interface, &net_ip, &net_mask, error_content);
/**//* 获得网络地址和网络掩码 */
pcap_handle = pcap_open_live(net_interface, BUFSIZ, 1, 0, error_content);
/**//* 打开网路接口 */
pcap_compile(pcap_handle, &bpf_filter, bpf_filter_string, 0, net_ip);
/**//* 编译过滤规则 */
pcap_setfilter(pcap_handle, &bpf_filter);
/**//* 设置过滤规则 */
if (pcap_datalink(pcap_handle) != DLT_EN10MB)
return ;
packet_content = pcap_next(pcap_handle, &protocol_header);
/**//* 捕获一个数据包,数据包内容返回给packet_content */
printf("--------------------*****----------------------- ");
printf("捕获到一个网络数据包 ");
printf("捕获时间: ");
printf("%s", ctime((const time_t*) &protocol_header.ts.tv_sec));
printf("数据包长度: ");
printf("%d ", protocol_header.len);
ethernet_protocol = (struct ether_header*)packet_content;
/**//* 获得数据包内容 */
printf("以太网类型: ");
ethernet_type = ntohs(ethernet_protocol->ether_type);