Hi,

I have traced through the code all the way down to function calls in
packet32.c and even looked over the device driver code.  But can see no
obvious reason why calling "pcap_setbuff" causes this unusual behaviour.

I traced the code through "pcap_read" to "PacketReceivePacket".

In PacketReceivePacket I checked to see if WaitForSingleObject was failing.
This was, however, returning a success, as was the "ReadFile" call.

"ReadFile" function was always returning zero (0) bytes though.  Which
resulted in "pcap_read" returning the default value of "n" which just
happens to correspond to a timeout response (i.e. zero).

I then tried a completely different way, and changed the "#define SIZE_BUFF"
in pcap-win32.c to 40960000 and did not call pcap_setbuff from my test
application.

This seemed to work fine.  No timeouts were generated and the kernel memory
usage went up by about 40MB as expected

So, I thought, that it may be that the 2 calls to "pcap_setbuff" were
somehow causing a problem.

To test this out, I commented out the call to "pcap_setbuff" in
"pcap_open_live" function in "pcap-win32.c" and called "pcap_setbuff" from
my test application to see if this would work.

This worked fine.  No timeouts were generated.

So, it looks like, for some reason, when there is heavy network load,
calling "pcap_setbuff" twice is causing problems.  This is regardless of the
size of the buffer.  I tried setting it to 10MB, 1MB and even 10K.  The only
difference I noticed was that the 10K buffer size caused the timeout
responses to occur once a second.  Whereas the other values resulted in
timeouts occuring as fast as they could come through.

I am including a copy of my test application at the bottom of this response.

Does anyone out there have any ideas how I can get around this without
customising wpcap.dll.

To build it just create a console App project in Visual C++ and put this
code into your main program file and link wpcap.lib .

Thanks

Steve

// WinPCapConsole.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#define REMOTE

#define HAVE_U_INT32_T
#include "pcap.h"
#include ".\winpcap\wpcap\libpcap\pcap-int.h"

/* prototype of the packet handler */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const
u_char *pkt_data);
void display_packet(char * cMessage, const struct pcap_pkthdr *header, const
u_char *pkt_data);
void ReadPackets(pcap_t *adhandle, bool bGetError);

main()
{
    pcap_if_t *alldevs;
    pcap_if_t *d;
    int inum;
    int i=0;
    pcap_t *adhandle;
    char errbuf[PCAP_ERRBUF_SIZE];
    
    /* Retrieve the device list */
    if (pcap_findalldevs(&alldevs, errbuf) == -1)
    {
        fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
        exit(1);
    }
    
    /* Print the list */
    for(d=alldevs; d; d=d->next)
    {
        printf("%d. %s", ++i, d->name);
        if (d->description)
            printf(" (%s)\n", d->description);
        else
            printf(" (No description available)\n");
    }
    
    if(i==0)
    {
        printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
        return -1;
    }
    
    printf("Enter the interface number (1-%d):",i);
    scanf("%d", &inum);
    
    if(inum < 1 || inum > i)
    {
        printf("\nInterface number out of range.\n");
        /* Free the device list */
        pcap_freealldevs(alldevs);
        return -1;
    }

        // enter the setbuff buffer size and the mintocopy buffer size
        char    sResponse[256]={0};
        int             nSetBuff=0;
        int             nMinToCopy=0;
        bool    bGetError=false;
        int             nSetNonBlock;
        int             sbresult;

        printf ("Enter the size of the buffer for pcap_setbuff
(-1:default):");
        scanf ("%s", sResponse);
    nSetBuff = atoi(sResponse);

        printf ("Enter the size for pcap_setmintocopy (-1:default):");
        scanf ("%s", sResponse);
        nMinToCopy = atoi(sResponse);
        
        printf ("Do you want to get error string when timeout occurs (0:no,
1:yes)?");
        scanf ("%s", sResponse);
        if (sResponse[0]=='1')
                bGetError=true;
        else
                bGetError=false;
        
        printf ("Do you want to read packets in non-blocking mode (0:no,
1:yes, 2:default)?");
        scanf ("%s", sResponse);
        nSetNonBlock = atoi(sResponse);

    /* Jump to the selected adapter */
    for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
    
    /* Open the adapter */
    if ( (adhandle= pcap_open_live(d->name, // name of the device
                                                                   65536,
// portion of the packet to capture. 
        
// 65536 grants that the whole packet will be captured on all the MACs.
                                                                   1,
// promiscuous mode
                                                                   1000,
// read timeout
                                                                   errbuf
// error buffer
                                                                        ) )
== NULL)
    {
        fprintf(stderr,"\nUnable to open the adapter. %s is not supported by
WinPcap\n");
        /* Free the device list */
        pcap_freealldevs(alldevs);
        return -1;
    }
    
    printf("\nlistening on %s...\n", d->description);

        // set the buffer size
        if (nSetBuff > 0)
        {
                sbresult = pcap_setbuff(adhandle, nSetBuff);
                printf ("SetBuff returned : %d\n", sbresult);
        }

        // set minimum bytes to copy
        if (nMinToCopy > 0)
        {
                sbresult = pcap_setmintocopy (adhandle, nMinToCopy);
                printf ("setmintocopy returned : %d\n", sbresult);
        }

        // set blocking state
        switch (nSetNonBlock)
        {
        case 0:         if (pcap_setnonblock(adhandle, 0, sResponse)==-1)
                                        printf("Error setting nonBlock to
false: %s\n", sResponse);
                                break;

        case 1:         if (pcap_setnonblock(adhandle, 1, sResponse)==-1)
                                        printf("Error setting nonBlock to
true: %s\n", sResponse);
                                break;

        case 2:
        default:        // do nothing
                                break;
        }

    /* At this point, we don't need any more the device list. Free it */
    pcap_freealldevs(alldevs);

    // start the capture - choose your method...
    ReadPackets(adhandle, bGetError);
//      pcap_loop(adhandle, 0, packet_handler, NULL);
    
        pcap_close(adhandle);
    return 0;
}

/* Callback function invoked by libpcap for every incoming packet */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const
u_char *pkt_data)
{
    struct tm *ltime;
    char timestr[16];
    
    /* convert the timestamp to readable format */
    ltime=localtime(&header->ts.tv_sec);
    strftime( timestr, sizeof timestr, "%H:%M:%S", ltime);
    
    printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len);
}

// display the details of the packet received on the screen
void display_packet(char * cMessage, const struct pcap_pkthdr *header, const
u_char *pkt_data)
{
    struct tm *ltime;
    char timestr[16];
    static long seconds;
    
    if (header!=0 && pkt_data!=0)
        {
                /* convert the timestamp to readable format */
                ltime=localtime(&header->ts.tv_sec);
                strftime( timestr, sizeof timestr, "%H:%M:%S", ltime);
                printf("%s.%.4d len:%d - %s\n", timestr, header->ts.tv_usec,
header->len, cMessage);
        }
        else
        {
                SYSTEMTIME st;
                
                GetSystemTime(&st);

                // error in reading packet
                printf("%02d:%02d:%02d.%04d - %s\n", st.wHour, st.wMinute,
st.wSecond,
        
st.wMilliseconds,cMessage);
        }
}

void ReadPackets(pcap_t *adhandle, bool bGetError)
{
        bool gotone=false;
        pcap_pkthdr * hdr;
        unsigned char * data;
        int retcode;

        while (1)
        {
                retcode = pcap_next_ex(adhandle, &hdr, &data);
                switch (retcode)
                {
                        case -2:        // eof reached whilst reading packet
                                            display_packet("Dried up", 0,
0);
                                                break;

                        case -1:        // error occurred
                                                display_packet("Error
reading packet, trying again", 0, 0);
                                                break;

                        case 0:         // timeout
                                                display_packet("Timeout
reading packet", 0, 0);
                                                if (bGetError)
        
display_packet(pcap_geterr(adhandle),0,0);
                                                break;

                        case 1:         // received packet ok
                                                display_packet("Got Packet",
hdr, data);
                                                break;
                }
        }
}

-----Original Message-----
From: Steve Fernandes [mailto:[EMAIL PROTECTED]
Sent: 14 May 2004 16:12
To: '[EMAIL PROTECTED]'
Subject: RE: [WinPcap-users] Timeout responses to pcap_getnext_ex with
hig h network load and using pcap_setbuff


I have tried changing the kernel buffer size down to 10MB and then 1MB.  But
this did not change the frequency of the timeout responses.

I then set the kernel buffer to 1000 and this did result in the timeouts
occuring once every second.  But the timeouts were still occuring and no
proper packets were being received.

There is one other point I failed to mention earlier...

The PC I am using has 2 Network adapters.  One is plugged into the normal
office network and the other is plugged into a non-switching hub along with
a second PC that I am using to generate the network traffic.

It is the network card plugged into the hub that I have been using for these
tests.

Thanks

Steve

-----Original Message-----
From: Robert Thornthwaite [mailto:[EMAIL PROTECTED]
Sent: 14 May 2004 15:45
To: [EMAIL PROTECTED]
Subject: RE: [WinPcap-users] Timeout responses to pcap_getnext_ex with
high network load and using pcap_setbuff


Try a smaller kernel buffer, say 10MB.

Robert Thornthwaite
Input/Output, Inc.
phone:  281 879 2112
email:   [EMAIL PROTECTED] 
web:     http://www.i-o.com/

> 


================================================================= This is
the WinPcap users list. It is archived at
 http://www.mail-archive.com/[EMAIL PROTECTED]/

 To unsubscribe use 
 mailto: [EMAIL PROTECTED]
=================================================================

______________________________________________________________________
This email has been scanned by the MessageLabs Email Security System.
For more information please visit http://www.messagelabs.com/email 
______________________________________________________________________


==================================================================
 This is the WinPcap users list. It is archived at
 http://www.mail-archive.com/[EMAIL PROTECTED]/

 To unsubscribe use 
 mailto: [EMAIL PROTECTED]
==================================================================

______________________________________________________________________
This email has been scanned by the MessageLabs Email Security System.
For more information please visit http://www.messagelabs.com/email 
______________________________________________________________________


==================================================================
 This is the WinPcap users list. It is archived at
 http://www.mail-archive.com/[EMAIL PROTECTED]/

 To unsubscribe use 
 mailto: [EMAIL PROTECTED]
==================================================================

Reply via email to