必要に迫られて翻訳した、wireshark-3.4.10 付属の wireshark-filter(4) の和訳です。
名前
wireshark-filter – Wireshark の表示フィルター文法とリファレンス
書式
wireshark [その他のオプション]
[ -Y “表示フィルターの式” | b<–display-filter “表示フィルターの式”> ]
tshark [その他のオプション] [ -Y “表示フィルターの式” ]
説明
WiresharkとTSharkは、パケットトレースからノイズを除去し、興味のあるパケットだけを見ることができる強力なフィルターエンジンを共有しています。 パケットがフィルタで指定した条件を満たしている場合、そのパケットはパケットリストに表示されます。 表示フィルターでは、プロトコル内のフィールドを特定の値と比較したり、フィールドとフィールドを比較したり、指定したフィールドやプロトコルの存在を確認したりすることができます。
フィルタは統計情報の生成やパケットリストの色分けなど、他の機能でも使用されます(後者はWiresharkでのみ使用可能)。このマニュアルページでは、フィルタのシンタックスについて説明します。フィルタフィールドの包括的なリファレンスは、Wireshark内と<https://www.wireshark.org/docs/dfref/>にある display filter reference にあります。
フィルターの文法
フィールドやプロトコルが存在するかチェックする
最も単純なフィルターでは、プロトコルやフィールドの存在をチェックすることができます。 IPプロトコルを含むすべてのパケットを見たい場合、フィルタは “ip”(引用符なし)となります。Token-Ring RIFフィールドを含むすべてのパケットを見るには、”tr.rif “を使います。
フィルター中のプロトコルやフィールドは、暗黙のうちに “exists “演算子を持っていると考えてください。
比較演算子
フィールドは値と比較することもできます。 比較演算子は英語のような省略形か、C言語のような記号で表すことができます:
eq, == | 等しい |
ne, != | 等しくない |
gt, > | より大きい |
lt, < | より小さい |
ge, >= | より大きいか等しい |
le, <= | より小さいか等しい |
検索演算子とマッチ演算子
Cのような構文ではなく、英語だけで表現される演算子もあります:
contains | プロトコル、フィールド、スライスに値が含まれているか。 |
matches, ~ | プロトコルやテキスト文字列が、指定されたPerl 互換の正規表現(大文字小文字を区別しない)にマッチするか。 |
contains “演算子では、文字列(引用符で囲む/囲まない)、バイト配列、またはCスタイルの文字定数として表現される1文字のシーケンスを検索するフィルタを使えます。 例えば、キャプチャ内の指定されたHTTP URLを検索するには、次のようなフィルタを使うことができます:
http contains "https://www.wireshark.org"
contains “演算子は、数値やIPアドレスのようなアトミックフィールドには使えません。
“matches” または “~” 演算子は、指定されたPerl互換正規表現(PCRE)にフィルタを適用させます。 matches “演算子はプロトコルとテキスト文字列表現を持つプロトコルフィールドにのみ実装されています。マッチはデフォルトでは大文字小文字を区別しません。 例えば、指定されたWAP WSP User-Agentを検索するには、次のように記述します:
wsp.user_agent matches "cldc"
これは、”cldc”、”CLDC”、”cLdC”、またはその他の大文字と小文字の組み合わせにマッチします。
大文字と小文字を区別するには、以下のようにします:
wsp.user_agent matches "(?-i)cldc"
これは PCRE の (?option) 構文の例です。(?-i) は大文字小文字を区別してパターンマッチを行いますが、他のオプションを指定することもできます。詳細は pcrepattern(3) man page (<https://perldoc.perl.org/perlre.html>) を参照してください。
関数
フィルター言語には以下の関数があります:
upper(string-field) | 文字列フィールドを大文字に変換する。 |
lower(string-field) | 文字列フィールドを小文字に変換する。 |
len(field) | 文字列またはバイト・フィールドのバイト長を返す。 |
count(field) | フレーム内のフィールドの出現回数を返す。 |
string(field) | 非文字列フィールドを文字列に変換する。 |
upper() および lower() は、大文字小文字を区別しない文字列比較を行う際に便利です。例えば以下のように書けます。
upper(ncp.nds_stream_name) contains "MACRO"
lower(mount.dump.hostname) == "angel"
string()は、フィールド値を文字列に変換します。”matches” や “contains” といった演算子で使用するのに適しています。整数フィールドは10進数表現に変換されます。 これは、IP/Ethernetアドレス(およびその他)に対して使用できますが、文字列フィールドやバイトフィールドに対しては使用できません。例えば
string(frame.number) matches "[13579]$"
は、奇数番目のパケットをすべて返します。
プロトコル・フィールドの型
各プロトコル・フィールドには、以下の通り型があります:
- ASN.1オブジェクト識別子
- ブール
- 文字列
- コンパイル済みのPerl互換正規表現(GRegex)オブジェクト
- 日付と時刻
- イーサネットまたはその他のMACアドレス
- EUI64アドレス
- 浮動小数点(単精度)
- 浮動小数点(倍精度)
- フレーム番号
- グローバルに一意の識別子
- IPv4アドレス
- IPv6アドレス
- IPXネットワーク番号
- ラベル
- プロトコル
- バイト列
- 符号付き整数、1、2、3、4、または8バイト
- 時間オフセット
- 符号なし整数、1、2、3、4、または8バイト
- 1バイトASCII文字
整数は、10進数、8進数、16進数、またはCスタイルの文字定数で表すことができます。 以下の6つの表示フィルタは等価です:
frame.pkt_len > 10
frame.pkt_len > 012
frame.pkt_len > 0xa
frame.pkt_len > '\n'
frame.pkt_len > '\xa'
frame.pkt_len > '\012'
ブール値は真か偽のどちらかです。 ブール値フィールドの値をテストする表示フィルター式では、”true “は1または他のゼロでない値として表現され、”false “はゼロとして表現されます。 ソースルートされたパケットを見つけるための表示フィルタは次のようになります:
tr.sr == 1
ソースルートされていないパケットを見つけるには、次のようにします:
tr.sr == 0
イーサネットアドレスとバイト配列は16進数で表されます。 16進数は、コロン、ピリオド、またはハイフンで区切ることができます:
eth.dst eq ff:ff:ff:ff:ff:ff
aim.data == 0.1.0.d
fddi.src == aa-aa-aa-aa-aa-aa
echo.data == 7a
IPv4アドレスは、ドット付き10進表記かホスト名で表すことができます:
ip.dst eq www.mit.edu
ip.src == 192.168.1.1
IPv4アドレスは数字と同じ論理演算子 eq、ne、gt、ge、lt、le で比較できます。 IPv4アドレスはホスト順に格納されるため、IPv4アドレスを表示フィルタで使用する際にエンディアンを気にする必要はありません。
クラスレス・インタードメイン・ルーティング(CIDR)表記は、IPv4アドレスが特定のサブネットにあるかどうかをテストするために使うことができます。 例えば、この表示フィルタは、129.111 という Class-Bネットワーク内のすべてのパケットを検出します:
ip.addr == 129.111.0.0/16
覚えておいてほしいのは、スラッシュの後の数字は、ネットワークを表すのに使われるビット数を表しているということです。 CIDR表記は、「sneezy」と同じクラスCネットワーク上のIPアドレスを見つけるこの例のように、ホスト名でも使うことができます:
ip.addr eq sneezy/24
CIDR記法はIPアドレスまたはホスト名にのみ使用でき、変数名には使用できません。 したがって、”ip.src/24 == ip.dst/24 “のような表示フィルタは(まだ)有効ではありません。
IPXネットワークは符号なし32ビット整数で表現されます。 IPXネットワークの値をテストする場合、16進数を使用することがほとんどでしょう:
ipx.src.net == 0xc0a82c00
文字列は二重引用符で囲みます:
http.request.method == "POST"
二重引用符の中でバックスラッシュを使用すると、二重引用符または8進数または16進数で表される任意のバイトを埋め込むことができます。
browser.comment == "An embedded \" double-quote"
16進数を使って “HEAD “を探す:
http.request.method == "\x48EAD"
8進数を使って “HEAD “を探す:
http.request.method == "\110EAD"
以下の例では、バックスラッシュを二重引用符の中のバックスラッシュでエスケープしなければならないことを意味しています。
smb.path contains “\\\\SERVER\\SHARE”
は、”smb.path” で “\\SERVER\SHARE を探します。
スライス演算子
フィールドがテキスト文字列あるいはバイト配列の場合は、 フィールドのスライスを取ることができます。 例えば、以下のようにイーサネットアドレスのベンダ部分(最初の3バイト)をフィルタリングすることができます:
eth.src[0:3] == 00:00:83
その他の例:
http.content_type[0:4]=="テキスト"
スライス演算子はプロトコル名にも使えます。 frame “プロトコルは、WiresharkやTSharkでキャプチャされたすべてのデータを包含する便利なものです。
token[0:5] ne 0.0.0.1.1
llc[0] eq aa
frame[100-199] contains "wireshark"
スライスの構文は以下の通りです:
[i:j] i = 開始オフセット, j = 長さ
[i-j] i = 開始オフセット, j = 終了オフセット, 包括指定.
[i] i = 開始オフセット, 長さ = 1
[:j] 開始オフセット = 0, 長さ = j
[i:] 開始オフセット = i, 終了オフセット = フィールドの終わり
オフセットは負にすることもでき、その場合はフィールドの終わりからのオフセットを示します。 フィールドの最後のバイトはオフセット-1、最後から1バイトはオフセット-2、といった具合です。 以下は、フレームの最後の4バイトをチェックする方法です:
frame[-4:4] == 0.1.2.3 または
frame[-4:] == 0.1.2.3
スライスは常に文字列またはバイト列と比較されます。特殊なケースとして、スライスの幅が1バイトしかない場合は、0xff以下の16進整数(つまり1バイト内に収まる)と比較できます。これは、1バイトを超えるバイト列では許されません。なぜなら、この場合マルチバイト整数のエンディアンを指定する必要があるからです。また10進数には使えません。これは、すでにバイト列として認められている16進数と混同してしまうからです。とはいえ、シングルバイトの16進数は便利です:
frame[4] == 0xff
スライスは、カンマ演算子を使って連結することができます:
ftp[1,3-5,9:] == 01:03:04:05:09:0a:0b
これは、オフセット1、オフセット3~5、オフセット9をftpデータの最後に連結(追加)します。
メンバーシップ演算子
フィールドが値の集合にマッチするかどうかを調べるには、単純に メンバーシップ演算子を使います。例えば、以下のようなフィルタで一般的なHTTP/HTTPSポートのトラフィックを見つけることができます:
tcp.port in {80 443 8080}
これをより冗長に指定した場合は以下のようになります:
tcp.port == 80 or tcp.port == 443 or tcp.port == 8080
HEADまたはGETメソッドを使ったHTTPリクエストを見つける:
http.request.method in {"HEAD" "GET"}
値のセットに範囲を含めることもできます:
tcp.port in {443 4430..4434}
ip.addr in {10.0.0.5 .. 10.0.0.9 192.168.1.1..192.168.1.9}
frame.time_delta in {10 .. 10.5}
型変換
フィールドがテキスト文字列またはバイト配列の場合、最も便利な方法で表現することができます。
したがって、例えば以下のフィルタは等価です:
http.request.method == "GET"
http.request.method == 47.45.54
また、範囲はどちらでも表現できます:
frame[60:2] gt 50.51
frame[60:2] gt "PQ"
ビットフィールド演算
ビットフィールド演算を用いたテストを定義することも可能す。現在、以下のビットフィールド演算がサポートされています:
bitwise_and, & | ビットごとの AND |
ビット単位のAND演算は、1つ以上のビットがセットされているかどうかをテストすることができます。 ビット単位のANDは、整数のプロトコルフィールドとスライスに作用します。
TCP SYNパケットをテストする場合、次のように書くことができます:
tcp.flags & 0x02
この式は、”tcp.flags “フィールドに0x02ビット、つまりSYNビットが設定されているパケットすべてにマッチします。
同様に、すべてのWSP GETメソッドと拡張GETメソッドのフィルタリングは、次のようにして行います:
wsp.pdu_type & 0x40
スライスを使用する場合、ビットマスクはバイト文字列として指定されなければならず、以下のようにスライス自身と同じバイト数でなければなりません:
ip[42:2] & 40:ff
論理式
テストは論理式を使って組み合わせることができます。 これらもC言語ライクな構文や英語ライクな略語で表現できます:
and, && | 論理 AND |
or, || | 論理 OR |
not, ! | 論理 NOT |
式は括弧でグループ化することもできます。 以下はすべて有効な表示フィルター式です:
tcp.port == 80 and ip.src == 192.168.2.1
not llc
http and frame[100-199] contains "wireshark"
(ipx.src.net == 0xbad && ipx.src.node == 0.0.0.0.0.1) || ip
式中にプロトコル名やフィールド名が出現するときはいつでも、暗黙のうちに “exists” 演算子が呼び出されることを覚えておいてください。 “exists” 演算子が最も高い優先度を持ちます。つまり、最初のフィルター式は、「tcp.portが存在し、かつそれが80に等しく、かつip.srcが存在し、かつそれが192.168.2.1に等しいパケットを表示してください」と読み取られなければなりません。
2番目のフィルター表現は、「(not (llc exists)を満たす)パケットを表示する」、言い換えれば「llcが存在しない」パケットと、つまりllcプロトコルを含まないすべてのパケットにマッチします。
3番目のフィルター式は、フレームのオフセット199が存在するという制約条件を含む、言い換えれば「少なくともフレームが200オクテットの長さを持つ」ということになります。
パケットごとに複数回出現するフィールドに関しては、特別な注意が必要です。 “ip.addr”はIPパケットごとに2回(送信元アドレスに1回、宛先アドレスに1回)出現します。 同様に、”tr.rif.ring”フィールドは、パケットごとに2回以上出現する可能性があります。 以下の2つの表現は等価ではありません:
ip.addr ne 192.168.4.1
not ip.addr eq 192.168.4.1
最初のフィルターは、「ip.addrが存在し、かつそれが192.168.4.1と等しくないパケットを表示する」という意味です。 つまりパケット中の1つのip.addrが192.168.4.1に等しくない限り、そのパケットは表示フィルタを通過(表示)します。他のip.addrが192.168.4.1に等しくても、パケットは表示されます。 2つ目のフィルタは、「ip.addrフィールドが192.168.4.1に等しいパケットを表示するな」というものです。片方のip.addrが192.168.4.1の場合、パケットは通過しません。どちらのip.addrフィールドも192.168.4.1でなければ、そのパケットは表示されます。
「ne」と「eq」演算子は、複数回繰り返されるフィールドを扱うときに、暗黙の「exists」修飾子を持っていると考えるとよいでしょう。”ip.addr ne 192.168.4.1″ は「192.168.4.1と等しくないip.addrが存在する」と考えることができます。一方 “not ip.addr eq 192.168.4.1” は、「192.168.4.1に等しいip.addrが存在しない」と考えることができます。
複数回繰り返されるフィールドには注意が必要です。これはしばしば混乱を引き起こします。
パケットトレースからノイズを削除するために表示フィルターを使う場合にも注意が必要です。例えば、アドレス224.1.2.3へのすべてのIPマルチキャストパケットをフィルタアウト(=表示しない)したい場合、:
ip.dst ne 224.1.2.3
のようにするのは制限が多すぎるかもしれません。”ip.dst”を使ったフィルタリングは、ルールを満たすIPパケットだけを選択します。IP以外のパケットも含め、それ以外のパケットは表示されません。非IPパケットも表示するには、次の2つの式のどちらかを使います:
not ip or ip.dst ne 224.1.2.3
not ip.addr eq 224.1.2.3
最初のフィルタは、”not ip”を使ってすべての非IPパケットを含め、”ip.dst ne 224.1.2.3″で不要なIPパケットをフィルタリングします。二つ目のフィルターは、既に上で説明したように、多重に発生するフィールドを使ったフィルタリングについて述べたものです。
フィルターフィールドリファレンス
表示フィルターの全リストは、ここでは紹介しきれません。以下の場所でリファレンスと例を見つけることができます:
- オンライン・ディスプレイ・フィルター・リファレンス:<https://www.wireshark.org/docs/dfref/>
- View:Internals:Wiresharkでサポートされているプロトコル
- コマンドラインの “tshark -G フィールド”
- Wireshark wiki:<https://gitlab.com/wireshark/wireshark/-/wikis/DisplayFilters>
注意事項
wireshark-filters man ページは Wireshark ディストリビューションの一部です。Wiresharkの最新バージョンは<https://www.wireshark.org>にあります。
matches” 演算子の正規表現は GLib の GRegex で提供されています。 以下を参照してください。
<https://developer.gnome.org/glib/2.32/glib-regex-syntax.html> または <https://www.pcre.org/> を参照してください。
このマニュアルページでは、キャプチャフィルタの構文については説明していません。キャプチャフィルタの説明については、 pcap-filter(7) のマニュアルページか、それが存在しない場合は tcpdump(8) を、それが存在しない場合は <https://gitlab.com/wireshark/wireshark/-/wikis/CaptureFilters> を参照してください。
ディスプレイフィルタについては、ユーザーズガイドにも記述されています: <https://www.wireshark.org/docs/wsug_html_chunked/ChWorkBuildDisplayFilterSection.html>
参照
wireshark(1), tshark(1), editcap(1), pcap(3), pcap-filter(7) または、これが存在しない場合はtcpdump(8)。
作者
そのコードの作者のリストについては、Wireshark man pageの作者リストを参照のこと。
3.4.10 2023-01-20 WIRESHARK-FILTER(4)