web-dev-qa-db-ja.com

tcpdumpでtcpパケットのペイロード長をフィルタリングする

greaterフィルタは、パケットを全長でフィルタリングします。ペイロードの長さでフィルタリングすることは可能ですか?これはディスプレイフィルターとして可能であることは知っていますが、キャプチャフィルターでこれを行うことができるかどうか疑問に思いました。

1
Simon Shkolnik

これを行う方法は、IPv4の場合、 tcpdump のマニュアルに例として示されているalmostです。場合:

ポート80との間で送受信されるすべてのIPv4HTTPパケットを印刷します。つまり、データを含むパケットのみを印刷します。たとえば、SYNパケットとFINパケット、およびACKのみのパケットは印刷しません。 (IPv6は、読者の演習として残されています。)

tcpdump 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'

tcpdumpの式は次のようにコンパイルされます [〜#〜] bpf [〜#〜]バイトコード (オプション-dtcpdumpに追加して、どのように表示されるかを確認してください)。これにより、ポインターを逆参照し、ポインターに対して算術演算とビット演算を実行できます。

上記のtcp一致とtcp[]逆参照では、TCPペイロードサイズを単純にフィルタリングすることはできません。したがって、次のフィルタは合計に差し引かれます IPv4パケット長 (変数) IPヘッダー長 残りの TCPセグメント 長さを取得し、結果から TCPセグメント を減算しますデータオフセット(したがって、TCPセグメントヘッダー+オプションの長さ)を削除します。残りの値がゼロ以外の場合、ペイロードにデータがあることを意味します。

したがって、たとえば、IPv4パケットをeth0インターフェイスで4〜6バイトのTCPデータペイロードと一致させるには、これは:

tcpdump -n -s0 -p -i eth0 'ip and tcp and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) >= 4) and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) <= 6)'

コンパイルされたバイトコード(ここでも、-dオプションを追加することで表示できます)が最適化され、結果(ここでは、Linux、tcpdump4.9.3およびlibpcap1.8.3)があと1行だけかかることを心配しないでください。繰り返しにもかかわらず、2番目の比較を追加するバイトコード。

1
A.B