8

TCP SYN パケットのセットをホストに送信し (raw ソケットを使用)、libpcap(フィルターを使用して) 応答を取得するプログラムがあります。これを非同期 I/O フレームワークに実装しようとしていますが、応答の一部が欠落しているようです(つまり、TCP SYN と応答の間libpcapよりも時間がかからない一連の最初のパケット)。100 microsecondspcap ハンドルは次のように設定されます。

pcap_t* pcap = pcap_open_live(NULL, -1, false, -1, errorBuffer);
pcap_setnonblock(pcap, true, errorBuffer);

次に、フィルター (filterExpression 文字列に含まれる) を追加します。

struct bpf_program filter;
pcap_compile(pcap, &filter, filterExpression.c_str(), false, 0);
pcap_setfilter(pcap, &filter);
pcap_freecode(&filter);

ループでは、各パケットを送信した後、select を使用して、libpcap から読み取れるかどうかを確認します。

int pcapFd = pcap_get_selectable_fd(pcap);
fd_set fdRead;
FD_ZERO(&fdRead);
FD_SET(pcapFd, &fdRead);
select(pcapFd + 1, &fdRead, NULL, NULL, &selectTimeout);

そしてそれを読んでください:

if (FD_ISSET(pcapFd, &fdRead)) {
     struct pcap_pkthdr* pktHeader;
     const u_char* pktData;
     if (pcap_next_ex(pcap, &pktHeader, &pktData) > 0) {
         // Process received response.
     }
     else {
         // Nothing to receive (or error).
     }
}

前に述べたように、一部のパケットが失われます (「何も受信しない」状態に陥ります)。これらのパケットがそこにあることはわかっています。なぜなら、これらのパケットを同期方式で (tcpdumpまたは実行中のスレッドを使用してpcap_loop) キャプチャできるからです。ここに詳細がありませんか?または、これは問題libpcapですか?

4

2 に答える 2

3

の FD が(または使用している呼び出し/メカニズムpcap_tによって) 読み取り可能であると報告された場合、ブロックせずに 1 つのパケットのみを読み取ることができるという保証はありません。select()poll()

を使用するpcap_next_ex()と、1 つのパケットのみが読み取られます。select()読み取り可能なパケットが複数ある場合は、別のpcap_next_ex(). これは、パケットごとに少なくとも 1 つのシステム コール ( select()) を意味し、使用している OS のバージョンと使用している libpcap のバージョンに応じて、さらに多くの呼び出しが発生する可能性があります。

代わりに、pcap_dispatch()-1 の packet-count 引数を指定して を呼び出した場合、その呼び出しは、1 回の読み取り操作で取得できるすべてのパケットを返し、それらすべてを処理します。したがって、ほとんどのプラットフォームでは、利用可能な複数のパケットがある場合、1 つまたは 2 つのシステム コールを伴う複数のパケット (これは、SYN フラッドでプログラムをテストしている場合に発生する可能性があるネットワーク トラフィックが高い場合に該当する可能性があります)。

さらに、メモリ マップド パケット キャプチャをサポートする Linux システムでは (2.6 以降のすべてのカーネルでサポートされていると思いますが、すべての 2.4 カーネルではないにしてもほとんどのカーネルでサポートされていると思います)、新しいバージョンの libpcap では、pcap_next_ex()回避するためにパケットのコピーを作成する必要があります。パケットを処理するコードの下からカーネルにパケットを変更させ、リングバッファー内のスロットを無期限に「ロックアップ」しないようにするため、余分なコピーが必要になります。

于 2012-07-25T00:49:38.060 に答える
2

これは、Linux でメモリ マッピングを使用する libpcap の問題のようです。詳細については、私の他の質問を参照してください。

于 2012-07-30T23:20:57.520 に答える