Вызов pcap_next заполняет pcap_pkthdr с len равным нулю

Я использую libpcap версии 1.1.1, собранный как статическая библиотека (libpcap.a). Когда я пытаюсь выполнить следующий блок кода на 64-битном RHEL 6 (сам исполняемый модуль построен как 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_header.len равно нулю при возврате pcap_next. На самом деле поле caplen, похоже, отражает размер пакета правильно. Если я пытаюсь сбросить память пакета с адреса пакета - данные, кажется, действительны. По лен поля, равного нулю, я знаю, что это неверно. Это должно быть, по крайней мере, как каплену величины. Это ошибка? Какие шаги я должен предпринять, чтобы исправить это?

GDB показывает содержимое pcap_header как:

(gdb) p pcap_header

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

Может быть, я могу применить обходной путь? Я не хочу обновлять версию libpcap.

2 ответа

Решение

Надеюсь, я погуглил описание дефекта " https://bugzilla.redhat.com/show_bug.cgi?id=557728", и, похоже, оно до сих пор актуально. Проблема исчезла, когда я связал свое приложение с версией libpcap для общей библиотеки вместо того, чтобы связать его со статической. Затем система связывает мое приложение с libpcap во время выполнения, которое поставляется с RHEL.

С уважением, Александр Черняев.

Ядра до версии 2.6.27 не поддерживают запуск 32-битных двоичных файлов с использованием libpcap 1.0 или более поздней версии на 64-битном ядре.

В libpcap 1.0 и более поздних версиях используется механизм захвата с отображением в памяти в ядрах Linux, в которых он есть, и первая версия этого механизма не обеспечивала совместное использование структур данных между ядром и кодом с использованием механизма захвата с отображением в память были расположены в памяти одинаково в 32-битном и 64-битном режиме.

Ядра 2.6, предшествующие ядру 2.6.27, имеют только первую версию этого механизма. Ядро 2.6.27 имеет вторую версию этого механизма, которая гарантирует, что структуры данных располагаются в памяти одинаково в 32-битном и 64-битном режиме, так что 32-битный код пользовательского режима работает одинаково поверх 32-битных и 64-битных ядер.

Другие вопросы по тегам