winpcap初次使用

winpcap是众多网络过滤嗅探分析工具使用的专业网络数据包捕获开发包。该作品库是开源作品,且全部用C编写,是十分适合学习网络编程的参考学习资料。

下面是调用winpcap函数的小例子,通过跟踪其运行过程,我们来初步了解 winpcap的运行流程。
首先是winpcap官网下载代码和LIB文件夹和INC文件夹以及安装包。
两个DLL需要vs2005编译,驱动需要WDK6000版本编译。
驱动编译时候使用其他版本可能出问题。我们需要将WDK的编译器目录设置为\winpcap\packetNtx,执行CompileDriver.bat,而不是直接到驱动源文件下执行BZ或者BUILD。
如果不需要调试的话,可以直接使用官网的安装包即可使用该库。

函数例子代码如下
#define WIN32
#define HAVE_REMOTE
#include <stdio.h>
#include "pcap.h"
#include <winsock.h>
/* 打印给定接口的所有有效信息*/
void ifprint(pcap_if_t *d);
/*把一个数字IP地址转换为一个字符串*/
char *iptos(u_long in);
int main()
{
pcap_if_t *alldevs;
pcap_if_t *d;
char errbuf[PCAP_ERRBUF_SIZE+1];
//char source[PCAP_ERRBUF_SIZE+1];
/*获取接口列表*/
if (pcap_findalldevs_ex("rpcap://", NULL, &alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf);
exit(1);
}
/*遍历列表,打印出每个条目的信息*/
for(d=alldevs;d;d=d->next)
{
printf("%s . %s \n",d->name,d->description);
}
/*释放接口列表*/
pcap_freealldevs(alldevs);
return 1;
}
这里的参数alldevs实际上就是
struct pcap_if {
struct pcap_if *next;
char *name;  /* name to hand to "pcap_open_live()" */
char *description; /* textual description of interface, or NULL */
struct pcap_addr *addresses;
bpf_u_int32 flags; /* PCAP_IF_ interface flags */
};
它记录了适配器的名字和说明等信息,而且还是整个适配器信息列表中的一员。
此函数仅仅是简单的调用 pcap_findalldevs_ex函数。开始调用函数pcap_parsesrcstr()分析source的类型 分为 (file, local, remote)三种,这里我们是local类型。实际真正得到适配器的函数为pcap_findalldevs。之后是分析获取到的适配器的名字和说明,添加上rpcap://。

pcap_findalldevs函数两次调用PacketGetAdapterNames()函数,第一次是查询实际获取的信息的BUFFER长度,分配适当长度的内存后,第二次才真正获取信息。此处返回的信息包含两种名字长度和适配器说明,中间以两个'\0'分割。
而实际上,Packet.dll中的PacketGetAdapterNames()将互斥的访问全局设备list,而list在通过查询驱动NPF获取设备信息。
实际上在用户层DLL函数中想驱动设备发送IOCTL码进行查询,NPF驱动在CONTROL_ROUTINE例程中进行相应,转化为request,调用windows的内核api
NdisRequest(
     &Status,
     Open->AdapterHandle,
     &pRequest->Request
     );
向设备查询和设置OID。
   
图片
//
openadapter
// OpenAdapter.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#define HAVE_REMOTE
#include <stdio.h>
#include "pcap.h"
#include <winsock.h>
#pragma comment(lib,"wpcap.lib")
#pragma comment(lib,"ws2_32.lib")

void packet_handler(u_char* param,
const struct pcap_pkthdr* header,const u_char* pkt_data);
int _tmain(int argc, _TCHAR* argv[])
{
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: %s\n",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,
  PCAP_OPENFLAG_PROMISCUOUS,
  1000,
  NULL,
  errbuf
  )) == NULL)
{
  fprintf(stderr,"\nUnable to open the adapter. \
    %s is not supported by Winpcap\n",d->name);
  pcap_freealldevs(alldevs);
  return -1;
}
printf("\nlistening on %s...\n",d->description);
pcap_freealldevs(alldevs);
pcap_loop(adhandle,0,packet_handler,NULL);
pcap_close(adhandle);
return 0;
}
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:%d\n",timestr,header->ts.tv_usec,header->len);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值