6.4. Building Display Filter Expressions

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]Tip

There are many display filter examples on the Wireshark Wiki Display Filter page at: https://gitlab.com/wireshark/wireshark/wikis/DisplayFilters.

6.4.1. Display Filter Fields

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 ViewInternalsSupported Protocols.

6.4.2. Comparing Values

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]Tip

English and C-like operators are interchangeable and can be mixed within a filter string.

Table 6.5. Display Filter comparison operators

EnglishC-likeDescriptionExample

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 matches a Perl-compatible regular expression

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

bitwise_and

&

Bitwise AND is non-zero

tcp.flags & 0x02


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

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

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.

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

6.4.3. Combining Expressions

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

EnglishC-likeDescriptionExample

and

&&

Logical AND

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

or

||

Logical OR

ip.src==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

[…​]

 

Subsequence

See “Slice Operator” below.

in

 

Set Membership

http.request.method in {"HEAD" "GET"}. See “Membership Operator” below.


6.4.4. Slice Operator

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.

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 {}. 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]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 56789 >= 4430 && 80 <= 4434 is true. In contrast, the membership operator tests a single 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.7, “Display Filter Functions”.

Table 6.7. 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.

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"

6.4.7. A Common Mistake with !=

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”.

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