Last updated on: June 16 2024.

Packet Capture

This page provides guidance and examples for capturing packets when troubleshooting a tunnel.

Define Scope

It is easy to capture too many packets and not the right ones at the same time.

Capturing all traffic or a significant amount per second can cause performance issues so it is vital to narrow the scope of the packet collection.

In general a complete packet capture for tunnel problems require a tcpdump filter for:

  • The host generating traffic.

  • The host receiving the traffic.

  • ICMP, ISAKMP and ESP packets sent and received between the two endpoint IPs.

ICMP is a useful signal of problems in a network.

Standard Capture

A local host is trying to ping remote host over a tunnel between the BIG-IP and peer

On the BIG-IP, define the IP addresses and capture to file:

localpeer=" "

tcpdump -s0 -i 0.0:nnn -C 100M -W 5 -w /shared/tmp/$HOSTNAME-ipsec.pcap "(net $lhs and net $rhs) or ((port 500 or port 4500 or esp or ah or icmp or icmp6) and (host $localpeer and host $remotepeer))"

Files are written to /shared/tmp/.

$HOSTNAME is already set on the BIG-IP.

“-C 100M -W 5” creates a rolling pcap of 5 files. When the file reaches 100MB, tcpdump creates a new file and copies packets to that, or replaces the oldest file if 5 files already exist. This means only 500MB of disk space is used and the packet capture can continue indefinitely until the problem reproduces.

Specific IPsec SAs

IPsec tunnel mode can have multiple selectors, meaning multiple IPsec SAs. What if traffic over one of the selectors was a problem? The IP address for all the IPsec SAs are all tied to the BIG-IP and remote peer’s IP addresses. Filtering for those two addresses captures all the tunnels between those two peers.

Determine the name of the selector, find the two SPIs for that selector and capture.


Find SPIs for traffic-selector:

[root@bigip-1-1:Active:Standalone] config # SPIS="$(tmsh show net ipsec ipsec-sa traffic-selector $selector | awk '/esp/{print $4}' | sed 's/SPI(0x\([a-f|0-9]*\).*/\1/')"

Check there are two SPI numbers:

[root@bigip-1-1:Active:Standalone] config # echo $SPIS
bec2922 7376bf9

If there are no SPIs, or just one SPI, the problem is with tunnel negotiation not with traffic inside the tunnel (because there’s no IPsec SAs for the traffic). Use the standard capture above.

Put the SPIs into a list:

[root@bigip-1-1:Active:Standalone] config # ASPI=($SPIS)

Run tcpdump with this filter. Add a ringdump expression if required (example in standard capture above).

tcpdump -nni 0.0:nnn "(net $lhs and net $rhs) or (esp and (ip[((ip[0]&0x0f)<<2):4]==0x${ASPI[0]} or ip[((ip[0]&0x0f)<<2):4]==0x${ASPI[1]}))"