diff --git a/scapy/config.py b/scapy/config.py index 032ab871593b68fb75b8ec7a8441f18a08cee7e7..12c6d0d7e9d3196502bcf46fb6750ab2bd51e5aa 100755 --- a/scapy/config.py +++ b/scapy/config.py @@ -301,6 +301,8 @@ checkIPID: if 0, doesn't check that IPID matches between IP sent and ICMP IP cit if 1, checks that they either are equal or byte swapped equals (bug in some IP stacks) if 2, strictly checks that they are equals checkIPsrc: if 1, checks IP src in IP and ICMP IP citation match (bug in some NAT stacks) +checkIPinIP: if True, checks that IP-in-IP layers match. If False, do not + check IP layers that encapsulates another IP layer check_TCPerror_seqack: if 1, also check that TCP seq and ack match the ones in ICMP citation iff : selects the default output interface for srp() and sendp(). default:"eth0") verb : level of verbosity, from 0 (almost mute) to 3 (verbose) @@ -334,6 +336,7 @@ contribs: a dict which can be used by contrib layers to store local configuratio checkIPID = 0 checkIPsrc = 1 checkIPaddr = 1 + checkIPinIP = True check_TCPerror_seqack = 0 verb = 2 prompt = ">>> " diff --git a/scapy/layers/inet.py b/scapy/layers/inet.py index 05091c44b5134075202b7e9e68b77992bea19c3d..1ed71e97f35b95031e26c06fbfe5a57b4f59aee0 100644 --- a/scapy/layers/inet.py +++ b/scapy/layers/inet.py @@ -402,14 +402,24 @@ class IP(Packet, IPTools): and (isinstance(self.payload, ICMP)) and (self.payload.type in [3,4,5,11,12]) ): return self.payload.payload.hashret() - else: - if self.dst == "224.0.0.251": # mDNS - return struct.pack("B", self.proto) + self.payload.hashret() - if conf.checkIPsrc and conf.checkIPaddr: - return strxor(inet_aton(self.src),inet_aton(self.dst))+struct.pack("B",self.proto)+self.payload.hashret() - else: - return struct.pack("B", self.proto)+self.payload.hashret() + if not conf.checkIPinIP and self.proto in [4, 41]: # IP, IPv6 + return self.payload.hashret() + if self.dst == "224.0.0.251": # mDNS + return struct.pack("B", self.proto) + self.payload.hashret() + if conf.checkIPsrc and conf.checkIPaddr: + return (strxor(inet_aton(self.src), inet_aton(self.dst)) + + struct.pack("B",self.proto) + self.payload.hashret()) + return struct.pack("B", self.proto) + self.payload.hashret() def answers(self, other): + if not conf.checkIPinIP: # skip IP in IP and IPv6 in IP + if self.proto in [4, 41]: + return self.payload.answers(other) + if isinstance(other, IP) and other.proto in [4, 41]: + return self.answers(other.payload) + if conf.ipv6_enabled \ + and isinstance(other, scapy.layers.inet6.IPv6) \ + and other.nh in [4, 41]: + return self.answers(other.payload) if not isinstance(other,IP): return 0 if conf.checkIPaddr: diff --git a/scapy/layers/inet6.py b/scapy/layers/inet6.py index 86c63aea50b25b421b12fae2603a4f5a2576824b..0e510fae89b658c48c71a6ebbf02e327c3a0140c 100644 --- a/scapy/layers/inet6.py +++ b/scapy/layers/inet6.py @@ -410,6 +410,9 @@ class IPv6(_IPv6GuessPayload, Packet, IPTools): elif (self.payload.type in [133,134,135,136,144,145]): return struct.pack("B", self.nh)+self.payload.hashret() + if not conf.checkIPinIP and self.nh in [4, 41]: # IP, IPv6 + return self.payload.hashret() + nh = self.nh sd = self.dst ss = self.src @@ -453,6 +456,13 @@ class IPv6(_IPv6GuessPayload, Packet, IPTools): return struct.pack("B", nh)+self.payload.hashret() def answers(self, other): + if not conf.checkIPinIP: # skip IP in IP and IPv6 in IP + if self.nh in [4, 41]: + return self.payload.answers(other) + if isinstance(other, IPv6) and other.nh in [4, 41]: + return self.answers(other.payload) + if isinstance(other, IP) and other.proto in [4, 41]: + return self.answers(other.payload) if not isinstance(other, IPv6): # self is reply, other is request return False if conf.checkIPaddr: diff --git a/test/regression.uts b/test/regression.uts index 11ab3978b3bd265b6f916ce29635488d467b8c91..ae2954d38f999df35f66f6c6382a77e3584ea21f 100644 --- a/test/regression.uts +++ b/test/regression.uts @@ -156,6 +156,26 @@ t=Ether()/IP()/TCP() x==y, x==z, x==t, y==z, y==t, z==t, w==x _ == (False, False, False, False, False, False, True) += answers +~ basic +a1, a2 = "1.2.3.4", "5.6.7.8" +p1 = IP(src=a1, dst=a2)/ICMP(type=8) +p2 = IP(src=a2, dst=a1)/ICMP(type=0) +assert p1.hashret() == p2.hashret() +assert not p1.answers(p2) +assert p2.answers(p1) +conf_back = conf.checkIPinIP +conf.checkIPinIP = True +px = [IP()/p1, IPv6()/p1] +assert not any(p.hashret() == p2.hashret() for p in px) +assert not any(p.answers(p2) for p in px) +assert not any(p2.answers(p) for p in px) +conf.checkIPinIP = False +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 + ############ ############