私は非常にトラフィックの多いネットワークの監視プログラムを書いています(HDビデオはネットワークを介してストリーミングされます)。ほとんどのパケットは非常に大きく、ヘッダーのみを監視したい(IPおよびUDP / TCPのみ)。もちろん、データ全体をコピーするオーバーヘッドを避けたいと思います。libpcapは必然的にパケット全体のコピーを私に与えますか?はいの場合、私のニーズに合ったライブラリはありますか?
1 に答える
ここには2つの質問があるようです。
- タイトルにあるもの。これは、libpcapがパケットをコピーするかどうかを尋ねているように聞こえます。
- 本体にあるもので、常にパケット全体をコピーするかどうかを尋ねます。
最初の質問の場合:
おそらく、libpcapがさまざまなOSで実行されるメカニズムを使用するコードによって少なくとも1つのコピーが実行されます。つまり、mbufs / skbuff/STREAMSバッファー/その他のメカニズムのバッファーへのコピーです。Linuxの場合、tpacketメカニズムが使用されていないとき、skbuffは、 libpcapが使用しているソケットの受信キューにキューイングされている可能性があります。PF_PACKET
別のコピーがある可能性があります-そのバッファからユーザーランドへのコピー。libpcapがLinuxtpacketメカニズム(libpcap 1.0以降がデフォルトで使用する)などの「ゼロコピー」メカニズムを使用している場合、2番目のコピーは発生しません。ゼロコピーメカニズムが使用されていない場合に発生します。
ただし、Linuxシステムを使用している場合、pcap_next()
またはpcap_next_ex()
Linuxシステムで、tpacketメカニズムを使用している場合は、メモリマップドバッファからプライベートバッファに別のコピーを作成します。pcap_dispatch()
またはを使用する場合、それは起こりませんpcap_loop()
。
2番目の質問の場合:
これが「snaplen」引数の目的pcap_open_live()
ですpcap_set_snaplen()
。これにより、「snaplen」バイト以下のパケットデータをキャプチャするように指定できます。つまり、コピーされるバイト数はそれ以下になります。
この長さにはリンク層ヘッダーが含まれ、802.11アダプターで取得される可能性のあるradiotapヘッダーなどの「メタデータ」ヘッダーが含まれる可能性があることに注意してください。このヘッダーは可変長である可能性があります(たとえば、802.11では802.11ヘッダーは可変長であり、radiotapヘッダーを取得している場合は、それらも可変長です)。
さらに、IPv4ヘッダーとTCPヘッダーの両方にオプションを含めることができ、IPv6パケットに拡張ヘッダーを含めることができるため、IPヘッダーとTCPヘッダーの長さも可変にすることができます。
これは、使用する「最悪の場合」のスナップショットの長さを決定する必要がある場合があることを意味します。「TCP/UDPヘッダーを超えて何も与えないでください」と明示的に言う方法はありません。「Nバイト以下を与えてください」としか言えません。