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