Skip to content
3 changes: 2 additions & 1 deletion ptf
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
30 changes: 29 additions & 1 deletion src/ptf/dataplane.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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("==============================")
Expand Down
10 changes: 8 additions & 2 deletions src/ptf/mask.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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):
Expand Down
26 changes: 26 additions & 0 deletions src/ptf/packet_scapy.py
Original file line number Diff line number Diff line change
Expand Up @@ -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