深度剖析WinPcap之(八)——打开与关闭适配器
2009-09-21 00:00:00 来源:WEB开发网所定义的一些函数指针
typedef int (*activate_op_t)(pcap_t *);
typedef int (*can_set_rfmon_op_t)(pcap_t *);
typedef int (*read_op_t)(pcap_t *, int cnt, pcap_handler, u_char *);
typedef int (*inject_op_t)(pcap_t *, const void *, size_t);
typedef int (*setfilter_op_t)(pcap_t *, struct bpf_program *);
typedef int (*setdirection_op_t)(pcap_t *, pcap_direction_t);
typedef int (*set_datalink_op_t)(pcap_t *, int);
typedef int (*getnonblock_op_t)(pcap_t *, char *);
typedef int (*setnonblock_op_t)(pcap_t *, int, char *);
typedef int (*stats_op_t)(pcap_t *, struct pcap_stat *);
#ifdef WIN32
typedef int (*setbuff_op_t)(pcap_t *, int);
typedef int (*setmode_op_t)(pcap_t *, int);
typedef int (*setmintocopy_op_t)(pcap_t *, int);
#endif
typedef void (*cleanup_op_t)(pcap_t *);
1.3 打开与关闭适配器的实例
我们在下面的示例程序中打开一个适配器并捕获数据包,该程序将每个通过该适配器的数据包长度打印出来,同时打印每个数据包的捕获时间。程序源代码如下:[openadapter]
#define WIN32
#define HAVE_REMOTE
#include <stdio.h>
#include "pcap.h"
#include <winsock.h>
/* 捕获数据包(packet handler)回调函数的原型*/
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
int main()
{
pcap_if_t *alldevs;
pcap_if_t *d;
int inum;
int i=0;
pcap_t *adhandle;
char errbuf[PCAP_ERRBUF_SIZE];
/* 获取本机网络设备列表*/
if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs: %sn", errbuf);
exit(1);
}
/* 打印网络设备列表*/
for(d=alldevs; d; d=d->next)
{
printf("%d. %s", ++i, d->name);
if (d->description)
printf(" (%s)n", d->description);
else
printf(" (No description available)n");
}
if(i==0)
{
printf("nNo interfaces found! Make sure WinPcap is installed.n");
return -1;
}
/*选择网络设备接口*/
printf("Enter the interface number (1-%d):",i);
scanf("%d", &inum);
if(inum < 1 || inum > i)
{
printf("nInterface number out of range.n");
/* 释放设备列表*/
pcap_freealldevs(alldevs);
return -1;
}
/* 跳转到选中的适配器*/
for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
/* 打开设备*/
if ( (adhandle= pcap_open(d->name, // 设备名
65536, // 65535保证能捕获到不同数据链路层上的每个数据包的全部内容
PCAP_OPENFLAG_PROMISCUOUS, // 混杂模式
1000, // 读取超时时间
NULL, // 远程机器验证
errbuf // 错误缓冲池
) ) == NULL)
{
fprintf(stderr,"nUnable to open the adapter. %s is not supported by WinPcapn", d->name);
/* 释放设备列表*/
pcap_freealldevs(alldevs);
return -1;
}
/*在选中的设备接口上监听数据*/
printf("nlistening on %s...n", d->description);
/* 释放设备列表*/
pcap_freealldevs(alldevs);
/* 开始捕获*/
pcap_loop(adhandle, 0, packet_handler, NULL);
return 0;
}
/* 每次捕获到数据包时,libpcap都会自动调用该回调函数*/
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
struct tm *ltime;
char timestr[16];
time_t local_tv_sec;
/* 将时间戳转换成可识别的格式*/
local_tv_sec = header->ts.tv_sec;
ltime=localtime(&local_tv_sec);
strftime( timestr, sizeof timestr, "%H:%M:%S", ltime);
/*打印数据包的捕获时间与数据包的长度*/
printf("%s,%.6d len:%dn", timestr, header->ts.tv_usec, header->len);
}
本例中,我们将pcap_open的snaplen参数值设定为65535,它比我们能遇到的最大的MTU还要大,同时使用混杂模式,因此可确信我们总能收到完整的数据包。
示例程序的运行结果如图8-2与图8-3所示:
图8-2 选择网络设备接口(此处选择2)
图8-3 打印捕获的时间与数据包的长度
出处: http://eslxf.blog.51cto.com/918801/203106
- ››深度解释攻击linux服务器的四种级别
- ››剖析java.util.concurrent锁
- ››剖析Android智能手机系统的更多功能
- ››深度分析地方社区网站的内容定位
- ››剖析Windows Azure Platform框架与组成
- ››剖析使用 ObjectOutputStream 可能引起的内存泄漏...
- ››剖析EWebEditor编辑器漏洞攻击案例
- ››剖析开源云:构建 Infrastructure as a Service 块...
- ››深度剖析 Android 和 iPhone OS
- ››深度分析:HTML5能否成为Flash终结者
- ››深度挖掘 更多Windows 7快捷模式
- ››深度挖掘 Windows 7快捷模式
更多精彩
赞助商链接