ECN Monitoring with tcpdump

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.

Note: Replace pppoe-wan with your network interface name. Use ip a or ifconfig to list available interfaces.

ECN: IPv4

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.

ECN: IPv6

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.

ECN: Combined IPv4/IPv6

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.

TCP ECN: IPv4

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:

TCP ECN: IPv6

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:

TCP ECN: Combined IPv4/IPv6

These 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))'

Remote Wireshark Capturing via SSH

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:

Note: 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 Codepoints Reference

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:

Back to Top