6.4. Building display filter expressions

Wireshark provides a simple but powerful display filter language that allows you to build quite complex filter expressions. You can compare values in packets as well as combine expressions into more specific expressions. The following sections provide more information on doing this.

[Tip]Tip

You will find a lot of Display Filter examples at the Wireshark Wiki Display Filter page at: https://wiki.wireshark.org/DisplayFilters.

6.4.1. Display filter fields

Every field in the packet details pane can be used as a filter string, this will result in showing only the packets where this field exists. For example: the filter string: tcp will show all packets containing the tcp protocol.

There is a complete list of all filter fields available through the menu item HelpSupported Protocols in the page “Display Filter Fields” of the “Supported Protocols” dialog.

6.4.2. Comparing values

You can build display filters that compare values using a number of different comparison operators. They are shown in Table 6.4, “Display Filter comparison operators”.

[Tip]Tip

You can use English and C-like terms in the same way, they can even be mixed in a filter string.

Table 6.4. Display Filter comparison operators

EnglishC-likeDescription and example

eq

==

Equal. ip.src==10.0.0.5

ne

!=

Not equal. ip.src!=10.0.0.5

gt

>

Greater than. frame.len > 10

lt

<

Less than. frame.len < 128

ge

>=

Greater than or equal to. frame.len ge 0x100

le

<=

Less than or equal to. frame.len <= 0x20

contains

 

Protocol, field or slice contains a value. sip.To contains "a1762"

matches

~

Protocol or text field match Perl regualar expression. http.host matches "acme\.(org|com|net)"

bitwise_and

&

Compare bit field value. tcp.flags & 0x02


In addition, all protocol fields have a type. Display Filter Field Types provides a list of the types and example of how to express them.

Display Filter Field Types

Unsigned integer

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
Signed integer
Can be 8, 16, 24, 32, or 64 bits. As with unsigned integers you can use decimal, octal, or hexadecimal.
Boolean

A boolean field is present in the protocol decode only if its value is true. For example, tcp.flags.syn is present, and thus true, only if the SYN flag is present in a TCP segment header.

The filter expression  `tcp.flags.syn` will select only  those packets for which
this flag exists, that is,  TCP segments where the segment header contains the
SYN flag. Similarly, to find source-routed token ring packets, use a filter
expression of  `tr.sr`.
Ethernet address

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
IPv4 address

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 address

ipv6.addr == ::1

As with IPv4 addresses, IPv6 addresses can match a subnet.
Text string
http.request.uri == "https://www.wireshark.org/"
udp contains 81:60:03

The example above match packets that contains the 3-byte sequence 0x81, 0x60, 0x03 anywhere in the UDP header or payload.

sip.To contains "a1762"

Above example match packets where SIP To-header contains the string "a1762" anywhere in the header.

http.host matches "acme\.(org|com|net)"

The example above match HTTP packets where the HOST header contains acme.org or acme.com or acme.net. Comparisons are case-insensitive. Note: Wireshark needs to be built with libpcre in order to be able to use the matches resp. {tilde} operator.

tcp.flags & 0x02

That expression will match all packets that contain a “tcp.flags” field with the 0x02 bit, i.e. the SYN bit, set.

6.4.3. Combining expressions

You can combine filter expressions in Wireshark using the logical operators shown in Table 6.5, “Display Filter Logical Operations”

Table 6.5. Display Filter Logical Operations

EnglishC-likeDescription and example

and

&&

Logical AND. ip.src==10.0.0.5 and tcp.flags.fin

or

||

Logical OR. ip.scr==10.0.0.5 or ip.src==192.1.1.1

xor

^^

Logical XOR. tr.dst[0:3] == 0.6.29 xor tr.src[0:3] == 0.6.29

not

!

Logical NOT. not llc

[…​]

 

See “Slice Operator” below.

in

 

See “Membership Operator” below.


6.4.4. Slice Operator

Wireshark allows you to select subsequences 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.

6.4.5. Membership Operator

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 {}.

tcp.port in {80 443 8080}

This can be considered a shortcut operator, as the previous expression could have been expressed as:

tcp.port == 80 || tcp.port == 443 || tcp.port == 8080

The set of values can also contain ranges:

tcp.port in {443 4430..4434}

This is not merely a shortcut for tcp.port == 443 || (tcp.port >= 4430 && tcp.port <= 4434). Comparison operators are usually satisfied when any field matches the filter, and thus a packet with ports 80 and 56789 would match this alternative display filter since 56789 >= 4430 && 80 <= 4434 is true. The membership operator instead tests the same field against the range condition.

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}

6.4.6. Functions

The display filter language has a number of functions to convert fields, see Table 6.6, “Display Filter Functions”.

Table 6.6. Display Filter Functions

FunctionDescription

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.


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.

6.4.7. A Common Mistake

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 “"!=" is deprecated or may have unexpected results” when you use it.

Often people use a filter string to display something like ip.addr == 1.2.3.4 which will display all packets containing the IP address 1.2.3.4.

Then they use ip.addr != 1.2.3.4 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 source or destination IP address equals 1.2.3.4. The reason for this, is that the expression ip.addr != 1.2.3.4 must be 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 reads “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”.

6.4.8. Sometimes Fields Change Names

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.type" is deprecated or may have unexpected results” when you use it. Support for the deprecated fields may be removed in the future.