From 70bd87e19d6c7cf98de83f87eb40a77487b908b7 Mon Sep 17 00:00:00 2001
From: Pierre LALET <pierre.lalet@cea.fr>
Date: Wed, 8 Mar 2017 08:29:57 +0100
Subject: [PATCH] Increase TCP.answers() robustness

---
 scapy/layers/inet.py | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/scapy/layers/inet.py b/scapy/layers/inet.py
index b1c04232..f20bf1d2 100644
--- a/scapy/layers/inet.py
+++ b/scapy/layers/inet.py
@@ -521,14 +521,29 @@ class TCP(Packet):
     def answers(self, other):
         if not isinstance(other, TCP):
             return 0
+        # RST packets don't get answers
+        if other.flags.R:
+            return 0
+        # We do not support the four-way handshakes with the SYN+ACK
+        # answer split in two packets (one ACK and one SYN): in that
+        # case the ACK will be seen as an answer, but not the SYN.
+        if self.flags.S:
+            # SYN packets without ACK are not answers
+            if not self.flags.A:
+                return 0
+            # SYN+ACK packets answer SYN packets
+            if not other.flags.S:
+                return 0
         if conf.checkIPsrc:
             if not ((self.sport == other.dport) and
                     (self.dport == other.sport)):
                 return 0
-        if abs(other.ack - self.seq) > 2:
+        # Do not check ack value for SYN packets without ACK
+        if not (other.flags.S and not other.flags.A) \
+           and abs(other.ack - self.seq) > 2:
             return 0
-        # Do not check ack value for RST packets when ack is 0
-        if self.flags.R and not self.ack:
+        # Do not check ack value for RST packets without ACK
+        if self.flags.R and not self.flags.A:
             return 1
         if abs(other.seq - self.ack) > 2 + len(other.payload):
             return 0
-- 
GitLab