别好:这会使程序变的复杂并且在象多线程或C++类这些情况下它看起来到象一块绊脚石。
在这些情况下pcap_next_ex()允许直接调用来接收包,它的参数和pcap_loop()相同:有一个网卡描述副,和两
个指针,这两个指针会被初始化并返回给用户,一个是pcap_pkthdr结构,另一个是接收数据的缓冲区。
下面的程序我门将循环调用前一节的例子中的回掉部分,只是把它移到了main里面了。
#include \ main() {
pcap_if_t *alldevs; pcap_if_t *d; int inum; int i=0;
pcap_t *adhandle; int res;
char errbuf[PCAP_ERRBUF_SIZE]; struct tm *ltime; char timestr[16];
struct pcap_pkthdr *header; u_char *pkt_data;
/* Retrieve the device list */
if (pcap_findalldevs(&alldevs, errbuf) == -1) {
fprintf(stderr,\ exit(1); }
/* Print the list */
for(d=alldevs; d; d=d->next) {
printf(\ if (d->description)
printf(\ else
printf(\ } if(i==0) {
printf(\ return -1; }
printf(\ scanf(\
if(inum < 1 || inum > i) {
printf(\ /* 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 adapter */
if ( (adhandle= pcap_open_live(d->name, // name of the device 65536, // portion of the packet to capture.
// 65536 grants that the whole packet will be captured on all the MACs. 1, // promiscuous mode 1000, // read timeout errbuf // error buffer ) ) == NULL) {
fprintf(stderr,\ /* Free the device list */ pcap_freealldevs(alldevs); return -1; }
printf(\
/* At this point, we don't need any more the device list. Free it */ pcap_freealldevs(alldevs);
/* 此处循环调用 pcap_next_ex来接受数据报*/
while((res = pcap_next_ex( adhandle, &header, &pkt_data)) >= 0){
if(res == 0)
/* Timeout elapsed */ continue;
/* convert the timestamp to readable format */ ltime=localtime(&header->ts.tv_sec);
strftime( timestr, sizeof timestr, \
printf(\ }
if(res == -1){
printf(\ return -1; } return 0; }
注:pcap_next_ex()只在Win32环境下才行因为它不是原始libpcap API中的一部分,这就意味着依赖于这个函
数的代码不会在UNIX下工作。那么为什么我们用pcap_next_ex()而不用pcap_next()?因为pcap_next()有许多
限制在很多情况下并不鼓励用它。首先它的效率很低因为它隐藏了回掉方法并且还依赖于pcap_dispatch()这个
函数。再次它不能够识别文件结束标志EOF所以对来自文件的数据流它几乎无能为力。 注意当pcap_next_ex()在成功,超时,出错和文件结束的情况下会返回不同的值。
循序渐进学习使用WINPCAP(五) ----数据流的过滤
WinPcap或libpca最强大的特点之一就是数据流的过滤引擎。它提供一种高效的方法来只捕获网络数据流的某些数据而且常常和系统的捕获机制相集成。过滤数据的函数是pcap_compile() 和 pcap_setfilter()来实现的。
pcap_compile()来编译一个过滤设备,它通过一个高层的boolean型变量和字串产生一系列的能够被底层驱动所解释的二进制编码。boolean表示语法能够在这个文件的过滤表示语法中找到。
pcap_setfilter() 用来联系一个在内核驱动上过滤的过滤器,这时所有网络数据包都将流经过滤器,并拷贝到应用程序中。
下面的代码展示了如何编译并社定一个过滤设备。注意我们必须从pcap_if结构中获得掩码,因为一些过滤器的创建需要这个参数。
下面的代码段中的pcap_compile()的\参数说明只有IPV4和TCP数据才会被内核保存并被传递到应用程序。
if(d->addresses != NULL)
/* 获得第一个接口地址的掩码 */
netmask=((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr; else
/* 如果这个接口没有地址那么我们假设他为C类地址 */ netmask=0xffffff;
//compile the filter
if(pcap_compile(adhandle, &fcode, \
fprintf(stderr,\ /* Free the device list */ pcap_freealldevs(alldevs); return -1; }
//set the filter
if(pcap_setfilter(adhandle, &fcode)<0){ fprintf(stderr,\ /* Free the device list */ pcap_freealldevs(alldevs); return -1; }
如何你想进一步查看本节中用过滤器过滤数据流的例子可以查看下一节《数据的解包》。
循序渐进学习使用WINPCAP(六) ---解析数据包
现在经过上几节的学习能够进行数据报的捕获和过滤了,我们想用一个简单的\world\程序将我们所学的
知识应用于实际。
这一节里我们将利用以前的代码并将其引申从而建立一个更实用的程序。该程序的主要目的是如何显示出所捕
获的数据报的内容,尤其是对它的协议头的分析和说明。这个程序名叫UDPdump它将在屏幕上显示出我们网络上
UDP数据的信息。
在此我们选择解析UDP而不用TCP因为他比TCP简单更加的直观明了。下面让我们来看看原代码。 /*
* Copyright (c) 1999 - 2002
* Politecnico di Torino. All rights reserved. *
* Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the Politecnico * di Torino, and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */
#include \
/* 4 BIT的IP头定义 */ typedef struct ip_address{ u_char byte1; u_char byte2; u_char byte3; u_char byte4; }ip_address;
/* IPv4 头的定义 */