예제 #1
0
        def create_vxlan_packet(self,
                                outer_da,
                                outer_sa,
                                outer_dip,
                                outer_sip,
                                vni,
                                inner_da,
                                inner_dip,
                                inner_sa="00:11:22:33:55:66",
                                inner_sip="192.168.0.44",
                                is_inner_vlan=False,
                                vlan_id=1):
            out_ether = scapy.Ether(dst=outer_da, src=outer_sa)
            out_ip = scapy.IP(dst=outer_dip, src=outer_sip)
            out_udp = scapy.UDP(dport=4789,
                                sport=random.randint(
                                    49152, 65535 - NUM_CONTINUOUS_PKT_COUNT))
            vxlan = scapy.VXLAN(vni=vni)

            ether = scapy.Ether(dst=inner_da, src=inner_sa)
            dot1q = scapy.Dot1Q(vlan=vlan_id)
            ip = scapy.IP(dst=inner_dip, src=inner_sip)
            udp = scapy.UDP(dport=22222, sport=11111)

            # minimum packet for untagged
            payload = "\0" * (64 - 4 - len(ether / ip / udp))

            packet_vxlan = out_ether / out_ip / out_udp / vxlan / ether / ip / udp / payload
            if is_inner_vlan:
                packet_inner = ether / dot1q / ip / udp / payload
            else:
                packet_inner = ether / ip / udp / payload
            return packet_vxlan, packet_inner
예제 #2
0
    def generate_expected_packet(self, inner_pkt):
        """
        Generate ip_in_ip packet for verifying.
        """
        inner_pkt = inner_pkt.copy()
        inner_pkt.ttl = inner_pkt.ttl - 1
        pkt = scapy.Ether(dst=self.active_tor_mac, src=self.standby_tor_mac) / \
            scapy.IP(src=self.standby_tor_ip, dst=self.active_tor_ip) / inner_pkt['IP']
        exp_pkt = Mask(pkt)
        exp_pkt.set_do_not_care_scapy(scapy.Ether, 'dst')

        exp_pkt.set_do_not_care_scapy(scapy.IP, "ihl")
        exp_pkt.set_do_not_care_scapy(scapy.IP, "tos")
        exp_pkt.set_do_not_care_scapy(scapy.IP, "len")
        exp_pkt.set_do_not_care_scapy(scapy.IP, "id")
        exp_pkt.set_do_not_care_scapy(scapy.IP, "flags")
        exp_pkt.set_do_not_care_scapy(scapy.IP, "frag")
        exp_pkt.set_do_not_care_scapy(scapy.IP, "ttl")
        exp_pkt.set_do_not_care_scapy(scapy.IP, "proto")
        exp_pkt.set_do_not_care_scapy(scapy.IP, "chksum")

        exp_pkt.set_do_not_care_scapy(scapy.TCP, "sport")
        exp_pkt.set_do_not_care_scapy(scapy.TCP, "seq")
        exp_pkt.set_do_not_care_scapy(scapy.TCP, "ack")
        exp_pkt.set_do_not_care_scapy(scapy.TCP, "reserved")
        exp_pkt.set_do_not_care_scapy(scapy.TCP, "dataofs")
        exp_pkt.set_do_not_care_scapy(scapy.TCP, "window")
        exp_pkt.set_do_not_care_scapy(scapy.TCP, "chksum")
        exp_pkt.set_do_not_care_scapy(scapy.TCP, "urgptr")
        exp_pkt.set_ignore_extra_bytes()

        return exp_pkt
예제 #3
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
예제 #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
예제 #5
0
    def simple_nvgrev6_packet(self,
                              pktlen=300,
                              eth_dst='00:01:02:03:04:05',
                              eth_src='00:06:07:08:09:0a',
                              dl_vlan_enable=False,
                              vlan_vid=0,
                              vlan_pcp=0,
                              dl_vlan_cfi=0,
                              ipv6_src='1::2',
                              ipv6_dst='3::4',
                              ipv6_fl=0,
                              ipv6_tc=0,
                              ipv6_ecn=None,
                              ipv6_dscp=None,
                              ipv6_hlim=64,
                              nvgre_version=0,
                              nvgre_tni=None,
                              nvgre_flowid=0,
                              inner_frame=None):
        '''
        @summary: Helper function to construct an IPv6 NVGRE packet
        '''
        if scapy.NVGRE is None:
            logging.error(
                "A NVGRE packet was requested but NVGRE is not supported by your Scapy. See README for more information"
            )
            return None

        if MINSIZE > pktlen:
            pktlen = MINSIZE

        nvgre_hdr = scapy.NVGRE(vsid=nvgre_tni, flowid=nvgre_flowid)

        if (dl_vlan_enable):
            pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
                scapy.Dot1Q(prio=vlan_pcp, id=dl_vlan_cfi, vlan=vlan_vid)/ \
                scapy.IPv6(src=ipv6_src, dst=ipv6_dst, fl=ipv6_fl, tc=ipv6_tc, hlim=ipv6_hlim, nh=47)/ \
                nvgre_hdr
        else:
            pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
                scapy.IPv6(src=ipv6_src, dst=ipv6_dst, fl=ipv6_fl, tc=ipv6_tc, hlim=ipv6_hlim, nh=47)/ \
                nvgre_hdr

        if inner_frame:
            pkt = pkt / inner_frame
        else:
            pkt = pkt / scapy.IP()
            pkt = pkt / ("D" * (pktlen - len(pkt)))

        return pkt
예제 #6
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
예제 #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
예제 #8
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
예제 #9
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
예제 #10
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)