クライアント(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番目の列のみが出力されます)
これに対する解決策はありますか?
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.
オプション-U
を-w
と組み合わせて使用すると、tcpdumpがパケットをすぐに書き込みます。
Tcpdumpは、パイプに書き込むときに出力をバッファリングしているようです。書き込みごとに出力をフラッシュするわけではないため、システムは約4kバイトのチャンクで出力を書き込みます。フィルターが出力を制限しているため、フィルターが十分な出力を書き込むまで何も表示されません。十分に収集されると、チャンクに書き出され、いくつかの行が表示されるはずです。
DNSルックアップを何度もトリガーして、何が起こるかを確認してください。
パケットが利用可能になり次第、パケットを確認する必要があるtcpdumpのリアルタイム監視ラッパーを構築しています。 -l
を使用しても、多少の遅延があります。
tcpdumpに--immediate-mode
が追加され、この問題が解決されました。これを機能させるために、-l
と組み合わせて使用しました。
この答え を参照してください。
expect
にはunbuffer
コマンドがあり、コマンドがttyに書き込んでいると想定して、バッファリングしないようにします。