From: Paul Vinciguerra Date: Sun, 10 Mar 2019 17:04:23 +0000 (-0700) Subject: VPP-1508: Use scapy.compat to manage packet level library differences. X-Git-Tag: v19.04-rc1~263 X-Git-Url: https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commitdiff_plain;h=a7427ec6f86cbeba7594f98e41fecab291d66b73 VPP-1508: Use scapy.compat to manage packet level library differences. Change-Id: Icdf6abc9e53d33b26fd1d531c7dda6be0bb9cb55 Signed-off-by: Paul Vinciguerra --- diff --git a/test/framework.py b/test/framework.py index 2c1c8291ed1..7656253294e 100644 --- a/test/framework.py +++ b/test/framework.py @@ -18,6 +18,8 @@ from threading import Thread, Event from inspect import getdoc, isclass from traceback import format_exception from logging import FileHandler, DEBUG, Formatter + +import scapy.compat from scapy.packet import Raw from hook import StepHook, PollHook, VppDiedError from vpp_pg_interface import VppPGInterface @@ -511,7 +513,11 @@ class VppTestCase(unittest.TestCase): if hasattr(cls, 'vpp'): if hasattr(cls, 'vapi'): + cls.logger.debug("Disconnecting class vapi client on %s", + cls.__name__) cls.vapi.disconnect() + cls.logger.debug("Deleting class vapi attribute on %s", + cls.__name__) del cls.vapi cls.vpp.poll() if cls.vpp.returncode is None: @@ -519,6 +525,8 @@ class VppTestCase(unittest.TestCase): cls.vpp.kill() cls.logger.debug("Waiting for vpp to die") cls.vpp.communicate() + cls.logger.debug("Deleting class vpp attribute on %s", + cls.__name__) del cls.vpp if cls.vpp_startup_failed: @@ -560,7 +568,6 @@ class VppTestCase(unittest.TestCase): def tearDown(self): """ Show various debug prints after each test """ - super(VppTestCase, self).tearDown() self.logger.debug("--- tearDown() for %s.%s(%s) called ---" % (self.__class__.__name__, self._testMethodName, self._testMethodDoc)) @@ -848,14 +855,14 @@ class VppTestCase(unittest.TestCase): def assert_packet_checksums_valid(self, packet, ignore_zero_udp_checksums=True): - received = packet.__class__(str(packet)) + received = packet.__class__(scapy.compat.raw(packet)) self.logger.debug( ppp("Verifying packet checksums for packet:", received)) udp_layers = ['UDP', 'UDPerror'] checksum_fields = ['cksum', 'chksum'] checksums = [] counter = 0 - temp = received.__class__(str(received)) + temp = received.__class__(scapy.compat.raw(received)) while True: layer = temp.getlayer(counter) if layer: @@ -872,7 +879,7 @@ class VppTestCase(unittest.TestCase): counter = counter + 1 if 0 == len(checksums): return - temp = temp.__class__(str(temp)) + temp = temp.__class__(scapy.compat.raw(temp)) for layer, cf in checksums: calc_sum = getattr(temp[layer], cf) self.assert_equal( @@ -889,9 +896,10 @@ class VppTestCase(unittest.TestCase): received_packet_checksum = getattr(received_packet[layer], field_name) if ignore_zero_checksum and 0 == received_packet_checksum: return - recalculated = received_packet.__class__(str(received_packet)) + recalculated = received_packet.__class__( + scapy.compat.raw(received_packet)) delattr(recalculated[layer], field_name) - recalculated = recalculated.__class__(str(recalculated)) + recalculated = recalculated.__class__(scapy.compat.raw(recalculated)) self.assert_equal(received_packet_checksum, getattr(recalculated[layer], field_name), "packet checksum on layer: %s" % layer) diff --git a/test/hook.py b/test/hook.py index 6c971c9937f..555fc2ea32a 100644 --- a/test/hook.py +++ b/test/hook.py @@ -5,6 +5,9 @@ import traceback from log import RED, single_line_delim, double_line_delim import ipaddress from subprocess import check_output, CalledProcessError + +import scapy.compat + from util import check_core_path, get_core_path @@ -31,7 +34,7 @@ class Hook(object): return val if len(val) == 6: return '{!s} ({!s})'.format(val, ':'.join(['{:02x}'.format( - ord(x)) for x in val])) + scapy.compat.orb(x)) for x in val])) try: # we don't call test_type(val) because it is a packed value. return '{!s} ({!s})'.format(val, str( diff --git a/test/test_acl_plugin_l2l3.py b/test/test_acl_plugin_l2l3.py index 73dd473c67f..2a99e86119b 100644 --- a/test/test_acl_plugin_l2l3.py +++ b/test/test_acl_plugin_l2l3.py @@ -28,6 +28,7 @@ from socket import inet_pton, AF_INET, AF_INET6 from random import choice, shuffle from pprint import pprint +import scapy.compat from scapy.packet import Raw from scapy.layers.l2 import Ether from scapy.layers.inet import IP, UDP, ICMP, TCP @@ -308,12 +309,14 @@ class TestACLpluginL2L3(VppTestCase): # Scapy IPv6 stuff is too smart for its own good. # So we do this and coerce the ICMP into unknown type if packet.haslayer(UDP): - data = str(packet[UDP][Raw]) + data = scapy.compat.raw(packet[UDP][Raw]) else: if l3 == IP: - data = str(ICMP(str(packet[l3].payload))[Raw]) + data = scapy.compat.raw(ICMP( + scapy.compat.raw(packet[l3].payload))[Raw]) else: - data = str(ICMPv6Unknown(str(packet[l3].payload)).msgbody) + data = scapy.compat.raw(ICMPv6Unknown( + scapy.compat.raw(packet[l3].payload)).msgbody) udp_or_icmp = packet[l3].payload payload_info = self.payload_to_info(data) packet_index = payload_info.index diff --git a/test/test_acl_plugin_macip.py b/test/test_acl_plugin_macip.py index d2d684abc11..6f99646e6e2 100644 --- a/test/test_acl_plugin_macip.py +++ b/test/test_acl_plugin_macip.py @@ -3,12 +3,14 @@ from __future__ import print_function """ACL plugin - MACIP tests """ import binascii +import ipaddress import random from socket import inet_ntop, inet_pton, AF_INET, AF_INET6 from struct import pack, unpack import re import unittest +import scapy.compat from scapy.packet import Raw from scapy.layers.l2 import Ether from scapy.layers.inet import IP, UDP @@ -194,8 +196,10 @@ class MethodHolder(VppTestCase): return acls def create_rules(self, mac_type=EXACT_MAC, ip_type=EXACT_IP, - acl_count=1, rules_count=[1]): + acl_count=1, rules_count=None): acls = [] + if rules_count is None: + rules_count = [1] src_mac = int("220000dead00", 16) for acl in range(2, (acl_count+1) * 2): rules = [] @@ -248,7 +252,7 @@ class MethodHolder(VppTestCase): ip4[3] = 0 ip6[8] = random.randint(100, 200) ip6[15] = 0 - ip_pack = '' + ip_pack = b'' for j in range(0, len(ip)): ip_pack += pack(' read back the pkt (with str()) to force computing these fields # probably other ways to accomplish this are possible - self.assertEqual(rx_srh.payload, IP(str(tx_ip))) + self.assertEqual(rx_srh.payload, IP(scapy.compat.raw(tx_ip))) self.logger.debug("packet verification: SUCCESS") @@ -495,7 +496,7 @@ class TestSRv6(VppTestCase): tx_ip = tx_pkt.getlayer(IPv6) # we can't just get the 2nd Ether layer # get the Raw content and dissect it as Ether - tx_eth1 = Ether(str(tx_pkt[Raw])) + tx_eth1 = Ether(scapy.compat.raw(tx_pkt[Raw])) # verify if rx'ed packet has no SRH self.assertFalse(rx_pkt.haslayer(IPv6ExtHdrSegmentRouting)) @@ -535,7 +536,7 @@ class TestSRv6(VppTestCase): # the whole rx'ed pkt beyond SRH should be equal to tx'ed pkt tx_ether = tx_pkt.getlayer(Ether) - self.assertEqual(Ether(str(rx_srh.payload)), tx_ether) + self.assertEqual(Ether(scapy.compat.raw(rx_srh.payload)), tx_ether) self.logger.debug("packet verification: SUCCESS") @@ -573,7 +574,7 @@ class TestSRv6(VppTestCase): # read back the dumped packet (with str()) # to force computing these fields # probably other ways are possible - p = Ether(str(p)) + p = Ether(scapy.compat.raw(p)) payload_info.data = p.copy() self.logger.debug(ppp("Created packet:", p)) pkts.append(p) @@ -736,7 +737,7 @@ class TestSRv6(VppTestCase): # take packet[Raw], convert it to an Ether layer # and then extract Raw from it payload_info = self.payload_to_info( - Ether(str(packet[Raw]))[Raw]) + Ether(scapy.compat.raw(packet[Raw]))[Raw]) return payload_info @@ -750,7 +751,7 @@ class TestSRv6(VppTestCase): :param compare_func: function to compare in and out packet """ self.logger.info("Verifying capture on interface %s using function %s" - % (dst_if.name, compare_func.func_name)) + % (dst_if.name, compare_func.__name__)) last_info = dict() for i in self.pg_interfaces: diff --git a/test/test_srv6_as.py b/test/test_srv6_as.py index 1ff7906e513..6b8e23c8520 100755 --- a/test/test_srv6_as.py +++ b/test/test_srv6_as.py @@ -9,6 +9,7 @@ from vpp_ip_route import VppIpRoute, VppRoutePath, DpoProto, VppIpTable from vpp_srv6 import SRv6LocalSIDBehaviors, VppSRv6LocalSID, VppSRv6Policy, \ SRv6PolicyType, VppSRv6Steering, SRv6PolicySteeringTypes +import scapy.compat from scapy.packet import Raw from scapy.layers.l2 import Ether, Dot1Q from scapy.layers.inet6 import IPv6, UDP, IPv6ExtHdrSegmentRouting @@ -488,7 +489,7 @@ class TestSRv6(VppTestCase): tx_ip.chksum = None # read back the pkt (with str()) to force computing these fields # probably other ways to accomplish this are possible - tx_ip = IP(str(tx_ip)) + tx_ip = IP(scapy.compat.raw(tx_ip)) self.assertEqual(payload, tx_ip) @@ -537,7 +538,7 @@ class TestSRv6(VppTestCase): payload = rx_ip.payload # the whole rx'ed pkt beyond SRH should be equal to tx'ed pkt - self.assertEqual(Ether(str(payload)), tx_ether) + self.assertEqual(Ether(scapy.compat.raw(payload)), tx_ether) self.logger.debug("packet verification: SUCCESS") @@ -590,7 +591,7 @@ class TestSRv6(VppTestCase): tx_ip2.chksum = None # read back the pkt (with str()) to force computing these fields # probably other ways to accomplish this are possible - tx_ip2 = IP(str(tx_ip2)) + tx_ip2 = IP(scapy.compat.raw(tx_ip2)) self.assertEqual(rx_ip, tx_ip2) @@ -609,7 +610,7 @@ class TestSRv6(VppTestCase): tx_ip = tx_pkt.getlayer(IPv6) # we can't just get the 2nd Ether layer # get the Raw content and dissect it as Ether - tx_eth1 = Ether(str(tx_pkt[Raw])) + tx_eth1 = Ether(scapy.compat.raw(tx_pkt[Raw])) # verify if rx'ed packet has no SRH self.assertFalse(rx_pkt.haslayer(IPv6ExtHdrSegmentRouting)) @@ -655,7 +656,7 @@ class TestSRv6(VppTestCase): # read back the dumped packet (with str()) # to force computing these fields # probably other ways are possible - p = Ether(str(p)) + p = Ether(scapy.compat.raw(p)) payload_info.data = p.copy() self.logger.debug(ppp("Created packet:", p)) pkts.append(p) @@ -817,7 +818,7 @@ class TestSRv6(VppTestCase): # take packet[Raw], convert it to an Ether layer # and then extract Raw from it payload_info = self.payload_to_info( - Ether(str(packet[Raw]))[Raw]) + Ether(scapy.compat.raw(packet[Raw]))[Raw]) return payload_info @@ -831,7 +832,7 @@ class TestSRv6(VppTestCase): :param compare_func: function to compare in and out packet """ self.logger.info("Verifying capture on interface %s using function %s" - % (dst_if.name, compare_func.func_name)) + % (dst_if.name, compare_func.__name__)) last_info = dict() for i in self.pg_interfaces: diff --git a/test/util.py b/test/util.py index fc0ebd73500..d27b3fb25e6 100644 --- a/test/util.py +++ b/test/util.py @@ -7,6 +7,7 @@ import six import sys import os.path +import scapy.compat from scapy.layers.l2 import Ether from scapy.layers.inet import IP from scapy.layers.inet6 import IPv6, IPv6ExtHdrFragment, IPv6ExtHdrRouting,\ @@ -282,7 +283,7 @@ def fragment_rfc791(packet, fragsize, _logger=None): """ logger = LoggerWrapper(_logger) logger.debug(ppp("Fragmenting packet:", packet)) - packet = packet.__class__(str(packet)) # recalculate all values + packet = packet.__class__(scapy.compat.raw(packet)) # recalc. all values if len(packet[IP].options) > 0: raise Exception("Not implemented") if len(packet) <= fragsize: @@ -290,7 +291,7 @@ def fragment_rfc791(packet, fragsize, _logger=None): pre_ip_len = len(packet) - len(packet[IP]) ip_header_len = packet[IP].ihl * 4 - hex_packet = str(packet) + hex_packet = scapy.compat.raw(packet) hex_headers = hex_packet[:(pre_ip_len + ip_header_len)] hex_payload = hex_packet[(pre_ip_len + ip_header_len):] @@ -327,7 +328,7 @@ def fragment_rfc8200(packet, identification, fragsize, _logger=None): :returns: list of fragments """ logger = LoggerWrapper(_logger) - packet = packet.__class__(str(packet)) # recalculate all values + packet = packet.__class__(scapy.compat.raw(packet)) # recalc. all values if len(packet) <= fragsize: return [packet] logger.debug(ppp("Fragmenting packet:", packet)) @@ -378,7 +379,7 @@ def fragment_rfc8200(packet, identification, fragsize, _logger=None): logger.debug(ppp("Per-fragment headers:", per_fragment_headers)) ext_and_upper_layer = packet.getlayer(last_per_fragment_hdr)[1] - hex_payload = str(ext_and_upper_layer) + hex_payload = scapy.compat.raw(ext_and_upper_layer) logger.debug("Payload length is %s" % len(hex_payload)) logger.debug(ppp("Ext and upper layer:", ext_and_upper_layer)) @@ -407,7 +408,7 @@ def fragment_rfc8200(packet, identification, fragsize, _logger=None): p[IPv6ExtHdrFragment].id = identification p[IPv6ExtHdrFragment].offset = 0 p[IPv6ExtHdrFragment].m = 1 - p = p.__class__(str(p)) + p = p.__class__(scapy.compat.raw(p)) logger.debug(ppp("Fragment %s:" % len(pkts), p)) pkts.append(p) offset = first_payload_len_nfb * 8 @@ -424,7 +425,7 @@ def fragment_rfc8200(packet, identification, fragsize, _logger=None): p[IPv6ExtHdrFragment].id = identification p[IPv6ExtHdrFragment].offset = offset / 8 p[IPv6ExtHdrFragment].m = 1 - p = p.__class__(str(p)) + p = p.__class__(scapy.compat.raw(p)) logger.debug(ppp("Fragment %s:" % len(pkts), p)) pkts.append(p) offset = offset + l_nfb * 8 diff --git a/test/vpp_pg_interface.py b/test/vpp_pg_interface.py index b22a93388a6..8792e6c3767 100644 --- a/test/vpp_pg_interface.py +++ b/test/vpp_pg_interface.py @@ -3,6 +3,8 @@ import time import socket import struct from traceback import format_exc, format_stack + +import scapy.compat from scapy.utils import wrpcap, rdpcap, PcapReader from scapy.plist import PacketList from vpp_interface import VppInterface @@ -414,7 +416,7 @@ class VppPGInterface(VppInterface): # Make Dot1AD packet content recognizable to scapy if arp_reply.type == 0x88a8: arp_reply.type = 0x8100 - arp_reply = Ether(str(arp_reply)) + arp_reply = Ether(scapy.compat.raw(arp_reply)) try: if arp_reply[ARP].op == ARP.is_at: self.test.logger.info("VPP %s MAC address is %s " % @@ -460,8 +462,11 @@ class VppPGInterface(VppInterface): ndp_reply = captured_packet.copy() # keep original for exception # Make Dot1AD packet content recognizable to scapy if ndp_reply.type == 0x88a8: + self._test.logger.info( + "Replacing EtherType: 0x88a8 with " + "0x8100 and regenerating Ethernet header. ") ndp_reply.type = 0x8100 - ndp_reply = Ether(str(ndp_reply)) + ndp_reply = Ether(scapy.compat.raw(ndp_reply)) try: ndp_na = ndp_reply[ICMPv6ND_NA] opt = ndp_na[ICMPv6NDOptDstLLAddr]