Ask Your Question

I am trying to capture TCP SYN on IPv6 packets but I only get IPv4.

asked 2022-05-12 18:14:35 +0000

updated 2022-05-12 22:59:43 +0000

cmaynard gravatar image
c:\progra~1\wireshark\tshark -i 5 -f "ip6" -f "tcp[tcpflags] & (tcp-syn|tcp-fin) != 0"
Capturing on 'Wi-Fi'
 ** (tshark:728) 11:00:25.279637 [Main MESSAGE] -- Capture started.

    1   0.000000 →    TCP 54 443 → 51978 [FIN, ACK] Seq=1 Ack=1 Win=286 Len=0
    2   0.000197 → TCP 54 51978 → 443 [FIN, ACK] Seq=1 Ack=2 Win=507 Len=0
    3   0.356084 →    TLSv1.2 85 Encrypted Alert
    4   0.356342 → TCP 54 51980 → 443 [FIN, ACK] Seq=1 Ack=33 Win=507 Len=0
    5   0.514348 →    TCP 54 443 → 52006 [FIN, ACK] Seq=1 Ack=1 Win=277 Len=0
    6   0.514538 → TCP 54 52006 → 443 [FIN, ACK] Seq=1 Ack=2 Win=509 Len=0
    7   0.554725 →    TCP 54 443 → 52007 [FIN, ACK] Seq=1 Ack=1 Win=277 Len=0
    8   0.554909 → TCP 54 52007 → 443 [FIN, ACK] Seq=1 Ack=2 Win=509 Len=0
8 packets captured

If I do only IP6, then I get IPv6 packets. But, I only want the ones with SYN!

c:\progra~1\wireshark\tshark -i 5 -f "ip6"
Capturing on 'Wi-Fi'

 ** (tshark:17652) 10:59:50.549674 [Main MESSAGE] -- Capture started.
    1   0.000000 2601:642:c202:9550:19ad:99f6:e7b4:26b1 → 2607:f8b0:4023:1c01::bc TCP 75 50002 → 5228 [ACK] Seq=1 Ack=1 Win=514 Len=1
    2   0.027870 2607:f8b0:4023:1c01::bc → 2601:642:c202:9550:19ad:99f6:e7b4:26b1 TCP 86 5228 → 50002 [ACK] Seq=1 Ack=2 Win=265 Len=0 SLE=1 SRE=2
    3   0.112625 fe80::1256:11ff:fe99:e3d7 → ff02::1      ICMPv6 174 Router Advertisement from 10:56:11:99:e3:d7
    4   2.882030 2601:642:c202:9550:19ad:99f6:e7b4:26b1 → 2607:f8b0:4005:809::2013 TCP 75 [TCP segment of a reassembled PDU]
edit retag flag offensive close merge delete

2 Answers

Sort by » oldest newest most voted

answered 2022-05-12 23:31:13 +0000

cmaynard gravatar image

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:

edit flag offensive delete link more

answered 2022-05-12 21:53:20 +0000

Chuckc gravatar image

You can have multiple capture filters on the tshark command line but not in a row. Last one in wins.
(if using multiple -f options they are meant to be sprinkled around the interface options)

tshark man page:

-f <capture filter="">
This option can occur multiple times. If used before the first occurrence of the -i option, it sets the default capture filter expression. If used after an -i option, it sets the capture filter expression for the interface specified by the last -i option occurring before this option. If the capture filter expression is not set specifically, the default capture filter expression is used if provided.

The second gotcha is filtering ipv6: BPF Byte filter for VLAN-IPv6-UDP stack
From pcap-filter.7:

Note that tcp, udp and other upper-layer protocol types only apply to IPv4, not IPv6 (this will be fixed in the future).

You can try a mix of capture filter with display filter:

$ tshark -i 5 -f "(tcp[tcpflags] & (tcp-syn|tcp-fin) != 0)" -Y ipv6

edit flag offensive delete link more


Thanks so much! Both the -Y and the fixed offsets work.

I am actually doing testing with IPv6 extension headers so down the road, that will pose a problem but I can deal with it when the time comes.

It will be good if the bug to capture both IPv4 and IPv6 when upper layer protocol is specified is fixed! I have not checked to see if the same happens for UDP. I am assuming it does.

Thanks again for taking the time to answer the question.

nalini elkins gravatar imagenalini elkins ( 2022-05-13 00:06:21 +0000 )edit

@cmaynard as many Sharkfest IPv6 presentations as there have been, I haven't done much with it in my lab. Here's a working (and now tested) command line:

tshark -i 5 -f "ip6" -Y "tcp.flags.syn == 1 or tcp.flags.fin == 1"

(I had tested with MDNS - udp port 5353 - but that didn't exercise the tcp[0] case you pointed out)

Chuckc gravatar imageChuckc ( 2022-05-13 13:48:11 +0000 )edit

The problem with that is that when you do both -f and -Y then you can't write the capture out. I need to write the packets and roll it.

nalini elkins gravatar imagenalini elkins ( 2022-05-13 13:59:03 +0000 )edit

OK, but this will capture all IPv6 packets, and not just those carrying TCP packets with the SYN or FIN bits set, which I thought was the goal, i.e., "But, I only want the ones with SYN!".

cmaynard gravatar imagecmaynard ( 2022-05-13 14:33:26 +0000 )edit

The problem is that you cannot mix -f and -Y and write out files. I do want to filter it. Do you understand?

nalini elkins gravatar imagenalini elkins ( 2022-05-13 14:41:07 +0000 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools


Asked: 2022-05-12 18:14:35 +0000

Seen: 67 times

Last updated: May 12