This document provides ready-to-use tcpdump commands for monitoring Explicit Congestion Notification (ECN) in network traffic. ECN is a mechanism that allows end-to-end notification of network congestion without dropping packets.
pppoe-wan
with your network interface name. Use ip a
or ifconfig
to list available interfaces.
These commands filter IPv4 packets based on their ECN codepoints in the IP header:
# NOT Not-ECT (any ECN-capable transport)
tcpdump -i pppoe-wan -v -n 'ip and (ip[1] & 0x3) != 0'
# Not-ECT (non ECN-capable transport)
tcpdump -i pppoe-wan -v -n 'ip and (ip[1] & 0x3) == 0'
# ECT(1) (ECN-capable transport, codepoint 1)
tcpdump -i pppoe-wan -v -n 'ip and (ip[1] & 0x3) == 1'
# ECT(0) (ECN-capable transport, codepoint 0)
tcpdump -i pppoe-wan -v -n 'ip and (ip[1] & 0x3) == 2'
# CE (Congestion Experienced)
tcpdump -i pppoe-wan -v -n 'ip and (ip[1] & 0x3) == 3'
For IPv4, the ECN field is contained in bits 0-1 of the second byte (ip[1]) of the IP header. The expression (ip[1] & 0x3)
extracts these two bits, and we then compare them with the ECN codepoints.
These commands filter IPv6 packets based on their ECN codepoints in the IPv6 header:
# NOT Not-ECT (any ECN-capable transport)
tcpdump -i pppoe-wan -v -n 'ip6 and (ip6[0:2] & 0x30) >> 4 != 0'
# Not-ECT (non ECN-capable transport)
tcpdump -i pppoe-wan -v -n 'ip6 and (ip6[0:2] & 0x30) >> 4 == 0'
# ECT(1) (ECN-capable transport, codepoint 1)
tcpdump -i pppoe-wan -v -n 'ip6 and (ip6[0:2] & 0x30) >> 4 == 1'
# ECT(0) (ECN-capable transport, codepoint 0)
tcpdump -i pppoe-wan -v -n 'ip6 and (ip6[0:2] & 0x30) >> 4 == 2'
# CE (Congestion Experienced)
tcpdump -i pppoe-wan -v -n 'ip6 and (ip6[0:2] & 0x30) >> 4 == 3'
For IPv6, the ECN field is in the Traffic Class field. The expression (ip6[0:2] & 0x30) >> 4
extracts the ECN bits (bits 4-5 of the first two bytes) and shifts them right by 4 positions to get values from 0-3.
These commands filter both IPv4 and IPv6 packets based on their ECN codepoints:
# NOT Not-ECT (any ECN-capable transport)
tcpdump -i pppoe-wan -v -n '(ip6 and (ip6[0:2] & 0x30) >> 4 != 0)' or '(ip and (ip[1] & 0x3) != 0)'
# ECT(1) (ECN-capable transport, codepoint 1)
tcpdump -i pppoe-wan -v -n '(ip6 and (ip6[0:2] & 0x30) >> 4 == 1)' or '(ip and (ip[1] & 0x3) == 1)'
# ECT(0) (ECN-capable transport, codepoint 0)
tcpdump -i pppoe-wan -v -n '(ip6 and (ip6[0:2] & 0x30) >> 4 == 2)' or '(ip and (ip[1] & 0x3) == 2)'
# CE (Congestion Experienced)
tcpdump -i pppoe-wan -v -n '(ip6 and (ip6[0:2] & 0x30) >> 4 == 3)' or '(ip and (ip[1] & 0x3) == 3)'
These commands combine the IPv4 and IPv6 filters using the logical OR operator to capture ECN traffic across both IP protocol versions simultaneously.
These commands filter IPv4 TCP packets based on their ECN flags in the TCP header:
# TCP ECN flags, ECN in action (either ECE or CWR)
tcpdump -i pppoe-wan -v -n '(tcp[tcpflags] & (tcp-ece|tcp-cwr) != 0)'
# TCP ECN flags, ECE: ECN-Echo (reported as E)
tcpdump -i pppoe-wan -v -n 'tcp[tcpflags] & tcp-ece != 0'
# TCP ECN flags, CWR: Congestion Window Reduced (reported as W)
tcpdump -i pppoe-wan -v -n 'tcp[tcpflags] & tcp-cwr != 0'
These filters look for TCP ECN flags:
These commands filter IPv6 TCP packets based on their ECN flags:
# TCP ECN flags, ECN in action (either ECE or CWR)
tcpdump -i pppoe-wan -v -n '((ip6[6] = 6) and (ip6[53] & 0xC0 != 0))'
# TCP ECN flags, ECE: ECN-Echo (reported as E)
tcpdump -i pppoe-wan -v -n '((ip6[6] = 6) and (ip6[53] & 0x40 != 0))'
# TCP ECN flags, CWR: Congestion Window Reduced (reported as W)
tcpdump -i pppoe-wan -v -n '((ip6[6] = 6) and (ip6[53] & 0x80 != 0))'
For IPv6, the TCP header needs special handling:
ip6[6] = 6
identifies TCP packets (protocol number 6)ip6[53]
accesses the TCP flags byte at offset 530xC0
is a mask for both ECE (0x40) and CWR (0x80) flagsThese commands filter both IPv4 and IPv6 TCP packets based on their ECN flags:
# TCP ECN flags, ECN in action (either ECE or CWR)
tcpdump -i pppoe-wan -v -n '(tcp[tcpflags] & (tcp-ece|tcp-cwr) != 0)' or '((ip6[6] = 6) and (ip6[53] & 0xC0 != 0))'
# TCP ECN flags, ECE: ECN-Echo (reported as E)
tcpdump -i pppoe-wan -v -n '(tcp[tcpflags] & tcp-ece != 0)' or '((ip6[6] = 6) and (ip6[53] & 0x40 != 0))'
# TCP ECN flags, CWR: Congestion Window Reduced (reported as W)
tcpdump -i pppoe-wan -v -n '(tcp[tcpflags] & tcp-cwr != 0)' or '((ip6[6] = 6) and (ip6[53] & 0x80 != 0))'
These commands let you capture traffic on a remote device and analyze it in real-time with Wireshark on your local machine:
# Generic OpenWrt example
ssh root@openwrt.lan tcpdump -i eth2.7 -U -s0 -w - 'not port 22' | sudo wireshark -k -i -
# macOS specific example
ssh root@192.168.42.1 tcpdump -i pppoe-wan -U -s0 -w - 'not port 22' | /Applications/Wireshark.app/Contents/MacOS/Wireshark -k -i -
Key options:
-U
: Packet-buffered output (for real-time viewing)-s0
: Capture full packets (no size limit)-w -
: Write to stdout instead of a filenot port 22
: Exclude SSH traffic (prevents capturing your SSH connection)-k -i -
: Wireshark starts capturing immediately from stdinNote: If you press Ctrl+C with this setup, Wireshark will also close. To properly end the capture, stop it in Wireshark first, save if needed, then close Wireshark.
ECN Codepoint | Binary | Description |
---|---|---|
Not-ECT | 00 | Non ECN-Capable Transport |
ECT(1) | 01 | ECN-Capable Transport, codepoint 1 |
ECT(0) | 10 | ECN-Capable Transport, codepoint 0 |
CE | 11 | Congestion Experienced |
References: