TShark: Complete Guide to Command-Line Packet Capture and Network Traffic Analysis Using Kali Linux

TShark: Complete Guide to Command-Line Packet Capture and Network Traffic Analysis Using Kali Linux

Tshark (Terminal-based Wireshark) is the command-line counterpart to Wireshark. It shares the exact same core packet-capture and dissection engine as Wireshark — the same protocol dissectors, the same filter language, the same capture library (libpcap/Npcap) — but exposes it entirely through a text-based interface instead of a GUI. This makes Tshark the tool of choice whenever packet analysis needs to happen without a graphical environment: on headless servers, over SSH sessions, inside automated pipelines, in CI/CD security testing, or on resource-constrained systems.

Because Tshark understands the identical capture filter (BPF) and display filter syntax as Wireshark, analysts can prototype filters visually in Wireshark and then port them directly to Tshark for scripted, repeatable, high-volume processing. Tshark can output data as plain text, fields in CSV, JSON, PDML/PSML XML, and more, making it easy to feed into other tools such as grep, awk, jq, Python scripts, or SIEM ingestion pipelines.

In Kali Linux, Tshark is installed as part of the wireshark / tshark packages and is heavily used in scripted penetration testing and network forensics workflows where a GUI is impractical.

How to Install

# Update package lists
sudo apt update

# Install tshark (also installs as part of the wireshark package group)
sudo apt install tshark -y

# During install you may again be prompted:
# "Should non-superusers be able to capture packets?" -> select <Yes>

Allow a non-root user to capture (same group mechanism as Wireshark):

sudo usermod -aG wireshark $USER
newgrp wireshark

Verify installation:

tshark --version

Expected output:

TShark (Wireshark) 4.2.5 (Git commit unknown)

Copyright 1998-2024 Gerald Combs <gerald@wireshark.org> and contributors.
License GPLv2+: GNU GPL version 2 or later
...
Compiled with libpcap, with POSIX capabilities, with libnl 3, with GLib 2.78.4
Running on Linux 6.6.15-amd64, with libpcap version 1.10.4

Syntax

tshark [OPTIONS] ...

General patterns:

tshark -i eth0                             # Live capture, printed to terminal
tshark -i eth0 -w out.pcapng                # Live capture, saved to a file
tshark -r in.pcapng                         # Read from an existing capture
tshark -r in.pcapng -Y "http.request"       # Read + display filter
tshark -r in.pcapng -T fields -e ip.src -e ip.dst   # Field extraction

All Command-Line Options (Kali Linux)

-h, --help                       Print help and exit
-v, --version                    Print version and exit

Capture:
  -i <interface>                  Name/index/pipe of interface (or 'any')
  -f <capture filter>             BPF capture filter
  -s <snaplen>                    Snapshot length
  -p                               Don't use promiscuous mode
  -I                               Capture in monitor mode
  -B <buffer size>                 Capture buffer size (MB)
  -y <link type>                   Link layer type
  -D                               Print interfaces list and exit
  -L                               Print link-layer types for interface and exit
  --list-time-stamp-types          List time stamp types for interface

Stop conditions:
  -c <packet count>                Stop after n packets
  -a <autostop cond.>              duration:NUM, filesize:NUM, files:NUM, packets:NUM

Output/ring buffer:
  -b <ringbuffer opt.>              duration:NUM, filesize:NUM, files:NUM
  -w <outfile|->                   Write raw packet data to outfile

Input file:
  -r <infile>                       Read packets from infile

Processing:
  -Y <display filter>               Apply display filter (post-capture)
  -R <read filter>                  Read filter (only with -2, two-pass mode)
  -n                                 Disable name resolution
  -N <mtnNdsv>                       Enable specific name resolution
  -d <selector>==<value>,<proto>     Decode as
  -2                                 Two-pass analysis

Output format:
  -T pdml|ps|psml|text|fields|json|jsonraw|ek     Output format
  -e <field>                         Field to display (used with -T fields)
  -E <field option>                  Field output options (header=y, separator=, quote=, etc.)
  -x                                 Add hex/ASCII dump to output
  -V                                 Add packet detail (verbose) view
  -O <protocols>                     Only show packet details for listed protocols
  -S <separator>                     Line separator for output records
  -t a|ad|d|dd|e|r|u|ud               Timestamp format
  -u s|hms                             Seconds format

Statistics:
  -z <statistics>                   Show statistics (e.g., io,phs / conv,tcp / http,tree)
  -q                                 Combined with capture, don't print packets
  -Q                                 Quit after capture (no display)

Miscellaneous:
  -K <keytab>                        Kerberos keytab
  -o <preference>:<value>            Set a preference
  -C <config profile>                Use configuration profile
  -G [report]                        Dump internal Wireshark data (fields, protocols, etc.)

5. Basic Usage (Expected Output in Bash)

List interfaces:

tshark -D

Output:

1. eth0
2. wlan0
3. lo (Loopback)
4. any
5. bluetooth0

Basic live capture (Ctrl+C to stop):

tshark -i eth0

Output:

Capturing on 'eth0'
    1 0.000000 192.168.1.10 → 8.8.8.8      DNS 74 Standard query 0x1a2b A example.com
    2 0.021345 8.8.8.8 → 192.168.1.10      DNS 90 Standard query response 0x1a2b A 93.184.216.34
    3 0.023110 192.168.1.10 → 93.184.216.34 TCP 74 51322 → 443 [SYN] Seq=0 Win=64240 Len=0
    4 0.045992 93.184.216.34 → 192.168.1.10 TCP 74 443 → 51322 [SYN, ACK] Seq=0 Ack=1 Win=65535 Len=0
^C4 packets captured

Practical Examples with Output

Example 1: Capture 20 packets and write to a file

tshark -i eth0 -c 20 -w capture.pcapng

Output:

Capturing on 'eth0'
20 packets captured

Example 2: Read a file and filter for HTTP requests

tshark -r capture.pcapng -Y "http.request"

Output:

   45 3.120044 192.168.1.10 → 93.184.216.34 HTTP 421 G ET /index.html HTTP/1.1
   88 5.882221 192.168.1.10 → 151.101.1.69  HTTP 389 G ET /style.css HTTP/1.1

Example 3: Extract specific fields to CSV format

tshark -r capture.pcapng -T fields -e frame.number -e ip.src -e ip.dst -e tcp.port -E header=y -E separator=, > flows.csv

Output (flows.csv, first lines):

frame.number,ip.src,ip.dst,tcp.port
1,192.168.1.10,8.8.8.8,
3,192.168.1.10,93.184.216.34,51322
4,93.184.216.34,192.168.1.10,443

Example 4: JSON output for scripted parsing

tshark -r capture.pcapng -Y "dns" -T json > dns.json

Output (dns.json excerpt):

[
  {
    "_index": "packets-2026-07-19",
    "_source": {
      "layers": {
        "frame": { "frame.number": "1" },
        "dns": {
          "dns.qry.name": "example.com",
          "dns.qry.type": "1"
        }
      }
    }
  }
]

Example 5: Protocol hierarchy statistics

tshark -r capture.pcapng -q -z io,phs

Output:

===================================================================
Protocol Hierarchy Statistics
Filter:

eth                                     frames:15234 bytes:12432011
  ip                                    frames:15036 bytes:12213984
    tcp                                 frames:11607 bytes:9812443
      http                              frames:1843  bytes:1921012
    udp                                 frames:3429   bytes:2301102
      dns                               frames:2880   bytes:1103221
===================================================================

Example 6: TCP conversation statistics

tshark -r capture.pcapng -q -z conv,tcp

Output:

================================================================================
TCP Conversations
Filter:<No Filter>
                                              |       <-      | |       ->      | |     Total     |
A                    B              Frames  Bytes   Frames Bytes   Frames Bytes  Duration
192.168.1.10:51322  93.184.216.34:443  420  310120   422   302011    842  612131  14.221
================================================================================

Example 7: Extract all unique DNS query names

tshark -r capture.pcapng -Y "dns.flags.response==0" -T fields -e dns.qry.name | sort -u

Output:

example.com
google.com
kali.org
pypi.org

Example 8: Live capture with rotating output files (ring buffer)

tshark -i eth0 -b filesize:10240 -b files:5 -w /var/captures/cap.pcapng

Output:

Capturing on 'eth0'
(writes cap.pcapng, cap.pcapng_00001_..., ... rotating after every 10MB,
 keeping a maximum of 5 files)

Example 9: Follow a TCP stream from the command line

tshark -r capture.pcapng -q -z follow,tcp,ascii,0

Output:

===================================================================
Follow: tcp,ascii
Filter: tcp.stream eq 0
Node 0: 192.168.1.10:51322
Node 1: 93.184.216.34:443

===================================================================

Example 10: Filter and count packets matching a BPF capture filter live

tshark -i eth0 -f "icmp" -c 5

Output:

Capturing on 'eth0'
    1 0.000000 192.168.1.10 → 8.8.8.8   ICMP 98 Echo (ping) request  id=0x1 seq=1/256
    2 0.020112 8.8.8.8 → 192.168.1.10   ICMP 98 Echo (ping) reply    id=0x1 seq=1/256
    3 1.001233 192.168.1.10 → 8.8.8.8   ICMP 98 Echo (ping) request  id=0x1 seq=2/512
    4 1.021002 8.8.8.8 → 192.168.1.10   ICMP 98 Echo (ping) reply    id=0x1 seq=2/512
    5 2.002344 192.168.1.10 → 8.8.8.8   ICMP 98 Echo (ping) request  id=0x1 seq=3/768
5 packets captured

Example 11: HTTP request/response statistics tree

tshark -r capture.pcapng -q -z http,tree

Output:

================================================================================
HTTP/Requests
Topic / Item        Count    Average  Min val  Max val  Rate (ms)   Percent
HTTP                  120                                            100%
  G ET                  95                                            79.17%
  POST                 25                                            20.83%
Status Code:200        88                                            73.33%
Status Code:404        12                                            10.00%
================================================================================

Example 12: Extract credentials from unencrypted FTP traffic

tshark -r ftp_capture.pcapng -Y "ftp.request.command==USER or ftp.request.command==PASS" -T fields -e ftp.request.command -e ftp.request.arg

Output:

USER    admin
PASS    Sup3rSecret!

Common Use Cases

  • Automated, scheduled packet captures on servers with no GUI (e.g., via cron).
  • Fast field extraction for feeding SIEMs, log pipelines, or custom Python/Bash analysis scripts.
  • CI/CD pipeline network testing — verifying that specific protocol handshakes occur as expected.
  • Remote packet analysis over SSH where forwarding a GUI is impractical.
  • Bulk statistics generation across many capture files for reporting.
  • Extracting IOCs (indicators of compromise) such as suspicious DNS queries or destination IPs from large pcap archives.
  • Lightweight, resource-constrained capture on embedded devices or cloud VMs.

Automation with Bash

Continuous capture with automatic daily rotation and filtering for suspicious DNS traffic:

#!/bin/bash
# dns_monitor.sh - captures traffic, extracts DNS queries hourly

IFACE="eth0"
OUTDIR="/var/log/tshark"
mkdir -p "$OUTDIR"

while true; do
    TS=$(date +%Y%m%d_%H%M%S)
    OUTFILE="${OUTDIR}/dns_${TS}.pcapng"
    tshark -i "$IFACE" -f "udp port 53" -a duration:3600 -w "$OUTFILE"
    tshark -r "$OUTFILE" -Y "dns.flags.response==0" -T fields -e frame.time -e ip.src -e dns.qry.name \
        >> "${OUTDIR}/dns_queries.log"
done

Batch-processing many pcap files to extract a summary CSV report:

#!/bin/bash
# summarize_pcaps.sh
echo "file,packets,tcp_packets,udp_packets,dns_queries" > summary.csv

for f in /data/pcaps/*.pcap; do
    total=$(tshark -r "$f" -q -z io,stat,0 2>/dev/null | grep -c "^|")
    tcp=$(tshark -r "$f" -Y "tcp" -T fields -e frame.number | wc -l)
    udp=$(tshark -r "$f" -Y "udp" -T fields -e frame.number | wc -l)
    dns=$(tshark -r "$f" -Y "dns.flags.response==0" -T fields -e frame.number | wc -l)
    echo "$f,$total,$tcp,$udp,$dns" >> summary.csv
done

echo "[*] Report written to summary.csv"

Piping live extracted fields directly into another tool (e.g., real-time alerting on suspicious ports):

tshark -i eth0 -f "tcp" -T fields -e ip.src -e tcp.dstport 2>/dev/null | \
while read -r src port; do
    if [[ "$port" == "4444" || "$port" == "1337" ]]; then
        echo "[ALERT] Suspicious connection from $src to port $port at $(date)"
    fi
done

Tips and Best Practices

  • Use -Q combined with -z statistics for lean, script-friendly summary output without printing every packet.
  • Prefer -T fields -e … over parsing -T text output with regex; field extraction is far more reliable for automation.
  • Use -2 (two-pass analysis) when applying read filters (-R) that depend on later packets, such as TCP reassembly-dependent filters.
  • Always apply capture filters (-f, BPF syntax) rather than display filters (-Y) when you can, since capture filters reduce the data volume at the point of capture and improve performance.
  • When writing automation, always redirect stderr (2>/dev/null) to avoid polluting parsed output with warnings.
  • Combine Tshark with jq for powerful JSON-based filtering: tshark -r file.pcap -T json | jq ‘.[]._source.layers.dns’.
  • Use ring buffers (-b) for long-running captures to avoid filling disk space.
  • Keep dissectors updated; run sudo apt upgrade tshark wireshark-common regularly since protocol dissection accuracy depends on dissector freshness.

Troubleshooting

Problem: “You don’t have permission to capture on that device.” Solution: Same fix as Wireshark — add user to wireshark group, ensure dumpcap has proper capabilities via setcap.

Problem: Tshark hangs with no output during a live capture. Solution: Confirm traffic is actually reaching the interface (ip -s link show eth0); check that a capture filter isn’t inadvertently excluding all traffic; try without -f first.

Problem: JSON/PDML output is too large / slow for very big captures. Solution: Apply a display filter before exporting, or extract only needed fields with -T fields -e instead of full -T json/-T pdml.

Problem: -z statistics show no output. Solution: Statistics with -z require -q in live-capture mode (otherwise packet-by-packet printing interferes); with -r file mode, ensure the requested -z name is spelled correctly (tshark -z help lists them).

Problem: Ring buffer files not rotating as expected. Solution: Ensure -w is used together with -b; ring buffer options only apply when writing raw capture files, not when using -T text output modes.

Problem: Slow performance during large-file field extraction. Solution: Avoid -x (hex dump) and -V (verbose) unless needed; they add significant processing overhead. Use targeted -Y filters to shrink the working set first.

References

  • Tshark man page: https://www.wireshark.org/docs/man-pages/tshark.html
  • Wireshark Display Filter Reference: https://www.wireshark.org/docs/dfref/
  • Wireshark User’s Guide (CLI chapter): https://www.wireshark.org/docs/wsug_html_chunked/AppToolstshark.html
  • Kali Linux Tools listing for Tshark: https://www.kali.org/tools/wireshark/
  • Wireshark Wiki (Statistics, -z options): https://wiki.wireshark.org/Statistics
Total
1
Shares

Leave a Reply

Previous Post
NetworkMiner: Complete Guide to Network Forensics and Packet Analysis Using Kali Linux

NetworkMiner: Complete Guide to Network Forensics and Packet Analysis Using Kali Linux

Next Post
Wireshark: Complete Guide to Packet Analysis and Network Troubleshooting Using Kali Linux

Wireshark: Complete Guide to Packet Analysis and Network Troubleshooting Using Kali Linux

Related Posts