diff --git a/scapy/layers/inet6.py b/scapy/layers/inet6.py index f1ecc210c06..0059c785a83 100644 --- a/scapy/layers/inet6.py +++ b/scapy/layers/inet6.py @@ -481,7 +481,20 @@ def answers(self, other): elif other.nh == 43 and isinstance(other.payload, IPv6ExtHdrSegmentRouting): # noqa: E501 return self.payload.answers(other.payload.payload) # Buggy if self.payload is a IPv6ExtHdrRouting # noqa: E501 elif other.nh == 60 and isinstance(other.payload, IPv6ExtHdrDestOpt): - return self.payload.answers(other.payload.payload) + # Extension Headers can show weird behavior. + # Linux's sk_buff considers the IPv6 Payload + # to be either TCP, UDP or ICMP. It does not + # consider Extension Headers to be the payload. + # Following similar architecture, this small + # modification lets packet flow with Destination + # Option on both, request and response packets + # be captured as well. + if UDP in self and UDP in other: + return self[UDP].answers(other[UDP]) + elif TCP in self and TCP in other: + return self[TCP].answers(other[TCP]) + else: + return self.payload.answers(other.payload.payload) elif self.nh == 60 and isinstance(self.payload, IPv6ExtHdrDestOpt): # BU in reply to BRR, for instance # noqa: E501 return self.payload.payload.answers(other.payload) else: diff --git a/test/scapy/layers/inet6.uts b/test/scapy/layers/inet6.uts index 206ab975c8a..cb0f7c25ac9 100644 --- a/test/scapy/layers/inet6.uts +++ b/test/scapy/layers/inet6.uts @@ -461,6 +461,18 @@ a = IPv6(b'`\x00\x00\x00\x00\x10<\xff\xfe\x80\x00\x00\x00\x00\x00\x00\x00\x00\x0 assert a.hashret() == b.hashret() assert b.answers(a) += IPv6 with DestOpt and UDP +a = IPv6(raw(IPv6(src="2001:db8::1", dst="2001:db8::2")/IPv6ExtHdrDestOpt()/UDP(sport=12345, dport=53))) +b = IPv6(raw(IPv6(src="2001:db8::2", dst="2001:db8::1")/IPv6ExtHdrDestOpt()/UDP(sport=53, dport=12345))) +assert a.hashret() == b.hashret() +assert b.answers(a) + += IPv6 with DestOpt and TCP +a = IPv6(raw(IPv6(src="2001:db8::1", dst="2001:db8::2")/IPv6ExtHdrDestOpt()/TCP(sport=12345, dport=80, flags="S", seq=1000))) +b = IPv6(raw(IPv6(src="2001:db8::2", dst="2001:db8::1")/IPv6ExtHdrDestOpt()/TCP(sport=80, dport=12345, flags="SA", seq=2000, ack=1001))) +assert a.hashret() == b.hashret() +assert b.answers(a) + = ICMPv6EchoRequest and ICMPv6EchoReply - answers() test 8 - (live) use Net6 ~ netaccess ipv6