web-dev-qa-db-ja.com

TCPDUMP出力をリアルタイムで処理/パイプする方法

クライアント(OpenWrt 10.04ルーター上)によるDNS要求をtcpdumpしたい場合は、

root@ROUTER:/etc# tcpdump -n -i br-lan dst port 53 2>&1       
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on br-lan, link-type EN10MB (Ethernet), capture size 96 bytes
22:29:38.989412 IP 192.168.1.200.55919 > 192.168.1.1.53: 5697+ A? foo.org. (25)
22:29:39.538981 IP 192.168.1.200.60071 > 192.168.1.1.53: 17481+ PTR? 150.33.87.208.in-addr.arpa. (44)
^C
2 packets captured
3 packets received by filter
0 packets dropped by kernel

それで十分です。だが。 tcpdumpの出力をリアルタイムでパイプできないのはなぜですか?

root@ROUTER:/etc# tcpdump -n -i br-lan dst port 53 2>&1 | awk '/\?/ {print $3}'
^C
root@ROUTER:/etc# 

Tcpdumpの後にawkなどを実行しても、何も出力されません。何故ですか? tcpdumpの出力をパイプライン処理でリアルタイムに処理できないのはなぜですか? (そのため、例:の例では、3番目の列のみが出力されます)

これに対する解決策はありますか?

28
LanceBaynes

man tcpdump

-l     Make stdout line buffered.  Useful if you want to see the data while 
       capturing it.  E.g.,

              tcpdump -l | tee dat

       or

              tcpdump -l > dat & tail -f dat

       Note that on Windows,``line buffered'' means ``unbuffered'', so that 
       WinDump will write each character individually if -l is specified.

       -U is similar to -l in its behavior, but it will cause output to be 
       ``packet-buffered'', so that the output is written to stdout at the 
       end of each packet rather than at the end of each line; this is 
       buffered on all platforms, including Windows.
36
Marcin

オプション-U-wと組み合わせて使用​​すると、tcpdumpがパケットをすぐに書き込みます。

7
Julius Junghans

Tcpdumpは、パイプに書き込むときに出力をバッファリングしているようです。書き込みごとに出力をフラッシュするわけではないため、システムは約4kバイトのチャンクで出力を書き込みます。フィルターが出力を制限しているため、フィルターが十分な出力を書き込むまで何も表示されません。十分に収集されると、チャンクに書き出され、いくつかの行が表示されるはずです。

DNSルックアップを何度もトリガーして、何が起こるかを確認してください。

3
Keith

パケットが利用可能になり次第、パケットを確認する必要があるtcpdumpのリアルタイム監視ラッパーを構築しています。 -lを使用しても、多少の遅延があります。

tcpdumpに--immediate-modeが追加され、この問題が解決されました。これを機能させるために、-lと組み合わせて使用​​しました。

この答え を参照してください。

2
anderspitman

expectにはunbufferコマンドがあり、コマンドがttyに書き込んでいると想定して、バッファリングしないようにします。

1
ninjalj