diff --git a/ptf b/ptf index 79becd0..64b8449 100755 --- a/ptf +++ b/ptf @@ -819,7 +819,8 @@ platform_mod = None try: platform_mod = import_module(config["platform_dir"], platform_name) except: - logging.warn("Failed to import " + platform_name + " platform module") + logging.warning("Failed to import " + platform_name + " platform module") + # logging.warn("Failed to import " + platform_name + " platform module") raise try: diff --git a/src/ptf/dataplane.py b/src/ptf/dataplane.py index fd250fe..7e307be 100644 --- a/src/ptf/dataplane.py +++ b/src/ptf/dataplane.py @@ -854,6 +854,33 @@ def format(self): in the output. If the expected packet is a scapy packet object, the output will include information about the fields in the packet. """ + # returns list of indexes of bytes not matching the expected packet + def get_indexes_not_equal(exp_pkt, pkt): + if isinstance(exp_pkt, mask.Mask): + if not exp_pkt.is_valid(): + return [] + ret = exp_pkt.pkt_match(pkt, with_indexes=True) + if type(ret) == bool: + # something went wrong, don't mark any bytes red + return None + else: + b, indxs_n_equal = ret + return indxs_n_equal + + e = bytes(exp_pkt) + p = bytes(pkt) + if len(e) < 60: + p = p[:len(e)] + + indxs_n_equal = [] + i = 0 + for b in p: + if b != e[i]: + indxs_n_equal.append(i) + i = i + 1 + + return indxs_n_equal + try: stdout_save = sys.stdout # The scapy packet dissection methods print directly to stdout, @@ -885,7 +912,8 @@ def format(self): # the expected packet's class. packet.ls(self.expected_packet.__class__(recent_packet)) print("--") - packet.hexdump(recent_packet) + indxs_n_equal = get_indexes_not_equal(self.expected_packet, recent_packet) + packet.hexdump_marked(recent_packet, indxs_n_equal) else: print("%d total packets." % self.packet_count) print("==============================") diff --git a/src/ptf/mask.py b/src/ptf/mask.py index 32afb48..1e596fa 100644 --- a/src/ptf/mask.py +++ b/src/ptf/mask.py @@ -79,7 +79,7 @@ def set_ignore_extra_bytes(self): def is_valid(self): return self.valid - def pkt_match(self, pkt): + def pkt_match(self, pkt, with_indexes=False): # just to be on the safe side pkt = bytearray(bytes(pkt)) # we fail if we don't match on sizes, or if ignore_extra_bytes is set, @@ -89,9 +89,15 @@ def pkt_match(self, pkt): ) < self.size: return False exp_pkt = bytearray(bytes(self.exp_pkt)) + indxs_n_equal = [] for i in range(self.size): if (exp_pkt[i] & self.mask[i]) != (pkt[i] & self.mask[i]): - return False + if not with_indexes: + return False + else: + indxs_n_equal.append(i) + if with_indexes: + return len(indxs_n_equal) == 0, indxs_n_equal return True def __str__(self): diff --git a/src/ptf/packet_scapy.py b/src/ptf/packet_scapy.py index a8a43b9..f6de833 100644 --- a/src/ptf/packet_scapy.py +++ b/src/ptf/packet_scapy.py @@ -148,6 +148,32 @@ def mysummary(self): pass +# modified scapy.utils.hexdump(packet) +# https://github.com/secdev/scapy/blob/master/scapy/utils.py +def hexdump_marked(in_packet, indxs_n_equal): + def red(inp_str): + return '\x1b[1;31m' + inp_str + '\x1b[0m' + + s = "" + x = scapy.utils.bytes_encode(in_packet) + x_len = len(x) + i = 0 + while i < x_len: + s += "%04x " % i + for j in range(16): + if i + j < x_len: + if indxs_n_equal is not None and i + j in indxs_n_equal: + s += red("%02X " % scapy.utils.orb(x[i + j])) + else: + s += "%02X " % scapy.utils.orb(x[i + j]) + else: + s += " " + s += " %s\n" % scapy.utils.sane(x[i:i + 16]) + i += 16 + # remove trailing \n + s = s[:-1] if s.endswith("\n") else s + print(s) + # Scapy has its own hexdump hexdump = scapy.utils.hexdump ls = scapy.packet.ls