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

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

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

Exit mobile version