Esempio n. 1
0
    def create_dhcp_discover_relayed_packet(self):
        my_chaddr = ''.join(
            [chr(int(octet, 16)) for octet in self.client_mac.split(':')])

        # Relay modifies the DHCPDISCOVER message in the following ways:
        #  1.) Increments the hops count in the DHCP header
        #  2.) Updates the gateway IP address in hte BOOTP header (if it is 0.0.0.0)
        #  3.) Replaces the source IP with the IP of the interface which the relay
        #      received the broadcast DHCPDISCOVER message on
        #  4.) Replaces the destination IP with the IP address of the DHCP server
        #      each message is being forwarded to
        # Here, the actual destination MAC should be the MAC of the leaf the relay
        # forwards through and the destination IP should be the IP of the DHCP server
        # the relay is forwarding to. We don't need to confirm these, so we'll
        # just mask them off later
        #
        # TODO: In IP layer, DHCP relay also replaces source IP with IP of interface on
        #       which it received the broadcast DHCPDISCOVER from client. This appears to
        #       be loopback. We could pull from minigraph and check here.
        ether = scapy.Ether(dst=self.BROADCAST_MAC,
                            src=self.uplink_mac,
                            type=0x0800)
        ip = scapy.IP(src=self.DEFAULT_ROUTE_IP,
                      dst=self.BROADCAST_IP,
                      len=328,
                      ttl=64)
        udp = scapy.UDP(sport=self.DHCP_SERVER_PORT,
                        dport=self.DHCP_SERVER_PORT,
                        len=308)
        bootp = scapy.BOOTP(op=1,
                            htype=1,
                            hlen=6,
                            hops=1,
                            xid=0,
                            secs=0,
                            flags=0x8000,
                            ciaddr=self.DEFAULT_ROUTE_IP,
                            yiaddr=self.DEFAULT_ROUTE_IP,
                            siaddr=self.DEFAULT_ROUTE_IP,
                            giaddr=self.relay_iface_ip
                            if not self.dual_tor else self.switch_loopback_ip,
                            chaddr=my_chaddr)
        bootp /= scapy.DHCP(
            options=[('message-type',
                      'discover'), ('relay_agent_Information',
                                    self.option82), ('end')])

        # If our bootp layer is too small, pad it
        pad_bytes = self.DHCP_PKT_BOOTP_MIN_LEN - len(bootp)
        if pad_bytes > 0:
            bootp /= scapy.PADDING('\x00' * pad_bytes)

        pkt = ether / ip / udp / bootp
        return pkt
Esempio n. 2
0
    def runSendReceiveTest(self, pkt2send, src_port, destination_ports):
        """
        @summary Send packet and verify it is received/not received on the expected ports
        """

        testutils.send_packet(self, src_port, pkt2send)
        (index, rcv_pkt,
         received) = self.receivePacketOnPorts(destination_ports)

        self.tests_total += 1

        if not received:
            return False

        scapy_pkt = scapy.Ether(rcv_pkt)

        if scapy.IP not in scapy_pkt:
            return False

        if self.expected_dst_mac and scapy_pkt.dst != self.expected_dst_mac:
            return False

        if scapy_pkt[scapy.IP].src != self.session_src_ip:
            return False

        if scapy_pkt[scapy.IP].dst != self.session_dst_ip:
            return False

        if scapy_pkt[scapy.IP].ttl != self.session_ttl:
            return False

        # TODO: Fanout modifies DSCP. TOS value is olways 0.
        #if (scapy_pkt[scapy.IP].tos >> 2) != self.session_dscp:
        #    return False

        payload = str(scapy_pkt[scapy.GRE].payload)[22:]
        inner_pkt = scapy.Ether(payload)

        return dataplane.match_exp_pkt(pkt2send, inner_pkt)
Esempio n. 3
0
    def greFilter(self, pkt_str):
        '''
        @summaty: Filter GRE packets
        '''
        try:
            pkt = scapy.Ether(pkt_str)

            if scapy.IP not in pkt:
                return False

            return pkt[scapy.IP].proto == self.GRE_PROTOCOL_NUMBER
        except:
            return False
Esempio n. 4
0
    def create_dhcp_ack_relayed_packet(self):
        my_chaddr = ''.join(
            [chr(int(octet, 16)) for octet in self.client_mac.split(':')])

        # Relay modifies the DHCPACK message in the following ways:
        #  1.) Replaces the source MAC with the MAC of the interface it received it on
        #  2.) Replaces the destination MAC with boradcast (ff:ff:ff:ff:ff:ff)
        #  3.) Replaces the source IP with the IP of the interface which the relay
        #      received it on
        #  4.) Replaces the destination IP with broadcast (255.255.255.255)
        #  5.) Replaces the destination port with the DHCP client port (68)
        ether = scapy.Ether(dst=self.BROADCAST_MAC,
                            src=self.relay_iface_mac,
                            type=0x0800)
        ip = scapy.IP(src=self.relay_iface_ip,
                      dst=self.BROADCAST_IP,
                      len=290,
                      ttl=64)
        udp = scapy.UDP(sport=self.DHCP_SERVER_PORT,
                        dport=self.DHCP_CLIENT_PORT,
                        len=262)
        bootp = scapy.BOOTP(op=2,
                            htype=1,
                            hlen=6,
                            hops=0,
                            xid=0,
                            secs=0,
                            flags=0x8000,
                            ciaddr=self.DEFAULT_ROUTE_IP,
                            yiaddr=self.client_ip,
                            siaddr=self.server_ip,
                            giaddr=self.relay_iface_ip
                            if not self.dual_tor else self.switch_loopback_ip,
                            chaddr=my_chaddr)
        bootp /= scapy.DHCP(options=[(
            'message-type',
            'ack'), ('server_id',
                     self.server_ip), (
                         'lease_time',
                         self.LEASE_TIME), ('subnet_mask',
                                            self.client_subnet), ('end')])

        # TODO: Need to add this to the packet creation functions in PTF code first!
        # If our bootp layer is too small, pad it
        #pad_bytes = self.DHCP_PKT_BOOTP_MIN_LEN - len(bootp)
        #if pad_bytes > 0:
        #    bootp /= scapy.PADDING('\x00' * pad_bytes)

        pkt = ether / ip / udp / bootp
        return pkt
Esempio n. 5
0
    def create_dhcp_discover_relayed_packet(self):
        my_chaddr = ''.join([
            chr(int(octet, 16)) for octet in self.client_iface_mac.split(':')
        ])

        # Relay modifies the DHCPDISCOVER message in the following ways:
        #  1.) Increments the hops count in the DHCP header
        #  2.) Updates the gateway IP address in hte BOOTP header (if it is 0.0.0.0)
        #  3.) Replaces the source IP with the IP of the interface which the relay
        #      received the broadcast DHCPDISCOVER message on
        #  4.) Replaces the destination IP with the IP address of the DHCP server
        #      each message is being forwarded to
        # Here, the actual destination MAC should be the MAC of the leaf the relay
        # forwards through and the destination IP should be the IP of the DHCP server
        # the relay is forwarding to. We don't need to confirm these, so we'll
        # just mask them off later
        #
        # TODO: Relay also replaces source IP with IP of interface on which it received the
        #       broadcast DHCPDISCOVER from client. This appears to be loopback.
        #       We could pull from minigraph and check here.
        pkt = scapy.Ether(dst=self.BROADCAST_MAC,
                          src=self.relay_iface_mac,
                          type=0x0800)
        pkt /= scapy.IP(src=self.DEFAULT_ROUTE_IP,
                        dst=self.BROADCAST_IP,
                        len=328,
                        ttl=64)
        pkt /= scapy.UDP(sport=self.DHCP_SERVER_PORT,
                         dport=self.DHCP_SERVER_PORT,
                         len=308)
        pkt /= scapy.BOOTP(op=1,
                           htype=1,
                           hlen=6,
                           hops=1,
                           xid=0,
                           secs=0,
                           flags=0x8000,
                           ciaddr=self.DEFAULT_ROUTE_IP,
                           yiaddr=self.DEFAULT_ROUTE_IP,
                           siaddr=self.DEFAULT_ROUTE_IP,
                           giaddr=self.relay_iface_ip,
                           chaddr=my_chaddr)
        pkt /= scapy.DHCP(options=[(
            'message-type',
            'discover'), ('relay_agent_Information',
                          self.relay_agent_info), ('end')])

        # The isc-dhcp-relay adds 44 bytes of padding to our discover packet
        pkt /= scapy.PADDING('\x00' * 44)
        return pkt
def fc_packet(pause_dur=65535, source_mac='00:11:22:33:44:55'):
    if pause_dur < 0 or pause_dur > 65535:
        return None

    eth_hdr = scapy.Ether(dst='01:80:c2:00:00:01', src=source_mac, type=0x8808)

    opcode = '\x00\x01'
    classtime = binascii.unhexlify(format(pause_dur, '04x'))
    pad = '\x00' * 42

    payload = opcode + classtime + pad
    pkt = eth_hdr / payload

    return pkt
Esempio n. 7
0
    def create_dhcp_request_relayed_packet(self):
        my_chaddr = ''.join(
            [chr(int(octet, 16)) for octet in self.client_mac.split(':')])

        # Here, the actual destination MAC should be the MAC of the leaf the relay
        # forwards through and the destination IP should be the IP of the DHCP server
        # the relay is forwarding to. We don't need to confirm these, so we'll
        # just mask them off later
        #
        # TODO: In IP layer, DHCP relay also replaces source IP with IP of interface on
        #       which it received the broadcast DHCPREQUEST from client. This appears to
        #       be loopback. We could pull from minigraph and check here.
        ether = scapy.Ether(dst=self.BROADCAST_MAC,
                            src=self.uplink_mac,
                            type=0x0800)
        ip = scapy.IP(src=self.DEFAULT_ROUTE_IP,
                      dst=self.BROADCAST_IP,
                      len=336,
                      ttl=64)
        udp = scapy.UDP(sport=self.DHCP_SERVER_PORT,
                        dport=self.DHCP_SERVER_PORT,
                        len=316)
        bootp = scapy.BOOTP(op=1,
                            htype=1,
                            hlen=6,
                            hops=1,
                            xid=0,
                            secs=0,
                            flags=0x8000,
                            ciaddr=self.DEFAULT_ROUTE_IP,
                            yiaddr=self.DEFAULT_ROUTE_IP,
                            siaddr=self.DEFAULT_ROUTE_IP,
                            giaddr=self.relay_iface_ip
                            if not self.dual_tor else self.switch_loopback_ip,
                            chaddr=my_chaddr)
        bootp /= scapy.DHCP(options=[(
            'message-type', 'request'), (
                'requested_addr', self.client_ip), (
                    'server_id',
                    self.server_ip), ('relay_agent_Information',
                                      self.option82), ('end')])

        # If our bootp layer is too small, pad it
        pad_bytes = self.DHCP_PKT_BOOTP_MIN_LEN - len(bootp)
        if pad_bytes > 0:
            bootp /= scapy.PADDING('\x00' * pad_bytes)

        pkt = ether / ip / udp / bootp
        return pkt
Esempio n. 8
0
def simple_eth_packet(pktlen=60,
                      eth_dst="00:01:02:03:04:05",
                      eth_src="00:06:07:08:09:0a",
                      vlan_vid=0,
                      vlan_pcp=0):
    pkt = scapy.Ether(dst=eth_dst, src=eth_src)
    if vlan_vid or vlan_pcp:
        pktlen += 4
        pkt /= scapy.Dot1Q(vlan=vlan_vid, prio=vlan_pcp)
        pkt[scapy.Dot1Q:1].type = DEFAULT_FDB_ETHERNET_TYPE
    else:
        pkt.type = DEFAULT_FDB_ETHERNET_TYPE
    pkt = pkt / ("0" * (pktlen - len(pkt)))

    return pkt
Esempio n. 9
0
    def createDhcpRequestRelayedPacket(self, dutMac):
        """
        Helper function that creates DHCP Request packet destined to DUT

        Args:
            dutMac(str): MAC address of DUT

        Returns:
            packet: DHCP Request packet
        """
        ether = scapy.Ether(dst=dutMac,
                            src=self.DHCP_RELAY["mac"],
                            type=0x0800)
        ip = scapy.IP(src=self.DHCP_RELAY["loopback"],
                      dst=self.DHCP_SERVER["ip"],
                      len=328,
                      ttl=64)
        udp = scapy.UDP(sport=self.DHCP_SERVER["port"],
                        dport=self.DHCP_SERVER["port"],
                        len=308)
        bootp = scapy.BOOTP(op=1,
                            htype=1,
                            hlen=6,
                            hops=1,
                            xid=0,
                            secs=0,
                            flags=0x8000,
                            ciaddr=str(INADDR_ANY),
                            yiaddr=str(INADDR_ANY),
                            siaddr=str(INADDR_ANY),
                            giaddr=self.DHCP_RELAY["ip"],
                            chaddr=''.join([
                                chr(int(octet, 16))
                                for octet in self.DHCP_CLIENT["mac"].split(':')
                            ]))
        bootp /= scapy.DHCP(
            options=[("message-type",
                      "request"), ("requested_addr", self.DHCP_CLIENT["ip"]
                                   ), ("server_id",
                                       self.DHCP_SERVER["ip"]), ("end")])

        pad_bytes = self.DHCP_PKT_BOOTP_MIN_LEN - len(bootp)
        if pad_bytes > 0:
            bootp /= scapy.PADDING("\x00" * pad_bytes)

        pkt = ether / ip / udp / bootp

        return pkt
Esempio n. 10
0
    def gre_filter(self, pkt_str):
        """
        Filters GRE packets.

        Keyword arguments:
        pkt_str -- the packet being filtered in string format
        """

        try:
            pkt = scapy.Ether(pkt_str)

            if scapy.IP not in pkt:
                return False

            return pkt[scapy.IP].proto == self.IP_PROTO_GRE
        except:
            return False
Esempio n. 11
0
    def create_dhcp_request_relayed_packet(self):
        my_chaddr = ''.join([
            chr(int(octet, 16)) for octet in self.client_iface_mac.split(':')
        ])

        # Here, the actual destination MAC should be the MAC of the leaf the relay
        # forwards through and the destination IP should be the IP of the DHCP server
        # the relay is forwarding to. We don't need to confirm these, so we'll
        # just mask them off later
        #
        # TODO: Relay also replaces source IP with IP of interface on which it received the
        #       broadcast DHCPDISCOVER from client. This appears to be loopback.
        #       We could pull from minigraph and check here.
        pkt = scapy.Ether(dst=self.BROADCAST_MAC,
                          src=self.relay_iface_mac,
                          type=0x0800)
        pkt /= scapy.IP(src=self.DEFAULT_ROUTE_IP,
                        dst=self.BROADCAST_IP,
                        len=328,
                        ttl=64)
        pkt /= scapy.UDP(sport=self.DHCP_SERVER_PORT,
                         dport=self.DHCP_SERVER_PORT,
                         len=308)
        pkt /= scapy.BOOTP(op=1,
                           htype=1,
                           hlen=6,
                           hops=1,
                           xid=0,
                           secs=0,
                           flags=0x8000,
                           ciaddr=self.DEFAULT_ROUTE_IP,
                           yiaddr=self.DEFAULT_ROUTE_IP,
                           siaddr=self.DEFAULT_ROUTE_IP,
                           giaddr=self.relay_iface_ip,
                           chaddr=my_chaddr)
        pkt /= scapy.DHCP(options=[(
            'message-type',
            'request'), ('requested_addr',
                         self.client_ip), ('server_id', self.server_ip),
                                   ('relay_agent_Information',
                                    self.relay_agent_info), ('end')])

        # The isc-dhcp-relay adds 32 bytes of padding to our request
        pkt /= scapy.PADDING('\x00' * 32)
        return pkt
Esempio n. 12
0
    def _send_and_check_mirror_packets(self, setup, mirror_session, ptfadapter,
                                       duthost, mirror_packet):
        expected_mirror_packet = self._get_expected_mirror_packet(
            mirror_session, setup, duthost, mirror_packet)

        ptfadapter.dataplane.flush()
        testutils.send(ptfadapter, self._get_src_port(setup), mirror_packet)
        _, received_packet = testutils.verify_packet_any_port(
            ptfadapter,
            expected_mirror_packet,
            ports=[self._get_monitor_port(setup, mirror_session, duthost)])

        logging.info("received: %s", packet.Ether(received_packet).summary())

        inner_packet = self._extract_mirror_payload(received_packet,
                                                    len(mirror_packet))
        logging.info("inner_packet: %s", inner_packet.summary())
        logging.info("expected_packet: %s", mirror_packet.summary())
        pytest_assert(
            Mask(inner_packet).pkt_match(mirror_packet),
            "Mirror payload does not match received packet")
Esempio n. 13
0
    def _extract_mirror_payload(self, encapsulated_packet, payload_size):
        pytest_assert(len(encapsulated_packet) >= self.OUTER_HEADER_SIZE,
                      "Incomplete packet, expected at least {} header bytes".format(self.OUTER_HEADER_SIZE))

        inner_frame = encapsulated_packet[-payload_size:]
        return packet.Ether(inner_frame)
Esempio n. 14
0
    def runTest(self):
        pass_cnt = 0
        tos = self.dscp << 2
        tos_bg = self.dscp_bg << 2
        if self.debug:
            # remove previous debug files
            files = glob.glob("/tmp/pfc_pause_{}*".format(self.dscp))
            for file in files:
                os.remove(file)
            current_time = datetime.datetime.now().strftime(
                "%Y-%m-%d_%H:%M:%S")
            log_file = open(
                "/tmp/pfc_pause_{}_{}".format(self.dscp, current_time), "w")
        """ If DUT needs to learn MAC addresses """
        if not self.dut_has_mac:
            pkt = simple_udp_packet(eth_dst=self.mac_dst,
                                    eth_src=self.mac_src,
                                    ip_src=self.ip_src,
                                    ip_dst=self.ip_dst)

            send_packet(self, self.port_src, pkt, 5)

            pkt = simple_udp_packet(eth_dst=self.mac_src,
                                    eth_src=self.mac_dst,
                                    ip_src=self.ip_dst,
                                    ip_dst=self.ip_src)

            send_packet(self, self.port_dst, pkt, 5)

        for x in range(self.pkt_count):
            sport = random.randint(0, 65535)
            dport = random.randint(0, 65535)

            pkt = simple_udp_packet(eth_dst=self.mac_dst,
                                    eth_src=self.mac_src,
                                    ip_src=self.ip_src,
                                    ip_dst=self.ip_dst,
                                    ip_tos=tos,
                                    udp_sport=sport,
                                    udp_dport=dport,
                                    ip_ttl=64)

            pkt_bg = simple_udp_packet(eth_dst=self.mac_dst,
                                       eth_src=self.mac_src,
                                       ip_src=self.ip_src,
                                       ip_dst=self.ip_dst,
                                       ip_tos=tos_bg,
                                       udp_sport=sport,
                                       udp_dport=dport,
                                       ip_ttl=64)

            exp_pkt = simple_udp_packet(ip_src=self.ip_src,
                                        ip_dst=self.ip_dst,
                                        ip_tos=tos_bg,
                                        udp_sport=sport,
                                        udp_dport=dport,
                                        ip_ttl=63)

            masked_exp_pkt = Mask(exp_pkt)
            masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "src")
            masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "dst")
            masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "ttl")
            masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "chksum")
            masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "tos")

            send_packet(self, self.port_src, pkt, 1)
            send_packet(self, self.port_src, pkt_bg, 1)

            pkts = capture_matched_packets(self, masked_exp_pkt, self.port_dst)

            if self.debug:
                for i, pkt in enumerate(pkts):
                    dump_msg = "Iteration {}:\n Pkt num {}:\n Hex dump: {}\n\n".format(
                        x, i, sc.utils.hexstr(pkt))
                    log_file.write(dump_msg)

            time.sleep(self.pkt_intvl)
            """ If the queue is paused, we should only receive the background packet """
            if self.queue_paused:
                pass_cnt += int(
                    len(pkts) == 1
                    and scapy.Ether(pkts[0])[scapy.IP].tos == tos_bg)

            else:
                pass_cnt += int(len(pkts) == 2)

        if self.debug:
            log_file.close()
        print "Passes: %d / %d" % (pass_cnt, self.pkt_count)
Esempio n. 15
0
    def send_and_verify(self, dst_ip, expected_ports, src_port, triple_encap = False):
        '''
        @summary: This function builds encap packet, send and verify their arrival.
        @dst_ip: the destination ip for the inner IP header
        @expected_ports: list of ports that a packet can arrived from 
        @src_port: the physical port that the packet will be sent from 
        @triple_encap: True to send triple encapsulated packet
        '''
        #setting parameters
        src_mac =  self.dataplane.get_mac(0, 0)
        dst_mac = '00:11:22:33:44:55'
        inner_src_ip = '2.2.2.2'
        router_mac = self.test_params['router_mac']
        dscp_in = random.randint(0, 32)
        tos_in = dscp_in << 2
        dscp_out = random.randint(0, 32)
        tos_out = dscp_out << 2
        if ("pipe" == self.test_params['dscp_mode']):
            exp_tos = tos_in
        elif("uniform" == self.test_params['dscp_mode']):
            exp_tos = tos_out
        else:
            print("ERROR: no dscp is configured")
            exit()

        default_packet_len = 100
        default_packet_add_header_len = 114

        #building the packets  and the expected packets
        if (not triple_encap):
            #for the double encap packet we will use IP header with TCP header without mac    
            inner_pkt = simple_ip_only_packet(ip_dst=dst_ip, ip_src=inner_src_ip, ip_ttl=64, ip_tos=tos_in)
            #after the decap process the retuning packet will be normal tcp packet, The TTL is taked from the inner layer and redused by one
            exp_pkt = simple_tcp_packet(pktlen=default_packet_add_header_len,
                                        eth_dst=dst_mac,
                                        eth_src=router_mac,
                                        ip_dst=dst_ip,
                                        ip_src=inner_src_ip,
                                        ip_tos=exp_tos,
                                        ip_ttl=63)
        else:
            #Building triple encap packet with SCAPY, because there is no PTF function for it, I use the defualt values for the TCP header
            tcp_hdr    = scapy.TCP(sport=1234, dport=80, flags="S", chksum=0)
            inner_pkt2 = scapy.IP(src='4.4.4.4', dst='3.3.3.3', tos=0, ttl=64, id=1, ihl=None) / tcp_hdr
            inner_pkt  = scapy.IP(src=inner_src_ip, dst=dst_ip, tos=tos_in, ttl=64, id=1, ihl=None,proto=4) / inner_pkt2
            inner_pkt  = inner_pkt/("".join([chr(x) for x in xrange(default_packet_len - len(inner_pkt))]))
            #The expected packet is also built by scapy, and the TTL is taked from the inner layer and redused by one
            exp_pkt    = scapy.Ether(dst=dst_mac, src=router_mac)/inner_pkt   
            exp_pkt['IP'].tos = exp_tos #this parameter is taken by the decap rule configuration 
            exp_pkt['IP'].ttl = 63

        pkt = simple_ipv4ip_packet(
                            eth_dst=router_mac,
                            eth_src=src_mac,
                            ip_src='1.1.1.1',
                            ip_dst=self.test_params['lo_ip'],
                            ip_tos=tos_out,
                            ip_ttl=random.randint(2, 63), 
                            inner_frame=inner_pkt)
        
        #send and verify the return packets
        masked_exp_pkt = Mask(exp_pkt)
        masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "dst")
        masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "src")
        send_packet(self, src_port, pkt)
        logging.info(".....Sending packet from port" + str(src_port) + " to " + dst_ip + ", Triple_encap: " + str(triple_encap))
        (matched, received) = verify_packet_any_port(self, masked_exp_pkt, expected_ports)
        assert received
        return (matched, received)
    def send_and_check_mirror_packets(self,
                                      setup,
                                      mirror_session,
                                      ptfadapter,
                                      duthost,
                                      mirror_packet,
                                      src_port=None,
                                      dest_ports=None,
                                      expect_recv=True,
                                      valid_across_namespace=True):
        expected_mirror_packet = self._get_expected_mirror_packet(
            mirror_session, setup, duthost, mirror_packet)

        if not src_port:
            src_port = self._get_random_src_port(setup)

        if not dest_ports:
            dest_ports = [
                self._get_monitor_port(setup, mirror_session, duthost)
            ]

        # In Below logic idea is to send traffic in such a way so that mirror traffic
        # will need to go across namespaces and within namespace. If source and mirror destination
        # namespace are different then traffic mirror will go across namespace via (backend asic)
        # else via same namespace(asic)

        src_port_namespace = self._get_port_namespace(setup, int(src_port))
        dest_ports_namespace = self._get_port_namespace(
            setup, int(dest_ports[0]))

        src_port_set = set()

        # Some of test scenario are not valid across namespaces so test will explicltly pass
        # valid_across_namespace as False (default is True)
        if valid_across_namespace == True or src_port_namespace == dest_ports_namespace:
            src_port_set.add(src_port)

        # To verify same namespace mirroring we will add destination port also to the Source Port Set
        if src_port_namespace != dest_ports_namespace:
            src_port_set.add(dest_ports[0])

        # Loop through Source Port Set and send traffic on each source port of the set
        for src_port in src_port_set:
            ptfadapter.dataplane.flush()
            testutils.send(ptfadapter, src_port, mirror_packet)

            if expect_recv:
                _, received_packet = testutils.verify_packet_any_port(
                    ptfadapter, expected_mirror_packet, ports=dest_ports)
                logging.info("Received packet: %s",
                             packet.Ether(received_packet).summary())

                inner_packet = self._extract_mirror_payload(
                    received_packet, len(mirror_packet))
                logging.info("Received inner packet: %s",
                             inner_packet.summary())

                inner_packet = Mask(inner_packet)

                # For egress mirroring, we expect the DUT to have modified the packet
                # before forwarding it. Specifically:
                #
                # - In L2 the SMAC and DMAC will change.
                # - In L3 the TTL and checksum will change.
                #
                # We know what the TTL and SMAC should be after going through the pipeline,
                # but DMAC and checksum are trickier. For now, update the TTL and SMAC, and
                # mask off the DMAC and IP Checksum to verify the packet contents.
                if self.mirror_type() == "egress":
                    mirror_packet[packet.IP].ttl -= 1
                    mirror_packet[packet.Ether].src = setup["router_mac"]

                    inner_packet.set_do_not_care_scapy(packet.Ether, "dst")
                    inner_packet.set_do_not_care_scapy(packet.IP, "chksum")

                logging.info("Expected inner packet: %s",
                             mirror_packet.summary())
                pytest_assert(inner_packet.pkt_match(mirror_packet),
                              "Mirror payload does not match received packet")
            else:
                testutils.verify_no_packet_any(ptfadapter,
                                               expected_mirror_packet,
                                               dest_ports)
Esempio n. 17
0
    def create_encap_packet(self,
                            dst_ip,
                            outer_pkt='ipv4',
                            triple_encap=False):
        """Creates an IPv4/IPv6 encapsulated packet in @outer_pkt packet
        @param dst_ip: Destination IP for inner packet. Depending @dst_ip IPv4 or IPv6 packet will be created
        @param outer_pkt: Outer packet type to encapsulate inner packet in (ipv4/ipv6)
        @param triple_encap: Whether to build triple encapsulated packet
        @return: built packet and expected packet to match after decapsulation"""

        src_mac = self.dataplane.get_mac(0, 0)
        dst_mac = '00:11:22:33:44:55'
        router_mac = self.test_params['router_mac']
        dscp_in = random.randint(0, 32)
        # TC for IPv6, ToS for IPv4
        tc_in = tos_in = dscp_in << 2
        dscp_out = random.randint(0, 32)
        tc_out = tos_out = dscp_out << 2
        if ("pipe" == self.test_params['dscp_mode']):
            exp_tc = exp_tos = tc_in
        elif ("uniform" == self.test_params['dscp_mode']):
            exp_tc = exp_tos = tc_out
        else:
            print("ERROR: no dscp is configured")
            exit()

        if ipaddress.ip_address(unicode(dst_ip)).version == 6:
            inner_src_ip = self.DEFAULT_INNER_V6_PKT_SRC_IP
            # build inner packet, if triple_encap is True inner_pkt would be double encapsulated
            inner_pkt = self.create_ipv6_inner_pkt_only(
                inner_src_ip, dst_ip, tos_in, triple_encap)

            # build expected packet based on inner packet
            # set the correct L2 fields
            exp_pkt = scapy.Ether(dst=dst_mac, src=router_mac) / inner_pkt

            # set expected TC value
            exp_pkt['IPv6'].tc = exp_tc
            # decrement TTL
            exp_pkt['IPv6'].hlim -= 1
        else:
            inner_src_ip = self.DEFAULT_INNER_V4_PKT_SRC_IP
            # build inner packet, if triple_encap is True inner_pkt would be double encapsulated
            inner_pkt = self.create_ipv4_inner_pkt_only(
                inner_src_ip, dst_ip, tos_in, triple_encap)

            # build expected packet based on inner packet
            # set the correct L2 fields
            exp_pkt = scapy.Ether(dst=dst_mac, src=router_mac) / inner_pkt

            # set expected ToS value
            exp_pkt['IP'].tos = exp_tos
            # decrement TTL
            exp_pkt['IP'].ttl -= 1

        if outer_pkt == 'ipv4':
            pkt = simple_ipv4ip_packet(eth_dst=router_mac,
                                       eth_src=src_mac,
                                       ip_src='1.1.1.1',
                                       ip_dst=self.test_params['lo_ip'],
                                       ip_tos=tos_out,
                                       ip_ttl=random.randint(2, 63),
                                       inner_frame=inner_pkt)
        elif outer_pkt == 'ipv6':
            pkt = simple_ipv6ip_packet(eth_dst=router_mac,
                                       eth_src=src_mac,
                                       ipv6_src='1::1',
                                       ipv6_dst=self.test_params['lo_ipv6'],
                                       ipv6_tc=tc_out,
                                       ipv6_hlim=random.randint(2, 63),
                                       inner_frame=inner_pkt)
        else:
            raise Exception("ERROR: invalid outer packet type ", outer_pkt)

        return pkt, exp_pkt
Esempio n. 18
0
    def runTest(self):
        pass_cnt = 0
        tos = self.dscp << 2
        tos_bg = self.dscp_bg << 2
        """ If DUT needs to learn MAC addresses """
        if not self.dut_has_mac:
            pkt = simple_udp_packet(eth_dst=self.mac_dst,
                                    eth_src=self.mac_src,
                                    ip_src=self.ip_src,
                                    ip_dst=self.ip_dst)

            send_packet(self, self.port_src, pkt, 5)

            pkt = simple_udp_packet(eth_dst=self.mac_src,
                                    eth_src=self.mac_dst,
                                    ip_src=self.ip_dst,
                                    ip_dst=self.ip_src)

            send_packet(self, self.port_dst, pkt, 5)

        for x in range(self.pkt_count):
            sport = random.randint(0, 65535)
            dport = random.randint(0, 65535)

            pkt = simple_udp_packet(eth_dst=self.mac_dst,
                                    eth_src=self.mac_src,
                                    ip_src=self.ip_src,
                                    ip_dst=self.ip_dst,
                                    ip_tos=tos,
                                    udp_sport=sport,
                                    udp_dport=dport,
                                    ip_ttl=64)

            pkt_bg = simple_udp_packet(eth_dst=self.mac_dst,
                                       eth_src=self.mac_src,
                                       ip_src=self.ip_src,
                                       ip_dst=self.ip_dst,
                                       ip_tos=tos_bg,
                                       udp_sport=sport,
                                       udp_dport=dport,
                                       ip_ttl=64)

            exp_pkt = simple_udp_packet(ip_src=self.ip_src,
                                        ip_dst=self.ip_dst,
                                        ip_tos=tos_bg,
                                        udp_sport=sport,
                                        udp_dport=dport,
                                        ip_ttl=63)

            masked_exp_pkt = Mask(exp_pkt)
            masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "src")
            masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "dst")
            masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "ttl")
            masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "chksum")
            masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "tos")

            send_packet(self, self.port_src, pkt, 1)
            send_packet(self, self.port_src, pkt_bg, 1)

            pkts = capture_matched_packets(self, masked_exp_pkt, self.port_dst)

            time.sleep(self.pkt_intvl)
            """ If the queue is paused, we should only receive the background packet """
            if self.queue_paused:
                pass_cnt += int(
                    len(pkts) == 1
                    and scapy.Ether(pkts[0])[scapy.IP].tos == tos_bg)

            else:
                pass_cnt += int(len(pkts) == 2)

        print "Passes: %d / %d" % (pass_cnt, self.pkt_count)
Esempio n. 19
0
    def test_encap(self,
                   ptf_port,
                   vni,
                   ptf_addr,
                   destination,
                   nhs,
                   test_ecn=False,
                   vlan=0):
        rv = True
        try:
            pkt_len = self.DEFAULT_PKT_LEN
            if 'vlan' != 0:
                tagged = True
                pkt_len += 4
            else:
                tagged = False

            options = {'ip_ecn': 0}
            options_v6 = {'ipv6_ecn': 0}
            if test_ecn:
                ecn = random.randint(0, 3)
                options = {'ip_ecn': ecn}
                options_v6 = {'ipv6_ecn': ecn}

            # ECMP support, assume it is a string of comma seperated list of addresses.
            returned_ip_addresses = {}
            check_ecmp = False
            for host_address in nhs:
                check_ecmp = True
                # This will ensure that every nh is used atleast once.
                for i in range(self.packet_count):
                    tcp_sport = get_incremental_value('tcp_sport')
                    valid_combination = True
                    if isinstance(ip_address(destination),
                                  ipaddress.IPv4Address) and isinstance(
                                      ip_address(ptf_addr),
                                      ipaddress.IPv4Address):
                        pkt_opts = {
                            "pktlen": pkt_len,
                            "eth_dst": self.dut_mac,
                            "eth_src": self.ptf_mac_addrs['eth%d' % ptf_port],
                            "ip_dst": destination,
                            "ip_src": ptf_addr,
                            "ip_id": 105,
                            "ip_ttl": 64,
                            "tcp_sport": tcp_sport,
                            "tcp_dport": VARS['tcp_dport']
                        }
                        pkt_opts.update(options)
                        pkt = simple_tcp_packet(**pkt_opts)
                        pkt_opts['ip_ttl'] = 63
                        pkt_opts['eth_src'] = self.dut_mac
                        exp_pkt = simple_tcp_packet(**pkt_opts)
                    elif isinstance(ip_address(destination),
                                    ipaddress.IPv6Address) and isinstance(
                                        ip_address(ptf_addr),
                                        ipaddress.IPv6Address):
                        pkt_opts = {
                            "pktlen": pkt_len,
                            "eth_dst": self.dut_mac,
                            "eth_src": self.ptf_mac_addrs['eth%d' % ptf_port],
                            "ipv6_dst": destination,
                            "ipv6_src": ptf_addr,
                            "ipv6_hlim": 64,
                            "tcp_sport": tcp_sport,
                            "tcp_dport": VARS['tcp_dport']
                        }
                        pkt_opts.update(options_v6)
                        pkt = simple_tcpv6_packet(**pkt_opts)
                        pkt_opts['ipv6_hlim'] = 63
                        pkt_opts['eth_src'] = self.dut_mac
                        exp_pkt = simple_tcpv6_packet(**pkt_opts)
                    else:
                        valid_combination = False
                    udp_sport = 1234  # Use entropy_hash(pkt), it will be ignored in the test later.
                    udp_dport = self.vxlan_port
                    if isinstance(ip_address(host_address),
                                  ipaddress.IPv4Address):
                        encap_pkt = simple_vxlan_packet(
                            eth_src=self.dut_mac,
                            eth_dst=self.random_mac,
                            ip_id=0,
                            ip_src=self.loopback_ipv4,
                            ip_dst=host_address,
                            ip_ttl=128,
                            udp_sport=udp_sport,
                            udp_dport=udp_dport,
                            with_udp_chksum=False,
                            vxlan_vni=vni,
                            inner_frame=exp_pkt,
                            **options)
                        encap_pkt[scapy.IP].flags = 0x2
                    elif isinstance(ip_address(host_address),
                                    ipaddress.IPv6Address):
                        encap_pkt = simple_vxlanv6_packet(
                            eth_src=self.dut_mac,
                            eth_dst=self.random_mac,
                            ipv6_src=self.loopback_ipv6,
                            ipv6_dst=host_address,
                            udp_sport=udp_sport,
                            udp_dport=udp_dport,
                            with_udp_chksum=False,
                            vxlan_vni=vni,
                            inner_frame=exp_pkt,
                            **options_v6)
                    send_packet(self, ptf_port, str(pkt))

                    masked_exp_pkt = Mask(encap_pkt)
                    masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "src")
                    masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "dst")
                    if isinstance(ip_address(host_address),
                                  ipaddress.IPv4Address):
                        masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "ttl")
                        masked_exp_pkt.set_do_not_care_scapy(
                            scapy.IP, "chksum")
                        masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "dst")
                    else:
                        masked_exp_pkt.set_do_not_care_scapy(
                            scapy.IPv6, "hlim")
                        masked_exp_pkt.set_do_not_care_scapy(
                            scapy.IPv6, "chksum")
                        masked_exp_pkt.set_do_not_care_scapy(scapy.IPv6, "dst")
                    masked_exp_pkt.set_do_not_care_scapy(scapy.UDP, "sport")
                    masked_exp_pkt.set_do_not_care_scapy(scapy.UDP, "chksum")

                    logger.info("Sending packet from port " + str(ptf_port) +
                                " to " + destination)

                    if self.expect_encap_success:
                        _, received_pkt = verify_packet_any_port(
                            self, masked_exp_pkt, self.t2_ports)
                        scapy_pkt = scapy.Ether(received_pkt)
                        # Store every destination that was received.
                        if isinstance(ip_address(host_address),
                                      ipaddress.IPv6Address):
                            dest_ip = scapy_pkt['IPv6'].dst
                        else:
                            dest_ip = scapy_pkt['IP'].dst
                        try:
                            returned_ip_addresses[
                                dest_ip] = returned_ip_addresses[dest_ip] + 1
                        except KeyError:
                            returned_ip_addresses[dest_ip] = 1

                    else:
                        check_ecmp = False
                        logger.info("Verifying no packet")
                        verify_no_packet_any(self, masked_exp_pkt,
                                             self.t2_ports)

            # Verify ECMP:
            if check_ecmp:
                self.verify_all_addresses_used_equally(nhs,
                                                       returned_ip_addresses)

            pkt.load = '0' * 60 + str(len(self.packets))
            self.packets.append((ptf_port, str(pkt).encode("base64")))

        finally:
            logger.info("")
Esempio n. 20
0
    def create_encap_packet(self,
                            dst_ip,
                            outer_pkt='ipv4',
                            triple_encap=False,
                            outer_ttl=None,
                            inner_ttl=None):
        """Creates an IPv4/IPv6 encapsulated packet in @outer_pkt packet
        @param dst_ip: Destination IP for inner packet. Depending @dst_ip IPv4 or IPv6 packet will be created
        @param outer_pkt: Outer packet type to encapsulate inner packet in (ipv4/ipv6)
        @param triple_encap: Whether to build triple encapsulated packet
        @outer_ttl: TTL for the outer layer
        @inner_ttl: TTL for the inner layer
        @return: built packet and expected packet to match after decapsulation
        """

        src_mac = self.dataplane.get_mac(0, 0)
        dst_mac = '00:11:22:33:44:55'
        router_mac = self.test_params['router_mac']

        # Set DSCP value for the inner layer
        dscp_in = self.DSCP_RANGE[self.dscp_in_idx]
        self.dscp_in_idx = (self.dscp_in_idx + 1) % len(
            self.DSCP_RANGE)  # Next packet will use a different DSCP

        # TC for IPv6, ToS for IPv4
        tc_in = tos_in = dscp_in << 2

        # Set DSCP value for the outer layer
        dscp_out = self.DSCP_RANGE[self.dscp_out_idx]
        self.dscp_out_idx = (self.dscp_out_idx + 1) % len(
            self.DSCP_RANGE)  # Next packet will use a different DSCP

        # TC for IPv6, ToS for IPv4
        tc_out = tos_out = dscp_out << 2

        if "pipe" == self.test_params['dscp_mode']:
            exp_tc = exp_tos = tc_in
        elif "uniform" == self.test_params['dscp_mode']:
            exp_tc = exp_tos = tc_out
        else:
            print("ERROR: no dscp is configured")
            exit()

        # Set TTL value for the outer layer
        if outer_ttl is None:
            outer_ttl = self.TTL_RANGE[self.ttl_out_idx]
            self.ttl_out_idx = (self.ttl_out_idx + 1) % len(
                self.TTL_RANGE)  # Next packet will use a different TTL

        # Set TTL value for the inner layer
        if inner_ttl is None:
            inner_ttl = self.TTL_RANGE[self.ttl_in_idx]
            self.ttl_in_idx = (self.ttl_in_idx + 1) % len(
                self.TTL_RANGE)  # Next packet will use a different TTL

        if "pipe" == self.test_params['ttl_mode']:
            exp_ttl = inner_ttl - 1
        elif "uniform" == self.test_params["ttl_mode"]:
            exp_ttl = outer_ttl - 1
        else:
            print("ERROR: unexpected ttl_mode is configured")
            exit()

        if ipaddress.ip_address(unicode(dst_ip)).version == 6:
            inner_src_ip = self.DEFAULT_INNER_V6_PKT_SRC_IP
            # build inner packet, if triple_encap is True inner_pkt would be double encapsulated
            inner_pkt = self.create_ipv6_inner_pkt_only(inner_src_ip,
                                                        dst_ip,
                                                        tos_in,
                                                        triple_encap,
                                                        hlim=inner_ttl)

            # build expected packet based on inner packet
            # set the correct L2 fields
            exp_pkt = scapy.Ether(dst=dst_mac, src=router_mac) / inner_pkt

            # set expected TC value
            exp_pkt['IPv6'].tc = exp_tc
            # decrement TTL
            exp_pkt['IPv6'].hlim = exp_ttl
        else:
            inner_src_ip = self.DEFAULT_INNER_V4_PKT_SRC_IP
            # build inner packet, if triple_encap is True inner_pkt would be double encapsulated
            inner_pkt = self.create_ipv4_inner_pkt_only(inner_src_ip,
                                                        dst_ip,
                                                        tos_in,
                                                        triple_encap,
                                                        ttl=inner_ttl)

            # build expected packet based on inner packet
            # set the correct L2 fields
            exp_pkt = scapy.Ether(dst=dst_mac, src=router_mac) / inner_pkt

            # set expected ToS value
            exp_pkt['IP'].tos = exp_tos
            # decrement TTL
            exp_pkt['IP'].ttl = exp_ttl

        if outer_pkt == 'ipv4':
            pkt = simple_ipv4ip_packet(eth_dst=router_mac,
                                       eth_src=src_mac,
                                       ip_src='1.1.1.1',
                                       ip_dst=self.test_params['lo_ip'],
                                       ip_tos=tos_out,
                                       ip_ttl=outer_ttl,
                                       inner_frame=inner_pkt)
        elif outer_pkt == 'ipv6':
            pkt = simple_ipv6ip_packet(eth_dst=router_mac,
                                       eth_src=src_mac,
                                       ipv6_src='1::1',
                                       ipv6_dst=self.test_params['lo_ipv6'],
                                       ipv6_tc=tc_out,
                                       ipv6_hlim=outer_ttl,
                                       inner_frame=inner_pkt)
        else:
            raise Exception("ERROR: invalid outer packet type ", outer_pkt)

        return pkt, exp_pkt
Esempio n. 21
0
def icmp_filter(pkt_str):
    try:
        pkt = scapy.Ether(pkt_str)
        return (scapy.ICMP in pkt)
    except:
        return False