Cygwin 和 WinPcap 4.1.3 时间戳 - 微秒问题 - header->ts.tv_usec 不正确 - C 程序
Cygwin and WinPcap 4.1.3 timestamp - microsecond issue - header->ts.tv_usec not correct - C program
我正在为 Windows 7 64 位主机系统(NIC 卡是 Realtek PCIe GBE 系列控制器)开发定制的数据包嗅探器,我正在使用使用 C 编程和 Cygwin 开发平台的 WinPcap 4.3.1 库.我能够通过我的程序读取传出和传入的 TCP 和 UDP 数据包。但是,我遇到了无法从 struct pcap_pkthdr 结构中获取正确的微秒时间戳的问题。以下是存在问题的程序的代码片段:
...
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);
...
以下是 控制台输出,我在 运行 中为这 2 个 printf() 语句获得:
1) 纪元为:1460262399
2)微秒为:1576252997999
以秒为单位的时间 (header->ts.tv_sec&0x00000000ffffffff) 是正确的,因为它转换为 2016-04-09::23:26:39 (yy-mm-dd:: hh-mm-ss 格式)
但是,微秒 (header->ts.tv_usec) 不正确,因为微秒的十六进制值是 0x16F0000016F,它总是显示这种重复模式(与不同的值)在低位和高位八位位组位置。我分析了内存转储,发现相同的值让我相信 header->ts.tv_usec 没有被 NPF 驱动程序正确填充。
我进行了大量搜索,但在任何地方都找不到这个问题。另外,我在不同的 AMD 和 Intel 机器上测试了代码,这个问题似乎仍然存在。
任何解决此问题的建议都将不胜感激。
实际上,在 WinPcap 中,在 tv_sec
.
中只有 32 位
WinPcap 使用 Microsoft's definition of struct timeval
- 它不需要 Cygwin,因此它不能使用 Cygwin 的定义 - 而且,在那个定义中,tv_sec
和 tv_usec
都是 long
,并且在 MSVC 中,long
是 32 位的 ,即使在 64 位平台上也是如此。 (64 位整数需要不同的数据类型。)
根据您的测试,Cygwin 的 struct timeval
在 64 位平台上有一个 64 位 tv_sec
和一个 64 位 tv_usec
。因此:
- Cygwin 无法在 64 位平台上与 WinPcap 一起工作;
- 使用 WinPcap 的 64 位 Cygwin 程序会认为 pcap 时间戳的秒和微秒字段是 64 位
tv_sec
字段,因此只有低 32 位有效,并且将认为内存中的一些随机位置是 tv_usec
字段,因此您会看到您报告的行为。
我正在为 Windows 7 64 位主机系统(NIC 卡是 Realtek PCIe GBE 系列控制器)开发定制的数据包嗅探器,我正在使用使用 C 编程和 Cygwin 开发平台的 WinPcap 4.3.1 库.我能够通过我的程序读取传出和传入的 TCP 和 UDP 数据包。但是,我遇到了无法从 struct pcap_pkthdr 结构中获取正确的微秒时间戳的问题。以下是存在问题的程序的代码片段:
...
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);
...
以下是 控制台输出,我在 运行 中为这 2 个 printf() 语句获得:
1) 纪元为:1460262399
2)微秒为:1576252997999
以秒为单位的时间 (header->ts.tv_sec&0x00000000ffffffff) 是正确的,因为它转换为 2016-04-09::23:26:39 (yy-mm-dd:: hh-mm-ss 格式)
但是,微秒 (header->ts.tv_usec) 不正确,因为微秒的十六进制值是 0x16F0000016F,它总是显示这种重复模式(与不同的值)在低位和高位八位位组位置。我分析了内存转储,发现相同的值让我相信 header->ts.tv_usec 没有被 NPF 驱动程序正确填充。
我进行了大量搜索,但在任何地方都找不到这个问题。另外,我在不同的 AMD 和 Intel 机器上测试了代码,这个问题似乎仍然存在。
任何解决此问题的建议都将不胜感激。
实际上,在 WinPcap 中,在 tv_sec
.
WinPcap 使用 Microsoft's definition of struct timeval
- 它不需要 Cygwin,因此它不能使用 Cygwin 的定义 - 而且,在那个定义中,tv_sec
和 tv_usec
都是 long
,并且在 MSVC 中,long
是 32 位的 ,即使在 64 位平台上也是如此。 (64 位整数需要不同的数据类型。)
根据您的测试,Cygwin 的 struct timeval
在 64 位平台上有一个 64 位 tv_sec
和一个 64 位 tv_usec
。因此:
- Cygwin 无法在 64 位平台上与 WinPcap 一起工作;
- 使用 WinPcap 的 64 位 Cygwin 程序会认为 pcap 时间戳的秒和微秒字段是 64 位
tv_sec
字段,因此只有低 32 位有效,并且将认为内存中的一些随机位置是tv_usec
字段,因此您会看到您报告的行为。