diff --git a/scapy/layers/inet.py b/scapy/layers/inet.py index 7d07e67d7f70548591f27b4a3d839367bb0d2b1d..f20bf1d273a883b455334b3e7863f34b05142224 100644 --- a/scapy/layers/inet.py +++ b/scapy/layers/inet.py @@ -521,11 +521,31 @@ 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.seq-self.ack) > 2+len(other.payload)): + # 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 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 return 1 def mysummary(self): diff --git a/test/regression.uts b/test/regression.uts index d53fe23e1384ce4e60c408ff3bf577add160c33e..050d028fc00ea65c4af500abb74373da35ea5d3d 100644 --- a/test/regression.uts +++ b/test/regression.uts @@ -304,6 +304,33 @@ assert all(p.hashret() == p2.hashret() for p in px) assert not any(p.answers(p2) for p in px) assert all(p2.answers(p) for p in px) conf.checkIPinIP = conf_back +prt1, prt2 = 12345, 54321 +s1, s2 = 2767216324, 3845532842 +p1 = IP(src=a1, dst=a2)/TCP(flags='SA', seq=s1, ack=s2, sport=prt1, dport=prt2) +p2 = IP(src=a2, dst=a1)/TCP(flags='R', seq=s2, ack=0, sport=prt2, dport=prt1) +assert p2.answers(p1) +assert not p1.answers(p2) +p1 = IP(src=a1, dst=a2)/TCP(flags='S', seq=s1, ack=0, sport=prt1, dport=prt2) +p2 = IP(src=a2, dst=a1)/TCP(flags='RA', seq=0, ack=s1+1, sport=prt2, dport=prt1) +assert p2.answers(p1) +assert not p1.answers(p2) +p1 = IP(src=a1, dst=a2)/TCP(flags='S', seq=s1, ack=0, sport=prt1, dport=prt2) +p2 = IP(src=a2, dst=a1)/TCP(flags='SA', seq=s2, ack=s1+1, sport=prt2, dport=prt1) +assert p2.answers(p1) +assert not p1.answers(p2) +p1 = IP(src=a1, dst=a2)/TCP(flags='A', seq=s1, ack=s2+1, sport=prt1, dport=prt2) +assert not p2.answers(p1) +assert p1.answers(p2) +p1 = IP(src=a1, dst=a2)/TCP(flags='S', seq=s1, ack=0, sport=prt1, dport=prt2) +p2 = IP(src=a2, dst=a1)/TCP(flags='SA', seq=s2, ack=s1+10, sport=prt2, dport=prt1) +assert not p2.answers(p1) +assert not p1.answers(p2) +p1 = IP(src=a1, dst=a2)/TCP(flags='A', seq=s1, ack=s2+1, sport=prt1, dport=prt2) +assert not p2.answers(p1) +assert not p1.answers(p2) +p1 = IP(src=a1, dst=a2)/TCP(flags='A', seq=s1+9, ack=s2+10, sport=prt1, dport=prt2) +assert not p2.answers(p1) +assert not p1.answers(p2) ############