创建一个应用,使用wpcap.dll
用微软Visual C++创建一个应用,使用wpcap.dll,可按照下列步骤:
- 在每个需要使用库导出的函数(functions exported by library)的源文件开始处,包含pcap.h头文件;
- 如果程序用到了WinPcap和Win32平台呢相关的函数,记得在预处理器定义中包含WPCAP;
- 如果程序用到了WinPcap的远程抓取功能,则需要在预处理器定义中加入HAVE_REMOTE,而不要在源文件中直接包含
头文件remote-ext.h;
- 根据你的目标平台(x86 或 x64),将wpcap.lib包含到连接选项中。x86的wpcap.lib可以在WinPcap developer’s pack的/lib目录
下找到,x64的wpcap.lib可以在/lib/x64目录下找到;
怎样设定Microsoft Visual Studio
Visual Studio 6
- 要增加一个预处理器定义,你必须从Project菜单中选择Settings,然后选择C/C++标签,在“Preprocessor Definitions”对话框中添加预处理定义;
- 要在Microsoft Visual C++中一个项目添加库,首先从Project菜单中选择Settings,然后选择Link标签,并将新库的名字加入
到“Object/library modules”文本编辑框中;
- 如果要添加Visual C++搜索库的路径,从Tools菜单中选择Options,然后选择Directories标签,并在下面的Directories中增
加相关路径;
Visual Studio 2005 (编译x64应用时必须)
- 要增加一个预处理器定义,你必须从Project菜单中选择Properties然后选择左边立标狂中的C/C++,再选择其下的Preprocessor,将定义添加在右边的Preprocessor Definitions文本框中;
- 要给项目增加库,选择Project菜单中的Properties,然后选中左边列表中的Linker,在选中其下的Input,将库的名字加入到右边的Additional Dependecies文本框中;
- 如果要添加Visual Studio搜索库的路径,从Tools菜单中选择Options,在左边的列表框内选中Project and Solutions,再选中其下的VC++ Directories,在右边选的Show directories for 下拉框中选中Library Files,并在其下面的输入框中加入相关路径;
- 如果要添加Visual Studio搜索的include路径,从Tools菜单中选择Options,在左边的列表框内选中Project and Solutions,再选中其下的VC++ Directories,在右边选的Show directories for 下拉框中选中Include Files,并在其下面的输入框中加入相关路径;
示例程序
提供一些示例程序来说明WinPcap API的用法。例子的源代码以及编译和运行它们需用到的文件,可以在Develper’s Pack中找到。处于教学(didactic)目的,我们在这里提供了可以浏览的代码:可以点击变量或者函数就会跳转到其对应的说明文档(本译文不提供该功能)。要看完整的示例代码,请看WinPcap教程(1):获取网卡列表。
包转储(Dump)
这个程序根据命令行不同的开关,从一个文件或者网卡读取包。如果没有提供源,程序将显示网卡列表,其中一个可以被选中。一旦抓包开始,程序将打印出时间邮戳,包的原始内容的长度。下面程序可以在Win32平台上编译运行,也可以在Unix上编译运行(提供的makefile)。
/*
* Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
* Copyright (c) 2005 - 2006 CACE Technologies, Davis (California)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Politecnico di Torino, CACE Technologies
* 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <stdlib.h>
#include <stdio.h>
//
// NOTE: remember to include WPCAP and HAVE_REMOTE among your
// preprocessor definitions.
//
#include <pcap.h>
#define LINE_LEN 16
int main(int argc, char **argv)
{
pcap_if_t *alldevs, *d;
pcap_t *fp;
u_int inum, i=0;
char errbuf[PCAP_ERRBUF_SIZE];
int res;
struct pcap_pkthdr *header;
const u_char *pkt_data;
printf("pktdump_ex: prints the packets of the network using WinPcap./n");
printf(" Usage: pktdump_ex [-s source]/n/n"
" Examples:/n"
" pktdump_ex -s file://c:/temp/file.acp/n"
" pktdump_ex -s rpcap:////Device//NPF_{C8736017-F3C3-4373-94AC-9A34B7DAD998}/n/n");
if(argc < 3)
{
printf("/nNo adapter selected: printing the device list:/n");
/* The user didn't provide a packet source: Retrieve the local device list */
if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs_ex: %s/n", errbuf);
return -1;
}
/* Print the list */
for(d=alldevs; d; d=d->next)
{
printf("%d. %s/n ", ++i, d->name);
if (d->description)
printf(" (%s)/n", d->description);
else
printf(" (No description available)/n");
}
if (i==0)
{
fprintf(stderr,"No interfaces found! Exiting./n");
return -1;
}
printf("Enter the interface number (1-%d):",i);
scanf_s("%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 ( (fp= pcap_open(d->name,
100 /*snaplen*/,
PCAP_OPENFLAG_PROMISCUOUS /*flags*/,
20 /*read timeout*/,
NULL /* remote authentication */,
errbuf)
) == NULL)
{
fprintf(stderr,"/nError opening adapter/n");
return -1;
}
}
else
{
// Do not check for the switch type ('-s')
if ( (fp= pcap_open(argv[2],
100 /*snaplen*/,
PCAP_OPENFLAG_PROMISCUOUS /*flags*/,
20 /*read timeout*/,
NULL /* remote authentication */,
errbuf)
) == NULL)
{
fprintf(stderr,"/nError opening source: %s/n", errbuf);
return -1;
}
}
/* Read the packets */
while((res = pcap_next_ex( fp, &header, &pkt_data)) >= 0)
{
if(res == 0)
/* Timeout elapsed */
continue;
/* print pkt timestamp and pkt len */
printf("%ld:%ld (%ld)/n", header->ts.tv_sec, header->ts.tv_usec, header->len);
/* Print the packet */
for (i=1; (i < header->caplen + 1 ) ; i++)
{
printf("%.2x ", pkt_data[i-1]);
if ( (i % LINE_LEN) == 0) printf("/n");
}
printf("/n/n");
}
if(res == -1)
{
fprintf(stderr, "Error reading the packets: %s/n", pcap_geterr(fp));
return -1;
}
return 0;
}
包过滤
这是一个更加复杂的libpcap示例,展示了如何创建和设置过滤器、如何将抓到内容的存入硬盘以及其他一些功能。该程序可以在Win32和Unix编译(分别提供了project和makefile)。Pcap_filter (pf.exe)是一个通用的包过滤应用:其输入参数是包源(可以是网卡或者文件),一个过滤器和一个输出文件。它将从源获取包,知道按下Ctrl+C或者整个文件已经被处理完毕,用过滤器处理输入的包,并将满足filter规则的包存入输出文件。Pcap_filter不仅可以根据特定的过滤器转储网络数据,也可以从先前保存的文件获取包。输入和输出文件的格式都是libpcap用的格式,也就是说和WinDump,tcpdump以及许多其他网络工具使用的格式是一样的。
/*
* Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
* Copyright (c) 2005 - 2006 CACE Technologies, Davis (California)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Politecnico di Torino, CACE Technologies
* 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <pcap.h>
#define MAX_PRINT 80
#define MAX_LINE 16
void usage();
void main(int argc, char **argv)
{
pcap_t *fp;
char errbuf[PCAP_ERRBUF_SIZE];
char *source=NULL;
char *ofilename=NULL;
char *filter=NULL;
int i;
pcap_dumper_t *dumpfile;
struct bpf_program fcode;
bpf_u_int32 NetMask;
int res;
struct pcap_pkthdr *header;
const u_char *pkt_data;
if (argc == 1)
{
usage();
return;
}
for(i=1;i < argc; i+= 2)
{
switch (argv[i] [1])
{
case 's':
{
source=argv[i+1];
};
break;
case 'o':
{
ofilename=argv[i+1];
};
break;
case 'f':
{
filter=argv[i+1];
};
break;
}
}
// open a capture from the network
if (source != NULL)
{
if ( (fp= pcap_open(source,
1514 /*snaplen*/,
PCAP_OPENFLAG_PROMISCUOUS /*flags*/,
20 /*read timeout*/,
NULL /* remote authentication */,
errbuf)
) == NULL)
{
fprintf(stderr,"/nUnable to open the adapter./n");
return;
}
}
else usage();
if (filter != NULL)
{
// We should loop through the adapters returned by the pcap_findalldevs_ex()
// in order to locate the correct one.
//
// Let's do things simpler: we suppose to be in a C class network ;-)
NetMask=0xffffff;
//compile the filter
if(pcap_compile(fp, &fcode, filter, 1, NetMask) < 0)
{
fprintf(stderr,"/nError compiling filter: wrong syntax./n");
return;
}
//set the filter
if(pcap_setfilter(fp, &fcode)<0)
{
fprintf(stderr,"/nError setting the filter/n");
return;
}
}
//open the dump file
if (ofilename != NULL)
{
dumpfile= pcap_dump_open(fp, ofilename);
if (dumpfile == NULL)
{
fprintf(stderr,"/nError opening output file/n");
return;
}
}
else usage();
//start the capture
while((res = pcap_next_ex( fp, &header, &pkt_data)) >= 0)
{
if(res == 0)
/* Timeout elapsed */
continue;
//save the packet on the dump file
pcap_dump((unsigned char *) dumpfile, header, pkt_data);
}
}
void usage()
{
printf("/npf - Generic Packet Filter./n");
printf("/nUsage:/npf -s source -o output_file_name [-f filter_string]/n/n");
exit(0);
}