Skip to content

Packet Capture

Chapter 88: Packet Capture and Network Analysis

Section titled “Chapter 88: Packet Capture and Network Analysis”

Comprehensive Guide to tcpdump, Wireshark, and Network Analysis

Section titled “Comprehensive Guide to tcpdump, Wireshark, and Network Analysis”

Packet capture is essential for network troubleshooting:

  • Debugging: See actual network traffic, not just logs
  • Security: Detect malicious traffic and attacks
  • Performance: Identify network bottlenecks
  • Compliance: Audit network communications
  • Root Cause: Network issues often need packet-level analysis

tcpdump and Wireshark are essential tools for any SRE or DevOps engineer.


Packet capture involves intercepting network packets as they travel across a network interface. This is essential for troubleshooting network issues, security analysis, and protocol debugging.

Packet Capture Architecture
+------------------------------------------------------------------+
| |
| Packet Capture Flow |
| |
| +-------------------------------------------------------------+|
| | Network Interface ||
| | +----------------------------------------------------------+ |
| | | Network Card (NIC) | |
| | | - Driver receives packets | |
| | | - Copies to kernel buffer | |
| | +----------------------------------------------------------+ |
| | | |
| | v |
| | +----------------------------------------------------------+ |
| | | Kernel (BPF) | |
| | | - Berkeley Packet Filter | |
| | | - Applies capture filter | |
| | | - Copies matching packets to userspace | |
| | +----------------------------------------------------------+ |
| | | |
| | v |
| | +----------------------------------------------------------+ |
| | | Capture Tool (tcpdump/Wireshark) | |
| | | - Receives filtered packets | |
| | | - Writes to file or displays | |
| | +----------------------------------------------------------+ |
| +------------------------------------------------------------+|
| |
| Capture Modes: |
| +----------------------------------------------------------+ |
| | Promiscuous | NIC accepts all packets (default) | |
| | Non-promiscuous | Only packets addressed to NIC | |
| | Monitor mode | All packets (wireless) | |
| +----------------------------------------------------------+ |
| |
+------------------------------------------------------------------+
PCAP File Format
+------------------------------------------------------------------+
| |
| PCAP Global Header (24 bytes): |
| +----------------------------------------------------------+ |
| | Magic Number (4 bytes) - 0xa1b2c3d4 or 0xd4c3b2a1 | |
| | Version Major (2 bytes) | |
| | Version Minor (2 bytes) | |
| | Thiszone (4 bytes) - Timezone offset | |
| | Sigfigs (4 bytes) - Timestamp accuracy | |
| | Snaplen (4 bytes) - Max packet length | |
| | Link Type (4 bytes) - Data link type (Ethernet=1) | |
| +----------------------------------------------------------+ |
| |
| Packet Header (16 bytes): |
| +----------------------------------------------------------+ |
| | Timestamp Seconds (4 bytes) | |
| | Timestamp Microseconds (4 bytes) | |
| | Captured Length (4 bytes) | |
| | Original Length (4 bytes) | |
| +----------------------------------------------------------+ |
| |
| Packet Data: |
| +----------------------------------------------------------+ |
| | Raw packet bytes | |
| +----------------------------------------------------------+ |
| |
| File Extensions: .pcap, .pcapng (PCAP Next Generation) |
| |
+------------------------------------------------------------------+

Terminal window
# Capture on specific interface
sudo tcpdump -i eth0
sudo tcpdump -i any
# Capture with hostname resolution (use -n to disable)
sudo tcpdump -i eth0 -n
# Capture specific number of packets
sudo tcpdump -i eth0 -c 100
# Capture to file
sudo tcpdump -i eth0 -w capture.pcap
# Read from file
tcpdump -r capture.pcap
tcpdump -r capture.pcap | head -20
# Verbose output
sudo tcpdump -i eth0 -v
sudo tcpdump -i eth0 -vv
sudo tcpdump -i eth0 -vvv
# Show packet contents
sudo tcpdump -i eth0 -X # Hex and ASCII
sudo tcpdump -i eth0 -XX # With link header
BPF Filter Syntax
+------------------------------------------------------------------+
| |
| Primitives (Basic): |
| +----------------------------------------------------------+ |
| | host x.x.x.x | Specific host | |
| | src host x.x.x.x | Source host | |
| | dst host x.x.x.x | Destination host | |
| | net x.x.x.x/nn | Network | |
| | src net x.x.x.x/nn | Source network | |
| | dst net x.x.x.x/nn | Destination network | |
| | port xx | Port | |
| | src port xx | Source port | |
| | dst port xx | Destination port | |
| | gateway hostname | Gateway | |
| +----------------------------------------------------------+ |
| |
| Protocols: |
| +----------------------------------------------------------+ |
| | tcp, udp, icmp, ip, ip6, arp, rarp, decnet | |
| +----------------------------------------------------------+ |
| |
| Direction: |
| +----------------------------------------------------------+ |
| | src, dst | |
| +----------------------------------------------------------+ |
| |
| Logical Operators: |
| +----------------------------------------------------------+ |
| | and (&&), or (||), not (!) | |
| +----------------------------------------------------------+ |
| |
| Examples: |
| +----------------------------------------------------------+ |
| | tcpdump host 10.0.0.1 | |
| | tcpdump port 80 | |
| | tcpdump src 10.0.0.1 and dst port 80 | |
| | tcpdump net 10.0.0.0/8 | |
| | tcpdump tcp and port 443 | |
| | tcpdump not port 22 | |
| +----------------------------------------------------------+ |
| |
+------------------------------------------------------------------+
Terminal window
# TCP flags
tcpdump 'tcp[tcpflags] & tcp-syn != 0' # SYN packets
tcpdump 'tcp[tcpflags] & tcp-ack != 0' # ACK packets
tcpdump 'tcp[tcpflags] & tcp-syn != 0 and tcp-ack == 0' # SYN only
tcpdump 'tcp[tcpflags] & tcp-rst != 0' # RST packets
tcpdump 'tcp[tcpflags] & tcp-fin != 0' # FIN packets
tcpdump 'tcp[tcpflags] & tcp-push != 0' # PSH packets
# Port ranges
tcpdump portrange 80-443
# ICMP types
tcpdump icmp[icmptype] == 8 # Echo request (ping)
tcpdump icmp[icmptype] == 0 # Echo reply
tcpdump icmp[icmptype] == 3 # Destination unreachable
# TCP connection establishment
tcpdump 'tcp[tcpflags] & (tcp-syn|tcp-ack) == (tcp-syn|tcp-ack)'
# HTTP requests
tcpdump -A 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420'
# Payload size
tcpdump 'tcp[2:2] > 1000' # Packets larger than 1000 bytes
# Combine filters
tcpdump -i eth0 'host 10.0.0.1 and (port 80 or port 443)'
tcpdump -i eth0 'not arp and not icmp'
Terminal window
# Timestamp formats
tcpdump -t # No timestamp
tcpdump -tt # Unix timestamp
tcpdump -ttt # Time since previous
tcpdump -tttt # Human readable with date
# Line numbers
tcpdump -n -l | nl
# Quick output (no DNS, less detail)
tcpdump -q
# Absolute sequence numbers
tcpdump -S
# Print packet length
tcpdump -e
# Complete packet dump
tcpdump -v -X

Terminal window
# Debian/Ubuntu
sudo apt install wireshark tshark
# RHEL/CentOS
sudo dnf install wireshark
# Arch Linux
sudo pacman -S wireshark-qt
# macOS
brew install --cask wireshark
Common Display Filters
+------------------------------------------------------------------+
| |
| Protocol Filters: |
| +----------------------------------------------------------+ |
| | tcp, udp, icmp, http, dns, ssh, ftp, smtp | |
| +----------------------------------------------------------+ |
| |
| Address Filters: |
| +----------------------------------------------------------+ |
| | ip.addr == 10.0.0.1 | |
| | ip.src == 10.0.0.1 | |
| | ip.dst == 10.0.0.1 | |
| | tcp.port == 80 | |
| | udp.port == 53 | |
| +----------------------------------------------------------+ |
| |
| HTTP Filters: |
| +----------------------------------------------------------+ |
| | http.request.method == "GET" | |
| | http.response.code == 200 | |
| | http.host == "example.com" | |
| | http.request.uri contains "/api/" | |
| +----------------------------------------------------------+ |
| |
| TCP Filters: |
| +----------------------------------------------------------+ |
| | tcp.flags.syn == 1 | |
| | tcp.flags.ack == 1 | |
| | tcp.flags.reset == 1 | |
| | tcp.analysis.retransmission | |
| | tcp.analysis.lost_segment | |
| +----------------------------------------------------------+ |
| |
| DNS Filters: |
| +----------------------------------------------------------+ |
| | dns.qry.type == 1 (A record) | |
| | dns.qry.type == 28 (AAAA record) | |
| | dns.resp.addr == 8.8.8.8 | |
| +----------------------------------------------------------+ |
| |
| Combined Filters: |
| +----------------------------------------------------------+ |
| | ip.addr == 10.0.0.1 and tcp.port == 80 | |
| | http.request.method == "POST" and ip.src == 10.0.0.5 | |
| | !(arp or icmp) | |
| +----------------------------------------------------------+ |
| |
+------------------------------------------------------------------+
Terminal window
# Capture packets
sudo tshark -i eth0 -c 100
sudo tshark -i eth0 -w capture.pcap
# Read and filter
tshark -r capture.pcap
tshark -r capture.pcap -Y "http.request"
tshark -r capture.pcap -Y "ip.addr == 10.0.0.1"
# Extract fields
tshark -r capture.pcap -T fields -e ip.src -e ip.dst -e tcp.port
# Statistics
tshark -r capture.pcap -z io,phs
tshark -r capture.pcap -z conv,tcp
tshark -r capture.pcap -z http,stat
tshark -r capture.pcap -z endpoints,ip
# Live capture with filters
sudo tshark -i eth0 -f "tcp port 80"
sudo tshark -i eth0 -f "host 10.0.0.1"
Terminal window
# Follow TCP stream
# In GUI: Right click → Follow → TCP Stream
# Export objects
# File → Export Objects → HTTP
# Expert information
# Analyze → Expert Information
# Decode as
# Right click → Decode As
# Time sequences
# Statistics → TCP Stream Graph → Time Sequence
# IO graphs
# Statistics → I/O Graph

Terminal window
# Capture HTTP traffic
sudo tcpdump -i eth0 -w http.pcap 'tcp port 80'
# Analyze HTTP requests
tcpdump -r http.pcap -n -A | grep "GET "
# Extract HTTP objects
# tshark -r http.pcap --export-objects "http,./export"
# HTTP statistics
tshark -r http.pcap -z http,stat
Terminal window
# Capture DNS
sudo tcpdump -i eth0 -w dns.pcap 'udp port 53'
# Show DNS queries
tcpdump -i eth0 -n 'udp port 53'
# DNS response codes
tcpdump -i eth0 -n -v 'udp port 53' | grep "DNS"
# Specific domain queries
tcpdump -i eth0 -n -v 'udp port 53' | grep "example.com"
Terminal window
# Capture TCP
sudo tcpdump -i eth0 -w tcp.pcap 'tcp'
# Show SYN packets (connection setup)
tcpdump -r tcp.pcap -n 'tcp[tcpflags] & tcp-syn != 0 and tcp-ack == 0'
# Show RST packets (connection reset)
tcpdump -r tcp.pcap -n 'tcp[tcpflags] & tcp-rst != 0'
# TCP handshake
tcpdump -r tcp.pcap -n -c 3 'host 10.0.0.1 and port 80'
# Retransmissions
tcpdump -r tcp.pcap -n 'tcp.analysis.retransmission'
Terminal window
# Find potential attacks
# SYN flood (many SYNs)
tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0 and tcp-ack == 0'
# Port scanning
tcpdump -i eth0 'tcp[13] = 2'
# Cleartext passwords
tcpdump -i eth0 port http or port ftp or port smtp -A
# Find ARP spoofing
tcpdump -i eth0 arp | grep -v reply
# Large ICMP (potential ping flood)
tcpdump -i eth0 'icmp and icmp[0] == 8 and icmp[8:4] > 1000'

Terminal window
# Calculate bandwidth from pcap
tcpdump -r capture.pcap -nn -c 1000 | awk '{print $10}' | cut -d. -f1 | bc
# Using tshark
tshark -r capture.pcap -q -z io,phs
# IO graph data
tshark -r capture.pcap -q -z "io,phs,ip"
# Packet size distribution
tshark -r capture.pcap -z "packetlen,sum,ip"
Terminal window
# Calculate RTT from SYN to SYN-ACK
tcpdump -r capture.pcap -nn -c 1000 'tcp[13] & 2 != 0' -tt | awk '{print $1}'
# Using tshark for timing
tshark -r capture.pcap -T fields -e frame.time_delta -e ip.src -e ip.dst
# TCP timing analysis
tshark -r capture.pcap -z "tcp,tree,ack"

  1. What is packet capture?

    • Intercepting network packets as they pass through a network interface
  2. What is the difference between tcpdump and Wireshark?

    • tcpdump is CLI-based; Wireshark has GUI (also tshark CLI)
  3. What is a BPF filter?

    • Berkeley Packet Filter - efficient kernel-level packet filtering
  4. What does promiscuous mode mean?

    • NIC accepts all packets, not just those addressed to it
  5. What is a PCAP file?

    • Packet capture file format for storing network traffic
  1. How do you capture only SYN packets?

    • tcpdump 'tcp[tcpflags] & tcp-syn != 0'
  2. What is the difference between capture and display filters?

    • Capture: BPF at kernel level; Display: Wireshark GUI filtering
  3. How do you analyze HTTP traffic?

    • tcpdump -i eth0 'tcp port 80'
  4. What is the TCP three-way handshake?

    • SYN → SYN-ACK → ACK
  5. How do you find retransmissions in tcpdump?

    • Use tcp.analysis.retransmission display filter in Wireshark
  1. Explain how packet capture works at the OS level

    • NIC driver → kernel buffer → BPF filter → userspace
  2. What is the difference between port mirroring and tap?

    • Port mirroring: switch copies traffic; TAP: hardware device copies
  3. How do you capture encrypted traffic?

    • Can’t decrypt, but can see metadata (timing, size, destinations)
  4. What are some indicators of compromise in packet capture?

    • Unusual ports, beaconing, large transfers to unknown IPs
  5. How do you handle high-bandwidth captures?

    • Ring buffers, sampling, filtering at capture point

WRONG:

Terminal window
# Capture everything - massive files
tcpdump -i eth0 -w capture.pcap
# Disk fills up quickly

CORRECT:

Terminal window
# Use BPF filters
tcpdump -i eth0 port 80 -w capture.pcap
tcpdump -i eth0 host 192.168.1.1 -w capture.pcap
tcpdump -i eth0 tcp and port 443 -w capture.pcap

Why: Unfiltered captures fill disk and are hard to analyze.


WRONG:

Terminal window
# Notpromisc mode - only sees own traffic
tcpdump -i eth0

CORRECT:

Terminal window
# Enable promiscuous mode
tcpdump -i eth0 -p
tcpdump -i eth0 -p port 80

Why: Need promiscuous mode to see all traffic on the network segment.


WRONG:

Terminal window
# Trying to see HTTPS content
tcpdump -i eth0 port 443
# Only seeing encrypted data

CORRECT:

Terminal window
# For HTTPS, use SSLKEYLOGFILE
SSLKEYLOGFILE=~/ssl-keys.txt curl https://example.com
# Then analyze in Wireshark with keys
# For debugging, use MITM proxy
# Or configure server to send plaintext

Why: Encrypted traffic can’t be read without keys.


WRONG:

Terminal window
# Production capture without limits
tcpdump -i any -w /var/log/capture.pcap
# System becomes extremely slow

CORRECT:

Terminal window
# Limit capture size
tcpdump -i eth0 -C 100 -W 5 -W /tmp/capture.pcap
# 100MB max per file, 5 files max
# Limit by packet count
tcpdump -i eth0 -c 1000 -w capture.pcap

Why: Packet capture can overwhelm production systems.


5. Not Using tcpdump vs Wireshark Properly

Section titled “5. Not Using tcpdump vs Wireshark Properly”

WRONG:

Terminal window
# Using tcpdump for complex analysis
tcpdump -r capture.pcap | grep HTTP
# Limited capabilities

CORRECT:

Terminal window
# Use tcpdump for capture, Wireshark for analysis
tcpdump -i eth0 -w capture.pcap
# Transfer to workstation and open in Wireshark
wireshark capture.pcap
# Or use tshark for CLI analysis
tshark -r capture.pcap -Y "http.request"

Why: Each tool has different strengths.


Quick Reference
+------------------------------------------------------------------+
| |
| tcpdump: |
| +----------------------------------------------------------+ |
| | sudo tcpdump -i eth0 | Capture | |
| | sudo tcpdump -i eth0 -w file.pcap | Save to file | |
| | tcpdump -r file.pcap | Read file | |
| | tcpdump -n host x.x.x.x | Filter by host | |
| | tcpdump port 80 | Filter by port | |
| | tcpdump -c 100 | Capture count | |
| +----------------------------------------------------------+ |
| |
| tshark: |
| +----------------------------------------------------------+ |
| | tshark -i eth0 -c 100 | Capture | |
| | tshark -r file.pcap | Read file | |
| | tshark -Y "filter" | Display filter | |
| | tshark -z io,phs | Protocol stats | |
| +----------------------------------------------------------+ |
| |
| BPF Primitives: |
| +----------------------------------------------------------+ |
| | host, src, dst, net, port, tcp, udp, icmp | |
| | and (&&), or (||), not (!) | |
| +----------------------------------------------------------+ |
| |
| Capture Flags: |
| +----------------------------------------------------------+ |
| | tcp-syn, tcp-ack, tcp-fin, tcp-rst, tcp-psh | |
| +----------------------------------------------------------+ |
| |
+------------------------------------------------------------------+