Linux Mint(17または17.1)では、tcpdumpを使用して次のコマンドでいくつかのパケットをキャプチャしました。
tcpdump -UnvXSs 4096 -B 1024 -i eth0
-Uオプションにもかかわらず、実際にパケットをすぐに出力するわけではありません。代わりに、ネットワークアクティビティが大量に発生した場合、より頻繁に出力されることを除いて、ほぼ毎秒保存され出力されます。 -lオプションも試しましたが、違いはありませんでした。より小さいバッファ(-Bパラメータ)を使用すると、より少ないトラフィックのためにより頻繁な出力が可能になりますが、可能な最小値はまだ128で、トラフィックが毎秒1回だけ出力されるのを見たいほど大きいです。
tcpdumpでstraceを実行しています。次の行で繰り返し一時停止します。
poll([{fd=3, events=POLLIN}], 1, 1000) = 1 ([{fd=3, revents=POLLIN}])
1秒間滞在して再開し、より多くのパケットを出力してpoll()呼び出しに戻ります。
これらの poll() 呼び出しが発生する前に 3 を返した最後のシステム呼び出しは、次のようになります。
socket(PF_PACKET, SOCK_RAW, 768) = 3
これらの poll() 呼び出しの間には write() 呼び出し以外には何もないため、DNS ルックアップやその他による遅延はありません。
したがって、tcpdumpが1秒あたり1回だけパケットを表示するのは、カーネルが同じ頻度でパケットを転送するためであると結論付けました。
カーネルがパケットを受信するとすぐにパケットを出力するにはどうすればよいですか?
Linux version 3.13.0-24-generic (buildd@batsu) (gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) ) #47-Ubuntu SMP Fri May 2 23:30:00 UTC 2014
答え1
したがって、tcpdumpが1秒あたり1回だけパケットを表示するのは、カーネルが同じ頻度でパケットを転送するためであると結論付けました。
pcap_open_live()
はい - tcpdumpを使用するか、またはを使用してpcap_create()
キャプチャデバイスを開くときのpcap_activate()
1秒のタイムアウトを指定します。これは、多くのオペレーティングシステム(最新バージョンのカーネルとlibpcapを含むLinuxディストリビューションだけでなく、* BSD、OSの効率を向上させるためにパケットバッファ全体を転送し、将来的に配信される予定です。
最新バージョンのtcpdumpは、パケットをバイナリ形式でファイルに保存するのではなく、パケットを印刷するときにこのバッファリングを無効にします。
カーネルがパケットを受信するとすぐにパケットを出力するにはどうすればよいですか?
最新バージョンの tcpdump を実行するか、tcpdump を変更して短いタイムアウトを指定するか、タイムアウトを完全に無効にします。