The goal of this post
This post is a quick reference for using the display filters in Wireshark. The display filter is used to filter a packet capture file or live traffic, and it is essential to know at least the basics if you want to use Wireshark for troubleshooting and other evaluations.
In this post, I’ll focus on the display filters for IPv4 only. Wireshark offers a wide range of tools that are out of this post’s scope. IPv6 will be added at some point.
There is no way to list every filter, and I try to concentrate on the most commonly used ones. In general, it is recommended to use the right-click function to add specific protocols/ fields/ values, etc, to the filter.
Nevertheless, a list of all display filters can be found here. I’ve added links to the specific category to every protocol in the rest of the post.
If you think I forgot something important or want to share more tips, feel free to reach out. I’d appreciate it, and I am happy to learn.
In an attempt to keep it to the basics, I left out topics like functions, variables, macros, arithmetic operators, and some other advanced things. As mentioned before, I’ll add IPv6 filters, some more context for when I use certain filters, more topics like OSPF, HTTP/s, and so others, and some more functions.
Difference display filter and capture filter
Capture filter
The capture filter - as the name suggests - is a filter for the capturing of packets itself. With this filter turned on, you can start packet capture, and everything filtered out won’t be saved. This is mainly for long packet captures or connections/devices with a lot of traffic helpful, and often enough necessary. Capture filters can have a different syntax and won’t be tackled in this post.
Display filter
The display filter hides filtered packets and is mainly used on already saved packet capture files or live traffic.
Just so you know the difference when you search for more commands.
Saving display filters #
There are two common ways to save filters. They can then be used in later sessions or help you switch between different filters, especially since certain filters can get very long.
Display filter bookmark
Display filter buttons
Color of the display filter bar #
- Green:
- Filter is accepted, syntax is ok
- Red:
- Filter is NOT accepted, syntax is wrong
- Yellow:
- Filter is accepted, syntax is ok, BUT the filter results might not be clear, e.x. if you reference a field that is present in multiple protocols
- (haven’t found too much information about it)
Operators #
Logical operators
It runs from left to right and can be grouped with parentheses ()
.
- Logical
AND
: and
/&&
- Logical
OR
: or
/||
- Logical
NOT
: not
/!
- e.x.
!ip.src == 10.10.10.1
- this would filter out everything with the source IP of10.10.10.1
- (Logical
XOR
): xor
/^^
- Side note: read it multiple times, but does not work for me. I just ‘craft’ something like this:
(x and !y)or(!x and y)
Comparison operators
- Equal:
eq
/==
- Not Equal:
ne
/!=
- Greater Than:
gt
/>
- Less Than:
lt
/<
- Greater than or Equal to:
ge
/>=
- Less than or Equal to:
le
/<=
Content filter
- Filters for protocol, field, or slice that contains a specific value:
contains
- ‘Does the protocol or text string match the given case-insensitive Perl-compatible regular expression’:
matches
/~
Boolean
The following formats are accepted:
option == 1
option == True
option == TRUE
option == 0
option == False
option == FALSE
Escape characters
- I prefer to use the ‘raw string’ function, instead of fighting with escape characters:
smb.path contains r"\\SERVER\SHARE"
List of escape sequences:
smb.path contains "\\\\SERVER\\SHARE"
\' single quote
\" double quote
\\ backslash
\a audible bell
\b backspace
\f form feed
\n line feed
\r carriage return
\t horizontal tab
\v vertical tab
\NNN arbitrary octal value
\xNN arbitrary hexadecimal value
\uNNNN Unicode codepoint U+NNNN
\UNNNNNNNN Unicode codepoint U+NNNNNNNN
Time filter #
frame.time >= "Dec 23, 2022 17:00:00" && frame.time <= "Dec 23, 2022 17:05:00"
This filter is a simple time filter. Right-click on frame.time
/ Arrival time in the frame, and add it to the filter to work with it. Directly right-clicking on the ‘time’ column and applying the filter won’t work since it inserts another format. I bet you can configure this, but I never bothered to try.
If you want to add more filters, simply put the time segment into parentheses, and add the new filter after or before it.
Side note: I am not sure if I am happy with the following format, and I might change it at some point. It is food enough for now, though.
- You can choose between multiple MAC address formats:
aa-bb-cc-dd-ee-ff
# dash delimiteraa:bb:cc:dd:ee:ff
# colon delimiteraabb.ccdd.eeff
# Cisco style- MAC / Ethernet address:
eth.addr==aa-bb-cc-dd-ee-ff
# Source+Destination MAC addresseth.src==aa-bb-cc-dd-ee-ff
# Source MAC addresseth.dst==aa-bb-cc-dd-ee-ff
# Destination MAC address- VLAN:
eth.vlan.id==1
IP #
- Filter for IP protocol:
ip
- Filter IP addresses:
ip.addr == 10.10.10.10
# source+destination IP addressip.src == 10.10.20.50
# source IP addressip.dst == 10.10.20.50
# destination IP address
Side note: You can filter whole subnets with CIDR notation like 10.10.20.0/24
too.
- Filter packet TTL:
ip.ttl == 64
ICMP #
- Filter for
ICMP
: icmp
- ICMP echo request (ping):
icmp.type == 8
- ICMP echo reply (ping):
icmp.type == 0
ARP #
- Target MAC address:
arp.dst.hw_mac
- Sender hardware address:
arp.src.hw
- Target IP address:
arp.dst.proto_ipv4
- Sender IP address:
arp.src.proto_ipv4
TCP #
- Filter for TCP:
tcp
- Filter TCP ports:
tcp.port == 53
# source+destination TCP porttcp.srcport == 68
# source TCP porttcp.dstport == 68
# destination TCP port
Side note: filtering ‘TCP streams’ is helpful, but it is easier to right click on the TCP segment, and filter there instead of tpying in a filter.
Examples
- General troubleshooting for packet loss:
tcp.analysis.flags && !tcp.analysis.window_update
- displays all retransmissions, duplicate ACKs, other TCP errors. I’ll use this in combination with IP filters to get a feeling for the connection quality.
- Look for 3-way-handshakes:
((tcp.flags == 0x02) || (tcp.flags == 0x12) ) || ((tcp.flags == 0x10) && (tcp.ack==1) && (tcp.len==0))
- Fitlers for TCP resets flag:
tcp.flags.reset==1
UDP #
- Filter for UDP:
udp
- Filter UDP ports:
udp.port == 53
# source+destination UDP portudp.srcport == 68
# source UDP portudp.dstport == 68
# destination UDP port
DHCP #
- Filter for dhcp
dhcp
- Filter for type (DORA)
dhcp.option.dhcp == 1
# Discoverdhcp.option.dhcp == 2
# Offerdhcp.option.dhcp == 3
# Requestdhcp.option.dhcp == 5
# Discover- Search for
hostname
: dhcp.option.hostname == "pleasejustwork"
- Seach for various options:
dhcp.option.type == 3
# Search for a specific option numberdhcp.option.dhcp_server_id == 10.10.20.1
# Option: (54) DHCP Server Identifierdhcp.option.type == 51
# Option: (51) IP Address Lease Timedhcp.option.subnet_mask == 255.255.255.0
# Option: (1) Subnet Mask (255.255.255.0)dhcp.option.router == 10.10.20.1
# Option: (3) Routerdhcp.option.domain_name_server == 9.9.9.9
# Option: (6) Domain Name Server- I won’t list all of them, but you can find all options here.
Examples
- Search for a DHCP discover message of specific MAC address:
(dhcp.hw.mac_addr == aa:bb:cc:dd:ee:ff) && (dhcp.option.dhcp == 1)
(eth.src == aa:bb:cc:dd:ee:ff) && (dhcp.option.dhcp == 1)
- Finding rogue DHCP server:
dhcp && !dhcp.option.dhcp == 1 && !dhcp.option.dhcp_server_id == 10.10.20.1
- it is DHCP, it is not a discover message, and is not our DHCP server for this network
(udp.dstport == 68) && !(dhcp.option.dhcp_server_id == 10.10.20.1)
- this is another option to check for the dst port ‘68’ and filter out our DHCP server
- Check if other DNS server are getting populated:
dhcp.option.dhcp == 2 && !(dhcp.option.domain_name_server == 9.9.9.9) && !(dhcp.option.domain_name_server == 149.112.112.112)
DNS #
- Filter for DNS queries:
dns
- Filter for DNS queries:
dns.flags.response == 0
- Filter for DNS responses:
dns.flags.response == 1
- Filter the domain on the DNS quieries:
dns.qry.name == "ittavern.com"
# Discover- Filter common DNS records:
dns.qry.type == 1
#A
recorddns.qry.type == 28
#AAAA
recorddns.qry.type == 16
#txt
recorddns.qry.type == 5
#CNAME
recorddns.qry.type == 33
#srv
recorddns.qry.type == 15
#MX
recorddns.qry.type == 2
#NS
record- Filter for the DNS server answer:
dns.a == 94.130.76.189
# answer of aA
recorddns.txt == "v=spf1 include:spf.protection.outlook.com -all"
# answer of aTXT
record request- and so on
Examples
- Look up what DNS servers are used:
(ip.dst == 10.64.0.1) && (dns)
- Show only DNS traffic of one client:
dns && (ip.dst==10.10.20.1 or ip.src==10.10.20.1)
- Check for slow responses:
dns.flags.rcode == 0 && dns.time > .3
# might needs some fine tuning depending on the env- Show DNS requests that couldn’t be resolved:
dns.flags.rcode != 0
Most recent Articles: