Network analysis is one of those skills that looks simple from the outside and keeps revealing new depth the longer you work with it. You can spend an afternoon learning the basics of tcpdump and still be discovering useful filter combinations three years later. That’s the nature of it. The tools covered in this guide – ifconfig, netstat, ss, tcpdump, and Wireshark are not beginner placeholders you graduate away from. They are the actual production tools that network engineers, incident responders, and penetration testers use every day in real environments.
This guide goes beyond the command syntax. It explains the underlying mechanics: why promiscuous mode matters at the hardware level, how Berkeley Packet Filter bytecode works, why Wireshark’s display filter language is fundamentally different from tcpdump‘s capture filter syntax, and how to read what these tools actually show you. If your goal is to understand what is happening on a network, not just run command, you’re in the right place.
What’s Network Analysis
At its core, network analysis means intercepting data in transit across a digital network and making sense of it. This covers everything from checking whether a remote host is alive, to reconstructing the full session data from a TCP stream, to identifying C2 beacon patterns in encrypted traffic through timing analysis.
The tools divide roughly into two categories. Passive tools such as sniffers and protocol analyzers capture traffic without injecting anything onto the wire. Active tools such as ping, traceroute, nmap send packets and analyze the responses. Most real investigations use both. You might use ping to confirm a host is up, netstat to see what local connections already exist, then tcpdump or Wireshark to capture and decode the actual traffic flow.

Security professionals use network analysis for several overlapping purposes: troubleshooting connectivity problems, detecting malware by its network behavior, reconstructing attack chains from packet captures, and baselining what normal traffic looks like so anomalies become visible. Each of these is a different use case with different filtering strategies, but the underlying toolset is the same.
Command-Line Network Analysis Tools
ifconfig / ip
ifconfig (interface configuration) is the classic command for viewing and configuring network interfaces on Linux and Unix systems. On Kali Linux:
kali > ifconfig
The output gives you everything you need to understand an interface at a glance: the IPv4 address (inet), the subnet mask (netmask), the broadcast address, the IPv6 address (inet6), and the MAC address (ether). You also see the loopback interface (lo) at 127.0.0.1, which is the system talking to itself.
Worth knowing: ifconfig is technically deprecated on most modern Linux distributions. It is part of the net-tools package, which is no longer maintained and was removed from default installs on Debian, Ubuntu, RHEL 8+, and others. The modern equivalent is the ip command from the iproute2 package:
# Show all interfaces (equivalent to ifconfig -a)ip addr show# Show a specific interfaceip addr show dev eth0# Show link-layer informationip link show

The ip command is more consistent, supports newer networking features (namespaces, VLANs, tunnels), and is faster because it queries the kernel through NETLINK rather than parsing /proc filesystem text files. That said, ifconfig is still available on most penetration testing distributions and many embedded or legacy systems, so knowing both matters.
ping and ICMP
ping is the first diagnostic most people reach for when something isn’t working. It sends ICMP Echo Request packets to a target and waits for ICMP Echo Reply responses:
kali > ping thecybersecguru.com# Or by IP address directly, which skips the DNS lookupkali > ping 192.0.78.156

The output tells you round-trip time (RTT) for each packet, whether packets are being dropped, and the target’s IP address (if you pinged by hostname). What ping actually proves is that ICMP traffic can reach the target and return to you, not that any services are running, not that TCP is open, and not that the host isn’t running a firewall that blocks ICMP while allowing everything else.
Some hardened servers and firewalls drop ICMP altogether. A failed ping does not mean the host is down. It means ICMP is filtered. This distinction matters in penetration testing – a host that does not respond to ping may still have open web, SSH, or RDP ports.
# Set a specific count so ping doesn't run foreverkali > ping -c 4 192.168.50.50# Flood ping (requires root) - useful for testing packet losskali > ping -f 192.168.50.50
netstat
netstat (network statistics) is a command-line tool that shows network connections, routing tables, interface statistics, and more. Despite being deprecated, it is still widely installed and muscle-memorized by a generation of engineers, so it stays relevant.
# Show all connections (listening and established)kali > netstat -a# Show only TCP connectionskali > netstat -at# Show only UDP connectionskali > netstat -au# Show only listening connectionskali > netstat -l# Show with process names and PIDs (requires root for other users' processes)kali > netstat -anp# Numeric output - skip DNS resolution, much fasterkali > netstat -an
The output columns to understand: Proto is the protocol (tcp, udp), Local Address is the socket on your machine, Foreign Address is the remote socket, and State is the TCP connection state: LISTEN (waiting for incoming connections), ESTABLISHED (active connection), TIME_WAIT (recently closed, waiting for stale packets to clear), CLOSE_WAIT (remote side closed, local side hasn’t yet), and others.
Security use case: piping netstat to grep to find unexpected connections. If something is beaconing out to an unknown IP on port 443, netstat -anp will show you the PID and process name.
# Find if Apache is listeningkali > netstat -a | grep http# Find all established connections to a suspicious IPkali > netstat -an | grep 192.168.1.200# Find processes listening on port 4444 (a common reverse shell port)kali > netstat -anp | grep :4444

ss (Socket Statistics)
ss is the modern replacement for netstat, part of the iproute2 package. It queries the kernel directly through the NETLINK socket interface rather than parsing /proc/net/ text files, which makes it significantly faster – especially on servers with thousands of open connections where netstat can take several seconds while ss returns results almost instantly.
# Show all connectionsss -a# Show TCP connections only, with process infosudo ss -tnp# Show listening sockets onlyss -l# Show UDP socketsss -u# Show sockets in ESTABLISHED statess -t state established# Filter to a specific portss -tnp sport = :22

The output format differs slightly from netstat. ss shows Recv-Q and Send-Q (receive and send queue depths), which netstat also shows but in less granular form. When Recv-Q is consistently nonzero on an ESTABLISHED connection, the application is not reading fast enough. When Send-Q is high, the remote end is not acknowledging fast enough. These queue values are genuinely useful for diagnosing slow-but-connected services.
The ss -p flag includes the process name and PID in parentheses next to each socket, like users:(("nginx",pid=2145,fd=6)), which gives you both the process name and the file descriptor number – more detail than netstat.
Practical note: netstat is not going away tomorrow. It is still installed on many systems, still taught in certifications, and still functional. But if you are writing new scripts or working on a system where speed matters, learn ss. It is actively maintained and will still be there when net-tools is fully retired.
Network Sniffers
A network sniffer (sometimes called a packet analyzer, protocol analyzer, or packet capture tool) intercepts and records the raw packets traversing a network interface. The captured data includes every layer of the packet: link layer (Ethernet frames), network layer (IP headers), transport layer (TCP/UDP), and the application payload.
The range of tools capable of sniffing is wide: SolarWinds Deep Packet Inspection, tcpdump, WinDump, Wireshark, NetworkMiner, Capsa, tshark, Zeek, and more. This guide focuses on tcpdump for command-line work and Wireshark for GUI-based analysis, which together cover the overwhelming majority of real-world packet analysis work.
Promiscuous Mode Explained
Here is a detail that trips people up: a standard network interface card (NIC) in normal operation only delivers to the host the packets addressed to that NIC’s MAC address (plus broadcast and multicast packets). Everything else – traffic between other hosts on the same network segment – gets ignored at the hardware level.
For effective sniffing, the NIC needs to operate in promiscuous mode, where it passes every frame it receives on the wire up to the operating system, regardless of destination MAC address. This is what makes passive sniffing work on shared-media networks (like an unswitched Ethernet segment or a wireless network).

# Enable promiscuous mode manuallyip link set eth0 promisc on# Verify it is enabled (look for PROMISC in the flags)ip link show eth0
Both tcpdump and Wireshark enable promiscuous mode automatically by default when they start capturing.
Two important caveats here. First, promiscuous mode is detectable. A host on the same network can probe for promiscuous-mode adapters using specific packet tests. This is relevant for red team engagements where stealth matters. Second, on modern switched networks, a NIC in promiscuous mode only sees traffic from its own switch port anyway (plus broadcast/multicast). To capture all traffic on a switch, you need a SPAN (Switched Port Analyzer) port or mirror port configured on the switch, which forwards copies of all traffic to your capture port. Without that, you only capture your own traffic plus broadcast.
For 802.11 wireless captures, there is a third mode worth knowing: monitor mode (rfmon mode). Promiscuous mode on a wireless interface only captures traffic for the network the adapter is associated with. Monitor mode allows capturing 802.11 management frames, control frames, and traffic from all networks on the current channel – useful for wireless auditing.
The pcap File Format
The standard file format for packet captures is .pcap (Packet Capture), originated by the libpcap project around 1987 as part of the original tcpdump. The format has a straightforward three-layer structure:
Global File Header: A fixed 24-byte header that opens the file. Contains a magic number (which identifies the file type and byte order), the libpcap format version (currently 2.4), the maximum captured packet length (the snapshot length or “snaplen”), and the link-layer type (which tells analysis tools whether to interpret packet data as Ethernet, Wi-Fi, etc.).
Per-Packet Header: For each captured packet, a 16-byte header carrying the timestamp (seconds and microseconds), the captured packet length, and the original packet length. When the captured length is less than the original length, the packet was truncated – useful to know during analysis.
Packet Data: The raw bytes of the packet itself, starting at the link layer as specified in the global header.

The .pcap format is universal. Snort, Suricata, Wireshark, tcpdump, aircrack-ng, and most security tools either read, write, or both for .pcap files. When you save a tcpdump capture with -w output.pcap, that file can be opened directly in Wireshark.
pcap vs pcapng
PCAPng (PCAP Next Generation) is the newer format, now the default in Wireshark. The key differences:
PCAPng supports multiple interfaces in a single capture file (the original .pcap format cannot mix interface types). It supports nanosecond timestamp precision vs. microsecond for classic pcap. It allows user comments and block-level annotations. It includes interface statistics blocks. And it handles the case where you capture on multiple interfaces simultaneously, increasingly common in modern network forensics.
For everyday use, .pcap is fine. For enterprise investigations, multi-interface captures, or situations where you need comment annotations on specific packets, .pcapng is worth using.
libpcap and WinPcap/Npcap
libpcap is the C library that provides the underlying packet capture functionality on Linux and macOS. tcpdump, Wireshark, Snort, and most other Unix-based tools use libpcap under the hood. The library handles putting the interface into promiscuous mode, calling into the kernel’s BPF subsystem to filter packets, and writing the pcap format.
On Windows, the equivalent is Npcap (the actively maintained successor to WinPcap, which was discontinued). Npcap is what Wireshark uses on Windows. Without one of these libraries, no sniffing tool can capture packets at the driver level.
tcpdump In Depth
tcpdump was first released in 1988, written by researchers at Lawrence Berkeley National Laboratory running BSD Unix. It remains the go-to tool for capturing and inspecting network traffic without a graphical interface. This matters more than it sounds: you often do not have GUI access on a remote server, a containerized system, a network appliance, or a system where running a heavyweight GUI would consume too many resources. tcpdump has near-zero overhead.
Start a basic capture:
kali > tcpdump
Packets start streaming immediately – mostly communication between your system and the default gateway, plus any other traffic on the interface. The output format is: timestamp / protocol / source > destination / TCP flags and header info.

To capture against a Windows host at 192.168.0.114, for instance, start a ping from a second terminal:
kali > ping 192.168.50.50
And watch tcpdump show the ICMP echo requests and replies in real time, including the protocol type and whether each packet is an echo request or echo reply.
How BPF Filtering Works Under the Hood
The filter language in tcpdump is BPF (Berkeley Packet Filter). What happens when you write a filter expression like host 192.168.0.114 and port 80 is not simple string matching against packet data. The expression gets compiled into BPF bytecode – a minimalist instruction set that runs directly in the kernel.
This architecture is intentional and important. BPF bytecode runs in a kernel-space virtual machine, which means packet filtering happens before packets cross the user-space boundary. Packets that do not match are discarded in the kernel. Only matching packets get copied to user space for tcpdump to display. This is why tcpdump can keep up with high-bandwidth interfaces without dropping packets, the filter runs as close to the wire as possible.

You can see the compiled BPF bytecode for any filter expression with the -d flag:
kali > tcpdump -d 'host 192.168.0.114 and port 80'
The output shows the BPF assembly instructions: load, jump-if-equal, return match, return drop. This is what the kernel actually executes per packet.
The BPF syntax used by tcpdump (and libpcap generally) is defined in the pcap-filter(7) man page. It is different from Wireshark’s display filter syntax – a confusion that trips up everyone at some point. tcpdump filters are capture filters, they decide what gets captured. Wireshark’s filters are display filters, they decide what gets shown from an already-captured dataset. The syntax is not compatible.
Essential tcpdump Flags
| Flag | Purpose |
|---|---|
-i eth0 | Capture on a specific interface (default: lowest-numbered) |
-n | Do not resolve hostnames – prevents slow DNS lookups |
-nn | Do not resolve hostnames or port names |
-v | Verbose output – decodes more header fields |
-vv | Very verbose – decodes all IP and TCP header fields, including user agent |
-vvv | Maximum verbosity |
-A | Print packet payload in ASCII |
-X | Print packet payload in both hex and ASCII |
-e | Print Ethernet MAC addresses |
-c 100 | Stop after capturing 100 packets |
-s 0 | Set snapshot length to unlimited (older versions default to 68 bytes, which truncates payloads) |
-w output.cap | Write raw packets to file instead of displaying them |
-r input.cap | Read from a previously saved capture file |
-l | Line-buffered output – useful when piping to grep |
-q | Quiet/minimal output |
-D | List all available interfaces |
-t | Suppress timestamps |
For real-world use, a common starting invocation is:
kali > tcpdump -i eth0 -nn -vv -s 0
This captures on eth0, skips DNS resolution, shows verbose headers, and captures full-length packets.
Filtering by IP Address
# Traffic to or from a specific hostkali > tcpdump host 192.168.50.50# Traffic only FROM a specific hostkali > tcpdump src host 192.168.50.50# Traffic only TO a specific hostkali > tcpdump dst host 192.168.50.50# Entire subnetkali > tcpdump net 192.168.0.0/24
Filtering by host is the most common starting point for any investigation. When you apply a host filter, tcpdump passes only packets where either the source or destination IP matches. You immediately cut out all the noise from other systems on the network.
When you start Apache on the Kali box and browse to it from the Windows host, you should see the three-way TCP handshake in the output. tcpdump represents the SYN flag as S, ACK as a ., and RST as R. So a complete handshake looks like:
SYN: S (client to server)SYN-ACK: S. (server to client)ACK: . (client to server)

This is the foundation of every TCP connection. When you do not see S. in response to S, the port is closed or filtered.
Filtering by Port
# Traffic on a specific port (any direction)kali > tcpdump port 80# Traffic TO a specific portkali > tcpdump dst port 80# Traffic FROM a specific portkali > tcpdump src port 80# Very verbose output for HTTP - decodes headers including user agentkali > tcpdump -vv dst port 80# Port rangekali > tcpdump portrange 8000-8080
The -vv dst port 80 combination is particularly useful. The very verbose flag causes tcpdump to decode IP and TCP headers and, for HTTP traffic, print the HTTP headers in the output. This lets you see HTTP method, URI, host header, and user agent string – enough to identify the browser and OS of the client.
Filtering by TCP Flags
This is where tcpdump gets genuinely powerful for security work. TCP flags sit at a specific byte offset in the TCP header, and BPF can match against individual bits.
# Only packets with SYN setkali > tcpdump 'tcp[tcpflags] == tcp-syn'# SYN set (and possibly other flags too - more permissive)kali > tcpdump 'tcp[tcpflags] & tcp-syn != 0'# Pure SYN (SYN set, ACK not set) - identifies new connection attemptskali > tcpdump 'tcp[13] & 0x12 = 0x02'# SYN-ACK (both SYN and ACK set) - identifies server responseskali > tcpdump 'tcp[13] & 0x12 = 0x12'# RST - identifies rejected connectionskali > tcpdump 'tcp[tcpflags] & tcp-rst != 0'# FIN - identifies connection teardownkali > tcpdump 'tcp[tcpflags] & tcp-fin != 0'
The tcp[13] notation is direct byte-offset access into the TCP header. Byte 13 (zero-indexed from the start of the TCP header) contains the TCP flags field. The bit values for each flag:
| Flag | Bit value |
|---|---|
| FIN | 0x01 |
| SYN | 0x02 |
| RST | 0x04 |
| PSH | 0x08 |
| ACK | 0x10 |
| URG | 0x20 |

Capturing only pure SYN packets (SYN set, ACK not set) is useful for detecting port scans. A scanner sending SYN packets to a range of ports will show up as a flood of SYN packets from one source IP with no corresponding handshakes completing.
Byte-Offset Filtering
The BPF byte-offset syntax gives you surgical control over what gets captured. The syntax is proto[offset:size], where offset is the byte position within the named protocol header, and size is 1, 2, or 4 bytes.
# Filter by IP TTL less than 10 (many hops used - potential traceroute or TTL-exceeded scenario)kali > tcpdump 'ip[8] < 10'# Filter for ICMP echo requests only (type 8)kali > tcpdump 'icmp[icmptype] = icmp-echo'# Filter for ICMP echo replies only (type 0)kali > tcpdump 'icmp[icmptype] = icmp-echoreply'# Filter by IP protocol number in the IP header (byte 9)kali > tcpdump 'ip[9] = 6' # TCPkali > tcpdump 'ip[9] = 17' # UDPkali > tcpdump 'ip[9] = 1' # ICMPkali > tcpdump 'ip[9] = 50' # ESP (encrypted VPN traffic)
This level of specificity matters in incident response. If you are hunting for specific malware that uses unusual IP header values (TTL manipulation, specific protocol fields), byte-offset filtering lets you find it without pulling in terabytes of noise.
Combining Filters
tcpdump supports logical AND, OR, and NOT in filter expressions:
# AND - traffic between Windows host and port 80kali > tcpdump host 192.168.0.114 and port 80# OR - HTTP or HTTPS traffickali > tcpdump port 80 or port 443# NOT - everything except traffic from a specific hostkali > tcpdump not host 192.168.0.114# Complex combinationkali > tcpdump 'tcp and (port 80 or port 443) and not host 192.168.1.1'
Two syntax notes: && is equivalent to and, || is equivalent to or, and ! is equivalent to not. In shell commands, wrap complex filter expressions in single quotes to prevent the shell from misinterpreting characters like parentheses, !, and &.
Credential and Artifact Hunting
One of the more operationally useful tcpdump techniques for penetration testers and red teamers is filtering for cleartext credential material. Several legacy protocols still transmit credentials in plaintext: HTTP basic auth, FTP (port 21), SMTP (port 25), POP3 (port 110), IMAP (port 143), and Telnet (port 23).
# Search for credential strings across common plaintext protocolskali > tcpdump port 80 or port 21 or port 25 or port 110 or port 143 or port 23 -lA | \ egrep -i 'pass=|pwd=|log=|login=|user=|username=|pw=|passw=|password='
The -l flag line-buffers the output (so grep receives complete lines), and -A prints the ASCII payload. The egrep pattern matches common parameter names used by web login forms. This is not a magic password sniffer. It only works against unencrypted traffic, but on internal networks where legacy protocols are in use, it surfaces real data fast.
User agent identification:
# Extract user agent strings from HTTP traffickali > tcpdump -vvAls0 | grep 'User-Agent:'# Extract cookieskali > tcpdump -vvAls0 | grep 'Set-Cookie\|Host:\|Cookie:'
Saving and Reading Capture Files
# Write raw packets to a file for later analysiskali > tcpdump -w myoutput.pcap# Read a capture file (output in the same format as live capture)kali > tcpdump -r myoutput.pcap# Read a file and apply a filter during readingkali > tcpdump -r myoutput.pcap 'host 192.168.0.114 and port 443'# Rotate capture files every 100MB with a timestamp in the filenamekali > tcpdump -w 'capture_%Y%m%d_%H%M%S.pcap' -G 3600 -C 100
The last example uses -G 3600 to rotate files every 3600 seconds (one hour) and -C 100 to roll to a new file every 100MB, whichever comes first. This is the pattern for long-term traffic logging.
Wireshark: The Gold Standard
Wireshark (formerly Ethereal) is the most widely used packet analyzer in the world. It wraps the same libpcap capture engine as tcpdump in a GUI that makes deep protocol analysis practical without memorizing hundreds of filter syntax rules.
Wireshark is built into Kali Linux. Launch it:
kali > wireshark &

Or through the application menu: Applications > 09-Sniffing and Spoofing > Wireshark.
When it opens, Wireshark asks which interface to listen on. If you are in a VM, select eth0. For a physical machine with wireless, select wlan0. A quick way to identify the right interface: look for the one with activity — the waveform displayed next to each interface shows packet rate in real time before you start capturing.
The Three Panes
Once a capture is running, Wireshark shows three panels:
Packet List Pane (top): Every captured packet in chronological order. Color-coded by protocol type — you can customize the colors, and defaults are generally useful: green for TCP, light blue for UDP, dark blue for DNS, and so on. Columns show: packet number, timestamp, source IP, destination IP, protocol, packet length, and a one-line summary. Clicking a row selects that packet and populates the other two panes.
Packet Details Pane (middle): The selected packet decoded in a tree structure, layer by layer. You can expand each layer: Frame (the raw capture metadata), Ethernet II (link-layer headers), Internet Protocol (IP headers with every field labeled), Transmission Control Protocol (TCP headers, flags, sequence numbers, window size), and then the application layer (HTTP, DNS, TLS, whatever the protocol is). This pane is where you spend most of your analysis time — clicking a field highlights the corresponding bytes in the third pane and shows a one-line description of what that field means.
Packet Bytes Pane (bottom): The raw payload of the selected packet in hexadecimal on the left and ASCII on the right. When you click a field in the Packet Details Pane, the corresponding bytes are highlighted here. When analyzing malware C2 traffic or hunting for specific payload patterns, this pane is where you verify what you think you are seeing.
Capture Filters vs Display Filters
This distinction matters and confuses a lot of people. There are two distinct filtering systems in Wireshark, with incompatible syntax:
Capture filters (BPF syntax, same as tcpdump) are applied before packets are stored. They reduce the volume of data written to disk. Set them in the Capture Options dialog before starting a capture. You cannot change them once a capture is running. Use these when you already know what you want and have a high-traffic environment.
Display filters (Wireshark’s own syntax) are applied to an already-captured dataset. They show or hide packets without deleting them. You can change them freely at any time during analysis. Use these for interactive investigation — try different filters, narrow down, pivot to related traffic.
The syntax differences:
| Task | Capture Filter (BPF) | Display Filter |
|---|---|---|
| By IP | host 192.168.1.1 | ip.addr == 192.168.1.1 |
| By port | port 80 | tcp.port == 80 |
| Protocol | tcp | tcp |
| Source IP | src host 192.168.1.1 | ip.src == 192.168.1.1 |
| Destination port | dst port 443 | tcp.dstport == 443 |
| Contains string | (BPF byte-offset syntax required) | tcp contains "facebook" |
Creating Filters in Wireshark
Protocol Filters
The simplest filter is a protocol name:
tcpudphttpdnssmtpftptlsicmparp
Type the protocol in the filter bar, watch it turn green (valid syntax), and press Enter. Wireshark hides all packets except those that contain that protocol. This is usually the first filter to apply — cut the noise down to the protocol you care about before narrowing further.
IP Address Filters
# Traffic to or from either directionip.addr == 192.168.1.107# Only traffic FROM this IPip.src == 192.168.1.107# Only traffic TO this IPip.dst == 192.168.1.107# Entire subnetip.addr == 192.168.1.0/24# Exclude an IP!(ip.addr == 192.168.1.1)
Note the double equals sign (==). A single = is not valid in Wireshark display filter syntax. This trips up people accustomed to shell syntax.
Port and Direction Filters
# Traffic on port 80 (either direction)tcp.port == 80# Traffic TO port 80tcp.dstport == 80# Traffic FROM port 443tcp.srcport == 443# Multiple ports using the set syntax (Wireshark 4.0+)tcp.port in {80, 443, 8080}# UDP DNSudp.port == 53
Content Filters
When you need to find traffic containing a specific string in the payload, use the contains operator:
# Find packets with "facebook" anywhere in the TCP payloadtcp contains facebook# HTTP requests containing a specific URIhttp.request.uri contains "login"# Find DNS queries for a specific domaindns.qry.name contains "malware"
For regular expression matching, use the matches operator (also written as ~):
# HTTP GET requests for .ru domainshttp matches "https?.*?\.ru"# Any packet matching a suspicious URL patternhttp.request.uri matches "\.php\?id=[0-9]+"
The matches operator uses PCRE (Perl-Compatible Regular Expressions) syntax. In tshark, you need to escape the inner quotes when using matches from the command line.
contains and matches cannot be used on atomic fields (numbers, IP addresses). They work on string and byte-sequence fields.
The Expression Builder
If you are not sure what field to filter on, the Expression builder (the dropdown to the right of the filter bar) provides a searchable list of every protocol and every field available for filtering — thousands of entries. Select a protocol, expand it to find the specific field, select a relation operator, and enter a value. Wireshark builds the filter expression for you.
Wireshark Operator Reference
| Operator | Meaning |
|---|---|
== | Equal to |
!= | Not equal to |
> | Greater than |
< | Less than |
>= | Greater than or equal to |
<= | Less than or equal to |
contains | Protocol or field contains a value |
matches or ~ | Field matches a PCRE regular expression |
in | Field value is a member of a set {val1, val2, val3} |
&& or and | Logical AND |
|| or or | Logical OR |
! or not | Logical NOT |
Common Pitfalls with Negation
Before Wireshark 3.6, negation with != on IP address fields had unintuitive behavior. The filter:
ip.addr != 10.43.54.65
did NOT mean “exclude all traffic involving this IP.” It meant “show packets where the source is not this IP AND the destination is not this IP.” A packet from 10.43.54.65 to another host would pass the filter because the destination was not 10.43.54.65. The correct way to exclude an IP was:
!(ip.addr == 10.43.54.65)
Wireshark 3.6 changed the != interpretation for fields that can appear on either side of a packet (like ip.addr), bringing it in line with what most users expected. But if you are working with captures in an older Wireshark version or writing filters that need to be backward compatible, use the !( ... == ...) form explicitly.
Following Streams
Individual packets in isolation are often not useful. What you want is the reconstructed conversation — the full HTTP request and response, the FTP command and data exchange, the SMTP session from EHLO to ..
Wireshark’s Follow Stream feature reconstructs and displays the full application-layer conversation from a sequence of related packets.
To use it: click any packet belonging to the conversation you want to follow, then right-click and select Follow > TCP Stream (or UDP Stream, or HTTP Stream, or TLS Stream for encrypted traffic where you have the session keys).
This opens a window showing the complete session content in ASCII, with client-to-server traffic in one color and server-to-client in another. At the bottom of the window, statistics show the byte counts for each direction.
What Follow Stream reveals that packet-by-packet analysis cannot: the full HTTP headers and body, the file that was downloaded, the commands typed in a Telnet session, the credentials passed in an FTP login sequence, the JSON payload from an API call. For incident response — reconstructing what an attacker did after initial access, for example — this is often the most direct path to the answer.
You can also follow streams on the command line using tshark:
# Follow TCP stream number 0 and output as ASCIItshark -r capture.pcap -z follow,tcp,ascii,0# Follow the first HTTP streamtshark -r capture.pcap -z follow,http,ascii,0
The filter Wireshark applies when you follow a stream — something like tcp.stream eq 3 — is just a display filter you can use directly to focus on that conversation. Note this number and use it to return to that stream if you close the follow window.
Statistics in Wireshark
The Statistics menu provides analytical summaries of an entire capture that go well beyond per-packet inspection.
Protocol Hierarchy (Statistics > Protocol Hierarchy): Shows every protocol present in the capture as a percentage of total packets and bytes. This is the fastest way to understand what a capture contains: if 40% of traffic is TLS, 30% is DNS, 20% is QUIC, and you were expecting only HTTP, something is unusual. Use this as a sanity check when you first open a capture file.
Conversations (Statistics > Conversations): Lists every unique pair of communicating hosts, with byte counts, packet counts, and duration for each conversation. The IP tab shows IP-level conversations, the TCP tab adds port information. Sorting by bytes descending quickly surfaces the highest-bandwidth connections — useful when looking for data exfiltration.
Endpoints (Statistics > Endpoints): Lists every unique host that appears in the capture, with traffic statistics. This is where you identify unknown IP addresses that should not be present on the network.
IO Graphs (Statistics > I/O Graph): Plots packet rate or byte rate over time. Beaconing malware shows up here as regular spikes at consistent intervals — a visual pattern that is hard to spot in the packet list but obvious on a time-series graph.
Flow Graph (Statistics > Flow Graph): Shows a sequence diagram of packet exchanges between endpoints, which is excellent for visualizing multi-step protocol exchanges like TCP handshakes, TLS negotiation, or DNS resolution sequences.
IPv4 Statistics > All Addresses (Statistics > IPv4 Statistics > All Addresses): Every IP address in the capture with packet counts and byte totals — useful for building a quick inventory of hosts seen in a capture.
For baselining purposes, run statistics against a known-good capture of normal traffic. Store the Protocol Hierarchy percentages and Endpoint list. When you capture the same network later and run the same statistics, deviations become visible — new protocols, new endpoints, unusual traffic volumes.
tshark: Wireshark on the Command Line
tshark is the command-line version of Wireshark. It uses Wireshark’s dissectors and display filter language, but runs without a GUI. This makes it useful for remote server analysis (where you cannot run a GUI efficiently), scripting, and batch processing of large capture files.
# Capture 100 packets on eth0, display verbose outputtshark -i eth0 -c 100 -V# Read a capture file and apply a display filtertshark -r capture.pcap -Y "ip.addr == 192.168.1.100 and tcp.port == 80"# Extract specific fields in tab-delimited formattshark -r capture.pcap -T fields -e ip.src -e ip.dst -e tcp.dstport# Apply a capture filter (BPF syntax) during live capturetshark -i eth0 -f "port 443"# Save filtered output to a new filetshark -r full_capture.pcap -Y "http" -w http_only.pcap# Show protocol statisticstshark -r capture.pcap -z io,phs -q# Follow TCP stream 0tshark -r capture.pcap -z follow,tcp,ascii,0 -q
The key distinction: -f takes a BPF capture filter (same syntax as tcpdump), while -Y takes a Wireshark display filter. They are not interchangeable.
Display filters in tshark are more powerful than capture filters but run after packets are already in memory, so on high-traffic live captures, using -Y alone can cause packet loss. For live captures with heavy traffic, apply a broad BPF capture filter with -f first, then use -Y to further refine the display.
For scripting and automation, the -T fields -e field.name pattern is invaluable. It produces structured, parseable output that can be piped to awk, sort, uniq, or fed into Python for further analysis.
Practical Exercises
Work through these in a lab environment with two machines — a Kali Linux box and any other system (a Windows VM works fine). The goal is not just to run the commands but to understand what each output is telling you.
Exercise 1: Filter only your own traffic with tcpdump
Find your IP address with ip addr show. Then run:
tcpdump -nn -i eth0 host YOUR_IP_HERE
Browse to a few sites in a browser and watch what appears. You should see DNS queries (UDP port 53) first, then TCP SYN packets, then SYN-ACK responses, then data transfer. Try to identify the three-way handshake sequence for each new connection.
Exercise 2: Capture and filter traffic from a specific website
Open a browser and navigate to thecybersecguru.com. At the same time, run Wireshark and apply the display filter:
ip.addr == <ip address of thecybersecguru.com>
You can find the IP by pinging the domain first. Follow the TCP stream for one of the connections. Read the raw HTTP request and response.
Exercise 3: Hunt for a string in live traffic
Navigate to a non-HTTPS web page (harder to find these days, but any http:// URL works). In Wireshark, apply:
tcp contains "hacker"
Or choose another word you expect to see on the page. If you find packets, check the Packet Bytes Pane and confirm the word appears in the ASCII view.
Exercise 4: Enumerate all connections to your system with netstat and ss
netstat -an | grep ESTABLISHEDss -tnp state established
Compare the output. Note the format differences and the additional detail (ss shows the file descriptor number). Look at which processes have established connections and whether any are unexpected.
Exercise 5: tcpdump credential hunt against a test HTTP server
If you have an Apache server running (systemctl start apache2), configure a basic auth protected directory and then attempt to log in from a browser. Capture with:
tcpdump -lA port 80 | egrep -i 'Authorization:|username|password'
HTTP Basic Auth credentials are Base64-encoded (not encrypted). You can decode them with echo 'base64string' | base64 -d.
Exercise 6: Wireshark stream statistics
Open a capture file in Wireshark (or use a live capture). Navigate to Statistics > Conversations > TCP tab. Sort by bytes descending. The top entry is your highest-bandwidth connection. Right-click it and select “Follow Stream” to see what was transferred.
Final Thoughts
The tools covered here are not steps on the way to something more sophisticated. They are the destination. tcpdump and Wireshark are what gets used in production incident response, in enterprise security operations centers, in penetration testing engagements, and in forensic investigations. The engineers who are most effective with these tools are not the ones who know the most flags — they are the ones who understand TCP enough to know what they are looking for before they start filtering.
Start with the exercises above. Then look at real captures from CTF challenges or public pcap repositories. The Wireshark sample captures page hosts dozens of captures across every protocol, including some that contain actual malware traffic. There is no better way to build the pattern recognition that makes network analysis genuinely useful than working with real packets.
This post first appeared at - The CyberSec Guru