Wireshark provides a display filter language that enables you to precisely control which packets are displayed. They can be used to check for the presence of a protocol or field, the value of a field, or even compare two fields to each other. These comparisons can be combined with logical operators, like "and" and "or", and parentheses into complex expressions.
The following sections will go into the display filter functionality in more detail.
Tip | |
---|---|
There are many display filter examples on the Wireshark Wiki Display Filter page at: https://gitlab.com/wireshark/wireshark/wikis/DisplayFilters. |
The simplest display filter is one that displays a single protocol. To only display packets containing a particular protocol, type the protocol into Wireshark’s display filter toolbar. For example, to only display TCP packets, type tcp into Wireshark’s display filter toolbar. Similarly, to only display packets containing a particular field, type the field into Wireshark’s display filter toolbar. For example, to only display HTTP requests, type http.request into Wireshark’s display filter toolbar.
You can filter on any protocol that Wireshark supports. You can also filter on any field that a dissector adds to the tree view, if the dissector has added an abbreviation for that field. A full list of the available protocols and fields is available through the menu item
→ → .You can build display filters that compare values using a number of different
comparison operators. For example, to only display packets to or
from the IP address 192.168.0.1, use ip.addr==192.168.0.1
.
A complete list of available comparison operators is shown in Table 6.5, “Display Filter comparison operators”.
Tip | |
---|---|
English and C-like operators are interchangeable and can be mixed within a filter string. |
Table 6.5. Display Filter comparison operators
English | C-like | Description | Example |
---|---|---|---|
eq | == | Equal |
|
ne | != | Not equal |
|
gt | > | Greater than |
|
lt | < | Less than |
|
ge | >= | Greater than or equal to |
|
le | <= | Less than or equal to |
|
contains | Protocol, field or slice contains a value |
| |
matches | ~ | Protocol or text field matches a Perl-compatible regular expression |
|
bitwise_and | & | Bitwise AND is non-zero |
|
All protocol fields have a type. Display Filter Field Types provides a list of the types with examples of how to use them in display filters.
Display Filter Field Types
Can be 8, 16, 24, 32, or 64 bits. You can express integers in decimal, octal, or hexadecimal. The following display filters are equivalent:
ip.len le 1500
ip.len le 02734
ip.len le 0x5dc
Can be 1 (for true), or 0 (for false).
A Boolean field is present whether its value is true or false. For example,
tcp.flags.syn
is present in all TCP packets containing the flag, whether
the SYN flag is 0 or 1. To only match TCP packets with the SYN flag set, you need
to use tcp.flags.syn == 1
.
6 bytes separated by a colon (:), dot (.), or dash (-) with one or two bytes between separators:
eth.dst == ff:ff:ff:ff:ff:ff
eth.dst == ff-ff-ff-ff-ff-ff
eth.dst == ffff.ffff.ffff
ip.addr == 192.168.0.1
Classless InterDomain Routing (CIDR) notation can be used to test if an IPv4 address is in a certain subnet. For example, this display filter will find all packets in the 129.111 Class-B network:
ip.addr == 129.111.0.0/16
ipv6.addr == ::1
As with IPv4 addresses, IPv6 addresses can match a subnet.
http.request.uri == "https://www.wireshark.org/"
udp contains 81:60:03
The display filter above matches packets that contains the 3-byte sequence 0x81, 0x60, 0x03 anywhere in the UDP header or payload.
sip.To contains "a1762"
The display filter above matches packets where the SIP To-header contains the string "a1762" anywhere in the header.
http.host matches "acme\.(org|com|net)"
The display filter above matches HTTP packets where the HOST header contains acme.org, acme.com, or acme.net. Comparisons are case-insensitive.
tcp.flags & 0x02
That display filter will match all packets that contain the “tcp.flags” field with the 0x02 bit, i.e. the SYN bit, set.
You can combine filter expressions in Wireshark using the logical operators shown in Table 6.6, “Display Filter Logical Operations”
Table 6.6. Display Filter Logical Operations
English | C-like | Description | Example |
---|---|---|---|
and | && | Logical AND |
|
or | || | Logical OR |
|
xor | ^^ | Logical XOR |
|
not | ! | Logical NOT |
|
[…] | Subsequence | See “Slice Operator” below. | |
in | Set Membership | http.request.method in {"HEAD" "GET"}. See “Membership Operator” below. |
Wireshark allows you to select a subsequence of a sequence in rather elaborate ways. After a label you can place a pair of brackets [] containing a comma separated list of range specifiers.
eth.src[0:3] == 00:00:83
The example above uses the n:m format to specify a single range. In this case n is the beginning offset and m is the length of the range being specified.
eth.src[1-2] == 00:83
The example above uses the n-m format to specify a single range. In this case n is the beginning offset and m is the ending offset.
eth.src[:4] == 00:00:83:00
The example above uses the :m format, which takes everything from the beginning of a sequence to offset m. It is equivalent to 0:m
eth.src[4:] == 20:20
The example above uses the n: format, which takes everything from offset n to the end of the sequence.
eth.src[2] == 83
The example above uses the n format to specify a single range. In this case the element in the sequence at offset n is selected. This is equivalent to n:1.
eth.src[0:3,1-2,:4,4:,2] == 00:00:83:00:83:00:00:83:00:20:20:83
Wireshark allows you to string together single ranges in a comma separated list to form compound ranges as shown above.
Wireshark allows you to test a field for membership in a set of values or
fields. After the field name, use the in
operator followed by the set items
surrounded by braces {}. For example, to display packets with a TCP source or
destination port of 80, 443, or 8080, you can use tcp.port in {80 443 8080}
.
The set of values can also contain ranges: tcp.port in {443 4430..4434}
.
Note | |
---|---|
The display filter tcp.port in {80 443 8080} is equivalent to tcp.port == 80 || tcp.port == 443 || tcp.port == 8080 However, the display filter tcp.port in {443 4430..4434} is not equivalent to tcp.port == 443 || (tcp.port >= 4430 && tcp.port <= 4434) This is because comparison operators are satisfied when any field
matches the filter, so a packet with a source port of 56789 and
destination port of port 80 would also match the second filter
since |
Sets are not just limited to numbers, other types can be used as well:
http.request.method in {"HEAD" "GET"} 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}
The display filter language has a number of functions to convert fields, see Table 6.7, “Display Filter Functions”.
Table 6.7. Display Filter Functions
Function | Description |
---|---|
upper | Converts a string field to uppercase. |
lower | Converts a string field to lowercase. |
len | Returns the byte length of a string or bytes field. |
count | Returns the number of field occurrences in a frame. |
string | Converts a non-string field to a string. |
The upper
and lower
functions can used to force case-insensitive matches:
lower(http.server) contains "apache"
.
To find HTTP requests with long request URIs: len(http.request.uri) > 100
.
Note that the len
function yields the string length in bytes rather than
(multi-byte) characters.
Usually an IP frame has only two addresses (source and destination), but in case
of ICMP errors or tunneling, a single packet might contain even more addresses.
These packets can be found with count(ip.addr) > 2
.
The string
function converts a field value to a string, suitable for use with operators
like "matches" or "contains". Integer fields are converted to their decimal representation.
It can be used with IP/Ethernet addresses (as well as others), but not with string or
byte fields.
For example, to match odd frame numbers:
string(frame.number) matches "[13579]$"
To match IP addresses ending in 255 in a block of subnets (172.16 to 172.31):
string(ip.dst) matches "^172\.(1[6-9]|2[0-9]|3[0-1])\..{1,3}\.255"
Using the != operator on combined expressions like eth.addr
, ip.addr
,
tcp.port
, and udp.port
will probably not work as expected. Wireshark
will show the warning “"!=" may have unexpected results” when you use it.
People often use a filter string like ip.addr == 1.2.3.4
to display all packets containing the IP address 1.2.3.4.
Then they use ip.addr != 1.2.3.4
expecting to see all packets not containing the IP
address 1.2.3.4 in it. Unfortunately, this does not do the expected.
Instead, that expression will even be true for packets where either the source or
destination IP address equals 1.2.3.4. The reason for this is because the
expression ip.addr != 1.2.3.4
is read as “the packet contains a field
named ip.addr with a value different from 1.2.3.4”. As an IP datagram contains
both a source and a destination address, the expression will evaluate to true
whenever at least one of the two addresses differs from 1.2.3.4.
If you want to filter out all packets containing IP datagrams to or from IP
address 1.2.3.4, then the correct filter is !(ip.addr == 1.2.3.4)
as it is read
“show me all the packets for which it is not true that a field named ip.addr
exists with a value of 1.2.3.4”, or in other words, “filter out all packets
for which there are no occurrences of a field named ip.addr with the value
1.2.3.4”.
As protocols evolve they sometimes change names or are superseded by newer standards. For example, DHCP extends and has largely replaced BOOTP and TLS has replaced SSL. If a protocol dissector originally used the older names and fields for a protocol the Wireshark development team might update it to use the newer names and fields. In such cases they will add an alias from the old protocol name to the new one in order to make the transition easier.
For example, the DHCP dissector was originally developed for the BOOTP protocol but as of Wireshark 3.0 all of the “bootp” display filter fields have been renamed to their “dhcp” equivalents. You can still use the old filter names for the time being, e.g. “bootp.type” is equivalent to “dhcp.type” but Wireshark will show the warning “"bootp" is deprecated” when you use it. Support for the deprecated fields may be removed in the future.