Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

From the pcap-filter man page under the BUGS section:

Arithmetic expression against transport layer headers, like tcp[0], does not work against IPv6 packets. It only looks at IPv4 packets.

Therefore, you can't use a capture filter such as tcp[tcpflags] & (tcp-syn|tcp-fin) != 0 and expect it to work with IPv6 packets. What you can do, and as far as I can tell, what you must do (at least for now) is use ip6 offsets to access the relevant byte where the TCP flags of interest are. For example:

-f "(ip6[6] = 6) and (ip6[53] & 0x03 != 0)"

How does this filter work?

  • ip6[6] = 6: This checks that the Next Header is TCP, as [6] is the offset to the IPv6 Next Header field (it's the 7th byte, but offsets are zero-based), and 6 is the Assigned Internet Protocol Number for TCP.
  • ip6[53] & 0x03 != 0: This checks that either the TCP SYN bit or the FIN bit is set (or both are set), as [53] is the offset to the lower 8 bits of TCP flags field (calculated as 40 bytes for a standard IPv6 header plus 14 more bytes as an additional offset into the TCP Header to get to the TCP flags of interest, again keeping in mind that offsets are zero-based), and then masking the 2 flags of interest, namely SYN and FIN with the & 0x03 part and finally ensuring that the result is non-zero, meaning at least one of those flags is set.
  • and: Both conditions must be true for the packet to match the filter.

And don't forget that you can verify the capture filter by running dumpcap -f "(ip6[6] = 6) and (ip6[53] & 0x03 != 0)" -d, which produces the following output (generated on a Windows 10 machine):

(000) ldh      [12]
(001) jeq      #0x86dd          jt 2    jf 7
(002) ldb      [20]
(003) jeq      #0x6             jt 4    jf 7
(004) ldb      [67]
(005) jset     #0x3             jt 6    jf 7
(006) ret      #262144
(007) ret      #0

Now, you might ask yourself why the offset of 20 is used on line 002 and why the offset of 67 is used on line 004 and that's because those are the offsets from the start of the packet, which includes the 14 byte Ethernet bytes as well, so if you subtract 14, you get the offsets I illustrated above.

DISCLAIMER: I calculated the offsets by hand but did not actually test this. It's possible I made a mistake in the offset calculations, so please do test this first.

CAVEATS: If the IPv6 packet contains any extension headers, then this filter will not work as is; however, you should be able to modify the filter to account for them as needed. That is left as an exercise for the reader.

Other References: