Operations 36 min read

20 Essential tcpdump Commands Every Ops Engineer Should Know

This comprehensive guide introduces tcpdump, the Linux equivalent of Wireshark, and walks through 20 frequently used command combinations covering basic packet capture, filtering by host, port, protocol, output formatting, performance tuning, advanced BPF filters, real‑world troubleshooting scenarios, and best‑practice recommendations for production environments.

Raymond Ops
Raymond Ops
Raymond Ops
20 Essential tcpdump Commands Every Ops Engineer Should Know

tcpdump Basics

How it works

tcpdump uses the libpcap library, reads packets from the network driver via an AF_PACKET socket, and performs filtering and formatting in user space.

Network → NIC driver → AF_PACKET socket → libpcap → tcpdump → user output

Requires root or CAP_NET_RAW capability.

# Check capability
tcpdump -D
# Run with sudo
sudo tcpdump -i eth0
# Add capabilities
sudo setcap cap_net_raw,cap_net_admin=eip /usr/sbin/tcpdump

Common options

-i <interface>   Specify interface
-c <count>       Capture a specific number of packets then exit
-n               Do not resolve hostnames
-nn              Do not resolve hostnames or ports
-v, -vv, -vvv    Increase verbosity
-X               Hex and ASCII payload
-XX              Hex, ASCII and Ethernet header
-e               Show link‑layer header
-s <snaplen>     Capture first <snaplen> bytes (0 = full packet)
-w <file>        Write to file
-r <file>        Read from file
-C <size>        Split output files by size (MB)
-G <seconds>     Split output files by time interval

Selecting interfaces

# List interfaces
tcpdump -D
# Capture on specific interface
tcpdump -i eth0
# Capture on all interfaces
tcpdump -i any
# Capture on loopback
tcpdump -i lo
# Docker bridge
tcpdump -i docker0
# VLAN 100
tcpdump -i eth0.100

Basic capture commands

Capture all traffic

# First 100 packets on eth0
tcpdump -i eth0 -c 100
# Continuous capture
tcpdump -i eth0
# Save to file
tcpdump -i eth0 -w /tmp/capture.pcap
# Tee effect: save and display
tcpdump -i eth0 -w /tmp/capture.pcap &
 tcpdump -r /tmp/capture.pcap | tail -f

Basic filter expressions

Host filtering

# Specific IP
tcpdump -i eth0 host 192.168.1.100
# Source or destination IP
tcpdump -i eth0 src 192.168.1.100
tcpdump -i eth0 dst 192.168.1.100
# Exclude IP
tcpdump -i eth0 not host 192.168.1.100
# Between two hosts
tcpdump -i eth0 host 192.168.1.100 and 192.168.1.200

Port filtering

# Specific port
tcpdump -i eth0 port 80
# Source or destination port
tcpdump -i eth0 src port 80
tcpdump -i eth0 dst port 80
# Exclude port
tcpdump -i eth0 not port 22
# Port range
tcpdump -i eth0 portrange 80-443
# Multiple ports
tcpdump -i eth0 port 80 or port 443
tcpdump -i eth0 port 80 or 443

Network filtering

# Subnet
tcpdump -i eth0 net 192.168.1.0/24
# Exclude subnet
tcpdump -i eth0 not net 192.168.1.0/24
# Combine network and port
tcpdump -i eth0 net 192.168.1.0/24 and port 80

Output formatting

Display control

# Numeric output only
tcpdump -i eth0 -nn port 80
# Verbosity levels
tcpdump -i eth0 -v port 80
tcpdump -i eth0 -vv port 80
tcpdump -i eth0 -vvv port 80
# Timestamps
tcpdump -i eth0 -tttt port 80   # full date‑time
tcpdump -i eth0 -tt port 80     # time only
tcpdump -i eth0 -ttttu port 80 # microsecond precision

Content display

# Link‑layer header
tcpdump -i eth0 -e port 80
# Hex + ASCII
tcpdump -i eth0 -X port 80
# Hex + ASCII + Ethernet header
tcpdump -i eth0 -XX port 80
# Header only (snaplen 68)
 tcpdump -i eth0 -s 68 port 80
# Full packet
 tcpdump -i eth0 -s 0 port 80
# ASCII strings
 tcpdump -i eth0 -A port 80

Saving and reading

# Save to file
 tcpdump -i eth0 -w /tmp/capture.pcap
# Read from file
 tcpdump -r /tmp/capture.pcap
# Read with additional filter
 tcpdump -r /tmp/capture.pcap 'tcp[tcpflags] & tcp-syn != 0'
# Compress on the fly
 tcpdump -i eth0 -w - | gzip > /tmp/capture.pcap.gz
 gunzip -c /tmp/capture.pcap.gz | tcpdump -r -
# Size‑based rotation (100 MB)
 tcpdump -i eth0 -C 100 -w /tmp/capture_%Y%m%d_%H%M%S.pcap
# Time‑based rotation (5 min)
 tcpdump -i eth0 -G 300 -w /tmp/capture_%Y%m%d_%H%M.pcap

TCP‑specific filters

TCP flag filtering

# SYN packets (connection establishment)
 tcpdump -i eth0 'tcp[tcpflags] == tcp-syn'
# SYN‑ACK packets
 tcpdump -i eth0 'tcp[tcpflags] == 18'
# ACK packets
 tcpdump -i eth0 'tcp[tcpflags] & tcp-ack != 0'
# FIN packets (connection termination)
 tcpdump -i eth0 'tcp[tcpflags] & tcp-fin != 0'
# RST packets (reset)
 tcpdump -i eth0 'tcp[tcpflags] & tcp-rst != 0'
# PSH‑ACK packets (data transfer)
 tcpdump -i eth0 'tcp[tcpflags] & 24 == 24'
# All handshake and teardown packets
 tcpdump -i eth0 'tcp[tcpflags] & (tcp-syn|tcp-fin|tcp-rst) != 0'
# SYN‑only packets (possible SYN flood)
 tcpdump -i eth0 'tcp[tcpflags] == tcp-syn'

TCP sequence and window

# Specific sequence number
 tcpdump -i eth0 'tcp[4:4] = 12345'
# Specific acknowledgment number
 tcpdump -i eth0 'tcp[8:4] = 54321'
# Non‑zero window (exclude zero‑window)
 tcpdump -i eth0 'tcp[tcpflags] & tcp-ack != 0 and tcp[14:2] > 0'
# Zero‑window warnings
 tcpdump -i eth0 'tcp[14:2] = 0 and tcp[tcpflags] & tcp-ack != 0'

TCP options filtering

# SYN with MSS option
 tcpdump -i eth0 'tcp[tcpflags] == tcp-syn and tcp[20] == 2 and tcp[21] == 4'
# SYN with Window Scale
 tcpdump -i eth0 'tcp[tcpflags] == tcp-syn and tcp[20] == 3 and tcp[21] == 3'
# Packets with SACK option
 tcpdump -i eth0 'tcp[tcpflags] & tcp-ack != 0 and tcp[tcpflags] & tcp-syn == 0 and tcp[21] >= 5'
# Packets with Timestamp option
 tcpdump -i eth0 'tcp[tcpflags] == tcp-syn and tcp[20] == 8 and tcp[21] == 10'

Real‑world scenarios

Analyzing HTTP requests

# GET requests (hex "GE")
 tcpdump -i eth0 -nn -A 'tcp[((tcp[12:1] & 0xf0) >> 2):2] = 0x4745' 2>/dev/null
# HTTP headers (push flag)
 tcpdump -i eth0 -nn -A 'tcp port 80 and tcp[tcpflags] & tcp-push != 0' | head -50
# Full HTTP session
 tcpdump -i eth0 -nn -X 'tcp port 80'
# HTTP responses (hex "HTTP")
 tcpdump -i eth0 -nn -A 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x48545450' 2>/dev/null
# Extract Host header
 tcpdump -i eth0 -nn -A 'tcp port 80' 2>/dev/null | grep -i "host:"

Analyzing DNS queries

# Queries and responses
 tcpdump -i eth0 -nn -v 'udp port 53'
# Queries only
 tcpdump -i eth0 -nn -A 'udp port 53 and udp[10:2] = 0x0100' 2>/dev/null
# Responses only
 tcpdump -i eth0 -nn -A 'udp port 53 and udp[10:2] = 0x8180' 2>/dev/null
# Queries for a specific domain (example.com)
 tcpdump -i eth0 -nn -v 'udp port 53 and ip[2:2] > 40' 2>/dev/null | grep "example.com"

Analyzing SSH sessions

# Connection establishment
 tcpdump -i eth0 -nn 'tcp port 22 and tcp[tcpflags] & (tcp-syn|tcp-fin|tcp-rst) != 0'
# Data transfer
 tcpdump -i eth0 -nn -X 'tcp port 22 and tcp[tcpflags] & tcp-ack != 0'
# Latency (timestamps)
 tcpdump -i eth0 -nn -tttt 'tcp port 22' 2>/dev/null | awk '{print $1, $NF}'
# Keepalive packets
 tcpdump -i eth0 -nn -v 'tcp port 22 and tcp[tcpflags] & tcp-ack != 0 and tcp[tcpflags] & tcp-psh != 0 and tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x01010500' 2>/dev/null

Analyzing MySQL connections

# Handshake (SYN)
 tcpdump -i eth0 -nn -X 'tcp port 3306 and tcp[tcpflags] & tcp-syn != 0'
# Queries (push flag)
 tcpdump -i eth0 -nn -A 'tcp port 3306 and tcp[tcpflags] & tcp-push != 0' | grep -E "(SELECT|INSERT|UPDATE|DELETE|COMMIT)"
# Responses (ACK)
 tcpdump -i eth0 -nn -A 'tcp port 3306 and tcp[tcpflags] & tcp-ack != 0' | head -100
# Full session capture
 tcpdump -i eth0 -nn -w /tmp/mysql.pcap 'tcp port 3306'

Analyzing Redis connections

# Commands (push flag)
 tcpdump -i eth0 -nn -X 'tcp port 6379 and tcp[tcpflags] & tcp-push != 0' 2>/dev/null
# Extract commands
 tcpdump -i eth0 -nn -A 'tcp port 6379' 2>/dev/null | strings | grep -E "^(GET|SET|DEL|HSET|HGET|EXPIRE|LRANGE)"
# Response time (requires timestamps)
 tcpdump -i eth0 -nn -tttt 'tcp port 6379' 2>/dev/null

Performance and resource control

Limiting capture size

# Header only
 tcpdump -i eth0 -s 68
# Header + payload
 tcpdump -i eth0 -s 100
# Full packet
 tcpdump -i eth0 -s 0
# Fixed packet count
 tcpdump -i eth0 -c 100
# Fixed capture time (e.g., 60 s)
 timeout 60 tcpdump -i eth0 -w /tmp/capture.pcap

File size control

# Split files at 100 MB
 tcpdump -i eth0 -C 100 -w /tmp/capture.pcap
# Keep at most 10 files (overwrite oldest)
 tcpdump -i eth0 -C 100 -W 10 -w /tmp/capture.pcap
# Time‑based rotation (every 5 min)
 tcpdump -i eth0 -G 300 -w /tmp/capture_%Y%m%d_%H%M.pcap
# Combined size and time rotation
 tcpdump -i eth0 -G 300 -C 50 -w /tmp/capture.pcap

Buffer settings

# Increase kernel receive buffer (MB)
 tcpdump -i eth0 -B 4096
# Adjust system buffers
 echo 16777216 > /proc/sys/net/core/rmem_max
 echo 16777216 > /proc/sys/net/core/rmem_default

Advanced techniques

Expression combination

# Simple logical operators
 tcpdump -i eth0 'host 192.168.1.100 and port 80'
 tcpdump -i eth0 'host 192.168.1.100 or host 192.168.1.200'
 tcpdump -i eth0 'not host 192.168.1.100'
 tcpdump -i eth0 'host 192.168.1.100 and not port 22'
# Complex combination
 tcpdump -i eth0 '(host 192.168.1.100 or host 192.168.1.200) and (port 80 or port 443)'
# Non‑local HTTP requests
 tcpdump -i eth0 'not net 192.168.0.0/24 and not net 10.0.0.0/8 and port 80'

Advanced BPF filters

# IP fragments
 tcpdump -i eth0 'ip[6:2] & 0x1fff != 0'
# TTL < 10
 tcpdump -i eth0 'ip[8] < 10'
# DSCP EF (0x80)
 tcpdump -i eth0 'ip[1] & 0xfc == 0x80'
# Specific IP protocol numbers
 tcpdump -i eth0 'ip[9] = 6'   # TCP
 tcpdump -i eth0 'ip[9] = 17'  # UDP
 tcpdump -i eth0 'ip[9] = 1'   # ICMP
# IP length > 600 bytes
 tcpdump -i eth0 'ip[2:2] > 600'
# TCP payload > 0
 tcpdump -i eth0 'tcp[tcpflags] & tcp-ack != 0 and (ip[2:2] - ((ip[0]&0xf)<<2) - ((tcp[12]&0xf0)>>2)) > 0'

Combining with other tools

# Real‑time HTTP request count
 tcpdump -i eth0 -nn 'tcp port 80' 2>/dev/null | awk '{print $5}' | sort | uniq -c | sort -rn
# Top 10 request IPs
 tcpdump -i eth0 -nn 'tcp port 80' 2>/dev/null | awk '{print $3}' | cut -d. -f1-4 | sort | uniq -c | sort -rn | head -10
# Periodic TCP state summary
 watch -n 1 "ss -tan | awk '{print $1}' | sort | uniq -c | sort -rn"
# Extract possible credentials (use with caution)
 tcpdump -i eth0 -nn -A 'tcp port 80' 2>/dev/null | strings | grep -iE "(password|passwd|pwd|token|secret)"

Using Wireshark for deep analysis

# Capture then open in Wireshark
 tcpdump -i eth0 -nn -s 0 -w /tmp/capture.pcap 'tcp port 8080'
# Real‑time streaming to Wireshark
 tcpdump -i eth0 -nn -s 0 -w - 'tcp port 8080' | wireshark -k -i -
# Remote capture, local analysis
 ssh root@server "tcpdump -i eth0 -nn -s 0 -w - 'tcp port 8080'" > /tmp/capture.pcap
# Export a specific connection from a file
 tcpdump -r /tmp/capture.pcap -w output.pcap "host 192.168.1.100"

Common fault diagnosis

Network latency analysis

# Capture timestamps for a port
 tcpdump -i eth0 -nn -tttt port 8080 2>/dev/null
# Example workflow (pseudo‑code):
# 1. Find client SYN packet
# 2. Find server SYN‑ACK packet
# 3. Compute time difference
 tcpdump -i eth0 -nn -tttt 'tcp port 80' 2>/dev/null | awk '
/SYN/ {syn=$2; syn_ip=$5}
/SYN.*ACK/ {print "SYN→SYN‑ACK:", syn, $2, $5}
/ACK.*8080/ {print "SYN‑ACK→ACK:", $2, $5}'

Connection reset diagnosis

# Capture RST packets
 tcpdump -i eth0 -nn 'tcp[tcpflags] & tcp-rst != 0'
# Capture RST with context (limit to 1000 packets)
 tcpdump -i eth0 -nn -c 1000 'tcp[tcpflags] & (tcp-rst|tcp-ack) != 0' 2>/dev/null
# Capture RST after connection is established
 tcpdump -i eth0 -nn 'tcp[tcpflags] & tcp-rst != 0 and tcp[tcpflags] & tcp-ack != 0'

Packet loss analysis

# SYN retransmission count (simple indicator)
 tcpdump -i eth0 -nn 'tcp[tcpflags] & tcp-syn != 0' 2>/dev/null | wc -l
# Duplicate ACKs (sign of loss)
 tcpdump -i eth0 -nn 'tcp[tcpflags] == tcp-ack and tcp[26:4] = 0x01000000' 2>/dev/null
# SACK blocks
 tcpdump -i eth0 -nn 'tcp[tcpflags] & tcp-ack != 0 and tcp[tcpflags] & tcp-syn == 0' 2>/dev/null | grep "SACK"

SYN flood diagnosis

# Capture all SYN packets
 tcpdump -i eth0 -nn 'tcp[tcpflags] == tcp-syn'
# Count SYNs per second
 tcpdump -i eth0 -nn 'tcp[tcpflags] == tcp-syn' 2>/dev/null | awk '{print $1}' | cut -d. -f1 | uniq -c
# Check half‑open queue
 ss -ltn state syn-recv
# Verify SYN cookie status
 cat /proc/sys/net/ipv4/tcp_syncookies
# Increase backlog if queue full
 sysctl -w net.ipv4.tcp_max_syn_backlog=4096
 sysctl -w net.core.somaxconn=4096

MTU problems

# Capture IP fragments
 tcpdump -i eth0 -nn 'ip[6:2] & 0x4000 != 0'
 tcpdump -i eth0 -nn 'ip[6:2] & 0x1fff != 0'
# Detect ICMP "fragmentation needed"
 tcpdump -i eth0 -nn 'icmp[icmptype] == 3 and icmp[icmpcode] == 4'
# Generic ICMP packets
 tcpdump -i eth0 -nn icmp

Practical scripts

Real‑time network monitoring script (SYN‑flood alert)

#!/bin/bash
INTERFACE=${1:-eth0}
THRESHOLD=${2:-100}
echo "=== Network Monitoring Started ==="
echo "Interface: $INTERFACE"
echo "Threshold: $THRESHOLD SYN/s"
rm -f /tmp/tcpdump_*.pcap
trap 'echo "Stopping..."; pkill -P $$; exit 0' INT
while true; do
    SYN_COUNT=$(timeout 1 tcpdump -i $INTERFACE -c 1000 'tcp[tcpflags] == tcp-syn' 2>/dev/null | wc -l)
    echo "$(date '+%Y-%m-%d %H:%M:%S') SYN count: $SYN_COUNT"
    if [ $SYN_COUNT -gt $THRESHOLD ]; then
        echo "Warning: SYN count exceeds threshold, possible SYN flood"
        echo "Saving capture..."
        timeout 60 tcpdump -i $INTERFACE -nn -w /tmp/tcpdump_$(date +%Y%m%d_%H%M%S).pcap 'tcp[tcpflags] == tcp-syn' &
    fi
    sleep 5
done

HTTP request analysis script

#!/bin/bash
PORT=${1:-80}
OUTPUT="/tmp/http_analysis_$(date +%Y%m%d_%H%M%S).txt"
echo "=== HTTP Traffic Analysis ===" | tee $OUTPUT
echo "Port: $PORT" | tee -a $OUTPUT
echo "Start time: $(date)" | tee -a $OUTPUT

# Recent 20 HTTP requests
echo "=== Recent 20 HTTP Requests ===" | tee -a $OUTPUT
timeout 30 tcpdump -i eth0 -nn -A "tcp port $PORT and tcp[tcpflags] & tcp-push != 0" 2>/dev/null \
    | grep -E "^(GET|POST|PUT|DELETE|HEAD|OPTIONS|PATCH)" | head -20 | tee -a $OUTPUT

# Request type statistics
echo "=== Request Type Statistics ===" | tee -a $OUTPUT
timeout 30 tcpdump -i eth0 -nn -c 1000 "tcp port $PORT" 2>/dev/null \
    | awk '/GET/ {g++; next} /POST/ {p++; next} /PUT/ {u++; next} /DELETE/ {d++; next} END {print "GET:", g, "POST:", p, "PUT:", u, "DELETE:", d}' \
    | tee -a $OUTPUT

# Top 10 destination IPs
echo "=== Top 10 Destination IPs ===" | tee -a $OUTPUT
timeout 30 tcpdump -i eth0 -nn -c 1000 "tcp port $PORT" 2>/dev/null \
    | awk '{print $5}' | cut -d. -f1-4 | sort | uniq -c | sort -rn | head -10 | tee -a $OUTPUT

echo "Analysis complete, saved to: $OUTPUT"

TCP connection state analysis script

#!/bin/bash
echo "=== TCP Connection State Analysis ==="
echo "Analysis time: $(date)"

# Current state counts
echo "=== Current State Counts ==="
ss -tan | awk 'NR>1 {print $1}' | sort | uniq -c | sort -rn

# TIME_WAIT details (top 20)
echo "=== TIME_WAIT Details TOP 20 ==="
ss -tan state time-wait | awk 'NR>1 {print $4}' | cut -d: -f1 | sort | uniq -c | sort -rn | head -20

# CLOSE_WAIT details
CLOSE_WAIT=$(ss -tan state close-wait | awk 'NR>1 {print $4}' | wc -l)
echo "CLOSE_WAIT connections: $CLOSE_WAIT"
if [ $CLOSE_WAIT -gt 100 ]; then
    echo "Warning: CLOSE_WAIT count high"
    ss -tan state close-wait | awk 'NR>1 {print $4, $5}' | head -20
fi

# SYN_RECVD details (possible attack)
SYN_RECV=$(ss -tan state syn-recv | awk 'NR>1 {print $4}' | wc -l)
echo "SYN_RECVD connections: $SYN_RECV"
if [ $SYN_RECV -gt 1000 ]; then
    echo "Warning: SYN_RECVD count high, possible SYN flood"
fi

# Established connections (top 20)
echo "=== Established Connections TOP 20 ==="
ss -tan state established | awk 'NR>1 {print $4}' | cut -d: -f1 | sort | uniq -c | sort -rn | head -20

Packet loss detection script

#!/bin/bash
INTERFACE=${1:-eth0}
TARGET=${2:-8.8.8.8}
echo "=== Network Packet Loss Detection ==="
echo "Target: $TARGET"
echo "Start time: $(date)"

# Ping test
echo "=== Ping Test ==="
ping -c 100 -i 0.2 $TARGET | tail -5

# TCP retransmission detection (10 s capture)
echo "=== TCP Retransmission Detection ==="
timeout 10 tcpdump -i $INTERFACE -c 10000 'tcp[tcpflags] & tcp-ack != 0' 2>/dev/null > /tmp/tcp_check.txt

SYN_COUNT=$(grep -c "SYN" /tmp/tcp_check.txt)
FIN_COUNT=$(grep -c "FIN" /tmp/tcp_check.txt)
RST_COUNT=$(grep -c "RST" /tmp/tcp_check.txt)
TOTAL=$(wc -l < /tmp/tcp_check.txt)

echo "Total packets: $TOTAL"
echo "SYN packets: $SYN_COUNT"
echo "FIN packets: $FIN_COUNT"
echo "RST packets: $RST_COUNT"
if [ $RST_COUNT -gt 10 ]; then
    echo "Warning: High RST count, possible connection issues"
fi

# System packet loss statistics
echo "=== System Packet Loss Statistics ==="
netstat -s | grep -iE "(segments retransmited|segment lost|lists overflow)" | head -10

rm -f /tmp/tcp_check.txt

Quick reference

Capture all packets: tcpdump -i eth0 Capture specific host: tcpdump -i eth0 host 192.168.1.100 Capture specific port: tcpdump -i eth0 port 80 Save to file: tcpdump -i eth0 -w file.pcap Read from file: tcpdump -r file.pcap Numeric output: tcpdump -i eth0 -nn Show packet content: tcpdump -i eth0 -X Capture SYN packets: tcpdump -i eth0 'tcp[tcpflags] == tcp-syn' Capture RST packets: tcpdump -i eth0 'tcp[tcpflags] & tcp-rst != 0' Capture HTTP traffic: tcpdump -i eth0 -A 'tcp port 80' Capture ICMP packets: tcpdump -i eth0 icmp Split files by size (100 MB):

tcpdump -i eth0 -C 100 -w file.pcap

Common errors

Omitting -i may capture nothing: use tcpdump -i eth0.

Not setting snaplen can produce huge files; use -s 68 or -s 100 when full payload is unnecessary.

Missing quotes around filter expressions cause shell parsing errors; always wrap expressions in single quotes, e.g., tcpdump -i eth0 'host 192.168.1.100 and port 80'.

Omitting -nn leads to slow DNS reverse lookups; use tcpdump -i eth0 -nn port 80 for faster output.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

network troubleshootingLinuxpacket captureBPFshell scriptingtcpdump
Raymond Ops
Written by

Raymond Ops

Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.