NAME
wireshark-filter - Wireshark display filter 显示过滤器语法手册
SYNOPSIS
1 | wireshark [other options] [ -Y "display filter expression" | --display-filter "display filter expression" ] |
DESCRIPTION
Wireshark 和 TShark 共享一个强大的过滤引擎,有助于从数据包列表中去除“噪音”,只看到您感兴趣的数据包。如果一个数据包符合你的过滤器中表达的要求,那么它就会显示在数据包列表中。显示过滤器可让您将协议中的字段与特定值进行比较,将字段与字段进行比较,并检查指定字段或协议是否存在。
过滤器也被其他功能所使用,如统计数据的生成和数据包列表的着色(后者只对Wireshark有效)。本手册页描述了它们的语法。可以在 Wireshark 和 https://www.wireshark.org/docs/dfref/ 的显示过滤器参考中找到过滤器字段的全部参考文档。
FILTER 语法
判断一个字段或者协议是否存在
最简单的过滤器允许您检查协议或字段是否存在。如果您想查看所有包含 IP 协议的数据包,过滤器将是 ip
。要查看包含 Token-Ring RIF 字段的所有数据包,请使用 tr.rif
。
每当一个协议或字段作为过滤器中一个函数的参数出现时,该协议或字段的存在运算符就会隐含地出现。即该参数表示对应的协议或字段是否存在。
值和运算符
每个字段都有一个值,该值可用于具有可比性的操作(可能是字面值、其他字段或函数结果)。字段的值不一定在 Wireshark 中显示或在 TShark 的输出中。例如,一个协议在语义上等同于它所跨越的字节序列,而不是它在协议树中显示的文本。
比较运算符
比较运算符可以通过类似英语的缩写或类似 C 的符号来表示:
1 | eq, == 相等 |
比较通常取决于值类型(例如,字符串的字典序和整数的算术。)一个字段可能在给定的帧中出现不止一次。在这种情况下,运算符是严格的,比如相等,则所有字段必须匹配条件,或不相等,任何字段都不匹配条件。不等式是等式的逻辑否定。下表包含所有相等运算符,它们的别名和含义:
1 | eq, any_eq, == Any field must be equal 任何字段都相等 |
运算符 any
或 all
可以与任何比较运算符一起使用,以使测试匹配任何或所有字段:
1 | all tcp.port > 1024 |
any
或 all
修饰符优先于比较运算符,例如 ===
和 any_eq
。
搜索和匹配运算符
其他运算符仅以英语表示,而不是类似 C 的语法:
1 | contains 协议、字段或切片是否包含某值 |
contains
运算符允许过滤器搜索以字符串表示的字符序列或以字节数组表示的字节。在任何隐式或显式转换之后,contains
运算符左侧的类型必须与右侧的类型相当。
例如,要在捕获中搜索给定的 HTTP URL,可以使用以下过滤器:
1 | http contains "https://www.wireshark.org" |
contains
运算符不能用于原子字段,例如数字或 IP 地址。
matches
或 ~
运算符允许过滤器应用于指定的 Perl 兼容正则表达式 (PCRE2)。正则表达式必须是双引号字符串。matches
运算符的左侧必须是字符串,可以是非字符串字段,可以隐式或显式转换为字符串。默认情况下,matches
不区分大小写。例如,要搜索给定的 WAP WSP User-Agent,您可以编写:
1 | wsp.header.user_agent matches "cldc" |
这将匹配 cldc、CLDC、cLdC 或任何其他大小写字母组合。
您可以使用强制区分大小写
1 | wsp.header.user_agent matches "(?-i)cldc" |
这是 PCRE2 的 (?option)
构造的一个示例。 (?-i)
执行区分大小写的模式匹配,但也可以指定其他选项。更多信息可以在 https://www.pcre.org/current/doc/html/pcre2pattern.html 手册页中找到。
Functions 函数
过滤器语言具有以下函数:
1 | upper(string-field) - 将参数(字符串字段)转为大写 |
upper()
和 lower()
可用于执行不区分大小写的字符串比较。例如:
1 | upper(ncp.nds_stream_name) contains "MACRO" |
string()
将字段值转换为字符串,适合与 matches
或 contains
等运算符一起使用。整数字段被转换为其十进制表示。它可以与 IP/Ethernet 地址(以及其他地址)一起使用,但不能与字符串或字节字段一起使用。例如:
1 | string(frame.number) matches "[13579]$" |
可以得到所有的序号为奇数的包。
max()
和 min()
接受任意数量的参数并返回一个值,分别为最大/最小。参数必须都具有相同的类型。
Protocol field types 协议字段类型
每个协议字段都有类型。类型有:
1 | ASN.1 object identifier, plain or relative |
整数可以用十进制、八进制、十六进制或二进制表示法表示,也可以表示为 C 风格的字符常量。以下七个显示过滤器是等效的:
1 | frame.len > 10 |
Boolean 布尔值表示真或假。在使用布尔字段值的显示过滤器表达式中,真 表示为单词 True 或 TRUE 或任何非零数字。 假 表示为 False 或 FALSE 或数字零。例如,token-ring 数据包的 source route 字段是布尔值。要查找任何 source route 为 真 的数据包,显示过滤器将是以下任何一种:
1 | tr.sr == 1 |
反之则是:
1 | tr.sr == 0 |
Ethernet 以太网地址和字节数组由十六进制数字表示。十六进制数字可以用冒号、句点或连字符分隔:
1 | eth.dst eq ff:ff:ff:ff:ff:ff |
IPv4 地址可以用点分十进制表示法或使用主机名表示:
1 | ip.src == 192.168.1.1 |
IPv4 地址可以用与数字相同的逻辑关系进行比较:eq、ne、gt、ge、lt 和 le。IPv4 地址按主机顺序存储,因此在显示过滤器中使用 IPv4 地址时不必担心它的字节顺序。
无类域间路由 (CIDR) 表示法可用于测试 IPv4 地址是否在某个子网中。例如,此显示过滤器将查找 129.111 网络中的所有数据包:
1 | ip.addr == 129.111.0.0/16 |
斜线后面的数字表示用于表示网络的位数。 CIDR 表示法也可以与主机名一起使用,例如在与 sneezy 相同的网络上查找 IP 地址的示例中(要求 sneezy 解析为 IP 地址以使过滤器有效):
1 | ip.addr eq sneezy/24 |
CIDR 表示法只能用于 IP 地址或主机名,不能用于变量名。因此,像 ip.src/24 == ip.dst/24
这样的显示过滤器无效。
Transaction 和其他 ID 通常由无符号 16 或 32 位整数表示,并格式化为带有“0x”前缀的十六进制字符串:
1 | (dhcp.id == 0xfe089c15) || (ip.id == 0x0373) |
字符串要用双引号括起来:
1 | http.request.method == "POST" |
在双引号内,您可以使用反斜杠嵌入双引号或以八进制或十六进制表示的任意字节。
1 | browser.comment == "An embedded \" double-quote" |
使用十六进制查找 “HEAD”:
1 | http.request.method == "\x48EAD" |
使用八进制查找“HEAD”:
1 | http.request.method == "\110EAD" |
这意味着您必须在双引号内使用反斜杠转义反斜杠。
1 | smb.path contains "\\\\SERVER\\SHARE" |
在 smb.path
中查找 ``\SERVER\SHARE`。这可以更方便地写成
1 | smb.path contains r"\\SERVER\SHARE" |
以 ‘r’ 为前缀的字符串文字称为“原始字符串”。此类字符串将反斜杠视为文字字符。双引号仍然可以用反斜杠转义,但请注意反斜杠始终保留在结果中。
下表列出了字符串和字符常量支持的所有转义序列:
1 | \' single quote |
日期和时间值可以采用 ISO 8601 格式或使用传统的格式:
1 | "2020-07-04T12:34:56" |
ISO 8601 中的“T”分隔符可以省略。 ISO 8601 支持时区指示符为 UTC 或与 UTC 的偏移量。传统格式可以在末尾附加值“UTC”以指定协调世界时的时间。否则,日期和时间值将被解释为本地时间。
The slice operator 切片运算符
如果字段是文本字符串或字节数组,您可以获取字段的切片。例如,您可以过滤以太网地址的 vendor 部分(前三个字节),如下所示:
1 | eth.src[0:3] == 00:00:83 |
另一个例子是:
1 | http.content_type[0:4] == "text" |
您也可以在协议名称上使用切片运算符。 frame
协议可能很有用,它包含 Wireshark 或 TShark 捕获的一个数据包的所有数据。
1 | token[0:5] ne 0.0.0.1.1 |
以下是切片语法:
1 | [i:j] i = start_offset, j = length |
Offsets 可以是负数,在这种情况下,它们表示距字段末尾的偏移量。倒数第一个字节的偏移量是 -1,倒数第二个字节的偏移量是 -2,依此类推。以下是检查帧的最后四个字节的方法:
1 | frame[-4:4] == 0.1.2.3 |
切片可以与字符串或字节序列进行比较。上面 0.1.2.3
是字节序列的一种十六进制表示方法,还可以等价写为 0:1:2:3
0-1-2-3
。
切片可以组合。您可以使用逗号运算符连接它们:
1 | ftp[1,3-5,9:] == 01:03:04:05:09:0a:0b |
这会将偏移量 1、偏移量 3-5 和偏移量 9 到末尾 的数据连接在一起。
The layer operator 层运算符
可以使用层运算符 (#) 将字段限制到协议栈中的某个层,后跟一个十进制数:
1 | ip.addr#2 == 192.168.30.40 |
仅匹配数据包中的内(第二)层。层使用简单的堆叠语义,协议层从 1 开始顺序计数。例如,在包含两个 IPv4 标头的数据包中,外部(第一层)源地址可以与“ip.src#1”匹配,内部(第二层)源地址可以匹配“ip.src#2”。
对于更复杂的范围,切片的语法是有效的:
1 | tcp.port#[2-4] |
表示第 2、3 或 4 层(含)。注意需要使用中括号。
The membership operator 成员关系运算符
可以简单地使用 in 运算符检查字段是在一组值中。例如,您可能会使用以下过滤器在常见的 HTTP/HTTPS 端口上找到流量:
1 | tcp.port in {80,443,8080} |
而不是使用更冗长的格式:
1 | tcp.port == 80 or tcp.port == 443 or tcp.port == 8080 |
查找 HEAD 或 GET 方法的 HTTP 请求:
1 | http.request.method in {"HEAD", "GET"} |
值集还可以包含范围:
1 | tcp.port in {443, 4430..4434} |
Implicit type conversions 隐式类型转换
作为字节序列的字段(包括协议)被隐式转换为字符串,以便与(双引号)文字字符串和原始字符串进行比较。
因此,例如,以下过滤器是等效的:
1 | tcp.payload contains "GET" |
如上所述,切片也可以通过任何一种方式进行比较:
1 | frame[60:2] gt 50.51 |
不会发生相反的情况;类字符串字段不会隐式转换为字节数组。(一些运算符允许将类字符串的字段与不带引号的文字进行比较,然后将其视为字符串;这通常不推荐使用,并且 matches 运算符特别不允许。为清楚起见,文字字符串应使用双引号。)
0xff 或更小的十六进制整数(这意味着它适合一个字节)可以隐式转换为字节字符串。这对于大于一个字节的十六进制整数是不允许的,因为这样需要指定多字节整数的字节顺序(端序)。此外,十进制或八进制数也不允许这样做,因为它们会与构成字节字符串文字的十六进制数字混淆。然而,单字节十六进制整数可能很方便:
1 | frame[4] == 0xff |
Bitwise operators 位运算符
也可以使用按位运算定义测试。目前支持以下位运算符:
1 | bitwise_and, & Bitwise AND |
按位 AND 运算允许屏蔽位并测试是否设置了一个或多个位。按位 AND 对整数协议字段和切片进行操作。
在测试 TCP SYN 数据包时,您可以编写:
1 | tcp.flags & 0x02 |
该表达式将匹配所有包含 tcp.flags
字段且设置了 0x02
位(即 SYN 位)的数据包。
要匹配本地管理的单播以太网地址,您可以使用:
1 | eth.addr[0] & 0x0f == 2 |
使用切片时,位掩码必须指定为字节字符串,并且它必须具有与切片本身相同的字节数,如下所示:
1 | ip[42:2] & 40:ff |
Arithmetic operators 算术运算符
通常的运算符术表达式:
1 | + Addition |
例如,可以使用如下表达式过滤大于或等于源端口加 1 的 UDP 目标端口:
1 | udp.dstport >= udp.srcport + 1 |
可以使用大括号对算术表达式进行分组(注意!!括号不适用于此):
1 | tcp.dstport >= 4 * {tcp.srcport + 3} |
不要将大括号的这种用法与集合成员资格混淆。
注意!!过滤器语法中的一个不幸的怪癖是减法运算符必须以空格字符开头,因此 A-B
必须写为 A -B
或 A - B
。
Protocol field references 协议字段引用
使用 ${some.proto.field}
形式的变量称为字段引用。字段引用是从 GUI 中当前选定的帧中读取的字段值。这对于构建动态过滤器很有用,例如从最后五分钟到所选帧的帧:
1 | frame.time_relative >= ${frame.time_relative} - 300 |
字段引用与宏共享类似的符号,但在过滤器语言中是不同的语法元素。
Logical expressions 逻辑表达式
可以使用逻辑表达式组合测试。这些也可以用类似 C 的语法或类似英语的缩写来表达。下表列出了从最高到最低优先级的逻辑运算符:
1 | not, ! Logical NOT (right-associative) |
计算总是从左到右进行。表达式也可以按括号分组。表达式 A and B or not C or D and not E or F
被解释为:
1 | (A and B) or (not C) or (D and (not E)) or F |
通常最好明确地使用括号进行分组。以下都是有效的显示过滤器表达式:
1 | tcp.port == 80 and ip.src == 192.168.2.1 |
请记住,每当表达式中出现协议或字段名称时,都会隐式调用 exists
运算符。 exists
运算符具有最高优先级。这意味着第一个过滤器表达式必须被读作“显示 tcp.port 存在且等于 80 且 ip.src 存在且等于 192.168.2.1 的数据包”。第二个过滤器表达式的意思是“显示不存在 llc 的数据包”,因此将匹配所有不包含 llc 协议的数据包。第三个过滤器表达式包含偏移量 199 必须存在的约束,也就是说帧长度最少也是 200。
每个 比较 对任何字段值都有一个隐式 存在 测试。使用显示过滤器从数据包列表中去除不需要的数据包时必须小心。例如,你想过滤掉所有发送到 224.1.2.3 地址的 IP 组播数据包,使用如下表达式可能过于严格:
1 | ip.dst ne 224.1.2.3 |
这和下面的写法一样:
1 | ip.dst and ip.dst ne 224.1.2.3 |
过滤器仅选择具有 ip.dst
字段的帧。不会显示任何其他帧,包括所有非 IP 数据包。要同时显示非 IP 数据包,您可以使用以下两个表达式之一:
1 | not ip.dst or ip.dst ne 224.1.2.3 |
第一个过滤器使用 not ip.dst
来包含所有非 IP 数据包,然后让 ip.dst ne 224.1.2.3
过滤掉不需要的 IP 数据包。第二个过滤器也否定隐式存在测试,因此是第一个过滤器更短的方法。
FILTER FIELD REFERENCE 过滤器字段参考
显示过滤器的整个列表太大,无法在此处列出。您可以在以下位置找到参考资料和示例:
- 在线显示过滤器参考:https://www.wireshark.org/docs/dfref/
- View:Internals:Supported Protocols in Wireshark
- tshark -G fields on the command line
- The Wireshark wiki: https://gitlab.com/wireshark/wireshark/-/wikis/DisplayFilters
NOTES
The wireshark-filter(4) manpage is part of the Wireshark distribution. The latest version of Wireshark can be found at https://www.wireshark.org.
Regular expressions in the “matches” operator are provided by the PCRE2 library. See https://www.pcre.org/ for more information.
This manpage does not describe the capture filter syntax, which is different. See the manual page of pcap-filter(7) or, if that doesn’t exist, tcpdump(8), or, if that doesn’t exist, https://gitlab.com/wireshark/wireshark/-/wikis/CaptureFilters for a description of capture filters.
Display Filters are also described in the User’s Guide: https://www.wireshark.org/docs/wsug_html_chunked/ChWorkBuildDisplayFilterSection.html
SEE ALSO
wireshark(1), tshark(1), editcap(1), pcap(3), pcap-filter(7) or tcpdump(8) if it doesn’t exist.
AUTHORS
See the list of authors in the Wireshark man page for a list of authors of that code.