コード例 #1
0
    def verify_tunneled_6o6(self, src_if, capture, sent,
                            tunnel_src, tunnel_dst,
                            dscp=0, ecn=0):

        self.assertEqual(len(capture), len(sent))
        tc = (dscp << 2) | ecn

        for i in range(len(capture)):
            try:
                tx = sent[i]
                rx = capture[i]

                tx_ip = tx[IPv6]
                rx_ip = rx[IPv6]

                self.assertEqual(rx_ip.src, tunnel_src)
                self.assertEqual(rx_ip.dst, tunnel_dst)
                self.assertEqual(rx_ip.tc, tc)

                rx_gre = GRE(scapy.compat.raw(rx_ip[IPv6].payload))

                self.assertEqual(rx_ip.plen, len(rx_gre))

                rx_ip = rx_gre[IPv6]

                self.assertEqual(rx_ip.src, tx_ip.src)
                self.assertEqual(rx_ip.dst, tx_ip.dst)

            except:
                self.logger.error(ppp("Rx:", rx))
                self.logger.error(ppp("Tx:", tx))
                raise
コード例 #2
0
ファイル: test_gre.py プロジェクト: jgallo542/vpp-1
    def verify_tunneled_6o4(self, src_if, capture, sent, tunnel_src,
                            tunnel_dst):

        self.assertEqual(len(capture), len(sent))

        for i in range(len(capture)):
            try:
                tx = sent[i]
                rx = capture[i]

                rx_ip = rx[IP]

                self.assertEqual(rx_ip.src, tunnel_src)
                self.assertEqual(rx_ip.dst, tunnel_dst)

                rx_gre = GRE(scapy.compat.raw(rx_ip[IP].payload))
                rx_ip = rx_gre[IPv6]
                tx_ip = tx[IPv6]

                self.assertEqual(rx_ip.src, tx_ip.src)
                self.assertEqual(rx_ip.dst, tx_ip.dst)

            except:
                self.logger.error(ppp("Rx:", rx))
                self.logger.error(ppp("Tx:", tx))
                raise
コード例 #3
0
    def test_gre_input_node(self):
        """ GRE gre input nodes not registerd unless configured """
        pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
               IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) /
               GRE())

        self.pg0.add_stream(pkt)
        self.pg_start()
        # no tunnel created, gre-input not registered
        err = self.statistics.get_counter(
            '/err/ip4-local/unknown ip protocol')[0]
        self.assertEqual(err, 1)
        err_count = err

        # create gre tunnel
        gre_if = VppGreInterface(self, self.pg0.local_ip4, "1.1.1.2")
        gre_if.add_vpp_config()

        self.pg0.add_stream(pkt)
        self.pg_start()
        # tunnel created, gre-input registered
        err = self.statistics.get_counter(
            '/err/ip4-local/unknown ip protocol')[0]
        # expect no new errors
        self.assertEqual(err, err_count)
コード例 #4
0
ファイル: test_lb.py プロジェクト: zengnotes/vpp
    def checkCapture(self, encap, isv4):
        self.pg0.assert_nothing_captured()
        out = self.pg1.get_capture(len(self.packets))

        load = [0] * len(self.ass)
        self.info = None
        for p in out:
            try:
                asid = 0
                gre = None
                if (encap == 'gre4'):
                    ip = p[IP]
                    asid = int(ip.dst.split(".")[3])
                    self.assertEqual(ip.version, 4)
                    self.assertEqual(ip.flags, 0)
                    self.assertEqual(ip.src, "39.40.41.42")
                    self.assertEqual(ip.dst, "10.0.0.%u" % asid)
                    self.assertEqual(ip.proto, 47)
                    self.assertEqual(len(ip.options), 0)
                    self.assertGreaterEqual(ip.ttl, 64)
                    gre = p[GRE]
                    self.checkInner(gre, isv4)
                elif (encap == 'gre6'):
                    ip = p[IPv6]
                    asid = ip.dst.split(":")
                    asid = asid[len(asid) - 1]
                    asid = 0 if asid == "" else int(asid)
                    self.assertEqual(ip.version, 6)
                    self.assertEqual(ip.tc, 0)
                    self.assertEqual(ip.fl, 0)
                    self.assertEqual(ip.src, "2004::1")
                    self.assertEqual(
                        socket.inet_pton(socket.AF_INET6, ip.dst),
                        socket.inet_pton(socket.AF_INET6, "2002::%u" % asid))
                    self.assertEqual(ip.nh, 47)
                    self.assertGreaterEqual(ip.hlim, 64)
                    # self.assertEqual(len(ip.options), 0)
                    gre = GRE(str(p[IPv6].payload))
                    self.checkInner(gre, isv4)
                if (encap == 'l3dsr'):
                    ip = p[IP]
                    asid = int(ip.dst.split(".")[3])
                    self.assertEqual(ip.version, 4)
                    self.assertEqual(ip.flags, 0)
                    self.assertEqual(ip.dst, "10.0.0.%u" % asid)
                    self.assertEqual(ip.tos, 0x1c)
                    self.assertEqual(len(ip.options), 0)
                load[asid] += 1
            except:
                self.logger.error(ppp("Unexpected or invalid packet:", p))
                raise

        # This is just to roughly check that the balancing algorithm
        # is not completly biased.
        for asid in self.ass:
            if load[asid] < len(self.packets) / (len(self.ass) * 2):
                self.logger.error("ASS is not balanced: load[%d] = %d" %
                                  (asid, load[asid]))
                raise Exception("Load Balancer algorithm is biased")
コード例 #5
0
ファイル: test_reassembly.py プロジェクト: yaoferics/vpp
    def test_fif4(self):
        """ Fragments in fragments (4o4) """

        # TODO this should be ideally in setUpClass, but then we hit a bug
        # with VppIpRoute incorrectly reporting it's present when it's not
        # so we need to manually remove the vpp config, thus we cannot have
        # it shared for multiple test cases
        self.tun_ip4 = "1.1.1.2"

        self.gre4 = VppGreInterface(self, self.pg0.local_ip4, self.tun_ip4)
        self.gre4.add_vpp_config()
        self.gre4.admin_up()
        self.gre4.config_ip4()

        self.route4 = VppIpRoute(
            self, self.tun_ip4, 32,
            [VppRoutePath(self.pg0.remote_ip4, self.pg0.sw_if_index)])
        self.route4.add_vpp_config()

        self.reset_packet_infos()
        for i in range(test_packet_count):
            info = self.create_packet_info(self.pg0, self.pg0)
            payload = self.info_to_payload(info)
            p = (IP(id=i, src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) /
                 UDP(sport=1234, dport=self.punt_port) / Raw(payload))
            size = self.packet_sizes[(i // 2) % len(self.packet_sizes)]
            self.extend_packet(p, size, self.padding)
            info.data = p

        fragments = [
            x for _, p in self._packet_infos.iteritems()
            for x in fragment_rfc791(p.data, 400)
        ]

        encapped_fragments = \
            [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
             IP(src=self.tun_ip4, dst=self.pg0.local_ip4) /
                GRE() /
                p
                for p in fragments]

        fragmented_encapped_fragments = \
            [x for p in encapped_fragments
             for x in fragment_rfc791(p, 200)]

        self.pg0.add_stream(fragmented_encapped_fragments)

        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        self.pg0.assert_nothing_captured()
        packets = self.punt4_socket.wait_for_packets(len(self._packet_infos))
        self.verify_capture(packets, IP)

        # TODO remove gre vpp config by hand until VppIpRoute gets fixed
        # so that it's query_vpp_config() works as it should
        self.gre4.remove_vpp_config()
コード例 #6
0
    def checkCapture(self, gre4, isv4):
        out = self.pg0.get_capture()
        # This check is edited because RA appears in output, maybe disable RA?
        # self.assertEqual(len(out), 0)
        self.assertLess(len(out), 20)
        out = self.pg1.get_capture()
        self.assertEqual(len(out), len(self.packets))

        load = [0] * len(self.ass)
        self.info = None
        for p in out:
            try:
                asid = 0
                gre = None
                if gre4:
                    ip = p[IP]
                    asid = int(ip.dst.split(".")[3])
                    self.assertEqual(ip.version, 4)
                    self.assertEqual(ip.flags, 0)
                    self.assertEqual(ip.src, "39.40.41.42")
                    self.assertEqual(ip.dst, "10.0.0.%u" % asid)
                    self.assertEqual(ip.proto, 47)
                    self.assertEqual(len(ip.options), 0)
                    self.assertGreaterEqual(ip.ttl, 64)
                    gre = p[GRE]
                else:
                    ip = p[IPv6]
                    asid = ip.dst.split(":")
                    asid = asid[len(asid) - 1]
                    asid = 0 if asid == "" else int(asid)
                    self.assertEqual(ip.version, 6)
                    self.assertEqual(ip.tc, 0)
                    self.assertEqual(ip.fl, 0)
                    self.assertEqual(ip.src, "2004::1")
                    self.assertEqual(
                        socket.inet_pton(socket.AF_INET6, ip.dst),
                        socket.inet_pton(socket.AF_INET6, "2002::%u" % asid))
                    self.assertEqual(ip.nh, 47)
                    self.assertGreaterEqual(ip.hlim, 64)
                    # self.assertEqual(len(ip.options), 0)
                    gre = GRE(str(p[IPv6].payload))
                self.checkInner(gre, isv4)
                load[asid] += 1
            except:
                error("Unexpected or invalid packet:")
                p.show()
                raise

        # This is just to roughly check that the balancing algorithm
        # is not completly biased.
        for asid in self.ass:
            if load[asid] < len(self.packets) / (len(self.ass) * 2):
                self.log("ASS is not balanced: load[%d] = %d" %
                         (asid, load[asid]))
                raise Exception("Load Balancer algorithm is biased")
コード例 #7
0
def main():
    args = TrafficScriptArg([
        'tx_dst_mac', 'rx_dst_mac', 'inner_src_ip', 'inner_dst_ip',
        'outer_src_ip', 'outer_dst_ip'
    ])

    tx_if = args.get_arg('tx_if')
    rx_if = args.get_arg('rx_if')
    tx_dst_mac = args.get_arg('tx_dst_mac')
    rx_dst_mac = args.get_arg('rx_dst_mac')
    inner_src_ip = args.get_arg('inner_src_ip')
    inner_dst_ip = args.get_arg('inner_dst_ip')
    outer_src_ip = args.get_arg('outer_src_ip')
    outer_dst_ip = args.get_arg('outer_dst_ip')

    rxq = RxQueue(rx_if)
    txq = TxQueue(tx_if)
    sent_packets = []

    tx_pkt_raw = Ether(dst=tx_dst_mac) / \
        IP(src=outer_src_ip, dst=outer_dst_ip) / \
        GRE() / \
        IP(src=inner_src_ip, dst=inner_dst_ip) / \
        ICMP()

    sent_packets.append(tx_pkt_raw)
    txq.send(tx_pkt_raw)
    ether = rxq.recv(2)

    if ether is None:
        raise RuntimeError("ICMP echo Rx timeout")

    # Check RX headers
    if ether.dst != rx_dst_mac:
        raise RuntimeError(
            "Matching of received destination MAC unsuccessful.")
    logger.debug("Comparison of received destination MAC: OK.")

    if ether['IP'].src != inner_src_ip:
        raise RuntimeError(
            "Matching of received inner source IP unsuccessful.")
    logger.debug("Comparison of received outer source IP: OK.")

    if ether['IP'].dst != inner_dst_ip:
        raise RuntimeError(
            "Matching of received inner destination IP unsuccessful.")
    logger.debug("Comparison of received outer destination IP: OK.")

    if ether['IP'].proto != IP_PROTOS.icmp:
        raise RuntimeError("IP protocol is other than ICMP.")
    logger.debug("Comparison of received ICMP protocol: OK.")

    sys.exit(0)
コード例 #8
0
ファイル: test_gre.py プロジェクト: jgallo542/vpp-1
 def create_tunnel_stream_6o6(self, src_if, tunnel_src, tunnel_dst, src_ip,
                              dst_ip):
     pkts = []
     for i in range(0, 257):
         info = self.create_packet_info(src_if, src_if)
         payload = self.info_to_payload(info)
         p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
              IPv6(src=tunnel_src, dst=tunnel_dst) / GRE() /
              IPv6(src=src_ip, dst=dst_ip) / UDP(sport=1234, dport=1234) /
              Raw(payload))
         info.data = p.copy()
         pkts.append(p)
     return pkts
コード例 #9
0
 def create_tunnel_stream_l2o4(self, src_if, tunnel_src, tunnel_dst):
     pkts = []
     for i in range(0, 257):
         info = self.create_packet_info(src_if, src_if)
         payload = self.info_to_payload(info)
         p = (
             Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
             IP(src=tunnel_src, dst=tunnel_dst) / GRE() /
             Ether(dst=RandMAC('*:*:*:*:*:*'), src=RandMAC('*:*:*:*:*:*')) /
             IP(src=str(RandIP()), dst=str(RandIP())) /
             UDP(sport=1234, dport=1234) / Raw(payload))
         info.data = p.copy()
         pkts.append(p)
     return pkts
コード例 #10
0
 def gen_encrypt_pkts(self,
                      sa,
                      sw_intf,
                      src,
                      dst,
                      count=1,
                      payload_size=100):
     return [
         Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) / sa.encrypt(
             IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) / GRE() /
             IP(src=self.pg1.local_ip4, dst=self.pg1.remote_ip4) /
             UDP(sport=1144, dport=2233) / Raw('X' * payload_size))
         for i in range(count)
     ]
コード例 #11
0
    def test_fif6(self):
        """ Fragments in fragments (6o6) """
        # TODO this should be ideally in setUpClass, but then we hit a bug
        # with VppIpRoute incorrectly reporting it's present when it's not
        # so we need to manually remove the vpp config, thus we cannot have
        # it shared for multiple test cases
        self.tun_ip6 = "1002::1"

        self.gre6 = VppGreInterface(self, self.src_if.local_ip6, self.tun_ip6)
        self.gre6.add_vpp_config()
        self.gre6.admin_up()
        self.gre6.config_ip6()

        self.vapi.ip_reassembly_enable_disable(
            sw_if_index=self.gre6.sw_if_index, enable_ip6=True)

        self.route6 = VppIpRoute(self,
                                 self.tun_ip6,
                                 128, [
                                     VppRoutePath(self.src_if.remote_ip6,
                                                  self.src_if.sw_if_index,
                                                  proto=DpoProto.DPO_PROTO_IP6)
                                 ],
                                 is_ip6=1)
        self.route6.add_vpp_config()

        self.reset_packet_infos()
        for i in range(test_packet_count):
            info = self.create_packet_info(self.src_if, self.dst_if)
            payload = self.info_to_payload(info)
            # Ethernet header here is only for size calculation, thus it
            # doesn't matter how it's initialized. This is to ensure that
            # reassembled packet is not > 9000 bytes, so that it's not dropped
            p = (Ether() /
                 IPv6(src=self.src_if.remote_ip6, dst=self.dst_if.remote_ip6) /
                 UDP(sport=1234, dport=5678) / Raw(payload))
            size = self.packet_sizes[(i // 2) % len(self.packet_sizes)]
            self.extend_packet(p, size, self.padding)
            info.data = p[IPv6]  # use only IPv6 part, without ethernet header

        fragments = [
            x for _, i in six.iteritems(self._packet_infos)
            for x in fragment_rfc8200(i.data, i.index, 400)
        ]

        encapped_fragments = \
            [Ether(dst=self.src_if.local_mac, src=self.src_if.remote_mac) /
             IPv6(src=self.tun_ip6, dst=self.src_if.local_ip6) /
                GRE() /
                p
                for p in fragments]

        fragmented_encapped_fragments = \
            [x for p in encapped_fragments for x in (
                fragment_rfc8200(
                    p,
                    2 * len(self._packet_infos) + p[IPv6ExtHdrFragment].id,
                    200)
                if IPv6ExtHdrFragment in p else [p]
            )
            ]

        self.src_if.add_stream(fragmented_encapped_fragments)

        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        self.src_if.assert_nothing_captured()
        packets = self.dst_if.get_capture(len(self._packet_infos))
        self.verify_capture(packets, IPv6)

        # TODO remove gre vpp config by hand until VppIpRoute gets fixed
        # so that it's query_vpp_config() works as it should
        self.gre6.remove_vpp_config()
コード例 #12
0
    def test_fif4(self):
        """ Fragments in fragments (4o4) """

        # TODO this should be ideally in setUpClass, but then we hit a bug
        # with VppIpRoute incorrectly reporting it's present when it's not
        # so we need to manually remove the vpp config, thus we cannot have
        # it shared for multiple test cases
        self.tun_ip4 = "1.1.1.2"

        self.gre4 = VppGreInterface(self, self.src_if.local_ip4, self.tun_ip4)
        self.gre4.add_vpp_config()
        self.gre4.admin_up()
        self.gre4.config_ip4()

        self.vapi.ip_reassembly_enable_disable(
            sw_if_index=self.gre4.sw_if_index, enable_ip4=True)

        self.route4 = VppIpRoute(
            self, self.tun_ip4, 32,
            [VppRoutePath(self.src_if.remote_ip4, self.src_if.sw_if_index)])
        self.route4.add_vpp_config()

        self.reset_packet_infos()
        for i in range(test_packet_count):
            info = self.create_packet_info(self.src_if, self.dst_if)
            payload = self.info_to_payload(info)
            # Ethernet header here is only for size calculation, thus it
            # doesn't matter how it's initialized. This is to ensure that
            # reassembled packet is not > 9000 bytes, so that it's not dropped
            p = (Ether() / IP(
                id=i, src=self.src_if.remote_ip4, dst=self.dst_if.remote_ip4) /
                 UDP(sport=1234, dport=5678) / Raw(payload))
            size = self.packet_sizes[(i // 2) % len(self.packet_sizes)]
            self.extend_packet(p, size, self.padding)
            info.data = p[IP]  # use only IP part, without ethernet header

        fragments = [
            x for _, p in six.iteritems(self._packet_infos)
            for x in fragment_rfc791(p.data, 400)
        ]

        encapped_fragments = \
            [Ether(dst=self.src_if.local_mac, src=self.src_if.remote_mac) /
             IP(src=self.tun_ip4, dst=self.src_if.local_ip4) /
                GRE() /
                p
                for p in fragments]

        fragmented_encapped_fragments = \
            [x for p in encapped_fragments
             for x in fragment_rfc791(p, 200)]

        self.src_if.add_stream(fragmented_encapped_fragments)

        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        self.src_if.assert_nothing_captured()
        packets = self.dst_if.get_capture(len(self._packet_infos))
        self.verify_capture(packets, IP)

        # TODO remove gre vpp config by hand until VppIpRoute gets fixed
        # so that it's query_vpp_config() works as it should
        self.gre4.remove_vpp_config()
        self.logger.debug(self.vapi.ppcli("show interface"))
コード例 #13
0
    def test_ip_mcast_gre(self):
        """ IP Multicast Replication over GRE"""

        gre_if_1 = VppGreInterface(self, self.pg1.local_ip4,
                                   self.pg1.remote_ip4).add_vpp_config()
        gre_if_2 = VppGreInterface(self, self.pg2.local_ip4,
                                   self.pg2.remote_ip4).add_vpp_config()
        gre_if_3 = VppGreInterface(self, self.pg3.local_ip4,
                                   self.pg3.remote_ip4).add_vpp_config()

        gre_if_1.admin_up()
        gre_if_1.config_ip4()
        gre_if_2.admin_up()
        gre_if_2.config_ip4()
        gre_if_3.admin_up()
        gre_if_3.config_ip4()

        #
        # An (S,G).
        # one accepting interface, pg0, 2 forwarding interfaces
        #
        route_1_1_1_1_232_1_1_1 = VppIpMRoute(
            self, "1.1.1.1", "232.2.2.2", 64,
            MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, [
                VppMRoutePath(gre_if_1.sw_if_index,
                              MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
                VppMRoutePath(gre_if_2.sw_if_index,
                              MRouteItfFlags.MFIB_ITF_FLAG_FORWARD),
                VppMRoutePath(gre_if_3.sw_if_index,
                              MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)
            ])
        route_1_1_1_1_232_1_1_1.add_vpp_config()

        #
        # a stream that matches the route for (1.1.1.1,232.2.2.2)
        #  small packets
        #
        tx = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
              IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) / GRE() /
              IP(src="1.1.1.1", dst="232.2.2.2") /
              UDP(sport=1234, dport=1234) / Raw('\a5' * 64)) * 63

        self.vapi.cli("clear trace")
        self.pg1.add_stream(tx)

        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        # We expect replications on Pg2 & 3
        # check the encap headers are as expected based on the egress tunnel
        rxs = self.pg2.get_capture(len(tx))
        for rx in rxs:
            self.assertEqual(rx[IP].src, gre_if_2.t_src)
            self.assertEqual(rx[IP].dst, gre_if_2.t_dst)
            self.assert_packet_checksums_valid(rx)

        rxs = self.pg3.get_capture(len(tx))
        for rx in rxs:
            self.assertEqual(rx[IP].src, gre_if_3.t_src)
            self.assertEqual(rx[IP].dst, gre_if_3.t_dst)
            self.assert_packet_checksums_valid(rx)
コード例 #14
0
class scapy(object):
    SCAPY_LAYERS = {
        'ether': Ether(dst="ff:ff:ff:ff:ff:ff"),
        'vlan': Dot1Q(),
        'etag': None,
        '1588': Ether(type=0x88f7),
        'arp': ARP(),
        'ipv4': IP(),
        'ipv4ihl': IP(ihl=10),
        'ipv4_ext': IP(frag=5),
        'ipv6': IPv6(src="::1"),
        'ipv6_ext': IPv6(src="::1", nh=43) / IPv6ExtHdrRouting(),
        'ipv6_ext2': IPv6() / IPv6ExtHdrRouting(),
        'udp': UDP(),
        'tcp': TCP(),
        'sctp': SCTP(),
        'icmp': ICMP(),
        'gre': GRE(),
        'raw': Raw(),
        'vxlan': Vxlan(),
        'inner_mac': Ether(),
        'inner_vlan': Dot1Q(),
        'inner_ipv4': IP(),
        'inner_ipv4_ext': IP(),
        'inner_ipv6': IPv6(src="::1"),
        'inner_ipv6_ext': IPv6(src="::1"),
        'inner_tcp': TCP(),
        'inner_udp': UDP(),
        'inner_sctp': SCTP(),
        'inner_icmp': ICMP(),
        'lldp': None,
        'ip_frag': IP(frag=5),
        'ipv6_frag': IPv6(src="::1") / IPv6ExtHdrFragment(),
        'ip_in_ip': IP() / IP(),
        'ip_in_ip_frag': IP() / IP(frag=5),
        'ipv6_in_ip': IP() / IPv6(src="::1"),
        'ipv6_frag_in_ip':
        IP() / IPv6(src="::1", nh=44) / IPv6ExtHdrFragment(),
        'nvgre': None,
        'geneve': "Not Implement",
    }

    def __init__(self):
        self.pkt = None
        pass

    def assign_pkt(self, pkt):
        self.pkt = pkt

    def add_layers(self, layers):
        self.pkt = None
        for layer in layers:
            if self.pkt is not None:
                self.pkt = self.pkt / self.SCAPY_LAYERS[layer]
            else:
                self.pkt = self.SCAPY_LAYERS[layer]

    def ether(self,
              pkt_layer,
              dst="ff:ff:ff:ff:ff:ff",
              src="00:00:20:00:00:00",
              type=None):
        if pkt_layer.name != "Ethernet":
            return
        pkt_layer.dst = dst
        pkt_layer.src = src
        if type is not None:
            pkt_layer.type = type

    def vlan(self, pkt_layer, vlan, prio=0, type=None):
        if pkt_layer.name != "802.1Q":
            return
        pkt_layer.vlan = int(vlan)
        pkt_layer.prio = prio
        if type is not None:
            pkt_layer.type = type

    def strip_vlan(self, element):
        value = None

        if self.pkt.haslayer('Dot1Q') is 0:
            return None

        if element == 'vlan':
            value = int(str(self.pkt[Dot1Q].vlan))
        return value

    def etag(self, pkt_layer, ECIDbase=0, prio=0, type=None):
        if pkt_layer.name != "802.1BR":
            return
        pkt_layer.ECIDbase = int(ECIDbase)
        pkt_layer.prio = prio
        if type is not None:
            pkt_layer.type = type

    def strip_etag(self, element):
        value = None

        if self.pkt.haslayer('Dot1BR') is 0:
            return None

        if element == 'ECIDbase':
            value = int(str(self.pkt[Dot1BR].ECIDbase))
        return value

    def strip_layer2(self, element):
        value = None
        layer = self.pkt.getlayer(0)
        if layer is None:
            return None

        if element == 'src':
            value = layer.src
        elif element == 'dst':
            value = layer.dst
        elif element == 'type':
            value = layer.type

        return value

    def strip_layer3(self, element):
        value = None
        layer = self.pkt.getlayer(1)
        if layer is None:
            return None

        if element == 'src':
            value = layer.src
        elif element == 'dst':
            value = layer.dst
        else:
            value = layer.getfieldval(element)

        return value

    def strip_layer4(self, element):
        value = None
        layer = self.pkt.getlayer(2)
        if layer is None:
            return None

        if element == 'src':
            value = layer.sport
        elif element == 'dst':
            value = layer.dport
        else:
            value = layer.getfieldval(element)

        return value

    def ipv4(self,
             pkt_layer,
             frag=0,
             src="127.0.0.1",
             proto=None,
             tos=0,
             dst="127.0.0.1",
             chksum=None,
             len=None,
             version=4,
             flags=None,
             ihl=None,
             ttl=64,
             id=1,
             options=None):
        pkt_layer.frag = frag
        pkt_layer.src = src
        if proto is not None:
            pkt_layer.proto = proto
        pkt_layer.tos = tos
        pkt_layer.dst = dst
        if chksum is not None:
            pkt_layer.chksum = chksum
        if len is not None:
            pkt_layer.len = len
        pkt_layer.version = version
        if flags is not None:
            pkt_layer.flags = flags
        if ihl is not None:
            pkt_layer.ihl = ihl
        pkt_layer.ttl = ttl
        pkt_layer.id = id
        if options is not None:
            pkt_layer.options = options

    def ipv6(self,
             pkt_layer,
             version=6,
             tc=0,
             fl=0,
             plen=0,
             nh=0,
             hlim=64,
             src="::1",
             dst="::1"):
        """
        Configure IPv6 protocal.
        """
        pkt_layer.version = version
        pkt_layer.tc = tc
        pkt_layer.fl = fl
        if plen:
            pkt_layer.plen = plen
        if nh:
            pkt_layer.nh = nh
        pkt_layer.src = src
        pkt_layer.dst = dst

    def tcp(self,
            pkt_layer,
            src=53,
            dst=53,
            flags=None,
            len=None,
            chksum=None):
        pkt_layer.sport = src
        pkt_layer.dport = dst
        if flags is not None:
            pkt_layer.flags = flags
        if len is not None:
            pkt_layer.len = len
        if chksum is not None:
            pkt_layer.chksum = chksum

    def udp(self, pkt_layer, src=53, dst=53, len=None, chksum=None):
        pkt_layer.sport = src
        pkt_layer.dport = dst
        if len is not None:
            pkt_layer.len = len
        if chksum is not None:
            pkt_layer.chksum = chksum

    def sctp(self, pkt_layer, src=53, dst=53, tag=None, len=None, chksum=None):
        pkt_layer.sport = src
        pkt_layer.dport = dst
        if tag is not None:
            pkt_layer.tag = tag
        if len is not None:
            pkt_layer.len = len
        if chksum is not None:
            pkt_layer.chksum = chksum

    def raw(self, pkt_layer, payload=None):
        if payload is not None:
            pkt_layer.load = ''
            for hex1, hex2 in payload:
                pkt_layer.load += struct.pack("=B",
                                              int('%s%s' % (hex1, hex2), 16))

    def gre(self, pkt_layer, proto=None):
        if proto is not None:
            pkt_layer.proto = proto

    def vxlan(self, pkt_layer, vni=0):
        pkt_layer.vni = vni

    def read_pcap(self, file):
        pcap_pkts = []
        try:
            pcap_pkts = rdpcap(file)
        except:
            pass

        return pcap_pkts

    def write_pcap(self, file):
        try:
            wrpcap(file, self.pkt)
        except:
            pass

    def send_pcap_pkt(self, crb=None, file='', intf='', count=1):
        if intf == '' or file == '' or crb is None:
            print "Invalid option for send packet by scapy"
            return

        content = 'pkts=rdpcap(\"%s\");sendp(pkts, iface=\"%s\", count=\"%s\" );exit()' % (
            file, intf, count)
        cmd_file = '/tmp/scapy_%s.cmd' % intf

        crb.create_file(content, cmd_file)
        crb.send_expect("scapy -c scapy_%s.cmd &" % intf, "# ")

    def print_summary(self):
        print "Send out pkt %s" % self.pkt.summary()

    def send_pkt(self, intf='', count=1):
        self.print_summary()

        if intf != '':
            # wait few seconds for link ready
            countdown = 600
            while countdown:
                link_st = subprocess.check_output("ip link show %s" % intf,
                                                  stderr=subprocess.STDOUT,
                                                  shell=True)
                if "LOWER_UP" in link_st:
                    break
                else:
                    time.sleep(0.01)
                    countdown -= 1
                    continue

            # fix fortville can't receive packets with 00:00:00:00:00:00
            if self.pkt.getlayer(0).src == "00:00:00:00:00:00":
                self.pkt.getlayer(0).src = get_if_hwaddr(intf)
            sendp(self.pkt, iface=intf, count=count)
コード例 #15
0
ファイル: test_reassembly.py プロジェクト: yaoferics/vpp
    def test_fif6(self):
        """ Fragments in fragments (6o6) """
        # TODO this should be ideally in setUpClass, but then we hit a bug
        # with VppIpRoute incorrectly reporting it's present when it's not
        # so we need to manually remove the vpp config, thus we cannot have
        # it shared for multiple test cases
        self.tun_ip6 = "1002::1"

        self.gre6 = VppGre6Interface(self, self.pg0.local_ip6, self.tun_ip6)
        self.gre6.add_vpp_config()
        self.gre6.admin_up()
        self.gre6.config_ip6()

        self.route6 = VppIpRoute(self,
                                 self.tun_ip6,
                                 128, [
                                     VppRoutePath(self.pg0.remote_ip6,
                                                  self.pg0.sw_if_index,
                                                  proto=DpoProto.DPO_PROTO_IP6)
                                 ],
                                 is_ip6=1)
        self.route6.add_vpp_config()

        self.reset_packet_infos()
        for i in range(test_packet_count):
            info = self.create_packet_info(self.pg0, self.pg0)
            payload = self.info_to_payload(info)
            p = (IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6) /
                 UDP(sport=1234, dport=self.punt_port) / Raw(payload))
            size = self.packet_sizes[(i // 2) % len(self.packet_sizes)]
            self.extend_packet(p, size, self.padding)
            info.data = p

        fragments = [
            x for _, i in self._packet_infos.iteritems()
            for x in fragment_rfc8200(i.data, i.index, 400)
        ]

        encapped_fragments = \
            [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
             IPv6(src=self.tun_ip6, dst=self.pg0.local_ip6) /
                GRE() /
                p
                for p in fragments]

        fragmented_encapped_fragments = \
            [x for p in encapped_fragments for x in (
                fragment_rfc8200(
                    p,
                    2 * len(self._packet_infos) + p[IPv6ExtHdrFragment].id,
                    200)
                if IPv6ExtHdrFragment in p else [p]
            )
            ]

        self.pg0.add_stream(fragmented_encapped_fragments)

        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        self.pg0.assert_nothing_captured()
        packets = self.punt6_socket.wait_for_packets(len(self._packet_infos))
        self.verify_capture(packets, IPv6)

        # TODO remove gre vpp config by hand until VppIpRoute gets fixed
        # so that it's query_vpp_config() works as it should
        self.gre6.remove_vpp_config()
コード例 #16
0
    def checkCapture(self, encap, isv4):
        self.pg0.assert_nothing_captured()
        out = self.pg1.get_capture(len(self.packets))

        load = [0] * len(self.ass)
        self.info = None
        for p in out:
            try:
                asid = 0
                gre = None
                if encap == "gre4":
                    ip = p[IP]
                    asid = int(ip.dst.split(".")[3])
                    self.assertEqual(ip.version, 4)
                    self.assertEqual(ip.flags, 0)
                    self.assertEqual(ip.src, "39.40.41.42")
                    self.assertEqual(ip.dst, "10.0.0.%u" % asid)
                    self.assertEqual(ip.proto, 47)
                    self.assertEqual(len(ip.options), 0)
                    gre = p[GRE]
                    self.checkInner(gre, isv4)
                elif encap == "gre6":
                    ip = p[IPv6]
                    asid = ip.dst.split(":")
                    asid = asid[len(asid) - 1]
                    asid = 0 if asid == "" else int(asid)
                    self.assertEqual(ip.version, 6)
                    self.assertEqual(ip.tc, 0)
                    self.assertEqual(ip.fl, 0)
                    self.assertEqual(ip.src, "2004::1")
                    self.assertEqual(
                        socket.inet_pton(socket.AF_INET6, ip.dst),
                        socket.inet_pton(socket.AF_INET6, "2002::%u" % asid),
                    )
                    self.assertEqual(ip.nh, 47)
                    # self.assertEqual(len(ip.options), 0)
                    gre = GRE(scapy.compat.raw(p[IPv6].payload))
                    self.checkInner(gre, isv4)
                elif encap == "l3dsr":
                    ip = p[IP]
                    asid = int(ip.dst.split(".")[3])
                    self.assertEqual(ip.version, 4)
                    self.assertEqual(ip.flags, 0)
                    self.assertEqual(ip.dst, "10.0.0.%u" % asid)
                    self.assertEqual(ip.tos, 0x1C)
                    self.assertEqual(len(ip.options), 0)
                    self.assert_ip_checksum_valid(p)
                    if ip.proto == IP_PROTOS.tcp:
                        self.assert_tcp_checksum_valid(p)
                    elif ip.proto == IP_PROTOS.udp:
                        self.assert_udp_checksum_valid(p)
                elif encap == "nat4":
                    ip = p[IP]
                    asid = int(ip.dst.split(".")[3])
                    self.assertEqual(ip.version, 4)
                    self.assertEqual(ip.flags, 0)
                    self.assertEqual(ip.dst, "10.0.0.%u" % asid)
                    self.assertEqual(ip.proto, 17)
                    self.assertEqual(len(ip.options), 0)
                    udp = p[UDP]
                    self.assertEqual(udp.dport, 3307)
                elif encap == "nat6":
                    ip = p[IPv6]
                    asid = ip.dst.split(":")
                    asid = asid[len(asid) - 1]
                    asid = 0 if asid == "" else int(asid)
                    self.assertEqual(ip.version, 6)
                    self.assertEqual(ip.tc, 0)
                    self.assertEqual(ip.fl, 0)
                    self.assertEqual(
                        socket.inet_pton(socket.AF_INET6, ip.dst),
                        socket.inet_pton(socket.AF_INET6, "2002::%u" % asid),
                    )
                    self.assertEqual(ip.nh, 17)
                    self.assertGreaterEqual(ip.hlim, 63)
                    udp = UDP(scapy.compat.raw(p[IPv6].payload))
                    self.assertEqual(udp.dport, 3307)
                load[asid] += 1
            except:
                self.logger.error(ppp("Unexpected or invalid packet:", p))
                raise

        # This is just to roughly check that the balancing algorithm
        # is not completely biased.
        for asid in self.ass:
            if load[asid] < int(len(self.packets) / (len(self.ass) * 2)):
                self.logger.error(
                    "ASS is not balanced: load[%d] = %d" % (asid, load[asid])
                )
                raise Exception("Load Balancer algorithm is biased")
コード例 #17
0
    def test_static(self):
        """1:1 NAT66 test"""
        flags = self.config_flags.NAT_IS_INSIDE
        self.vapi.nat66_add_del_interface(is_add=1,
                                          flags=flags,
                                          sw_if_index=self.pg0.sw_if_index)
        self.vapi.nat66_add_del_interface(is_add=1,
                                          sw_if_index=self.pg1.sw_if_index)
        self.vapi.nat66_add_del_static_mapping(
            local_ip_address=self.pg0.remote_ip6,
            external_ip_address=self.nat_addr,
            is_add=1,
        )

        # in2out
        pkts = []
        p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
             IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) / TCP())
        pkts.append(p)
        p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
             IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) / UDP())
        pkts.append(p)
        p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
             IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
             ICMPv6EchoRequest())
        pkts.append(p)
        p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
             IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) / GRE() /
             IP() / TCP())
        pkts.append(p)
        self.pg0.add_stream(pkts)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        capture = self.pg1.get_capture(len(pkts))

        for packet in capture:
            try:
                self.assertEqual(packet[IPv6].src, self.nat_addr)
                self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
                self.assert_packet_checksums_valid(packet)
            except:
                self.logger.error(ppp("Unexpected or invalid packet:", packet))
                raise

        # out2in
        pkts = []
        p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
             IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) / TCP())
        pkts.append(p)
        p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
             IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) / UDP())
        pkts.append(p)
        p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
             IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
             ICMPv6EchoReply())
        pkts.append(p)
        p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
             IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) / GRE() / IP() /
             TCP())
        pkts.append(p)
        self.pg1.add_stream(pkts)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        capture = self.pg0.get_capture(len(pkts))
        for packet in capture:
            try:
                self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
                self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
                self.assert_packet_checksums_valid(packet)
            except:
                self.logger.error(ppp("Unexpected or invalid packet:", packet))
                raise

        sm = self.vapi.nat66_static_mapping_dump()
        self.assertEqual(len(sm), 1)
        self.assertEqual(sm[0].total_pkts, 8)
コード例 #18
0
def main():
    args = TrafficScriptArg([
        'tx_dst_mac', 'tx_src_mac', 'tx_outer_dst_ip', 'tx_outer_src_ip',
        'tx_inner_dst_ip', 'tx_inner_src_ip', 'rx_dst_mac', 'rx_src_mac',
        'rx_outer_dst_ip', 'rx_outer_src_ip'
    ])

    tx_if = args.get_arg('tx_if')
    rx_if = args.get_arg('rx_if')
    tx_dst_mac = args.get_arg('tx_dst_mac')
    tx_src_mac = args.get_arg('tx_src_mac')
    tx_outer_dst_ip = args.get_arg('tx_outer_dst_ip')
    tx_outer_src_ip = args.get_arg('tx_outer_src_ip')
    tx_inner_dst_ip = args.get_arg('tx_inner_dst_ip')
    tx_inner_src_ip = args.get_arg('tx_inner_src_ip')
    rx_dst_mac = args.get_arg('rx_dst_mac')
    rx_src_mac = args.get_arg('rx_src_mac')
    rx_outer_dst_ip = args.get_arg('rx_outer_dst_ip')
    rx_outer_src_ip = args.get_arg('rx_outer_src_ip')
    udp_src = 1234
    udp_dst = 2345
    udp_payload = 'udp_payload'

    rxq = RxQueue(rx_if)
    txq = TxQueue(tx_if)
    sent_packets = []

    tx_pkt_raw = Ether(dst=tx_dst_mac, src=tx_src_mac) / \
        IP(src=tx_outer_src_ip, dst=tx_outer_dst_ip) / \
        GRE() / \
        IP(src=tx_inner_src_ip, dst=tx_inner_dst_ip) / \
        UDP(dport=udp_dst, sport=udp_src) / \
        udp_payload

    sent_packets.append(tx_pkt_raw)
    txq.send(tx_pkt_raw)
    ether = rxq.recv(2, ignore=sent_packets)

    if ether is None:
        raise RuntimeError("ICMP echo Rx timeout")

    # Check RX headers
    if ether.dst != rx_dst_mac:
        raise RuntimeError(
            "Matching of received destination MAC unsuccessful.")
    logger.debug("Comparison of received destination MAC: OK.")

    if ether.src != rx_src_mac:
        raise RuntimeError("Matching of received source MAC unsuccessful.")
    logger.debug("Comparison of received source MAC: OK.")

    if ether['IP'].src != rx_outer_src_ip:
        raise RuntimeError(
            "Matching of received outer source IP unsuccessful.")
    logger.debug("Comparison of received outer source IP: OK.")

    if ether['IP'].dst != rx_outer_dst_ip:
        raise RuntimeError(
            "Matching of received outer destination IP unsuccessful.")
    logger.debug("Comparison of received outer destination IP: OK.")

    if ether['IP'].proto != IP_PROTOS.gre:
        raise RuntimeError("IP protocol is not GRE.")
    logger.debug("Comparison of received GRE protocol: OK.")

    if ether['IP']['GRE']['IP'].src != tx_inner_src_ip:
        raise RuntimeError(
            "Matching of received inner source IP unsuccessful.")
    logger.debug("Comparison of received inner source IP: OK.")

    if ether['IP']['GRE']['IP'].dst != tx_inner_dst_ip:
        raise RuntimeError(
            "Matching of received inner destination IP unsuccessful.")
    logger.debug("Comparison of received inner destination IP: OK.")

    # check udp
    udp = ether['IP']['GRE']['IP']['UDP']
    if udp.dport != udp_dst:
        raise RuntimeError("UDP dport error {} != {}.".format(
            udp.dport, udp_dst))
    print "UDP dport: OK."

    if udp.sport != udp_src:
        raise RuntimeError("UDP sport error {} != {}.".format(
            udp.sport, udp_src))
    print "UDP sport: OK."

    if str(udp.payload) != udp_payload:
        raise RuntimeError("UDP payload check unsuccessful {} != {}.".format(
            udp.payload, udp_payload))
    print "UDP payload: OK."

    sys.exit(0)