Winpcap学习第二天

转载 2006年06月08日 16:03:00
今天在阅读Winpcap Manual的时候发现一句话:

 

       “This means that on shared media (like non-switched Ethernet), WinPcap will be able to capture the packets of other hosts.”

   我理解为:如果在通过没有交换功能的集线器连接的网络上,只要把网卡设置为混杂(promiscuous)模式,winpcap能够捕获到其他主机通信的数据包。如果是具有交换功能的集线器连接的网络winpcap还能管用吗?这个在后边的实习中将会进行试验。

    试验程序2:

 

/*
* 截获数据包的试验。先打印出所有网络适配器的列表,然后选择
* 想在哪个适配器上截获数据包。然后通过pcap_loop()函数将截获
* 的数据包传给回调函数packet_handler()处理。

* 通过该程序初步了解了使用winpcap截获数据包的步骤以及一些在
* 截获数据包时非常重要的函数和结构体。
* 2006-1-26
*/

#include <pcap.h>
#include <remote-ext.h>

/* Prototype of the 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];

 /* Retrieve the devices list on the local machine */
 if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
 {
  fprintf(stderr, "Error in pcap_findalldevs: %s/n", errbuf);
  exit(1);
 }

 /* Print the list */
 for (d = alldevs; d; d = d->next)
 {
  /* Print name */
  printf("%d. %s", ++ i, d->name);

  /* Print description */
  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;
 }

 /* Select an adapter */
 printf("Enter the interface number (1 - %d):", i);
 scanf("%d", &inum);

 if (inum < 1 || inum > i)
 {
  printf("/nInterface number out of range./n");
  /* Free the device list */
  pcap_freealldevs(alldevs);
  return -1;
 }

 /* Jump to the selected adapter */
 for (d = alldevs, i = 0; i < inum - 1; d = d->next, ++ i);

 /*Open the device */
 if ((adhandle = pcap_open(d->name, /* name of the device */
  65536,         /* portion of the packet to capture */
  /* 65535 guarantees that the whole packet will be captured on all the link layers */
  PCAP_OPENFLAG_PROMISCUOUS,     /* promiscuous mode */
  1000,         /* read timeout */
  NULL,         /* authentication on the remote machine */
  errbuf         /* error buffer */
  )) == NULL)
 {
   fprintf(stderr, "/nnable to open the adapter. %s is not supported by Winpcap/n", d->name);
   /* Free the devices list */
   pcap_freealldevs(alldevs);

   return -1;
 }

 printf("/nlistening on %s.../n", d->description);

 /* At this point, we don't need any more the device list. Free it */
 pcap_freealldevs(alldevs);
 /* start the capture */
 pcap_loop(adhandle, 0, packet_handler, NULL);

 return 1;
}

/* Callback function invoked by libpcap for every incoming packet */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) {
 struct tm *ltime;
 char timestr[16];

 /* convert the timestamp to readable format */
 ltime = localtime(&header->ts.tv_sec);
 strftime(timestr, sizeof(timestr), "%H:%M:%S", ltime);
 printf("%s, %.6d len:%d/n", timestr, header->ts.tv_usec, header->len);
}

 

函数1:

pcap_t *pcap_open(const char *               source,

int                              snaplen,

int                              flags,

int                              read_timeout,

struct pcap_rmtauth *       auth,

char *                        errbuf

)

    为捕获/发送数据打开一个普通的源。pcap_open()能够替代所有的pcap_open_xxx()函数,它隐藏了不同的pcap_open_xxx()之间的差异,所以程序员不必使用不同的open函数。

source:的是包含要打开的源名称的以’/0’结尾的字符串。源名称得包含新的源规范语法(Source Specification Syntax),并且它不能为NULL。为了方便的使用源语法,请记住:(1)pcap_findalldevs_ex()返回的适配器(网卡)可以直接被pcap_open()使用;(2)万一用户想传递他自己的源字符串给pcap_open(),pcap_createsrcstr()可以创建正确的源标识。

snaplen:需要保留的数据包的长度。对每一个过滤器接收到的数据包,第一个‘snaplen’字节的内容将被保存到缓冲区,并且传递给用户程序。例如,snaplen等于100,那么仅仅每一个数据包的第一个100字节的内容被保存。简言之就是从每一个包的开头到snaplen的那段内容将被保存。

flags:保存一些由于抓包需要的标志。Winpcap定义了三种标志:

l         PCAP_OPENFLAG_PROMISCUOUS:1,它定义了适配器(网卡)是否进入混杂模式(promiscuous mode)。

l         PCAP_OPENFLAG_DATATX_UDP:2,它定义了数据传输(假如是远程抓包)是否用UDP协议来处理。

l         PCAP_OPENFLAG_NOCAPTURE_RPCAP:4,它定义了远程探测器是否捕获它自己产生的数据包。

read_timeout:以毫秒为单位。read timeout被用来设置在遇到一个数据包的时候读操作不必立即返回,而是等待一段时间,让更多的数据包到来后从OS内核一次读多个数据包。并非所有的平台都支持read timeout;在不支持read timeout的平台上它将被忽略。

auth:一个指向’struct pcap_rmtauth’的指针,保存当一个用户登录到某个远程机器上时的必要信息。假如不是远程抓包,该指针被设置为NULL。

errbuf:一个指向用户申请的缓冲区的指针,存放当该函数出错时的错误信息。

返回值是一个’pcap_t’指针,它可以作为下一步调用(例如pcap_compile()等)的参数,并且指定了一个已经打开的Winpcap会话。在遇到问题的情况下,它返回NULL并且’errbuf’变量保存了错误信息。

 

函数2:

int pcap_loop(  pcap_t*           p,

int                   cnt,

pcap_hander    callback,

u_char*           user

)

    收集一群数据包。pcap_loop()与pcap_dispatch()类似,但是它会一直保持读数据包的操作直到cnt包被处理或者发生了错误。当有活动的读超时(read timeout)时它并不返回。然而,对pcap_open_live()指定一个非0的读超时(read timeout),当发生超时的时候调用pcap_dispatch()来接收并处理到来的所有数据包更好。Cnt指明了返回之前要处理数据包的最大数目。如果cnt为负值,pcap_loop()将一直循环(直到发生错误才停止)。如果出错时返回-1;如果cnt用完时返回0;如果在任何包被处理前调用pcap_breakloop()来中止循环将返回-2。所以,如果程序中使用了pcap_breakloop(),必须准确的来判断返回值是-1还是-2,而不能简单的判断<0。

 

函数3:

hypedef void (* pcap_handler)(u_char* user,

const struct pcap_pkthdr* pkt_header,

const u_char* pkt_data)

    接收数据包的回调函数原型。当用户程序使用pcap_dispatch()或者pcap_loop(),数据包以这种回调的方法传给应用程序。用户参数是用户自己定义的包含捕获会话状态的参数,它必须跟pcap_dispatch()和pcap_loop()的参数相一致。pkt_hader是与抓包驱动有关的头。pkt_data指向包里的数据,包括协议头。

 

结构体1:

struct pcap_pkthdr {

      struct timeval ts;

      bpf_u_int32 caplen;

      bpf_u_int32 len;

}

ts:时间戳

cpalen:当前分组的长度

len:数据包的长度

相关文章推荐

hibernate学习笔记第二天的源码

  • 2017年03月21日 12:26
  • 7.81MB
  • 下载

spring 学习第二天

  • 2009年11月26日 18:04
  • 2KB
  • 下载

Network学习17_循序渐进学WinPcap

去年开始学习winpcap,当时翻译了一点,现在打算把这个工作完成了。我的水平比较差,翻译的很不到位,不过对于初次接触winpcap的人应该还是有点帮助吧。不过不知道我这样来翻译是不是侵犯了人家的版权...

WinPcap学习(九)发送数据包

原始的libcap库是不支持发送数据包的,因此,这是属于WinPcap的扩展。 使用pcap_sendpacket()发送单个数据包 打开适配器以后,调用pcap_sendpacket()来发送手工制...

循序渐进学习使用WinPcap(一)

转载自安全焦点(翻译者yiedu),本文部分有修改。 一些需要知道的细节描述(前言):       这一部分展示了如何使用WinPcap-API的不同的功能,它作为一个使用指南被划分为一系列的课时...

循序渐进学习使用WINPCAP(四)

不用callback捕获数据报 这节的例子很像先前的一章(获得网卡的高级信息),但是这一节中使用的是pcap_next_ex()而非pcap_loop()。 pcap_loop()函数的基于回调包...

循序渐进学习使用WINPCAP(九)

收集统计网络流量 这一章将展示WinPcap的另一项高级功能:收集网络流量的统计信息。WinPcap的统计引擎在内核层级上对到来的数据进行分类。如果你想了解更多的细节请,可以查看NPF驱动指南。 ...

循序渐进学习使用WINPCAP(二)

获得已安装网络驱动器的高级信息 在第一章中演示了如何获得已存在适配器的基本信息(名字和描述)。事实上,WinPcap同样也提供其他的高级信息,特别是 pcap_findalldevs_ex()这个函...

Winpcap学习笔记(一):VS2017+wpdpcap环境配置

//

WinPcap学习(四)打开适配器并捕获数据包

打开设备的函数是pcap_open()。下面参数snaplen,flags和to_ms的解释说明 snaplen制定要捕获数据包中的哪些部分。在一些操作系统中(比如xBSD和Win32),驱动可以被...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Winpcap学习第二天
举报原因:
原因补充:

(最多只允许输入30个字)