Main Page | Modules | Data Structures | File List | Data Fields | Globals | Related Pages

Using WinPcap in your programs
[WinPcap user's manual]

Creating an application that uses wpcap.dll

To create an application that uses wpcap.dll with Microsoft Visual C++, follow these steps:

Remember that:

Sample programs

A couple of sample programs are provided to show the usage of the WinPcap API. The source of the examples, along with all the files needed to compile and run them, can be found in the Developer's Pack.  For didactic purpose we provide here a browsable version of the code: it is possible to click on the variables and functions to jump the documentation of each of them. For a more complete set of samples, try WinPcap Tutorial Section.

Packet Dump

This program reads packets from a file or a network adapter, depending on a command line switch. If a source is not provided, the program shows a list of available adapters, one of which can be selected. Once the capture is started, the program prints the timestamp, the length and the raw contents of the packets. Once compiled, it will run on all the Win32 platforms. It can be compiled to run on Unix as well (the makefile is provided).

/* * 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 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("%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; }
00001 /* 00002 * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) 00003 * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) 00004 * All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 00010 * 1. Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * 2. Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in the 00014 * documentation and/or other materials provided with the distribution. 00015 * 3. Neither the name of the Politecnico di Torino, CACE Technologies 00016 * nor the names of its contributors may be used to endorse or promote 00017 * products derived from this software without specific prior written 00018 * permission. 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00021 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00022 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00023 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00024 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00025 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00026 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00027 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00028 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00029 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00030 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 * 00032 */ 00033 00034 00035 #include <stdlib.h> 00036 #include <stdio.h> 00037 00038 // 00039 // NOTE: remember to include WPCAP and HAVE_REMOTE among your 00040 // preprocessor definitions. 00041 // 00042 00043 #include <pcap.h> 00044 00045 #define LINE_LEN 16 00046 00047 main(int argc, char **argv) 00048 { 00049 pcap_if_t *alldevs, *d; 00050 pcap_t *fp; 00051 u_int inum, i=0; 00052 char errbuf[PCAP_ERRBUF_SIZE]; 00053 int res; 00054 struct pcap_pkthdr *header; 00055 const u_char *pkt_data; 00056 00057 printf("pktdump_ex: prints the packets of the network using WinPcap.\n"); 00058 printf(" Usage: pktdump_ex [-s source]\n\n" 00059 " Examples:\n" 00060 " pktdump_ex -s file://c:/temp/file.acp\n" 00061 " pktdump_ex -s rpcap://\\Device\\NPF_{C8736017-F3C3-4373-94AC-9A34B7DAD998}\n\n"); 00062 00063 if(argc < 3) 00064 { 00065 00066 printf("\nNo adapter selected: printing the device list:\n"); 00067 /* The user didn't provide a packet source: Retrieve the local device list */ 00068 if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) 00069 { 00070 fprintf(stderr,"Error in pcap_findalldevs_ex: %s\n", errbuf); 00071 return -1; 00072 } 00073 00074 /* Print the list */ 00075 for(d=alldevs; d; d=d->next) 00076 { 00077 printf("%d. %s\n ", ++i, d->name); 00078 00079 if (d->description) 00080 printf(" (%s)\n", d->description); 00081 else 00082 printf(" (No description available)\n"); 00083 } 00084 00085 if (i==0) 00086 { 00087 fprintf(stderr,"No interfaces found! Exiting.\n"); 00088 return -1; 00089 } 00090 00091 printf("Enter the interface number (1-%d):",i); 00092 scanf("%d", &inum); 00093 00094 if (inum < 1 || inum > i) 00095 { 00096 printf("\nInterface number out of range.\n"); 00097 00098 /* Free the device list */ 00099 pcap_freealldevs(alldevs); 00100 return -1; 00101 } 00102 00103 /* Jump to the selected adapter */ 00104 for (d=alldevs, i=0; i< inum-1 ;d=d->next, i++); 00105 00106 /* Open the device */ 00107 if ( (fp= pcap_open(d->name, 00108 100 /*snaplen*/, 00109 PCAP_OPENFLAG_PROMISCUOUS /*flags*/, 00110 20 /*read timeout*/, 00111 NULL /* remote authentication */, 00112 errbuf) 00113 ) == NULL) 00114 { 00115 fprintf(stderr,"\nError opening adapter\n"); 00116 return -1; 00117 } 00118 } 00119 else 00120 { 00121 // Do not check for the switch type ('-s') 00122 if ( (fp= pcap_open(argv[2], 00123 100 /*snaplen*/, 00124 PCAP_OPENFLAG_PROMISCUOUS /*flags*/, 00125 20 /*read timeout*/, 00126 NULL /* remote authentication */, 00127 errbuf) 00128 ) == NULL) 00129 { 00130 fprintf(stderr,"\nError opening source: %s\n", errbuf); 00131 return -1; 00132 } 00133 } 00134 00135 /* Read the packets */ 00136 while((res = pcap_next_ex( fp, &header, &pkt_data)) >= 0) 00137 { 00138 00139 if(res == 0) 00140 /* Timeout elapsed */ 00141 continue; 00142 00143 /* print pkt timestamp and pkt len */ 00144 printf("%ld:%ld (%ld)\n", header->ts.tv_sec, header->ts.tv_usec, header->len); 00145 00146 /* Print the packet */ 00147 for (i=1; (i < header->caplen + 1 ) ; i++) 00148 { 00149 printf("%.2x ", pkt_data[i-1]); 00150 if ( (i % LINE_LEN) == 0) printf("\n"); 00151 } 00152 00153 printf("\n\n"); 00154 } 00155 00156 if(res == -1) 00157 { 00158 fprintf(stderr, "Error reading the packets: %s\n", pcap_geterr(fp)); 00159 return -1; 00160 } 00161 00162 return 0; 00163 }

Packet Filter

This is a more complete example of libpcap usage. It shows, among other things, how to create and set filters and how to save a capture to disk. It can be compiled under Win32 or Unix (projects and makefiles are provided). Pcap_filter (pf.exe) is a general-purpose packet filtering application: its input parameters are a source of packets (it can be a physical interface or a file), a filter and an output file. It takes packets from the source until CTRL+C is pressed or the whole file is processed, applies the filter to the incoming packets and saves them to the output file if they satisfy the filter. Pcap_filter can be used to dump network data according to a particular filter, but also to extract a set of packets from a previously saved file. The format of both input and output files is the format used by libpcap, i.e. same of WinDump, tcpdump and many other network tools.

/* * 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); }
00001 /* 00002 * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) 00003 * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) 00004 * All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 00010 * 1. Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * 2. Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in the 00014 * documentation and/or other materials provided with the distribution. 00015 * 3. Neither the name of the Politecnico di Torino, CACE Technologies 00016 * nor the names of its contributors may be used to endorse or promote 00017 * products derived from this software without specific prior written 00018 * permission. 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00021 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00022 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00023 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00024 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00025 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00026 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00027 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00028 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00029 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00030 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 * 00032 */ 00033 00034 00035 #include <stdlib.h> 00036 #include <stdio.h> 00037 00038 #include <pcap.h> 00039 00040 #define MAX_PRINT 80 00041 #define MAX_LINE 16 00042 00043 00044 void usage(); 00045 00046 00047 void main(int argc, char **argv) 00048 { 00049 pcap_t *fp; 00050 char errbuf[PCAP_ERRBUF_SIZE]; 00051 char *source=NULL; 00052 char *ofilename=NULL; 00053 char *filter=NULL; 00054 int i; 00055 pcap_dumper_t *dumpfile; 00056 struct bpf_program fcode; 00057 bpf_u_int32 NetMask; 00058 int res; 00059 struct pcap_pkthdr *header; 00060 const u_char *pkt_data; 00061 00062 if (argc == 1) 00063 { 00064 usage(); 00065 return; 00066 } 00067 00068 for(i=1;i < argc; i+= 2) 00069 { 00070 00071 switch (argv[i] [1]) 00072 { 00073 case 's': 00074 { 00075 source=argv[i+1]; 00076 }; 00077 break; 00078 00079 case 'o': 00080 { 00081 ofilename=argv[i+1]; 00082 }; 00083 break; 00084 00085 case 'f': 00086 { 00087 filter=argv[i+1]; 00088 }; 00089 break; 00090 } 00091 } 00092 00093 // open a capture from the network 00094 if (source != NULL) 00095 { 00096 if ( (fp= pcap_open(source, 00097 1514 /*snaplen*/, 00098 PCAP_OPENFLAG_PROMISCUOUS /*flags*/, 00099 20 /*read timeout*/, 00100 NULL /* remote authentication */, 00101 errbuf) 00102 ) == NULL) 00103 { 00104 fprintf(stderr,"\nUnable to open the adapter.\n"); 00105 return; 00106 } 00107 } 00108 00109 else usage(); 00110 00111 if (filter != NULL) 00112 { 00113 // We should loop through the adapters returned by the pcap_findalldevs_ex() 00114 // in order to locate the correct one. 00115 // 00116 // Let's do things simpler: we suppose to be in a C class network ;-) 00117 NetMask=0xffffff; 00118 00119 //compile the filter 00120 if(pcap_compile(fp, &fcode, filter, 1, NetMask) < 0) 00121 { 00122 fprintf(stderr,"\nError compiling filter: wrong syntax.\n"); 00123 return; 00124 } 00125 00126 //set the filter 00127 if(pcap_setfilter(fp, &fcode)<0) 00128 { 00129 fprintf(stderr,"\nError setting the filter\n"); 00130 return; 00131 } 00132 00133 } 00134 00135 //open the dump file 00136 if (ofilename != NULL) 00137 { 00138 dumpfile= pcap_dump_open(fp, ofilename); 00139 00140 if (dumpfile == NULL) 00141 { 00142 fprintf(stderr,"\nError opening output file\n"); 00143 return; 00144 } 00145 } 00146 else usage(); 00147 00148 //start the capture 00149 while((res = pcap_next_ex( fp, &header, &pkt_data)) >= 0) 00150 { 00151 00152 if(res == 0) 00153 /* Timeout elapsed */ 00154 continue; 00155 00156 //save the packet on the dump file 00157 pcap_dump((unsigned char *) dumpfile, header, pkt_data); 00158 00159 } 00160 } 00161 00162 00163 void usage() 00164 { 00165 00166 printf("\npf - Generic Packet Filter.\n"); 00167 printf("\nUsage:\npf -s source -o output_file_name [-f filter_string]\n\n"); 00168 exit(0); 00169 }

documentation. Copyright (c) 2002-2005 Politecnico di Torino. Copyright (c) 2005-2006 CACE Technologies. All rights reserved.