1

静的ライブラリ ( libpcap.a ) としてビルドされたバージョン1.1.1のlibpcapを使用しています。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フィールドの時点で、それが無効であることはわかっています。少なくともキャプレンの大きさであるはずです。バグですか?これを修正するには、どのような手順を踏む必要がありますか?

GDB はpcap_header の内容を次のように表示します。

(gdb) p pcap_header

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

たぶん、いくつかの回避策を適用できますか?libpcapのバージョンをアップグレードしたくありません。

4

2 に答える 2

1

2.6.27 カーネルより前のカーネルは、64 ビット カーネルで libpcap 1.0 以降を使用した 32 ビット バイナリの実行をサポートしていません。

libpcap 1.0 以降は、利用可能な Linux カーネルで「メモリ マップ」キャプチャ メカニズムを使用します。このメカニズムの最初のバージョンでは、「メモリ マップ」キャプチャ メカニズムを使用して、カーネルとコードの間でデータ構造が共有されることが保証されませんでした。 32ビットモードと64ビットモードで同じようにメモリに配置されました。

2.6.27 カーネルより前の 2.6 カーネルには、そのメカニズムの最初のバージョンしかありません。2.6.27 カーネルには、そのメカニズムの 2 番目のバージョンがあり、データ構造が 32 ビット モードと 64 ビット モードで同じようにメモリに配置されるため、32 ビット ユーザー モード コードは同じように機能します。 32 ビットおよび 64 ビット カーネル上。

于 2013-02-21T20:40:55.443 に答える
0

「 https://bugzilla.redhat.com/show_bug.cgi?id=557728 」の欠陥の説明をグーグルで検索したところ、現在でも関連しているようです。アプリケーションを静的バージョンではなく共有ライブラリ バージョンのlibpcapにリンクすると、問題はなくなりました。次に、システムは、実行時に RHEL に同梱されているlibpcapにリンクされたアプリを取得します。

敬具、アレクサンダー・チェルニャエフ。

于 2013-02-27T17:20:04.417 に答える