[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 *)&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>
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