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

Loris Degioanni loris.degioanni at gmail.com
Wed Jun 8 16:37:29 GMT 2005


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



More information about the Winpcap-users mailing list