[Winpcap-users] Problems when I try to capture packetsfrom multiple devices in Windows XP.

Loris Degioanni loris.degioanni at gmail.com
Thu Jun 9 17:10:29 GMT 2005


Liang,

Liang Yang wrote:
> Hi Loris,
> 
> Thanks a lot for your reply.  I used this filter function to set filter 
> and cpature packet from single device without using 
> WaitForMultipleObjects, it works fine.
> So you mean I can not set filter if I want to capture packets from 
> multple devices using WaitForMultipleObjects?

Of course you can filter. But if you set an *infinite* timeout in the 
wait and you set a very selective filter, you have to remember that 
winpcap has a feature called mintocopy.
Mintopcopy is used to minimize the number of system calls: the driver 
buffers the packets in kernel memory, and delivers them to user level 
only when there is a certain amount of them (normally 16 kbytes) or when 
the timeout expires. If you set an infinite timeout, you'll have to wait 
16ks, which could take a long time if you drop most of the packets.
In fact, if you run your program and reload the Amazon page several 
times, after a while WaitForMultipleObjects will return.
The easy solution for you is to put a timeout in the way.

> 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?

I don't have any warning. I'm compiling using the 3.1b4 developer's 
pack, I modified one of the examples.

Loris


> Liang
> 
> 
> 
> ----- Original Message ----- From: "Loris Degioanni" 
> <loris.degioanni at gmail.com>
> To: <winpcap-users at winpcap.org>
> Sent: Wednesday, June 08, 2005 9:37 AM
> Subject: Re: [Winpcap-users] Problems when I try to capture packetsfrom 
> multiple devices in Windows XP.
> 
> 
>> I think the problem is in your filter: I tried to run the program 
>> changing:
>>
>> ApplyFilter(pdevArray[i++], alldevs, filter);
>>
>> into:
>>
>> i++;
>>
>> WaitForMultipleObjects seems to work as expected.
>>
>> Loris
>>
>>
>>
>> Liang Yang wrote:
>>
>>> 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 <http://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 <file://\\ip>" );
>>>  sprintf( filter, "%s && %s", filter, sfilter );
>>>  sprintf( filter, "%s && ip proto \\tcp <file://\\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 *)&in;
>>>     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 <mailto:guy at alum.mit.edu>>
>>> To: <winpcap-users at winpcap.polito.it 
>>> <mailto: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 
>>> <mailto:winpcap-users-request at winpcap.polito.it?body=unsubscribe>
>>>  > ==================================================================
>>>  >
>>>
>>>
>>> ------------------------------------------------------------------------
>>>
>>> _______________________________________________
>>> Winpcap-users mailing list
>>> Winpcap-users at winpcap.org
>>> https://www.winpcap.org/mailman/listinfo/winpcap-users
>>
>> _______________________________________________
>> Winpcap-users mailing list
>> Winpcap-users at winpcap.org
>> https://www.winpcap.org/mailman/listinfo/winpcap-users
>>
> _______________________________________________
> Winpcap-users mailing list
> Winpcap-users at winpcap.org
> https://www.winpcap.org/mailman/listinfo/winpcap-users
> 



More information about the Winpcap-users mailing list