Ejemplo n.º 1
0
    rx_stats = drone.getStats(rx_port)

    if tx_stats.port_stats[0].tx_pkts == rx_stats.port_stats[0].rx_pkts:
        print "traffic test passed"

    elif tx_stats.port_stats[0].tx_pkts == 0:
        raise Exception("Problems with Ostinato")

    else:
        raise Exception("traffic test failed")

    log.info('tx pkts = %d' % (tx_stats.port_stats[0].tx_pkts))
    log.info('rx pkts = %d' % (rx_stats.port_stats[0].rx_pkts))
    #retrieve and dump received packets
    log.info('getting Rx capture buffer')
    buff = drone.getCaptureBuffer(rx_port.port_id[0])
    drone.saveCaptureBuffer(buff, 'capture.pcap')
    os.system('tshark -r capture.pcap')
    os.remove('capture.pcap')

    # delete streams
    log.info('deleting tx_streams')
    drone.deleteStream(stream_id)

    # bye for now
    drone.disconnect()

except Exception as ex:
    log.exception(ex)
    sys.exit(1)
Ejemplo n.º 2
0
class Drone():
    def __init__(self, host_name='127.0.0.1', port_number=7878, tx_port_list=None, rx_port_list=None):
        self.__drone = DroneProxy(host_name, port_number)
        if tx_port_list:
            self.__tx_port_list = tx_port_list.all_ports
        else:
            self.__tx_port_list = None
        if rx_port_list:
            self.__rx_port_list = rx_port_list.all_ports
        else:
            self.__rx_port_list = None

    def connect(self):
        self.__drone.connect()
        self.tx_port_clear_stats()
        self.rx_port_clear_stats()
        return self

    def disconnect(self):
        self.__drone.disconnect()
        return self

    def add_stream_list(self, stream_list):
        self.current_stream_list = stream_list
        self.__drone.addStream(stream_list.all_streams)
        self.__drone.modifyStream(stream_list.all_streams_configurations)
        return self

    def remove_stream_list(self, stream_id_list):
        self.__drone.deleteStream(stream_id_list)
        return self

    def remove_current_stream_list(self):
        assert(self.current_stream_list)
        self.__drone.deleteStream(self.current_stream_list.all_streams)
        return self

    def fetch_stream_id_list(self):
        assert(self.__tx_port_list)
        stream_id_list = self.__drone.getStreamIdList(self.__tx_port_list.port_id[0])
        return stream_id_list

    def fetch_port_id_list(self):
        port_id_list = self.__drone.getPortIdList()
        return port_id_list

    def get_port_config_list(self):
        port_config_list = self.__drone.getPortConfig(self.fetch_port_id_list())
        return port_config_list

    def start_transmit(self):
        assert(self.__tx_port_list)
        self.tx_port_clear_stats()
        self.__drone.startTransmit(self.__tx_port_list)
        return self

    def wait_for_transmission_complete(self, time_out=None):
        time_start = time.time()
        while True:
            time.sleep(1)
            tx_stats = self.fetch_stats_tx_port()
            print('transmit rate %s bps' % (tx_stats.tx_bps * 8))
            if (not tx_stats.state.is_transmit_on)\
            or (time_out and (time.time() - time_start > time_out)):
                break
            else:
                print('waiting for transmit to finish ,elapsed time %s seconds' % (time.time() - time_start))

        print('transmit total time %s seconds' % (time.time() - time_start))
        return self

    def stop_transmit(self):
        assert(self.__tx_port_list)
        self.__drone.stopTransmit(self.__tx_port_list)
        return self

    def __start_capture(self, port_list):
        assert(port_list)
        self.__drone.startCapture(port_list)

    def __stop_capture(self, port_list):
        assert(port_list)
        self.__drone.stopCapture(port_list)

    def __clear_stats(self, port_list):
        # assert(port)
        if port_list:
            self.__drone.clearStats(port_list)

    def __fetch_stats_port(self, port_list):
        assert(port_list)
        stats = self.__drone.getStats(port_list)
        return stats.port_stats[0]

    def __fetch_capture_buffer(self, port_list, buffer_file_name='capture.pcap'):
        assert(port_list)
        buffer = self.__drone.getCaptureBuffer(port_list.port_id[0])
        self.__drone.saveCaptureBuffer(buffer, buffer_file_name)
        # os.system('tshark -r ' + buffer_file_name)
        # os.remove(buffer_file_name)

    def tx_port_start_capture(self):
        self.__start_capture(self.__tx_port_list)
        return self

    def tx_port_stop_capture(self):
        self.__stop_capture(self.__tx_port_list)
        return self

    def tx_port_clear_stats(self):
        self.__clear_stats(self.__tx_port_list)
        return self

    def rx_port_start_capture(self):
        self.__start_capture(self.__rx_port_list)
        return self

    def rx_port_stop_capture(self):
        self.__stop_capture(self.__rx_port_list)
        return self

    def rx_port_clear_stats(self):
        self.__clear_stats(self.__rx_port_list)
        return self

    def fetch_stats_tx_port(self):
        return self.__fetch_stats_port(self.__tx_port_list)

    def fetch_capture_buffer_tx_port(self):
        self.__fetch_capture_buffer(self.__tx_port_list, buffer_file_name='tx_port_capture.pcap')

    def fetch_stats_rx_port(self):
        return self.__fetch_stats_port(self.__rx_port_list)

    def fetch_capture_buffer_rx_port(self):
        self.__fetch_capture_buffer(self.__rx_port_list, buffer_file_name='rx_port_capture.pcap')
Ejemplo n.º 3
0
    rx_stats = drone.getStats(rx_port)

    if tx_stats.port_stats[0].tx_pkts == rx_stats.port_stats[0].rx_pkts:
        print "traffic test passed"

    elif tx_stats.port_stats[0].tx_pkts == 0:
        raise Exception("Problems with Ostinato")

    else:
        raise Exception("traffic test failed")

    log.info('tx pkts = %d' % (tx_stats.port_stats[0].tx_pkts))
    log.info('rx pkts = %d' % (rx_stats.port_stats[0].rx_pkts))
    #retrieve and dump received packets
    log.info('getting Rx capture buffer')
    buff = drone.getCaptureBuffer(rx_port.port_id[0])
    drone.saveCaptureBuffer(buff, 'capture.pcap')
    os.system('tshark -r capture.pcap')
    os.remove('capture.pcap')

    # delete streams
    log.info('deleting tx_streams')
    drone.deleteStream(stream_id)

    # bye for now
    drone.disconnect()

except Exception as ex:
    log.exception(ex)
    sys.exit(1)
Ejemplo n.º 4
0
class Traffic(object):
    """Class for traffic streams"""
    def __init__(self):
        self.drone = DroneProxy('127.0.0.1')
        self.drone.connect()

        self.port_id_list = self.drone.getPortIdList()
        self.port_config_list = self.drone.getPortConfig(self.port_id_list)
        self.tx_port = ost_pb.PortIdList()
        self.rx_port = ost_pb.PortIdList()
        self.interfaces = self._getInterfaces()
        self.addedInterfaces = []
        self.tx_stats = None

    def __del__(self):
        """Cleanup the streams"""
        for interface in self.interfaces:
            self.drone.deleteStream(interface['stream_id_list'])
        self.drone.disconnect()

    def _getInterfaces(self):
        """Create a list of interface dicts which can be used for streams"""
        interfaces = []
        for port in self.port_config_list.port:
            stream_id_list = ost_pb.StreamIdList()
            stream_id_list.stream_id.add().id = 1
            stream_id_list.stream_id.add().id = 2
            stream_id_list.stream_id.add().id = 3
            stream_id_list.stream_id.add().id = 4
            stream_id_list.stream_id.add().id = 5
            stream_id_list.port_id.id = port.port_id.id
            self.drone.addStream(stream_id_list)
            stream_cfg = ost_pb.StreamConfigList()
            stream_cfg.port_id.id = port.port_id.id

            interface = {
                'name': port.name,
                'port_id': port.port_id,
                'port_id_id': port.port_id.id,
                'stream_id_list': stream_id_list,
                'stream_cfg': stream_cfg,
                'stream_id': 1,
            }
            interfaces.append(interface)
        return interfaces

    def _cleanupRun(self):
        """Delete all current streams, so that we can create new
           once for the next run"""
        for interface in self.interfaces:
            stream_id_list = interface['stream_id_list']
            port_id = interface['port_id_id']
            self.drone.deleteStream(stream_id_list)
            self.drone.addStream(stream_id_list)
            stream_cfg = ost_pb.StreamConfigList()
            stream_cfg.port_id.id = port_id
            interface['stream_cfg'] = stream_cfg
            interface['stream_id'] = 1

    def _getInterfaceByName(self, interface_name):
        """Return the interface dict for a given interface name"""
        for interface in self.interfaces:
            if interface['name'] == interface_name:
                return interface
        raise NameError('getInterface called for unknown interface name')

    def _getInterfaceByPortId(self, port_id):
        """Return the interface dict for a given interface name"""
        for interface in self.interfaces:
            if interface['port_id_id'] == port_id:
                return interface
        raise NameError('getInterface called for unknown interface name')

    def _getInterfaceId(self, interface_name):
        """Return the Ostinato ID for an interface name"""
        for interface in self.interfaces:
            if interface['name'] == interface_name:
                return interface['port_id_id']
        raise NameError('getInterfaceId called for unknown interface {0}'.
                        format(interface_name))

    def getInterfaceNames(self):
        """Return a list of interface names which can be used for streams"""
        return [interface['name'] for interface in self.interfaces]

    def addInterface(self, interface_name):
        """Add an interface to the configuration. It will then be used for
           transmit and receive"""
        dbg_print('addInterface({0})'.format(interface_name))
        self.addedInterfaces.append(interface_name)
        port_id = self._getInterfaceId(interface_name)
        self.rx_port.port_id.add().id = port_id
        self.tx_port.port_id.add().id = port_id

    def _getInterfaceMacAddress(self, interface):
        """Return the MAC address of an interface"""
        return 0x001020304000 + interface['port_id_id']

    def _getInterfaceIPAddress(self, interface):
        """Return the IP address of an interface"""
        return 0xc0a83a0a + interface['port_id_id']

    def _addEthernetHeader(self, stream, src_mac, dst_mac):
        """Add an Ethernet header to a stream"""
        proto = stream.protocol.add()
        proto.protocol_id.id = ost_pb.Protocol.kMacFieldNumber
        proto.Extensions[mac].src_mac = src_mac
        proto.Extensions[mac].dst_mac = dst_mac

    def _addEthertypeIP(self, stream):
        """Add an Ethernet Type header for IP to a stream"""
        proto = stream.protocol.add()
        proto.protocol_id.id = ost_pb.Protocol.kEth2FieldNumber
        proto.Extensions[eth2].type = 0x0800
        proto.Extensions[eth2].is_override_type = True

    def _addIPHeader(self, stream, src_ip, dst_ip):
        """Add an IP header to a stream"""
        proto = stream.protocol.add()
        proto.protocol_id.id = ost_pb.Protocol.kIp4FieldNumber
        proto.Extensions[ip4].src_ip = src_ip
        proto.Extensions[ip4].dst_ip = dst_ip

    def _addUdpHeader(self, stream, src_port, dst_port):
        """Add a UDP header to a stream"""
        proto = stream.protocol.add()
        proto.protocol_id.id = ost_pb.Protocol.kUdpFieldNumber
        proto.Extensions[udp].is_override_src_port = True
        proto.Extensions[udp].is_override_dst_port = True
        proto.Extensions[udp].src_port = src_port
        proto.Extensions[udp].dst_port = dst_port

    def _addIGMPHeader(self, stream, igmp_type, group):
        """Add an IGMP header to a stream"""
        proto = stream.protocol.add()
        proto.protocol_id.id = ost_pb.Protocol.kIgmpFieldNumber
        proto.Extensions[igmp].type = igmp_type
        proto.Extensions[igmp].group_address.v4 = group

    def _addIGMPRequestHeader(self, stream, group):
        """Add an IGMP Request header to a stream"""
        self._addIGMPHeader(stream, IGMPv2_REQUEST, group)

    def _addStream(self, stream_cfg, interface, num_packets, packets_per_sec):
        """Add a stream to an interface, and return it"""
        stream = stream_cfg.stream.add()
        stream.stream_id.id = interface['stream_id']
        interface['stream_id'] = interface['stream_id'] + 1
        stream.core.is_enabled = True
        stream.core.frame_len = 128
        stream.control.num_packets = num_packets
        stream.control.packets_per_sec = packets_per_sec
        return stream

    def _addUDPPacketStream(self, stream, src_mac, dst_mac, src_ip, dst_ip):
        """Add a UDP packets to a stream"""
        self._addEthernetHeader(stream, src_mac=src_mac,
                                dst_mac=dst_mac)
        self._addEthertypeIP(stream)
        self._addIPHeader(stream, src_ip=src_ip, dst_ip=dst_ip)
        self._addUdpHeader(stream, 0x1234, 0x4321)

        proto = stream.protocol.add()
        proto.protocol_id.id = ost_pb.Protocol.kPayloadFieldNumber

    def addUDPStream(self, src_interface_name, dst_interface_name,
                     num_packets, packets_per_sec):
        """Add a UDP stream from the source interface to the destination
           interface"""
        dbg_print('addUDPStream({0} {1} {2} {3})'.format(src_interface_name,
                                                         dst_interface_name,
                                                         num_packets,
                                                         packets_per_sec))
        src_interface = self._getInterfaceByName(src_interface_name)
        dst_interface = self._getInterfaceByName(dst_interface_name)
        stream_cfg = src_interface['stream_cfg']
        stream = self._addStream(stream_cfg, src_interface, num_packets,
                                 packets_per_sec)
        src_mac = self._getInterfaceMacAddress(src_interface)
        dst_mac = self._getInterfaceMacAddress(dst_interface)
        src_ip = self._getInterfaceIPAddress(src_interface)
        dst_ip = self._getInterfaceIPAddress(dst_interface)

        self._addUDPPacketStream(stream, src_mac, dst_mac, src_ip, dst_ip)
        self.drone.modifyStream(stream_cfg)

    def addUDPBroadcastStream(self, src_interface_name, num_packets,
                              packets_per_sec):
        """Add a UDP broadcast stream from the source interface to the
           broadcast address"""
        dbg_print('addUDPBroadcastStream({0} {1} {2})'.
                  format(src_interface_name,
                         num_packets,
                         packets_per_sec))
        src_interface = self._getInterfaceByName(src_interface_name)
        stream_cfg = src_interface['stream_cfg']
        stream = self._addStream(stream_cfg, src_interface, num_packets,
                                 packets_per_sec)
        src_mac = self._getInterfaceMacAddress(src_interface)
        dst_mac = 0xffffffffffff
        src_ip = self._getInterfaceIPAddress(src_interface)
        dst_ip = 0xc0a82aff

        self._addUDPPacketStream(stream, src_mac, dst_mac, src_ip, dst_ip)
        self.drone.modifyStream(stream_cfg)

    def addUDPMulticastStream(self, src_interface_name, group_str, num_packets,
                              packets_per_sec):
        """Add a UDP multicast stream from the source interface to the
           group address"""
        dbg_print('addUDPMulticastStream({0} {1} {2} {3})'.
                  format(src_interface_name,
                         group_str,
                         num_packets,
                         packets_per_sec))
        src_interface = self._getInterfaceByName(src_interface_name)
        stream_cfg = src_interface['stream_cfg']
        stream = self._addStream(stream_cfg, src_interface, num_packets,
                                 packets_per_sec)
        src_mac = self._getInterfaceMacAddress(src_interface)
        group = ipaddress.ip_address(group_str.decode())
        dst_mac = 0x01005e000000 + (int(group) & 0x07fffff)
        src_ip = self._getInterfaceIPAddress(src_interface)
        dst_ip = int(group)

        self._addUDPPacketStream(stream, src_mac, dst_mac, src_ip, dst_ip)
        self.drone.modifyStream(stream_cfg)

    def addIGMPRequestStream(self, src_interface_name, group, num_packets,
                             packets_per_sec):
        """Add a IGMP request stream from the source interface to the
           group address"""
        dbg_print('addIGMPStream({0} {1} {2})'.
                  format(src_interface_name, group, num_packets))
        src_interface = self._getInterfaceByName(src_interface_name)
        stream_cfg = src_interface['stream_cfg']
        stream = self._addStream(stream_cfg, src_interface, num_packets,
                                 packets_per_sec)
        src_mac = self._getInterfaceMacAddress(src_interface)
        dst_mac = 0x01005e00001
        src_ip = self._getInterfaceIPAddress(src_interface)
        dst_ip = group

        self._addEthernetHeader(stream, src_mac=src_mac,
                                dst_mac=dst_mac)
        self._addEthertypeIP(stream)
        self._addIPHeader(stream, src_ip=src_ip, dst_ip=dst_ip)
        self._addIGMPRequestHeader(stream, group)

        self.drone.modifyStream(stream_cfg)

    def learningStream(self, interface_name):
        """Create a stream on the interface for bridge learning. Two broadcast
           packets will be sent, so allowing the switch to learn the source
           MAC address on the interface."""
        dbg_print('learningStream({0})'.format(interface_name))
        self.addUDPBroadcastStream(interface_name, 2, 1)

    def learning(self):
        """Perform learning on each port, by sending a couple of packet,
           so that the bridge learns the address on the interface"""
        dbg_print('learning')
        for interface_name in self.addedInterfaces:
            self.learningStream(interface_name)
        frame = inspect.stack()[1][0]
        method = inspect.stack()[1][3]
        test = get_class_from_frame(frame).__name__
        self._run(test, method)

    def _saveCapture(self, testname, methodname, interface_name):
        """Save the capture file for one interface"""
        filename = "{0}-{1}-{2}.pcap".format(testname, methodname,
                                             interface_name)
        interface = self._getInterfaceByName(interface_name)
        buff = self.drone.getCaptureBuffer(interface['port_id'])
        self.drone.saveCaptureBuffer(buff, filename)

    def _saveCaptures(self, testname, methodname):
        """Save the capture files, using the test name as a prefix"""
        for interface_name in self.addedInterfaces:
            self._saveCapture(testname, methodname, interface_name)

    def _run(self, test, method):
        """Do the real work"""
        self.drone.clearStats(self.tx_port)
        self.drone.clearStats(self.rx_port)
        self.drone.startCapture(self.rx_port)
        self.drone.startTransmit(self.tx_port)

        done = False
        while not done:
            done = True
            tx_stats = self.drone.getStats(self.tx_port)
            for port_stats in tx_stats.port_stats:
                if port_stats.state.is_transmit_on:
                    done = False
            time.sleep(1)

        self.drone.stopTransmit(self.tx_port)
        self.drone.stopCapture(self.rx_port)
        self.tx_stats = self.drone.getStats(self.tx_port)
        self._saveCaptures(test, method)
        self._cleanupRun()

    def run(self):
        """Run the streams"""
        dbg_print('run')
        frame = inspect.stack()[1][0]
        method = inspect.stack()[1][3]
        test = get_class_from_frame(frame).__name__
        self._run(test, method)

    def getStats(self, interface_name):
        """Return the interface statistics"""
        dbg_print('getStats({0})'.format(interface_name))
        port_id = self._getInterfaceId(interface_name)
        for port_stats in self.tx_stats.port_stats:
            if port_stats.port_id.id == port_id:
                stats = {
                    'rx_pkts': port_stats.rx_pkts,
                    'rx_pps': port_stats.rx_pps,
                    'rx_bps': port_stats.rx_bps,
                    'tx_pkts': port_stats.tx_pkts,
                    'tx_pps': port_stats.tx_pps,
                    'tx_bps': port_stats.tx_bps,
                    'rx_drops': port_stats.rx_drops,
                    'rx_errors': port_stats.rx_errors,
                    'rx_fifo_errors': port_stats.rx_fifo_errors,
                    'rx_frame_errors': port_stats.rx_frame_errors,
                }
                return stats
Ejemplo n.º 5
0
def main():
    # initialize defaults
    use_defaults = False
    host_name = '127.0.0.1' # default drone host name
    tx_port_number = 0
    src_mac = 0x000c292eba20 # pkt src mac, modify it 
    dst_mac = 0x18b169091010 # pkt dst mac, modify it
    src_ip = ipstr2long('192.168.168.2') # pkt scr ip, modify it
    dst_ip = ipstr2long('192.168.166.2') # pkt dst ip, modify it
    
    # compute total num of streams
    total_streams = sum([x[1] for x in ICMP_TYPE_CODE])
    print 'Total number of streams: %d' %total_streams
    
    # setup logging
    log = logging.getLogger(__name__)
    logging.basicConfig(level=logging.INFO)

    # command-line option/arg processing
    if len(sys.argv) > 1:
        if sys.argv[1] in ('-d', '--use-defaults'):
            use_defaults = True
        if sys.argv[1] in ('-h', '--help'):
            print('%s [OPTION]...' % (sys.argv[0]))
            print('Options:')
            print(' -d --use-defaults   run using default values')
            print(' -h --help           show this help')
            sys.exit(0)

    if not use_defaults:
        s = raw_input('Drone\'s Hostname/IP [%s]: ' % (host_name))
        host_name = s or host_name

    drone = DroneProxy(host_name)
    drone.TransmitMode = 'sequential'

    try:
        # connect to drone
        log.info('connecting to drone(%s:%d)' 
                % (drone.hostName(), drone.portNumber()))
        drone.connect()

        # retreive port id list
        log.info('retreiving port list')
        port_id_list = drone.getPortIdList()

        # retreive port config list
        log.info('retreiving port config for all ports')
        port_config_list = drone.getPortConfig(port_id_list)

        if len(port_config_list.port) == 0:
            log.warning('drone has no ports!')
            sys.exit(1)

        print('Port List')
        print('---------')
        print (port_config_list)
        for port in port_config_list.port:
            print('%d.%s (%s)' % (port.port_id.id, port.name, port.description))
            # use a loopback port as default tx/rx port 
            if ('lo' in port.name or 'loopback' in port.description.lower()):
                tx_port_number = port.port_id.id

        if not use_defaults:
            p = raw_input('Tx Port Id [%d]: ' % (tx_port_number))
            if p:
                tx_port_number = int(p)

        tx_port = ost_pb.PortIdList()
        tx_port.port_id.add().id = tx_port_number;

        sid = 1
        for icmp_stream in ICMP_TYPE_CODE:
            stype = icmp_stream[0]
            for scode in range(icmp_stream[1]):
                # add a stream
                print 'icmp (type, code) = (%d, %d)' %(stype, scode)
                stream_id = ost_pb.StreamIdList()
                stream_id.port_id.CopyFrom(tx_port.port_id[0])
                stream_id.stream_id.add().id = sid
                log.info('adding tx_stream %d' % stream_id.stream_id[0].id)
                drone.addStream(stream_id)

                # configure the stream
                stream_cfg = ost_pb.StreamConfigList()
                stream_cfg.port_id.CopyFrom(tx_port.port_id[0])
                s = stream_cfg.stream.add()
                s.stream_id.id = stream_id.stream_id[0].id
                s.core.is_enabled = True
                s.control.num_packets = 1

                # setup stream protocols as mac:eth2:ip4:icmp
                # setup mac header
                p = s.protocol.add()
                p.protocol_id.id = ost_pb.Protocol.kMacFieldNumber
                p.Extensions[mac].dst_mac = dst_mac
                p.Extensions[mac].src_mac = src_mac

                p = s.protocol.add()
                p.protocol_id.id = ost_pb.Protocol.kEth2FieldNumber

                #setup ip header
                p = s.protocol.add()
                p.protocol_id.id = ost_pb.Protocol.kIp4FieldNumber
                ip = p.Extensions[ip4]
                ip.src_ip = src_ip 
                ip.dst_ip = dst_ip 
                ip.dst_ip_mode = Ip4.e_im_fixed

                # setup icmp header
                p = s.protocol.add()
                p.protocol_id.id = ost_pb.Protocol.kIcmpFieldNumber
                icmp_va = p.Extensions[icmp] 
                icmp_va.icmp_version = Icmp.kIcmp4  # icmp version
                icmp_va.type = stype                # icmp type
                icmp_va.code = scode                # icmp code
                
                s.protocol.add().protocol_id.id = ost_pb.Protocol.kPayloadFieldNumber
            
                s.control.unit = ost_pb.StreamControl.e_su_packets # Send: Packets
		s.control.mode = ost_pb.StreamControl.e_sm_fixed # Mode: Fixed

                if sid < total_streams:
                    s.control.next = ost_pb.StreamControl.e_nw_goto_next
                else:
                    s.control.next = ost_pb.StreamControl.e_nw_goto_id # e_nw_stop

                s.core.ordinal = sid - 1 # keep stream transmitted in order
                sid += 1
                s.control.packets_per_sec = 20 # transmit rate: pkts per second
               
                log.info('configuring tx_stream %d' % stream_id.stream_id[0].id)
                drone.modifyStream(stream_cfg)

        log.info('clearing tx stats')
        drone.clearStats(tx_port)

        # start transmit
        log.info('starting transmit')
        drone.startTransmit(tx_port)

        # wait for transmit to finish
        log.info('waiting for transmit to finish ...')
        while True:
            try:
                time.sleep(5)
                tx_stats = drone.getStats(tx_port)
                if tx_stats.port_stats[0].state.is_transmit_on == False:
                    break
            except KeyboardInterrupt:
                log.info('Transmit terminated by user!!!')
                break

        # stop transmit and capture
        log.info('stopping transmit')
        drone.stopTransmit(tx_port)

        # get tx/rx stats
        log.info('retreiving stats')
        tx_stats = drone.getStats(tx_port)

        log.info('tx pkts = %d' % (tx_stats.port_stats[0].tx_pkts))

        # retrieve and dump received packets
        #log.info('getting Rx capture buffer')
        #drone.saveCaptureBuffer(buff, 'capture.pcap')
        #log.info('dumping Rx capture buffer')
        #os.system('tshark -r capture.pcap')
        #os.remove('capture.pcap')

        # delete streams
        log.info('deleting tx_stream %d' % stream_id.stream_id[0].id)
        drone.deleteStream(stream_id)
        # desconnect drone
        drone.disconnect()

    except Exception as ex:
        log.exception(ex)
        sys.exit(1)
Ejemplo n.º 6
0
def main():
    # initialize defaults
    use_defaults = False
    host_name = '127.0.0.1'  # default drone host name
    tx_port_number = 0
    src_mac = 0x000c292eba20  # pkt src mac, modify it
    dst_mac = 0x18b169091010  # pkt dst mac, modify it
    src_ip = ipstr2long('192.168.168.2')  # pkt scr ip, modify it
    dst_ip = ipstr2long('192.168.166.2')  # pkt dst ip, modify it

    # compute total num of streams
    total_streams = sum([x[1] for x in ICMP_TYPE_CODE])
    print 'Total number of streams: %d' % total_streams

    # setup logging
    log = logging.getLogger(__name__)
    logging.basicConfig(level=logging.INFO)

    # command-line option/arg processing
    if len(sys.argv) > 1:
        if sys.argv[1] in ('-d', '--use-defaults'):
            use_defaults = True
        if sys.argv[1] in ('-h', '--help'):
            print('%s [OPTION]...' % (sys.argv[0]))
            print('Options:')
            print(' -d --use-defaults   run using default values')
            print(' -h --help           show this help')
            sys.exit(0)

    if not use_defaults:
        s = raw_input('Drone\'s Hostname/IP [%s]: ' % (host_name))
        host_name = s or host_name

    drone = DroneProxy(host_name)
    drone.TransmitMode = 'sequential'

    try:
        # connect to drone
        log.info('connecting to drone(%s:%d)' %
                 (drone.hostName(), drone.portNumber()))
        drone.connect()

        # retreive port id list
        log.info('retreiving port list')
        port_id_list = drone.getPortIdList()

        # retreive port config list
        log.info('retreiving port config for all ports')
        port_config_list = drone.getPortConfig(port_id_list)

        if len(port_config_list.port) == 0:
            log.warning('drone has no ports!')
            sys.exit(1)

        print('Port List')
        print('---------')
        print(port_config_list)
        for port in port_config_list.port:
            print('%d.%s (%s)' %
                  (port.port_id.id, port.name, port.description))
            # use a loopback port as default tx/rx port
            if ('lo' in port.name or 'loopback' in port.description.lower()):
                tx_port_number = port.port_id.id

        if not use_defaults:
            p = raw_input('Tx Port Id [%d]: ' % (tx_port_number))
            if p:
                tx_port_number = int(p)

        tx_port = ost_pb.PortIdList()
        tx_port.port_id.add().id = tx_port_number

        sid = 1
        for icmp_stream in ICMP_TYPE_CODE:
            stype = icmp_stream[0]
            for scode in range(icmp_stream[1]):
                # add a stream
                print 'icmp (type, code) = (%d, %d)' % (stype, scode)
                stream_id = ost_pb.StreamIdList()
                stream_id.port_id.CopyFrom(tx_port.port_id[0])
                stream_id.stream_id.add().id = sid
                log.info('adding tx_stream %d' % stream_id.stream_id[0].id)
                drone.addStream(stream_id)

                # configure the stream
                stream_cfg = ost_pb.StreamConfigList()
                stream_cfg.port_id.CopyFrom(tx_port.port_id[0])
                s = stream_cfg.stream.add()
                s.stream_id.id = stream_id.stream_id[0].id
                s.core.is_enabled = True
                s.control.num_packets = 1

                # setup stream protocols as mac:eth2:ip4:icmp
                # setup mac header
                p = s.protocol.add()
                p.protocol_id.id = ost_pb.Protocol.kMacFieldNumber
                p.Extensions[mac].dst_mac = dst_mac
                p.Extensions[mac].src_mac = src_mac

                p = s.protocol.add()
                p.protocol_id.id = ost_pb.Protocol.kEth2FieldNumber

                #setup ip header
                p = s.protocol.add()
                p.protocol_id.id = ost_pb.Protocol.kIp4FieldNumber
                ip = p.Extensions[ip4]
                ip.src_ip = src_ip
                ip.dst_ip = dst_ip
                ip.dst_ip_mode = Ip4.e_im_fixed

                # setup icmp header
                p = s.protocol.add()
                p.protocol_id.id = ost_pb.Protocol.kIcmpFieldNumber
                icmp_va = p.Extensions[icmp]
                icmp_va.icmp_version = Icmp.kIcmp4  # icmp version
                icmp_va.type = stype  # icmp type
                icmp_va.code = scode  # icmp code

                s.protocol.add(
                ).protocol_id.id = ost_pb.Protocol.kPayloadFieldNumber

                s.control.unit = ost_pb.StreamControl.e_su_packets  # Send: Packets
                s.control.mode = ost_pb.StreamControl.e_sm_fixed  # Mode: Fixed

                if sid < total_streams:
                    s.control.next = ost_pb.StreamControl.e_nw_goto_next
                else:
                    s.control.next = ost_pb.StreamControl.e_nw_goto_id  # e_nw_stop

                s.core.ordinal = sid - 1  # keep stream transmitted in order
                sid += 1
                s.control.packets_per_sec = 20  # transmit rate: pkts per second

                log.info('configuring tx_stream %d' %
                         stream_id.stream_id[0].id)
                drone.modifyStream(stream_cfg)

        log.info('clearing tx stats')
        drone.clearStats(tx_port)

        # start transmit
        log.info('starting transmit')
        drone.startTransmit(tx_port)

        # wait for transmit to finish
        log.info('waiting for transmit to finish ...')
        while True:
            try:
                time.sleep(5)
                tx_stats = drone.getStats(tx_port)
                if tx_stats.port_stats[0].state.is_transmit_on == False:
                    break
            except KeyboardInterrupt:
                log.info('Transmit terminated by user!!!')
                break

        # stop transmit and capture
        log.info('stopping transmit')
        drone.stopTransmit(tx_port)

        # get tx/rx stats
        log.info('retreiving stats')
        tx_stats = drone.getStats(tx_port)

        log.info('tx pkts = %d' % (tx_stats.port_stats[0].tx_pkts))

        # retrieve and dump received packets
        #log.info('getting Rx capture buffer')
        #drone.saveCaptureBuffer(buff, 'capture.pcap')
        #log.info('dumping Rx capture buffer')
        #os.system('tshark -r capture.pcap')
        #os.remove('capture.pcap')

        # delete streams
        log.info('deleting tx_stream %d' % stream_id.stream_id[0].id)
        drone.deleteStream(stream_id)
        # desconnect drone
        drone.disconnect()

    except Exception as ex:
        log.exception(ex)
        sys.exit(1)
Ejemplo n.º 7
0
class Drone(object):
    """Wrapper for ``ostinato.core.DroneProxy``.

    All the protocol buffer related methods are prefixed with ``_o_`` and are
    for internal use only.

    Args:

        host (str): ip address or hostname of the host running the drone
            instance you want to connect to.
        connect (bool): if True, attempt to connect to the remote instance when
            the object is initialized. Otherwise, it can be done manually later
            with :meth:`connect()`
    """

    def __init__(self, host, connect=True):
        self._drone = DroneProxy(host)
        if connect is True:
            self.connect()
        self.ports = []

    def connect(self):
        """
        Connect to the remote drone instance. By default, it is already called
        when the object is created.
        """
        self._drone.connect()

    def disconnect(self):
        """
        Disconnect from the remote drone instance.
        """
        self._drone.disconnect()

    def reconnect(self):
        """
        Reconnect to the remote drone instance.
        """
        self._drone.disconnect()
        self._drone.connect()

    def fetch_ports(self):
        """
        Get the list of all the ports on the remote host. They are stored in
        the :attr:`ports` dictionnary.
        """
        o_ports = self._drone.getPortConfig(self._drone.getPortIdList())
        for o_port in o_ports.port:
            port_id = o_port.port_id.id
            port = self.get_port_by_id(port_id)
            if port is None:
                self.ports.append(Port(self, port_id))
            else:
                port.fetch()

    def get_port_by_id(self, port_id):
        for port in self.ports:
            if port.port_id == port_id:
                return port

    def get_port(self, name):
        """
        Get ports from :attr:`ports` by name. If the port is not found,
        ``None`` is returned.
        """
        for port in self.ports:
            if port.name == name:
                return port

    def __str__(self):
        return 'drone({})'.format(self._drone.host)