C++ pcap_下一次调用使用len等于零填充pcap_pkthdr

C++ pcap_下一次调用使用len等于零填充pcap_pkthdr,c++,c,libpcap,C++,C,Libpcap,我正在使用libpcap版本1.1.1的静态库(libpcap.a)。当我尝试在RHEL 6 64位(可执行模块本身构建为32位ELF图像)上执行以下代码块时,我遇到了分段错误: const unsigned char* packet; pcap_pkthdr pcap_header = {0}; unsigned short ether_type = 0; while ( ether_type != ntohs( 0x800 ) ) { packet = pcap_next ( m_

我正在使用libpcap版本1.1.1的静态库(libpcap.a)。当我尝试在RHEL 6 64位(可执行模块本身构建为32位ELF图像)上执行以下代码块时,我遇到了分段错误:

const unsigned char* packet;
pcap_pkthdr pcap_header = {0};
unsigned short ether_type = 0;

while ( ether_type != ntohs( 0x800 ) )
{
    packet = pcap_next ( m_pcap_handle, &pcap_header );
    if (packet != NULL)
    {
        memcpy ( &ether_type, &( packet[ 12 ] ), 2 );
    }
    else
    {
    /*Sleep call goes here*/
    }
}

if ( raw_buff ->data_len >= pcap_header.caplen )
{
    memcpy ( raw_buff->data, &(packet[14]), pcap_header.len -14 );
    raw_buff->data_len = pcap_header.len -14;
    raw_buff->timestamp = pcap_header.ts; 
}
一点调查显示pcap_头。len字段在pcap_next返回时等于零。事实上,caplen字段似乎正确地反映了数据包大小。如果我试图从数据包地址转储数据包内存,则数据似乎有效。由于len字段等于零,我知道它无效。它至少应该是caplen量级。是虫子吗?我应该采取什么步骤来修复这个问题

GDB将pcap_标题的内容显示为:

(gdb)p pcap_头

$1={ts={tv_sec=5242946,tv_usec=1361456997},caplen=66,len=0}


也许我可以申请一些变通办法?我不想升级libpcap版本。

2.6.27内核之前的内核不支持在64位内核上使用libpcap 1.0或更高版本运行32位二进制文件

libpcap 1.0及更高版本在可用的Linux内核上使用“内存映射”捕获机制,该机制的第一个版本没有确保内核和使用“内存映射”捕获机制的代码之间共享的数据结构在32位和64位模式下以相同的方式部署在内存中


2.6.27内核之前的2.6内核只有该机制的第一个版本。2.6.27内核有该机制的第二个版本,它确保数据结构在32位和64位模式下以相同的方式排列在内存中,因此,32位用户模式代码在32位和64位内核上的工作方式相同。

2.6.27内核之前的内核不支持在64位内核上使用libpcap 1.0或更高版本运行32位二进制文件

libpcap 1.0及更高版本在可用的Linux内核上使用“内存映射”捕获机制,该机制的第一个版本没有确保内核和使用“内存映射”捕获机制的代码之间共享的数据结构在32位和64位模式下以相同的方式部署在内存中

2.6.27内核之前的2.6内核只有该机制的第一个版本。2.6.27内核有该机制的第二个版本,它确实确保了数据结构在32位和64位模式下以相同的方式排列在内存中,因此32位用户模式代码在32位和64位内核上的工作方式相同。

希望我在谷歌上搜索“”缺陷描述,它现在似乎仍然相关。当我将应用程序链接到共享库版本的libpcap而不是静态版本时,问题就消失了。然后,系统在运行时将我的应用程序链接到RHEL附带的libpcap

衷心感谢您,Alexander Chernyaev。

希望我在谷歌上搜索到了“”缺陷描述,它现在似乎仍然相关。当我将应用程序链接到共享库版本的libpcap而不是静态版本时,问题就消失了。然后,系统在运行时将我的应用程序链接到RHEL附带的libpcap


衷心感谢您,Alexander Chernyaev。

也许您的代码的其余部分弄乱了头数据。尝试在valgrind下运行你的应用程序,看看内存管理是否有其他问题。请注意,caplen是你需要关心的长度。它表示捕获的数据包中有多少数据。len成员是数据包在导线上的原始长度,但您可能没有捕获到所有长度(主要取决于snaplen设置),如果len