[Winpcap-users] Problems when I try to capture packets from
multiple devices in Windows XP.
Liang Yang
multisyncfe991 at hotmail.com
Sun Jun 5 22:36:33 GMT 2005
Hi,
I tried to implement packet capturing from multiple devices in Windows
XP using pcap_geteven and WaitForMultipleEvents, but it does not work. I
will really appreciate if you can take a look at my program and point out any errors.
I use WinPcap 3.0
I already worked out a program which can capture packets from single device successfully. But when I
tried multi-threaded method or use events without multi-threads to capture packets from multiple devices,
I could not make the code work. The program just hang there and no packet is captured. Attached is my program(the filter is set up
successfully when I run the program).
BTW, when I built this program and I get two warnings:
c:\stun\wdcap\seqcap.c(85) : warning C4013: 'pcap_getevent' undefined;
assuming extern returning int
c:\stun\wdcap\seqcap.c(85) : warning C4047: '=' : 'void *' differs in levels
of indirection from 'int '
But actually get_getevent is well-defined. Why this happen?
Thanks a lot,
Liang
int main()
{
capture_tcp_syn("dst host www.amazon.com");
return 0;
}
int ifprint(pcap_if_t *d);
char *iptos(u_long in);
void RetrievePacket(pcap_t* pdev);
int ApplyFilter(pcap_t *hdev, pcap_if_t *devlist, char *filter);
struct packet *packetCap;
//*************************************************************
struct packet * capture_tcp_type(char* sfiltere, char * tfilter);
struct packet * capture_packet(char *filter);
struct packet * capture_tcp_syn(char* sfilter)
{
return capture_tcp_type( sfilter, "tcp[13] = 0x02" );
}
struct packet * capture_tcp_type(char* sfilter, char* tfilter )
{
char filter[512];
sprintf( filter, "ether proto \\ip" );
sprintf( filter, "%s && %s", filter, sfilter );
sprintf( filter, "%s && ip proto \\tcp", filter );
sprintf( filter, "%s && %s", filter, tfilter );
return capture_packet( filter );
}
struct packet *capture_packet(char *filter) {
pcap_if_t *alldevs;
pcap_if_t *d;
pcap_t* pdevArray[12];
char errbuf[PCAP_ERRBUF_SIZE];
HANDLE handleArray[12];
DWORD WaitObj;
int i, j;
// Retrieve the device list
if (pcap_findalldevs(&alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
exit(1);
}
i = 0;
for(d=alldevs; d; d=d->next)
{
if (ifprint(d))
{
if ( (pdevArray[i]= pcap_open_live(d->name, 590, 0, -1, errbuf) ) ==
NULL)
{
fprintf(stderr,"\nUnable to open the adapter. %s is not supported by
WinPcap\n");
return NULL;
}
handleArray[i] = pcap_getevent(pdevArray[i]);
ApplyFilter(pdevArray[i++], alldevs, filter);
}
}
WaitObj = WaitForMultipleObjects(i, handleArray, 0, INFINITE);
RetrievePacket(pdevArray[WaitObj - WAIT_OBJECT_0]);
for(j=0;j<i;j++)
CloseHandle(handleArray[j]);
// At this point, we don't need any more the device list. Free it
pcap_freealldevs(alldevs);
return packetCap;
}
void RetrievePacket(pcap_t* pdev)
{
struct pcap_pkthdr *pkt_header;
int pkt_size;
u_char *pkt_data;
u_char *pdata;
int res;
while((res = pcap_next_ex( pdev, &pkt_header, &pkt_data)) >= 0){
if(res == 0)
// Timeout elapsed
continue;
//check that caplen is equal to packet length
if (pkt_header->caplen!=pkt_header->len)
{
printf("Inconsistent header: CapLen %d\t Len
%d\n",pkt_header->caplen,pkt_header->len);
return;
}
pkt_size = pkt_header->caplen;
if (!(pdata = (unsigned char *)malloc(pkt_size * sizeof(char))))
{
printf("Memory allocation error for captured packet\n");
return;
}
// copy the packet
memcpy(pdata, pkt_data, pkt_size);
if (!(packetCap = (struct packet *)malloc( sizeof( struct packet ))))
{
printf("Memory allocation error for captured packet\n");
return;
}
packetCap->data = pdata;
packetCap->length = pkt_size;
return;
}
if(res == -1){
printf("Error reading the packets: %s\n", pcap_geterr(pdev));
return;
}
return;
}
int ApplyFilter(pcap_t *hdev, pcap_if_t *devlist, char *filter)
{
u_int netmask;
int retvalue;
struct bpf_program fcode;
if(devlist->addresses!=NULL)
netmask=((struct sockaddr_in
*)(devlist->addresses->netmask))->sin_addr.S_un.S_addr;
else
netmask=0xffffffff;
//compile the filter
retvalue=pcap_compile(hdev,&fcode,filter,1,netmask);
if(retvalue<0)
{
printf("\n Unable to compile the filter\n");
return 0;
}
//Set the filter
retvalue=pcap_setfilter(hdev,&fcode);
if(retvalue<0)
{
printf("\n Unable to set the filter\n");
return 0;
}
printf("\n Filter applied successfully\n");
return 1;
}
// Print all the available information on the given interface
int ifprint(pcap_if_t *d)
{
pcap_addr_t *a;
int phyDevice = 0;
// Name
printf("%s\n",d->name);
// Description
if (d->description)
printf("\tDescription: %s\n",d->description);
else
printf(" (No description available)\n");
// Loopback Address
printf("\tLoopback: %s\n", (d->flags & PCAP_IF_LOOPBACK)?"yes":"no");
// IP addresses
for(a=d->addresses;a;a=a->next) {
printf("\tAddress Family: #%d\n",a->addr->sa_family);
switch(a->addr->sa_family)
{
case AF_INET:
printf("\tAddress Family Name: AF_INET\n");
if (a->addr)
printf("\tAddress: %s\n",iptos(((struct sockaddr_in
*)a->addr)->sin_addr.s_addr));
if (a->netmask)
printf("\tNetmask: %s\n",iptos(((struct sockaddr_in
*)a->netmask)->sin_addr.s_addr));
if (a->broadaddr)
printf("\tBroadcast Address: %s\n",iptos(((struct sockaddr_in
*)a->broadaddr)->sin_addr.s_addr));
if (a->dstaddr)
printf("\tDestination Address: %s\n",iptos(((struct sockaddr_in
*)a->dstaddr)->sin_addr.s_addr));
break;
default:
printf("\tAddress Family Name: Unknown\n");
break;
}
if (!(d->flags & PCAP_IF_LOOPBACK))
phyDevice = 1;
}
printf("\n");
return phyDevice;
}
// From tcptraceroute, convert a numeric IP address to a string
#define IPTOSBUFFERS 12
char *iptos(u_long in)
{
static char output[IPTOSBUFFERS][3*4+3+1];
static short which;
u_char *p;
p = (u_char *)∈
which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);
sprintf(output[which], "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
return output[which];
}
----- Original Message -----
From: "Guy Harris" <guy at alum.mit.edu>
To: <winpcap-users at winpcap.polito.it>
Sent: Monday, May 09, 2005 1:11 PM
Subject: Re: [WinPcap-users] How to capture packet from "Any" device using
WinPcap.
> Liang Yang wrote:
>
>> In libpcap, we can use "any" as the device name to capture packets from
>> any devices.
>
> In libpcap *ON LINUX* you can use "any" as the device name to capture from
> all devices.
>
> On other UN*Xes the "any" device isn't supported.
>
>> But Windows XP does not support "Any" device and I do not want to ask the
>> user to select which device to capture packets. How to do this using
>> WinPCap?
>
> You'd have to capture on all of the devices separately. At least with
> WinPcap 3.1 beta (and perhaps 3.0), you could open several devices and
> capture on all of them with a single loop using WaitForMultipleEvents() or
> MsgWaitForMultipleEvents(), using handles you get from pcap_getevent().
>
>
> ==================================================================
> This is the WinPcap users list. It is archived at
> http://www.mail-archive.com/winpcap-users@winpcap.polito.it/
>
> To unsubscribe use mailto:
> winpcap-users-request at winpcap.polito.it?body=unsubscribe
> ==================================================================
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.winpcap.org/pipermail/winpcap-users/attachments/20050605/888c7a44/attachment.html
More information about the Winpcap-users
mailing list