[WinPcap-users] How to capture packet from "Any" device using WinPcap.

Guy Harris guy at alum.mit.edu
Sun Jun 5 22:47:06 GMT 2005


Liang Yang wrote:

> Hi,
>
> I tried to implement this 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'm mainly a UN*X developer; it's best to ask questions such as this on 
the winpcap-users mailing list, so I'll forward it there.

> I already worked out a program which can capture packets from single 
> device successfully. But I tried multi-threaded and 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.
>
> 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/[email protected]/
>>
>> To unsubscribe use mailto: 
>> winpcap-users-request at winpcap.polito.it?body=unsubscribe
>> ==================================================================
>>
>
>




More information about the Winpcap-users mailing list