WinPcap是一个基于Win32平台的,用于捕获网络数据包并进行分析的开源库.
大多数网络应用程序通过被广泛使用的操作系统元件来访问网络,比如sockets。 这是一种简单的实现方式,因为操作系统 已经妥善处理了底层具体实现细节(比如协议处理,封装数据包等等),并且提供了一个与读写文件类似的,令人熟悉的接口。
然而,有些时候,这种“简单的方式”并不能满足任务的需求,因为有些应用程序需要直接访问网 络中的数据包。也就是说,那些应用程序需要访问原始数据包,即没有被操作系统利用网络协议处理过的数据包。
WinPcap产生的目的,就是为Win32应用程序提供这种访问方式; WinPcap提供了以下功能
以上这些功能需要借助安装在Win32内核中的网络设备驱动程序才能实现,再加上几个动态链接库DLL。
所有这些功能都能通过一个强大的编程接口来表现出来,易于开发,并能在不同的操作系统上使用。 这本手册的主要目标是在一些程序范例的帮助下,叙述这些编程接口的使用。 如果您现在就想开始摸索这些功能,您可以直接进入 WinPcap用户手册.
WinPcap可以被用来制作许多类型的网络工具,比如具有分析,解决纷争,安全和监视功能的工具。特别地,一些基于WinPcap的典型应用有:
WinPcap能 独立地 通过主机协议发送和接受数据,如同TCP-IP。 这就意味着WinPcap不能阻止、过滤或操纵同一机器上的其他应用程序的通讯: 它仅仅能简单地"监视"在网络上传输的数据包。所以,它不能提供类似网络流量控制、服务质量调度和个人防火墙之类的支持。
编写第一个WinPcap程序的方法:从http://www.winpcap.org/install/default.htm下载安装WinPcap,从http://www.winpcap.org/devel.htm下载开发包,把头文件和库文件包含进来。
第一个WinPcap程序:
#ifdef _MSC_VER /* * we do not want the warnings about the old deprecated and unsecure CRT functions * since these examples can be compiled under *nix as well */ #define _CRT_SECURE_NO_WARNINGS #endif #include "pcap.h" #pragma comment(lib, "wpcap") #pragma comment(lib, "ws2_32") /* 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 device list */ if(pcap_findalldevs(&alldevs, errbuf) == -1) { fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf); exit(1); } /* Print the list */ 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"); /* 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 */ /* 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 (nonzero means promiscuous) 1000, // read timeout errbuf // error buffer )) == NULL) { fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name); /* Free the device 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); pcap_close(adhandle); return 0; } /* 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]; time_t local_tv_sec; /* * unused parameters */ (VOID)(param); (VOID)(pkt_data); /* convert the timestamp to readable format */ 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); }
运行情况如下: