pcap_next调用用len等于零填充pcap_pkthdr

时间:2013-02-21 16:39:24

标签: c++ c libpcap

我正在使用版本 1.1.1 libpcap 构建为静态库( 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_next 返回时,一些调查显示 pcap_header.len 字段等于零。事实上, caplen 字段似乎相应地反映了数据包大小。如果我尝试从数据包地址转储数据包内存 - 数据似乎是有效的。由于 len 字段等于零,我知道它无效。它应该至少是 caplen 幅度。这是一个错误吗?我应采取哪些措施来解决这个问题?

GDB将 pcap_header 内容显示为:

(gdb)p pcap_header

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

也许我可以应用一些解决方法?我不想升级 libpcap 版本。

2 个答案:

答案 0 :(得分:1)

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位内核上运行相同。

答案 1 :(得分:0)

希望我用Google搜索“https://bugzilla.redhat.com/show_bug.cgi?id=557728”缺陷描述,现在似乎它仍然具有相关性。当我将我的应用程序链接到 libpcap 的共享库版本而不是将其与静态库链接时,问题就消失了。然后系统将我的应用程序链接到运行时的 libpcap ,该程序随RHEL一起提供。

真诚的,Alexander Chernyaev。