Repository navigation
EN_Net_Packet_Analysis
Q19. Explain the header structures of an Ethernet Frame, IP Packet, and TCP Segment, and how to analyze actual packets.
Per-Layer Encapsulation Structure:
┌─────────────────────────────────────────────────────────┐
│ Ethernet Frame (Layer 2) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ IP Packet (Layer 3) │ │
│ │ ┌─────────────────────────────────────────────────┐ │ │
│ │ │ TCP Segment (Layer 4) │ │ │
│ │ │ ┌─────────────────────────────────────────────┐ │ │ │
│ │ │ │ Application Data (Layer 7) │ │ │ │
│ │ │ └─────────────────────────────────────────────┘ │ │ │
│ │ └─────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
Ethernet Frame Structure (minimum 64 bytes ~ maximum 1518 bytes total):
┌──────────┬─────┬──────────┬──────────┬──────┬─────────┬─────┐
│ Preamble │ SFD │ Dst MAC │ Src MAC │ Type │ Payload │ FCS │
│ 7 bytes │1 byte│ 6 bytes │ 6 bytes │2 bytes│46-1500 │4 bytes│
└──────────┴─────┴──────────┴──────────┴──────┴─────────┴─────┘
Preamble: 10101010... (synchronization signal)
SFD: 10101011 (Start Frame Delimiter)
Dst MAC: Destination MAC address (e.g., aa:bb:cc:dd:ee:ff)
Src MAC: Source MAC address
Type: 0x0800 (IPv4), 0x0806 (ARP), 0x86DD (IPv6)
Payload: Upper-layer data (minimum 46 bytes - including padding)
FCS: CRC-32 error detection (Frame Check Sequence)
IP Packet Structure (IPv4, minimum 20 bytes):
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
┌───────┬───────┬───────────────┬───────────────────────────────┐
│Version│ IHL │ TOS/DSCP │ Total Length │
│ (4) │ (4) │ (8 bits) │ (16 bits) │
├───────────────────────────────┼───┬───────────────────────────┤
│ Identification │Flg│ Fragment Offset │
│ (16 bits) │(3)│ (13 bits) │
├───────────────┬───────────────┼───────────────────────────────┤
│ TTL │ Protocol │ Header Checksum │
│ (8 bits) │ (8 bits) │ (16 bits) │
├───────────────┴───────────────┴───────────────────────────────┤
│ Source IP Address │
│ (32 bits) │
├───────────────────────────────────────────────────────────────┤
│ Destination IP Address │
│ (32 bits) │
├───────────────────────────────────────────────────────────────┤
│ Options (if IHL > 5) │
└───────────────────────────────────────────────────────────────┘
Version: 4 (IPv4)
IHL: Header Length (5 = 20 bytes, max 15 = 60 bytes)
TOS/DSCP: Quality of Service (priority)
Total Len: Total length of header + data
ID: Packet identification during fragmentation
Flags: bit 0: Reserved (0)
bit 1: DF (Don't Fragment)
bit 2: MF (More Fragments)
TTL: Packet lifetime (decremented by 1 at each hop, discarded when it reaches 0)
Protocol: 6 (TCP), 17 (UDP), 1 (ICMP)
Checksum: IP header error detection
TCP Segment Structure (minimum 20 bytes):
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
┌───────────────────────────────┬───────────────────────────────┐
│ Source Port │ Destination Port │
│ (16 bits) │ (16 bits) │
├───────────────────────────────┴───────────────────────────────┤
│ Sequence Number │
│ (32 bits) │
├───────────────────────────────────────────────────────────────┤
│ Acknowledgment Number │
│ (32 bits) │
├───────┬───────┬─┬─┬─┬─┬─┬─┬─┬─┬───────────────────────────────┤
│ Offset│ Res. │C│E│U│A│P│R│S│F│ Window Size │
│ (4) │ (3) │W│C│R│C│S│S│Y│I│ (16 bits) │
│ │ │R│E│G│K│H│T│N│N│ │
├───────┴───────┴─┴─┴─┴─┴─┴─┴─┴─┴───────────────────────────────┤
│ Checksum │ Urgent Pointer │
│ (16 bits) │ (16 bits) │
├───────────────────────────────┴───────────────────────────────┤
│ Options (if Offset > 5) │
│ (variable) │
└───────────────────────────────────────────────────────────────┘
Seq Number: Position of the first byte of data
Ack Number: Position of the next data to be received
Flags:
- CWR (Congestion Window Reduced): congestion window reduced
- ECE (ECN-Echo): congestion notification
- URG (Urgent): urgent data
- ACK (Acknowledgment): acknowledgment
- PSH (Push): immediate delivery
- RST (Reset): force connection termination
- SYN (Synchronize): start connection
- FIN (Finish): terminate connection
Window Size: Receive buffer size (Flow Control)
Actual Packet Analysis (tcpdump):
# Capture HTTP GET requests
sudo tcpdump -i eth0 -nn -X 'tcp port 80 and host example.com'
Output:
14:30:15.123456 IP 192.168.1.10.54321 > 93.184.216.34.80: Flags [S], seq 1234567890
0x0000: 4500 003c 1c46 4000 4006 b1e6 c0a8 010a E..<.F@.@.......
0x0010: 5db8 d822 d431 0050 499d 162a 0000 0000 ]..".1.PI..*....
0x0020: a002 7210 e32d 0000 0204 05b4 0402 080a ..r..-..........
Analysis:
0x4500: Version=4, IHL=5, TOS=00
0x003c: Total Length = 60 bytes
0x1c46: Identification
0x4000: Flags=DF (Don't Fragment)
0x40: TTL = 64
0x06: Protocol = TCP (6)
0xc0a8010a: Source IP = 192.168.1.10
0x5db8d822: Dest IP = 93.184.216.34
0xd431: Source Port = 54321
0x0050: Dest Port = 80
0xa002: Data Offset = 10 (40 bytes), Flags = SYN / 0x7210: Window Size = 29200Wireshark Display Filters:
TCP 3-Way Handshake:
tcp.flags.syn==1 && tcp.flags.ack==0 # SYN
tcp.flags.syn==1 && tcp.flags.ack==1 # SYN-ACK
tcp.flags.syn==0 && tcp.flags.ack==1 && tcp.seq==1 # ACK
HTTP requests:
http.request.method == "GET"
http.response.code == 200
Retransmitted packets:
tcp.analysis.retransmission
Slow responses:
tcp.time_delta > 0.1
Packet loss:
tcp.analysis.lost_segment
Q20. What are the packet fragmentation problems caused by MTU/MSS mismatch, and how does PMTUD work?
MTU vs MSS:
MTU (Maximum Transmission Unit):
┌─────────────────────────────────────────────┐
│ Ethernet Header (14) │ IP Packet (1500) │ FCS (4) │
└─────────────────────────────────────────────┘
↑
MTU = 1500 bytes
MSS (Maximum Segment Size):
┌──────────────────────────────────────────────────────┐
│ IP Header (20) │ TCP Header (20) │ TCP Data (1460) │
└──────────────────────────────────────────────────────┘
↑
MSS = 1460 bytes
Formula: MSS = MTU - IP Header(20) - TCP Header(20)
Common MTU Values:
Ethernet: 1500 bytes
802.1Q VLAN: 1504 bytes (VLAN tag 4 bytes)
PPPoE: 1492 bytes (PPPoE header 8 bytes)
VPN (IPsec): 1400 bytes (encryption overhead about 100 bytes)
GRE Tunnel: 1476 bytes (GRE header 24 bytes)
VXLAN: 1450 bytes (VXLAN header 50 bytes)
Jumbo Frame: 9000 bytes (data center)
Packet Fragmentation Problem:
Scenario: Client MTU=1500, intermediate path MTU=1400
Client → Router1 (MTU 1500) → Router2 (MTU 1400) → Server
1. Client: sends a 1500-byte packet
2. Router2: MTU exceeded, fragmentation needed
DF Flag = 0 (fragmentation allowed):
Original: [IP Header | 1480 bytes data]
Fragment1: [IP Header | 1376 bytes | MF=1]
Fragment2: [IP Header | 104 bytes | MF=0]
DF Flag = 1 (fragmentation prohibited):
Router2: sends ICMP "Fragmentation Needed"
packet discarded
PMTUD (Path MTU Discovery) Operation:
1. Client: sends a 1500-byte packet with the DF flag set
2. Reaches the MTU 1400 router:
→ ICMP Type 3 Code 4 (Fragmentation Needed and DF set) response
→ Next-Hop MTU: 1400
3. Client: updates its Path MTU to 1400
→ retransmits a 1400-byte packet
4. Successfully passes all segments along the path
→ Path MTU = 1400 confirmed
5. Adjusts MSS for the TCP Connection:
MSS = 1400 - 20(IP) - 20(TCP) = 1360 bytes
PMTUD Practice:
# Test MTU with ping
ping -M do -s 1472 8.8.8.8
# -M do: set the DF flag
# -s 1472: 1472 bytes of data (1500 - 20 IP - 8 ICMP)
Success: 1472 bytes fit → MTU 1500
Failure: ICMP "Frag needed" → MTU < 1500
# Find the Path MTU by binary search
ping -M do -s 1400 8.8.8.8 # success
ping -M do -s 1450 8.8.8.8 # success
ping -M do -s 1470 8.8.8.8 # failure
ping -M do -s 1460 8.8.8.8 # success
→ Path MTU = 1488~1497 (1460~1469 + 20 IP + 8 ICMP); probe 1461~1469 to pin it downPMTUD Black Hole Problem:
Problem: a firewall blocks ICMP "Fragmentation Needed"
Client ─── Router (MTU 1400, ICMP blocked) ─── Server
│ │
└──── 1500 bytes (DF=1) ────X (discarded) │
│ │
└──── waits for ICMP response ────X (timeout)│
│ │
└──── retransmit ────X (repeat) │
Result: connection fails or is extremely slow
Solutions:
1. TCP MSS Clamping (recommended):
# Clamp MSS with iptables
iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN \
-j TCPMSS --set-mss 1360
# Cisco router
interface GigabitEthernet0/0
ip tcp adjust-mss 1360
How it works:
Forcibly lowers the MSS option in SYN packets
→ both sides use smaller segments
→ no fragmentation occurs2. Manual MTU Adjustment:
# Linux
ip link set dev eth0 mtu 1400
# Windows
netsh interface ipv4 set subinterface "Ethernet" mtu=1400
# Persistent setting (Linux /etc/network/interfaces)
auto eth0
iface eth0 inet dhcp
mtu 14003. PLPMTUD (Packetization Layer PMTUD):
TCP's own PMTUD (RFC 4821):
- Does not rely on ICMP
- Discovers MTU using probe packets
- More reliable but slower
MSS Calculation in VPN Environments:
IPsec VPN:
Physical MTU: 1500
IPsec Overhead: ~100 (ESP header, IV, Padding, Auth)
Effective MTU: 1400
TCP MSS: 1400 - 20(IP) - 20(TCP) = 1360
VXLAN:
Physical MTU: 1500
VXLAN Overhead: 50 (Outer Ethernet 14 + Outer IP 20 + Outer UDP 8 + VXLAN 8)
Effective MTU: 1450
TCP MSS: 1450 - 20 - 20 = 1410
Monitoring:
# Check for fragmented packets
tcpdump -i eth0 'ip[6:2] & 0x3fff != 0'
# Check Path MTU (Linux)
ip route get 8.8.8.8 | grep mtu
# Check TCP MSS (Wireshark)
tcp.options.mssScenario 1: Slow Website Response
Symptom: Web page loading takes more than 5 seconds
tcpdump Capture:
# Capture HTTP traffic on port 80 with microsecond timestamps
sudo tcpdump -i eth0 -nn -tttt -s 65535 'tcp port 80' -w slow-web.pcap
# Live analysis (with timestamps)
sudo tcpdump -i eth0 -nn -tttt 'host example.com and tcp port 80'
Output:
2024-01-15 14:30:00.123456 IP 192.168.1.10.54321 > 93.184.216.34.80: Flags [S]
2024-01-15 14:30:00.323456 IP 93.184.216.34.80 > 192.168.1.10.54321: Flags [S.]
↑ 200ms delay (SYN-ACK)
2024-01-15 14:30:00.323789 IP 192.168.1.10.54321 > 93.184.216.34.80: Flags [.]
2024-01-15 14:30:00.324567 IP 192.168.1.10.54321 > 93.184.216.34.80: ... HTTP GET
2024-01-15 14:30:05.123456 IP 93.184.216.34.80 > 192.168.1.10.54321: ... HTTP 200
↑ 4.8s delay (server response)Wireshark Analysis:
1. Statistics → Conversations → TCP
→ check Duration 4.8s and Bytes
2. Statistics → I/O Graph
→ visualize traffic over time
→ spot the response wait periods
3. Display Filter:
tcp.time_delta > 1.0
→ show only packets delayed 1s or more
4. Expert Info (Analyze → Expert Information)
→ check for "TCP Window Full" warnings
→ server window too small (small receive buffer)
Cause: Insufficient server TCP Window Size (16KB) Solution: Increase the server receive buffer
sysctl -w net.ipv4.tcp_rmem='4096 87380 6291456'Scenario 2: Intermittent Packet Loss
Symptom: Degraded VoIP call quality, dropouts
tcpdump Capture:
# Capture RTP traffic (typically UDP ports 10000-20000)
sudo tcpdump -i eth0 -nn -s 65535 'udp portrange 10000-20000' -w voip.pcap
# Packet loss (by RTP sequence number, requires tshark)
tshark -r voip.pcap -d udp.port==10000,rtp -q -z rtp,streamsWireshark Analysis:
1. Telephony → RTP → RTP Streams
→ Packet Loss: 3.5% (normal < 1%)
→ Jitter: 50ms (normal < 30ms)
2. Display Filter:
rtp
→ check RTP Sequence Numbers
→ detect gaps in the increasing sequence
3. I/O Graph:
Y Axis: SUM(rtp.timestamp)
→ uneven pattern = Jitter
4. Expert Info:
→ many "Out-of-Order" warnings
Additional Root-Cause Analysis:
# Check network interface errors
ethtool -S eth0 | grep -E 'err|drop|fifo'
rx_dropped: 12345 ← receive buffer overflow
tx_errors: 678 ← transmit errors
# Interface statistics
ip -s link show eth0
RX errors 12345
# System log
dmesg | grep -i 'network\|eth0'
[ 123.456] eth0: RX buffer overflowSolution:
# Increase Ring Buffer size
ethtool -G eth0 rx 4096 tx 4096
# QoS setup (VoIP priority)
tc qdisc add dev eth0 root handle 1: prio bands 3
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \
match ip dport 10000 0xffff flowid 1:1Scenario 3: Surge in TCP Retransmissions
Symptom: Application response delays, CPU usage normal
tcpdump Pattern Analysis:
# Capture SYN/FIN/RST packets (BPF cannot identify retransmissions → use Wireshark `tcp.analysis.retransmission`)
sudo tcpdump -i eth0 -nn 'tcp[tcpflags] & (tcp-syn|tcp-fin|tcp-rst) != 0' -w flags.pcap
# Detect SYN Flood (count SYNs per source IP)
sudo tcpdump -i eth0 -nn 'tcp[tcpflags] == tcp-syn' | \
awk '{print $3}' | cut -d. -f1-4 | sort | uniq -c | sort -nr | head
Output:
5432 192.168.1.100 ← abnormally many SYNs
234 192.168.1.101
123 192.168.1.102
# Warn only on sources above the threshold (100)
sudo tcpdump -i eth0 -nn -q 'tcp[tcpflags] == tcp-syn' | \
awk '{print $3}' | cut -d. -f1-4 | sort | uniq -c | \
awk '$1 > 100 {print "Possible SYN flood from", $2, "with", $1, "SYNs"}'Wireshark Expert Analysis:
1. Statistics → TCP StreamGraph → Time-Sequence (Stevens)
→ many horizontal lines = waiting on retransmission
2. Display Filter:
tcp.analysis.retransmission
tcp.analysis.fast_retransmission
tcp.analysis.duplicate_ack
3. Retransmission rate:
Statistics → Protocol Hierarchy
→ TCP Retransmission: 15% (normal < 3%)
4. Follow TCP Stream:
→ RST after the 3-Way Handshake
→ suspected SYN Flood attack
Attack Confirmation:
# Count half-open (SYN_RECV) connections
netstat -an | grep SYN_RECV | wc -l
12345 ← abnormal (normal < 100)
# Enable SYN Cookies (temporary defense)
sysctl -w net.ipv4.tcp_syncookies=1
# Fewer SYN-ACK retries (clears half-open connections faster)
sysctl -w net.ipv4.tcp_synack_retries=1
# iptables Rate Limiting
iptables -A INPUT -p tcp --syn -m limit --limit 10/s --limit-burst 20 -j ACCEPT
iptables -A INPUT -p tcp --syn -j DROPScenario 4: DNS Query Failure
Symptom: Name resolution retries every 5 seconds with no response, then times out
tcpdump DNS Analysis:
# Capture DNS queries/responses
sudo tcpdump -i eth0 -nn -s 65535 'udp port 53' -w dns-issue.pcap
# Live monitoring
sudo tcpdump -i eth0 -nn 'port 53'
Output:
14:30:00.123 IP 192.168.1.10.54321 > 8.8.8.8.53: 12345+ A? example.com
14:30:05.123 IP 192.168.1.10.54321 > 8.8.8.8.53: 12345+ A? example.com
↑ retry after 5s
(no response)Wireshark Analysis:
1. Display Filter:
dns.flags.response == 0 && !dns.response_in
→ show only unanswered queries
2. Statistics → DNS
→ Query Rate: 100/s
→ Response Rate: 0/s
→ 100% loss
3. Follow UDP Stream:
→ confirm the firewall blocks the DNS server
→ ICMP "Port Unreachable" received
Problem Diagnosis:
# Test DNS server connectivity
dig @8.8.8.8 example.com
# Check the firewall
sudo iptables -L -n -v | grep 'dpt:53'
0 0 DROP udp -- * * 0.0.0.0/0 8.8.8.8 udp dpt:53
# Test an alternate DNS server
dig @1.1.1.1 example.com # Cloudflare DNS worksSolution:
# Fix the firewall rules
iptables -D OUTPUT -p udp --dport 53 -d 8.8.8.8 -j DROP
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
# Update /etc/resolv.conf
nameserver 1.1.1.1
nameserver 8.8.8.8Useful tcpdump Filters:
The HTTP GET request, SYN, and RST filters are covered in Q23 under 4. TCP Flag Filtering and 6. Payload Search. This list collects only the remaining filters.
# Specific MAC address
tcpdump -i eth0 ether host aa:bb:cc:dd:ee:ff
# VLAN tag
tcpdump -i eth0 'vlan and host 192.168.1.10'
# Large packets (over 1400 bytes)
tcpdump -i eth0 'ip[2:2] > 1400'
# ICMP Redirect
tcpdump -i eth0 'icmp[icmptype] == 5'Advanced Wireshark Filters:
# Packets with TCP Window 0 (flow control)
tcp.window_size == 0
# TCP Zero Window Probe
tcp.analysis.zero_window_probe
# Delayed ACK
tcp.analysis.ack_rtt > 0.2
# TCP Out-of-Order
tcp.analysis.out_of_order
# Specific HTTP User-Agent
http.user_agent contains "bot"
# SSL/TLS Handshake failure
tls.alert_message.desc == 40 # Handshake Failure
TCP Flow Control vs Congestion Control:
Flow Control:
- Purpose: prevent receiver buffer overflow
- Mechanism: TCP Window Size (Receiver Advertised Window)
- Scope: Point-to-Point (sender ↔ receiver)
Congestion Control:
- Purpose: prevent network congestion
- Mechanism: Congestion Window (cwnd)
- Scope: End-to-End (entire path)
TCP Congestion Control State Machine:
┌─────────────────────────────────────────────────────────┐
│ Slow Start │
│ cwnd: 1 MSS → 2 → 4 → 8 → 16 ... (Exponential) │
│ cwnd += 1 MSS per ACK │
└────────────────┬────────────────────────────────────────┘
│ cwnd >= ssthresh (Slow Start Threshold)
↓
┌─────────────────────────────────────────────────────────┐
│ Congestion Avoidance │
│ cwnd growth: Linear (1 MSS per RTT) │
│ cwnd += MSS * MSS / cwnd per ACK │
└────────────────┬────────────────────────────────────────┘
│ Packet Loss detected
↓
┌───────┴────────┐
│ │
3 Dup ACK Timeout
│ │
↓ ↓
┌─────────────┐ ┌──────────────────┐
│ Fast │ │ Slow Start │
│ Recovery │ │ (restart at 1) │
│ ssthresh= │ │ ssthresh= │
│ cwnd/2 │ │ cwnd/2 │
│ cwnd= │ │ cwnd= 1 MSS │
│ ssthresh+3 │ │ │
└─────────────┘ └──────────────────┘
Concrete Example:
Initial state:
cwnd = 1 MSS (1460 bytes)
ssthresh = 64 MSS (93,440 bytes)
RTT = 100ms
Round 1 (Slow Start):
- send 1 MSS → receive ACK → cwnd = 2 MSS
Round 2:
- send 2 MSS → receive 2 ACKs → cwnd = 4 MSS
Round 3:
- send 4 MSS → receive 4 ACKs → cwnd = 8 MSS
...
Round 7:
- cwnd = 64 MSS = 93,440 bytes
- cwnd >= ssthresh → switch to Congestion Avoidance
Round 8 (Congestion Avoidance):
- send 64 MSS → receive 64 ACKs
- cwnd += 64 * 1460 / 93440 = 1 MSS
- cwnd = 65 MSS
Round 9:
- cwnd = 66 MSS (Linear growth)
Round 15:
- Packet Loss (3 Duplicate ACK)
- Fast Retransmit triggered
- ssthresh = cwnd / 2 = 36 MSS
- cwnd = ssthresh + 3 = 39 MSS
- enter Fast Recovery
Major Congestion Control Algorithms:
1. Reno (Classic):
- Fast Retransmit: 3 Duplicate ACK → retransmit immediately
- Fast Recovery: halve cwnd, then switch to Congestion Avoidance
- Timeout: cwnd = 1, restart Slow Start
2. Cubic (Linux default):
- Window growth follows a cubic function
- Remembers the window at the last loss (Wmax)
- Grows cautiously near Wmax
- Optimized for high-speed networks (Long Fat Networks)
K = cubic_root((Wmax - cwnd) / C)
cwnd = C * (t - K)³ + Wmax
Advantage: uses bandwidth quickly even with long RTT
3. BBR (Bottleneck Bandwidth and RTT):
- Developed by Google (2016)
- Based on measured Bandwidth and RTT, not on loss
- 4 states: Startup, Drain, ProbeBW, ProbeRTT
Advantages:
- Mitigates Bufferbloat
- Stable even under Packet Loss
- Used by YouTube, Google Cloud, and others
sysctl -w net.ipv4.tcp_congestion_control=bbr
TCP Window Scaling (RFC 1323, obsoleted by RFC 7323):
Problem:
TCP Window Size field: 16 bits → max 65,535 bytes
High-speed network (10 Gbps, RTT 100ms):
- BDP (Bandwidth-Delay Product) = 10Gbps * 100ms = 125 MB
- The default Window Size caps throughput
Throughput = Window Size / RTT = 65KB / 0.1s = 650 KB/s
→ only ~5 Mbps used on a 10 Gbps link
Solution: Window Scale Option
Carried in the TCP SYN packet:
┌────────────────────────────────┐
│ Option Kind: 3 (Window Scale) │
│ Option Length: 3 │
│ Shift Count: 7 │ ← 2^7 = 128x scaling
└────────────────────────────────┘
Actual Window Size = (TCP Header Window) << (Shift Count)
e.g.: Header Window = 65,535
Shift Count = 7
Actual Window = 65,535 * 128 = 8,388,480 bytes (8 MB)
→ filling a 125 MB BDP needs Shift Count >= 11 (65,535 * 2^11 ≈ 128 MB)
Checking Window Scaling:
# Inspect SYN packets with tcpdump
sudo tcpdump -i eth0 -nn -vv 'tcp[tcpflags] & tcp-syn != 0'
Output:
IP 192.168.1.10.54321 > 93.184.216.34.80: Flags [S], seq 123, win 65535,
options [mss 1460,nop,wscale 7,nop,nop,TS val 123 ecr 0,sackOK,eol]
↑ wscale 7 = 128x scaling
# Wireshark analysis
tcp.options.wscale.shift
tcp.window_size_scalefactorPractical Settings (Linux):
# TCP receive buffer size
sysctl -w net.ipv4.tcp_rmem='4096 87380 134217728'
# min default max (128 MB, >= BDP 125 MB)
# TCP send buffer size
sysctl -w net.ipv4.tcp_wmem='4096 16384 134217728'
# min default max (128 MB, >= BDP 125 MB)
# Enable Window Scaling (default 1)
sysctl -w net.ipv4.tcp_window_scaling=1
# SACK (Selective Acknowledgment) enable
sysctl -w net.ipv4.tcp_sack=1
# Enable Timestamps (RTT measurement)
sysctl -w net.ipv4.tcp_timestamps=1
# Throughput calculation
# BDP = Bandwidth * RTT
# 10 Gbps * 100ms = 1.25 GB/s * 0.1s = 125 MB
# Window Size >= BDPPerformance Measurement:
# Test throughput with iperf3
iperf3 -c server.example.com -t 60 -P 4
Output (before tuning):
[ 5] 0.00-60.00 sec 5.12 GBytes 734 Mbits/sec receiver
↑ Window Size too small
# After Window Scaling:
[ 5] 0.00-60.00 sec 65.3 GBytes 9.35 Gbits/sec receiver
↑ nearly full bandwidth used
# Monitor cwnd
ss -i | grep -i cwnd
cubic wscale:7,7 rto:204 rtt:3.5/2 cwnd:10 send 33.1Mbps
↑ Window Scale ↑ Congestion WindowDiagnosing Performance Problems with Wireshark:
1. TCP Window Full:
→ receiver window too small
→ sender has to wait
tcp.analysis.window_full
2. TCP Zero Window:
→ receiver buffer full
→ sending stops
tcp.window_size == 0
3. TCP Window Update:
→ receiver announces a larger window
tcp.analysis.window_update
Fix:
- Increase the receive buffer size
- Enable Window Scaling
- Speed up application processing
BPF (Berkeley Packet Filter) Syntax:
Basic Structure:
[protocol] [direction] [type] [value]
protocol: ip, ip6, arp, tcp, udp, icmp
direction: src, dst, src and dst, src or dst
type: host, net, port, portrange
Practical Examples:
1. Communication Between Specific Hosts:
# Both directions
tcpdump host 192.168.1.10
# Source only
tcpdump src host 192.168.1.10
# Destination only
tcpdump dst host 192.168.1.10
# Traffic between two hosts
tcpdump host 192.168.1.10 and host 192.168.1.202. Network Range:
# Subnet
tcpdump net 192.168.1.0/24
tcpdump net 192.168.1.0 mask 255.255.255.0
# Multiple subnets
tcpdump 'net 192.168.1.0/24 or net 10.0.0.0/8'3. Port Filtering:
# Single port
tcpdump port 80
tcpdump dst port 443
# Port range
tcpdump portrange 10000-20000
# Multiple ports
tcpdump 'port 80 or port 443 or port 8080'
# Exclude a specific port
tcpdump 'not port 22'4. TCP Flag Filtering:
# SYN packets only
tcpdump 'tcp[tcpflags] & tcp-syn != 0'
tcpdump 'tcp[13] & 2 != 0' # same (byte offset 13, bit 1)
# SYN-ACK
tcpdump 'tcp[tcpflags] & (tcp-syn|tcp-ack) == (tcp-syn|tcp-ack)'
tcpdump 'tcp[13] == 18' # SYN(2) + ACK(16) = 18
# FIN packets
tcpdump 'tcp[tcpflags] & tcp-fin != 0'
# RST packets
tcpdump 'tcp[tcpflags] & tcp-rst != 0'
# PSH-ACK (data transfer)
tcpdump 'tcp[tcpflags] & (tcp-push|tcp-ack) == (tcp-push|tcp-ack)'
# ACK only (no SYN, FIN, RST)
tcpdump 'tcp[tcpflags] == tcp-ack'5. IP Header Filtering:
# Specific TTL value
tcpdump 'ip[8] == 64' # TTL = 64
# TTL < 10 (suspicious packets)
tcpdump 'ip[8] < 10'
# Packets with IP options
tcpdump 'ip[0] & 0x0f > 5' # IHL > 5 (options present)
# DF (Don't Fragment) flag
tcpdump 'ip[6] & 0x40 != 0'
# MF (More Fragments) flag
tcpdump 'ip[6] & 0x20 != 0'
# Fragmented packets
tcpdump 'ip[6:2] & 0x1fff != 0'
# ToS/DSCP value
tcpdump 'ip[1] & 0xfc == 0xb8' # EF (Expedited Forwarding)6. Payload Search:
# HTTP GET requests
tcpdump -A 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420'
# "GET " ASCII
# HTTP POST
tcpdump -A 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x504f5354'
# "POST"
# HTTP response (any status code, matches "HTTP")
tcpdump -A 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x48545450'
# "HTTP"
# Identify the SSH protocol
tcpdump -A 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x5353482d'
# "SSH-"7. Compound Filters:
# External → internal web traffic (ports 80, 443)
tcpdump 'dst net 192.168.0.0/16 and (port 80 or port 443)'
# All traffic except SSH
tcpdump 'not port 22'
# DNS queries from a specific host
tcpdump 'src host 192.168.1.10 and dst port 53'
# ICMP Echo Request/Reply
tcpdump 'icmp[icmptype] == 8 or icmp[icmptype] == 0'
# ARP requests only
tcpdump 'arp[6:2] == 1' # ARP opcode = 1 (request)Performance Optimization:
1. Capture Filter vs Display Filter:
# Good: Capture Filter (BPF, kernel level)
tcpdump -i eth0 'host 192.168.1.10'
→ unneeded packets are never captured
→ saves CPU/memory
# Bad: capture everything, then filter
tcpdump -i eth0 -w all.pcap
wireshark all.pcap # using a Display Filter
→ excessive disk I/O
→ huge capture files2. Snapshot Length Optimization:
# Headers only (default 262144)
tcpdump -i eth0 -s 96 'tcp'
# Ethernet(14) + IP(20) + TCP(20) + Options(42) = 96 bytes
# Full packets (payload analysis needed)
tcpdump -i eth0 -s 65535 'port 80'
# No snaplen limit (0 = full packet, same as the 262144 default)
tcpdump -i eth0 -s 0 'tcp'3. Buffer Size Adjustment:
# Default buffer: 2 MB
tcpdump -i eth0 -B 16384 'port 80'
# 16 MB buffer (high-speed network)
# Check dropped packets
tcpdump -i eth0 -vv 'port 80'
^C
950 packets captured
1000 packets received by filter
50 packets dropped by kernel ← buffer too small4. Using a Ring Buffer (File Rotation):
# Rotate 5 files of 10MB (50MB total)
tcpdump -i eth0 -C 10 -W 5 -w capture.pcap 'port 80'
# capture.pcap0, capture.pcap1, ..., capture.pcap4
# Time-based rotation (every 5 minutes)
tcpdump -i eth0 -G 300 -w 'capture-%Y%m%d-%H%M%S.pcap'5. Leveraging Multiple Cores:
# Set CPU Affinity
taskset -c 0 tcpdump -i eth0 -w cpu0.pcap 'port 80'
taskset -c 1 tcpdump -i eth1 -w cpu1.pcap 'port 443'
# PF_RING (high-performance packet capture)
tcpdump -i eth0@1 -w capture.pcap # PF_RING channel 16. Real-Time Analysis vs File Storage:
# Live analysis (printed to screen)
tcpdump -i eth0 -l 'port 80' | grep "GET"
# -l: Line Buffered (immediate output)
# Save to file, then analyze (recommended)
tcpdump -i eth0 -w capture.pcap 'port 80'
wireshark capture.pcap7. Sampling:
# Keep every 10th packet (BPF has no random sampling, so extract after capture with tshark, Wireshark 4.0+)
tcpdump -i eth0 -w capture.pcap 'tcp'
tshark -r capture.pcap -Y 'frame.number % 10 == 0' -w sampled.pcapAdvanced BPF Examples:
Web Traffic Analysis:
# HTTP headers only (first 1024 bytes)
tcpdump -i eth0 -s 1024 -A 'tcp port 80 and (
(tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420) or
(tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x48545450)
)'
# HTTPS ClientHello (TLS Handshake)
tcpdump -i eth0 '(tcp[((tcp[12:1] & 0xf0) >> 2)] = 0x16) and
(tcp[((tcp[12:1] & 0xf0) >> 2) + 1] = 0x03) and
(tcp[((tcp[12:1] & 0xf0) >> 2) + 5] = 0x01)'Security Analysis:
The SYN Flood detection pipeline (per-source-IP counts and the threshold warning) is covered in Q21 Scenario 3.
# Detect Port Scans (many bare SYNs)
tcpdump -i eth0 'tcp[tcpflags] == tcp-syn and src net 192.168.1.0/24'
# DNS Amplification
tcpdump -i eth0 'udp port 53 and ip[2:2] > 512'Performance Testing:
# High-speed network (10 Gbps)
# plain tcpdump: handles ~1 Gbps
# PF_RING: ~10 Gbps
# DPDK: ~40 Gbps
# Measure tcpdump performance
time tcpdump -i eth0 -c 100000 -w /dev/null 'tcp'
real 0m2.345s
user 0m0.123s
sys 0m1.234s
→ ~42,000 pps (packets per second)💡 Term Explanation:
- For detailed explanations of the terms used in the packet analysis questions (Q19-Q23) — Ethernet Frame, IP Packet, TCP Segment, MTU/MSS, PMTUD, TCP Window Scaling, BPF, etc. —
- refer to the Consolidated Key Terms > Packet Analysis & Security section.