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.
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 outputRequires 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/tcpdumpCommon 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 intervalSelecting 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.100Basic 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 -fBasic 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.200Port 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 443Network 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 80Output 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 precisionContent 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 80Saving 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.pcapTCP‑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/nullAnalyzing 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/nullPerformance 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.pcapFile 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.pcapBuffer 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_defaultAdvanced 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=4096MTU 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 icmpPractical 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
doneHTTP 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 -20Packet 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.txtQuick 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.pcapCommon 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.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Raymond Ops
Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
