Check out these great references as well: |
Our custom profiles repository for Wireshark |
Our Udemy course on Wireshark |
Our Udemy course on Wireless Packet capture |
If you are a Wireshark power user, you know the importance of complex display filters to narrow searches for very particular items. The challenge can be to recall these filters, end edit them in different analysis cases. Also, if you want to be able to replace addresses, the possibility of typos and time being lost becomes evident, if not frustrating.
Luckily Wireshark has a very little known capability called display filter macros. In the entire Wireshark web site, there may be 10 total sentences dedicated to the capability. Ok it might be 12 sentences.
Here is how it works. You have to define the macro first, using variables, that when you execute the macro, the variables are then inserted. Let’s start with a really simple one that you probably would never actually define because, like most of us, you know the filter by heart: the ip.addr == a.b.c.d filter.
Creating Your First Simple Display FIlter Macro
To define the macro select Analyze> Display Filter Macros and you will get the following pop-up:
As with any of the Wireshark lists, click the “+” sign to add a macro.
Enter the name of the macro (no spaces allowed): I used IPA
Then enter the macro syntax: ip.addr == $1
The $1 is essentially a variable, and you can have multiple variables in complex macros.
Click OK.
Now in a capture, type the following into the display filter: ${IPA:192.168.1.1} and apply the filter (replace the 192.168.1.1 address with anything you want):
OK perfect, – now we know now this works, let’s take it a step further (and more useful).
Taking it to the Next Level
Let’s say we wanted to find a particular IP address pair. One option would be the Conversation Filter. Or we could create a macro based on a more complex filter syntax. We will have two variables: $1 and $2 for the two addresses.
The normal display filter would look like this: ip.addr==17.248.185.174 && ip.addr==192.168.1.114
So let’s create a macro we will call IPAP (for IP Address Pair) and use the syntax replacing the addresses with $1 and $2:
Now if I want to find a set of packets between an IP address pair, I simply type ${IPAP:17.248.185.174;192.168.1.114} in the display filter:
The key here is that a semicolon separates the variables.
By now you have probably also noticed that Display Macros are stored by profile. So different Profiles can have different profile specific macros.
Using Macros inside Display Filter Expressions
You can also use Display Filter Macros inside expressions.
For example if you defined a macro to be called ‘priv24’ and then defined the macro syntax to be ‘192.168.1.0/24’, you could in a display filter enter something like:
ip.addr == ${priv24}
The result would be the same as typing ‘ip.addr == 192.168.1.0/24’
If you are a network admistrator, you can imagine how using this could save a lot of time typing addresses.
Interesting Macro Syntax Variations
Another thing you can do is use the Wireshark Display Macro syntax to perform quick filters on your trace. For example:
- ip.addr == ${ip.src} will find all packets that have the same source IP address as the selected packet
- tcp.stream == ${tcp.stream} will find all packets in the current selected packet tcp stream (assumes you have a valid tcp packet selected)
These are not technically macros, so you would not save them as such, instead you would simply save these as Display filters in your pick list/bookmark list.
Useful Macros
So let’s create a cheat sheet of macros you may find useful and you can add them to your favorite profiles:
Macro Name | Purpose | Macro Filter Syntax | Display Filter Syntax to call the Macro |
n/a | Find all IP addresses that match the Source IP of current selected packet | ip.addr == ${ip.src} | n/a |
n/a | Find all IP addresses that match the Destination IP of current selected packet | ip.addr == ${ip.dst} | n/a |
n/a | Find all packets in the TCP stream of the current selected packet | tcp.stream == ${tcp.stream} | n/a |
n/a | Find all DNS packets belonging to the selected packet (usually query response pairs) | dns.id == ${dsn.id} | n/a |
TCPConv | Filter a particular TCP conversation knowing Source, destination, and TCP Port | ((ip.src == $1 and ip.dst == $2 and tcp.srcport == $3 and tcp.dstport == $4) or (ip.src == $2 and ip.dst == $1 and tcp.srcport == $4 and tcp.dstport == $3)) | ${TCPConv:192.168.1.10;192.168.1.13;8080} |
ARPrq | Find all ARP Requests | arp.opcode == 0x0001 | ${ARPrq} |
ARPrp | Find all ARP Responses | arp.opcode == 0x0002 | $(ARPrp} |
DNSrq | Find all DNS Requests | dns.flags.response == 0 | ${DNSrq} |
DNSrp | Find all DNS Responses | dns.flags.response == 1 | ${DNSrp} |
DNSer | Find all DNS Errors | dns.flags.rcode != 0 | ${DNSer} |
ICMPrq | Find all ICMPv4 Requests | icmp.type == 8 | ${ICMPrq} |
ICMPrp | Find all ICMPv4 Responses | icmp.type == 0 | ${ICMPrp} |
ICMPred | Find all ICMPv4 redirects except IP Address w.x.y.z | icmp.type == 5 and ip.src != $1 | ${ICMPred:w.x.y.z} |
SSLhs | Find all SSL Handshake packets | ssl.record.content_type==22 | ${SSLhs} |
NoBeacons | Wireless: remove all Beacon Frames | wlan.fc.subtype != 8 | ${NoBeacons} |
JustBeacons | Wireless: show only Beacon Frames | wlan.fc.subtype == 8 | ${JustBeacons} |
SSIDn | Wireless: show only management frames with SSID x where x is the SSID term | wlan_mgt.ssid == \x22$1\x22 | ${SSIDn:x} |
Probes | Wireless: show only the probe frames | wlan.fc.subtype==4 or wlan.fc.subtype==5 | ${Probes} |
plcmall | IP Telephony – find all PLCM packets | eth.addr[0:3] == 00-04-f2 || bootp.hw.mac_addr[0:3] == 00-04-f2 | ${plcmall} |
plcm | IP Telephony – find PLCM for a particular MAC 12-34-56 | eth.addr == 00-04-f2-$1 || bootp.hw.mac_addr == 00-04-f2-$1 | ${plcm:12-34-56} |
issall | IP Telephony – find all ISS packets | eth.addr[0:3] == 00-26-fd || bootp.hw.mac_addr[0:3] == 00-26-fd | ${issall} |
iss | IP Telephony – find ISS packets for a particular MAC 12-34-56 | eth.addr == 0026-fdf0-$1 || bootp.hw.mac_addr == 0026-fdf0-$1 | ${iss:1234} |
Be sure to check back here often as we will keep adding to the list. Any you would add?
I hope you find this article and its content helpful. Comments are welcomed below. If you would like to see more articles like this, please support us by clicking the patron link where you will receive free bonus access to courses and more, or simply buying us a cup of coffee!, and all comments are welcome!