Search code examples
ctimestampcygwinwinpcap

Cygwin and WinPcap 4.1.3 timestamp - microsecond issue - header->ts.tv_usec not correct - C program


I am working on developing a customized packet sniffer for Windows 7 64 bit host system (NIC card is Realtek PCIe GBE Family Controller) and am using WinPcap 4.3.1 library using C programming and Cygwin development platform. I am able to read outgoing and incoming TCP and UDP packets through my program. However, I am stuck in a problem of not able to get correct timestamp in microsecond from the struct pcap_pkthdr structure. Following is the code snippet from the program where the problem exists:

... 

int getPacket; 
struct pcap_pkthdr *header;  
const u_char *pkt_data;  

/* Sniff the packets */  
while((getPacket= pcap_next_ex(handle, &header, &pkt_data)) >= 0)   
{      

printf("\n 1) Epoch is: %ld",header->ts.tv_sec&0x00000000ffffffff);     

printf("\n 2) Microsecond is:  %ld",header->ts.tv_usec);   

...  

Following is the console output that I got for these 2 printf() statements in a run:

1) Epoch is: 1460262399
2) Microsecond is: 1576252997999

Time in seconds (header->ts.tv_sec&0x00000000ffffffff) is correct as it translates to 2016-04-09::23:26:39 (yy-mm-dd::hh-mm-ss format)

However, the Microsecond (header->ts.tv_usec) is not correct as the hex value of Microsecond is 0x16F0000016F that always shows this kind of repeating pattern (with different values) at the low and high octet positions. I have analyzed memory dumps and found the same values that makes me believe that the header->ts.tv_usec is not filled correctly by the NPF driver.

I did a lot of search and could not find this issue reported anywhere. Also, I tested the code on separate AMD and Intel machines and the issue seems to linger.

Any suggestion(s) to solve this problem would be highly appreciated.


Solution

  • Actually, in WinPcap, there are only 32 bits in tv_sec.

    WinPcap uses Microsoft's definition of struct timeval - it does not require Cygwin, so it can't use Cygwin's definition - and, in that definition, tv_sec and tv_usec are both long, and, in MSVC, long is 32-bit even on 64-bit platforms. (You need a different data type for a 64-bit integer.)

    From your test, Cygwin's struct timeval has a 64-bit tv_sec and a 64-bit tv_usec on 64-bit platforms. Therefore:

    1. Cygwin will not work with WinPcap on 64-bit platforms;
    2. a 64-bit Cygwin program using WinPcap will think that the seconds and microseconds fields of a pcap time stamp are a 64-bit tv_sec field, so only the lower 32 bits will be valid, and will think that some random locations in memory are the tv_usec field, so you'll see the behavior that you're reporting.