tshark: Wireshark’s dissection on the command line
Wireshark’s brain, tcpdump’s ergonomics
tcpdump gives you fast, low-overhead capture; Wireshark gives you deep protocol dissection. tshark is the bridge — Wireshark’s dissectors and display-filter language, but on the terminal and scriptable. That makes it the right tool when you want to extract fields, follow streams, compute statistics, or emit JSON/CSV for downstream processing without opening a GUI. This page covers capture vs. display filters, field extraction, output formats, stream following, statistics, TLS decryption, and the one-liners that turn a capture into data.
Introduction
tshark is the command-line version of Wireshark. Where tcpdump excels at fast, low-overhead capture with BPF filtering, tshark brings Wireshark’s deep protocol dissection to the terminal — parsing hundreds of protocols, extracting fields by name, and producing structured output suitable for scripting.
Both tools use libpcap for capture, so the capture side is equivalent. The difference is in what you can do with the packets after capture: tshark understands application-layer protocols, can follow streams, decrypt TLS (given keys), and output JSON or CSV for downstream processing.
Basic Usage
# Capture on default interface, print to terminal
tshark
# Capture on a specific interface
tshark -i eth0
# List available interfaces
tshark -D
# Capture to a file
tshark -i eth0 -w capture.pcap
# Read from a saved file
tshark -r capture.pcap
# Limit capture to N packets
tshark -i eth0 -c 100
# Capture for N seconds
tshark -i eth0 -a duration:30
Display Filters
tshark supports two distinct filter systems:
- Capture filters (
-f): BPF syntax, same astcpdump. Applied in the kernel at capture time. - Display filters (
-Y): Wireshark display filter syntax. Applied after decode, can reference any dissected field.
Display filters are far more expressive than BPF because they operate on fully decoded packets.
# Show only HTTP traffic
tshark -r capture.pcap -Y 'http'
# Show only DNS queries
tshark -r capture.pcap -Y 'dns.flags.response == 0'
# Show only DNS responses with NXDOMAIN
tshark -r capture.pcap -Y 'dns.flags.rcode == 3'
# Show only TLS ClientHello packets
tshark -r capture.pcap -Y 'tls.handshake.type == 1'
# Show HTTP requests with a specific User-Agent
tshark -r capture.pcap -Y 'http.user_agent contains "curl"'
# Show TCP connections that were reset
tshark -r capture.pcap -Y 'tcp.flags.reset == 1'
# Show ICMP echo requests
tshark -r capture.pcap -Y 'icmp.type == 8'
# Show packets larger than 1400 bytes
tshark -r capture.pcap -Y 'frame.len > 1400'
# Combine with and/or
tshark -r capture.pcap -Y 'ip.src == 10.0.0.1 and tcp.port == 443'
Capture Filters
# Capture only traffic to/from a host (BPF, same as tcpdump)
tshark -i eth0 -f 'host 10.0.0.1'
# Capture only port 80 and 443
tshark -i eth0 -f 'tcp port 80 or tcp port 443'
# Capture and immediately apply a display filter
tshark -i eth0 -f 'not port 22' -Y 'http'
Extracting Specific Fields
The -T fields mode prints only the fields you specify with -e. This is extremely useful for extracting data for scripting.
# Extract source IP, destination IP, and protocol
tshark -r capture.pcap -T fields -e ip.src -e ip.dst -e ip.proto
# Extract DNS query names
tshark -r capture.pcap -Y 'dns' -T fields -e dns.qry.name
# Extract HTTP request URIs
tshark -r capture.pcap -Y 'http.request' -T fields -e http.request.method -e http.request.uri -e http.host
# Extract TLS SNI (Server Name Indication) — hostnames from encrypted traffic
tshark -r capture.pcap -Y 'tls.handshake.extensions_server_name' -T fields -e tls.handshake.extensions_server_name
# Add a header line and use tab separation
tshark -r capture.pcap -Y 'dns' -T fields -e frame.number -e ip.src -e dns.qry.name -E header=y -E separator=,
Field Output Options (-E)
| Option | Values | Description |
|---|---|---|
header=y/n |
y, n |
Print column header row |
separator=, |
any char | Field delimiter (default: tab) |
quote=d/s/n |
d, s, n |
Quote fields with double, single, or no quotes |
occurrence=f/l/a |
f, l, a |
For repeated fields: first, last, or all occurrences |
Output Formats
# Default columnar output
tshark -r capture.pcap
# JSON output (one object per packet, fully decoded)
tshark -r capture.pcap -T json
# JSON with only selected fields
tshark -r capture.pcap -T jsonfields -e ip.src -e ip.dst
# PDML (XML, Packet Details Markup Language)
tshark -r capture.pcap -T pdml
# Plain text fields
tshark -r capture.pcap -T fields -e frame.number -e ip.src
# EK (Elasticsearch bulk import JSON)
tshark -r capture.pcap -T ek
Following Streams
# Follow a TCP stream (reassembles the full conversation)
tshark -r capture.pcap -z follow,tcp,ascii,0
# Follow stream number 3
tshark -r capture.pcap -z follow,tcp,ascii,3
# Follow a UDP stream
tshark -r capture.pcap -z follow,udp,ascii,0
# Follow HTTP stream
tshark -r capture.pcap -z follow,http,ascii,0
The stream index corresponds to Wireshark’s stream numbering. Use tcp.stream == N as a display filter to identify which stream you want first.
Statistics
tshark -z provides a wide range of built-in statistics.
# Protocol hierarchy — what protocols are present and how much traffic each carries
tshark -r capture.pcap -z io,phs -q
# Conversation list (all IP pairs that communicated)
tshark -r capture.pcap -z conv,ip -q
# TCP conversation list
tshark -r capture.pcap -z conv,tcp -q
# Endpoint list (all IPs seen)
tshark -r capture.pcap -z endpoints,ip -q
# HTTP request/response statistics
tshark -r capture.pcap -z http,tree -q
# DNS statistics
tshark -r capture.pcap -z dns,tree -q
# IO statistics (packet counts per time interval)
tshark -r capture.pcap -z io,stat,1 -q
# Expert info (warnings, errors, notes from dissectors)
tshark -r capture.pcap -z expert -q
The -q flag suppresses per-packet output so only the statistics are shown.
TLS Decryption
If you have the session keys (via SSLKEYLOGFILE), tshark can decrypt TLS traffic.
# Capture while logging TLS keys from your browser or application
export SSLKEYLOGFILE=~/tls-keys.log
chromium &
tshark -i eth0 -w capture.pcap
# Decrypt during analysis
tshark -r capture.pcap -o tls.keylog_file:tls-keys.log -Y 'http'
# Extract decrypted HTTP URIs
tshark -r capture.pcap -o tls.keylog_file:tls-keys.log -Y 'http.request' \
-T fields -e http.request.uri
Many runtimes support SSLKEYLOGFILE: Chrome, Firefox, curl, Python’s ssl module (via a wrapper), and OpenSSL applications built with the right hooks.
Useful One-Liners
# Top talkers — count packets per source IP
tshark -r capture.pcap -T fields -e ip.src | sort | uniq -c | sort -rn | head
# All unique DNS names queried
tshark -r capture.pcap -Y 'dns.flags.response == 0' -T fields -e dns.qry.name | sort -u
# All HTTP hosts contacted
tshark -r capture.pcap -Y 'http.request' -T fields -e http.host | sort -u
# All TLS SNI names (encrypted traffic destinations)
tshark -r capture.pcap -Y 'tls.handshake.type == 1' -T fields -e tls.handshake.extensions_server_name | sort -u
# Extract HTTP response codes and URIs
tshark -r capture.pcap -Y 'http.response' -T fields -e http.request.uri -e http.response.code
# Find all files transferred over HTTP (Content-Disposition or content-type)
tshark -r capture.pcap -Y 'http' -T fields -e http.content_type -e http.file_data
# Count packets by protocol
tshark -r capture.pcap -T fields -e frame.protocols | sort | uniq -c | sort -rn
Comparing tshark and tcpdump
| Feature | tcpdump | tshark |
|---|---|---|
| Protocol dissection | Basic (IP/TCP/UDP headers) | Deep (hundreds of protocols) |
| Filter syntax | BPF only | BPF (capture) + display filters |
| Field extraction | No | Yes (-T fields -e) |
| Stream reassembly | No | Yes (-z follow) |
| JSON/structured output | No | Yes (-T json, -T ek) |
| TLS decryption | No | Yes (with key log) |
| Overhead | Very low | Higher (full decode) |
| Availability | Ubiquitous | Requires Wireshark install |
Use tcpdump when you need fast, lightweight capture — especially on embedded systems or servers without Wireshark installed. Use tshark when you need protocol-aware filtering, field extraction, or stream reassembly.
Key takeaways
tsharkis Wireshark’s engine on the CLI: samelibpcapcapture astcpdump, same dissectors and display filters as Wireshark, but scriptable.- Two filter flags:
-ftakes a BPF capture filter (kernel, capture time);-Ytakes a Wireshark display filter (post-decode, any dissected field). Display filters are far more expressive. -T fields -e <field>is the workhorse for scripting — pull named fields out of decoded packets and shape them with-E(header, separator, quoting, occurrence).- Structured output (
-T json,-T ek,-T pdml) and built-in statistics (-z ..., with-qto suppress per-packet lines) turn a capture into analyzable data. - It can reassemble streams (
-z follow,...) and decrypt TLS given anSSLKEYLOGFILE— thingstcpdumpcan’t do. - Reach for
tcpdumpwhen you need ubiquity and minimal overhead; reach fortsharkwhen you need protocol awareness, field extraction, or stream reassembly.
References
- tshark man page. https://www.wireshark.org/docs/man-pages/tshark.html
- Wireshark display filter reference (all fields). https://www.wireshark.org/docs/dfref/
- Wireshark User’s Guide. https://www.wireshark.org/docs/wsug_html_chunked/
Related course pages: Capturing traffic with tcpdump · Analyzing traffic with Wireshark · Network flow analysis
🛠️ Maintenance note:
tsharkoutput formats and-zstatistic names evolve between Wireshark major releases (the-T ek/jsonfieldsmodes especially), and display-filter field names occasionally change — the linked display filter reference is authoritative. Re-verify the TLS-keylog decryption flow each term, since browser/runtime support forSSLKEYLOGFILEshifts.