Wireshark is a world-class packet analyzer available on Linux, Windows, and macOS. Its filters are flexible and sophisticated, but sometimes, counterintuitive. We’ll explain the “gotchas” you need to be on the lookout for.
Packet Analysis with Real Bite
Wireshark is one of the jewels of the open-source world. It’s a world-class software tool, used by professionals and amateurs alike to investigate and diagnose networking issues. Software developers use it to pinpoint and characterize bugs in communications routines. Security researchers use it to capture and unpick malicious activity on a network.
A typical workflow is to run Wireshark in Capture mode, so it records network traffic through one of the network interfaces on the computer. The network packets are displayed in real time, as they’re captured. However, it’s in the post-capture analysis that the granular detail of what’s going on in the network is revealed.
The captured packets are called a trace. When the capture is complete the trace can be stepped through, packet by packet. You’re able to inspect any packet in the tiniest detail, map out network “conversations” between devices, and use filters to include (or exclude) packets from your analysis.
Wireshark’s filtering capabilities are second to none, with great flexibility and resolving power. There are subtleties to their syntax that make it easy to write a filter and get a result that doesn’t meet your expectations.
If you don’t understand how filters work in Wireshark, you’ll never get out of first gear and throttle the capabilities of the software.
When you install Wireshark, you’re asked whether anyone using a non-root account should be able to capture network traces. Saying no to this might be an attractive idea. You might not want everyone to be able to see what’s happening on the network. However, installing Wireshark so that only those with root privileges can use it means all its components will run with elevated permissions.
Wireshark contains over 2 million lines of complicated code, and it interacts with your computer at the lowest level. Best security practices advise that as little code as possible should run with elevated privileges—especially when its operating at such a low level.
It’s far more secure to run Wireshark with a regular user account. We can still restrict who has the ability to run Wireshark. This requires a few extra setup steps, but it’s the safest way to proceed. The data capture elements of Wireshark will still run with elevated privileges, but the rest of
Wireshark runs as a normal process.
To start the installation on Ubuntu, type:
sudo apt-get install wireshark
On Fedora, type:
sudo dnf install wireshark
On Manjaro, use this command:
sudo pacman -Syu wireshark-qt
During installation, you’ll see the screen below, recommending that you don’t run
Wireshark as root. Press Tab to move the red highlight to “<OK>” and press the Space bar.
On the next screen, press Tab to move the red highlight to “<YES>” and press the Space bar.
Wireshark, you must be a member of the “wireshark” group, which is created during installation. This allows you to control who can run
Wireshark. Anyone who isn’t in the “wireshark” group can’t run
To add yourself to the “Wireshark” group use this command:
sudo usermod -a -G wireshark $USER
For your new group membership to take effect, you can log out and back in, or use this command:
To see if you’re in the new group, use the
You should see “wireshark” in the list of groups.
You can launch Wireshark with the command below. The ampersand (
Wireshark as a background task, meaning you can carry on using the terminal window. You can even close the terminal window and Wireshark will continue to run.
Type the following:
The Wireshark interface appears. The network interface devices present in your computer are listed, along with some built-in pseudo-devices.
A wavy line next to an interface means it’s live and network traffic is passing through it. A flat line means there’s no activity on the interface. The top item in this list is “enp0s3,” the wired connection for this computer and, as expected, it shows activity.
To start capturing packets, we right-click “enp0s3,” and then select “Start Capture” in the context menu.
You can set filters to reduce the amount of traffic Wireshark captures. We prefer to capture everything and filter out anything we don’t want to see when doing an analysis. This way, we know everything that happened is in the trace. You don’t want to inadvertently miss a network event that explains the situation you’re investigating due to your capture filter.
Of course, for high-traffic networks, traces can quickly become very large, so filtering at capture makes sense in this scenario. Or, perhaps you just prefer it that way.
Note that the syntax for capture filters is slightly different than that for displays.
The highlighted icons in the image above indicate the following, from left to right:
- Shark fin: If this is blue, clicking it will start a packet capture. If Wireshark is capturing packets, this icon will be gray.
- Square: If this is red, clicking it will stop a running packet capture. If Wireshark isn’t capturing packets, this icon will be gray.
- Shark fin with circular arrow: If this is green, clicking it will stop the currently running trace. This gives you the opportunity to save or discard the captured packets, and restart the trace. If Wireshark isn’t capturing packets, this icon will be gray.
Analyzing the Trace
Clicking the red square icon will stop the data capture so you can analyze the packets captured in the trace. The packets are presented in time order, and color coded according to the protocol of the packet. The details of the highlighted packet are displayed in the two lower panes in the Wireshark interface.
A simple way to make reading the trace easier is to have Wireshark provide meaningful names for the source and destination IP addresses of the packets. To do this, click View > Name Resolution and select “Resolve Network Addresses.”
Wireshark will attempt to resolve the name of the devices that sent and received each packet. It won’t be able to identify every device, but those it can will help you read the trace.
Scrolling the display to the left will reveal more columns on the right. The info column shows any information Wireshark can detect from the packet. In the example below, we see some
ping requests and responses.
By default, Wireshark displays all packets in the order in which they were traced. Many devices send packets back and forth simultaneously. This means a single conversation between two devices is likely to have packets from others interlaced between them.
To examine a single conversation, you can isolate it by protocol. The protocol for each packet is shown in the protocol column. Most of the protocols you’ll see belong to the TCP/IP family. You can specify the exact protocol or use Ethernet as sort of a catchall.
Right-click any of the packets in the sequence you want to examine, and then click Conversation Filter > Ethernet. In the example below, we selected a
ping request packet.
The sequence of packets is shown without others between them, as Wireshark auto-generated a filter to do this. It’s displayed in the filter bar and highlighted in green, which indicates the syntax of the filter is correct.
To clear the filter, click “X” on the filter bar.
Creating Your Own Filters
Let’s put a simple filter in the filter bar:
ip.addr == 192.168.4.20
This selects all packets that have been sent from or received by the device with IP address 192.168.4.20. Note the double equals signs (
==) with no space between them.
To see the packets sent by a device (the source), you can use
ip.src; to see packets that have arrived at a device (the destination), you can use
ip.dst, as shown below:
ip.dst == 192.168.4.20 && ip.src == 192.168.4.28
Note the use of a double ampersand (
&&) to indicate the logical “and.” This filter looks for packets that arrived at 192.168.4.20 from 192.168.4.28.
People new to Wireshark filters often think a filter like this will capture all packets between two IP addresses, but that’s not the case.
What it actually does is filter all packets to or from IP address 192.168.4.20, regardless of where they came from or to where they were sent. It does the same with all packets from IP address 192.168.4.28. To put it more simply, it filters all traffic to or from either IP address.
You can look for activity on other protocols, too. For example, you can type this filter to look for HTTP requests:
To exclude packets that either came from or were sent to a device, use an exclamation point (
!) and enclose the filter in parentheses [
!(ip.addr == 192.168.4.14)
This filter excludes all packets sent to or from 192.168.4.14.
It’s counterintuitive because the filter contains the equality operator (
). You might have expected you’d type this filter like so:
However, this won’t work.
You can also search for strings within packets, by protocol. This filter searches for Transmission Control Protocol (TCP) packets that contain the string “youtube”:
tcp contains youtube
A filter that looks for retransmission is useful as a way to check whether there’s a connectivity issue. Retransmissions are packets that are re-sent because they were damaged or lost during the initial transmission. Too many retransmissions indicates a slow connection or a device that’s slow to respond.
Type the following:
Birth, Life, Death, and Encryption
A network connection between two devices is initiated whenever one contacts the other and sends a
SYN (synchronize) packet. The receiving device then sends an
ACK (acknowledgment) packet. It indicates if it will accept the connection by sending a
ACK are actually two flags in the same packet. The original device acknowledges the
SYN by sending an
ACK, and then the devices establish a network connection.
This is called the three-way handshake:
A -> SYN -> B A <- SYN, ACK <- B A -> ACK -> B
In the screenshot below, someone on the computer “nostromo.local” makes a Secure Shell (SSH) connection to the computer “ubuntu20-04.local.” The three-way handshake is the first part of the communication between the two computers. Note that the two lines containing the
SYN packets are color coded in dark gray.
Scrolling the display to show the columns to the right reveals the
ACK handshake packets.
You’ll notice that the packet interchange between the two computers alternates between the TCP and SSH protocols. The data packets are passed through the encrypted SSH connection, but message packets (like
ACK) are sent via TCP. We’ll filter out the TCP packets shortly.
When the network connection is no longer needed, it’s discarded. The packet sequence to break a network connection is a four-way handshake.
One side sends a
FIN (finish) packet. The other end sends an
ACK to acknowledge the
FIN, and then also sends a
FIN to indicate it agrees the connection should be dropped. The first side sends an
ACK for the
FIN it just received, and the network connection is then dismantled.
Here’s what the four-way handshake looks like:
A -> FIN -> B A <- FIN, ACK <- B A -> ACK -> B
Sometimes, the original
FIN piggybacks on an
ACK packet that was going to be sent anyway, as shown below:
A -> FIN, ACK -> B A <- FIN, ACK <- B A -> ACK -> B
This is what happens in this example.
If we want to see only the SSH traffic for this conversation, we can use a filter that specifies that protocol. We type the following to see all traffic using the SSH protocol to and from the remote computer:
ip.addr == 192.168.4.25 && ssh
This filters out everything except SSH traffic to and from 192.168.4.25.
Other Useful Filter Templates
When you’re typing a filter into the filter bar, it will remain red until the filter is syntactically correct. It will turn green when the filter is correct and complete.
If you type a protocol, such as
shh, followed by a period (
.), a menu appears. It will list recent filters that contained that protocol, and all the fields that can be used in filters for that protocol name.
For example, with
ip, you can use
ip.host, and dozens of others.
Use the following filter templates as the basis of your filters:
- To only show HTTP protocol packets:
- To only show DNS protocol packets:
- To only show TCP packets with 4000 as a source or destination port:
- To display all TCP reset packets:
- To filter out ARP, ICMP, and DNS packets:
!(arp or icmp or dns)
- To display all retransmissions in a trace:
- To filter flags (like
FIN): You have to set a comparison value for these:
1means the flag is set, and
0means it’s not. So, an example would be:
tcp.flags.syn == 1.
We’ve covered some of the guiding principles and fundamental uses of display filters here, but, of course, there’s a lot more.
To appreciate the full scope and power of
Wireshark filters, be sure to check out its online reference.