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