def cleanup(self): instance = ByteBlower.InstanceGet() self.wireless_endpoint.Lock(False) if self.meetingpoint is not None: instance.MeetingPointRemove(self.meetingpoint)
def __setup_byteblower_port(self): instance = ByteBlower.InstanceGet() assert isinstance(instance, ByteBlower) # Connect to the server self.server = instance.ServerAdd(self.server_address) # create and configure the port. self.port = self.server.PortCreate(self.server_interface) # configure the MAC address on the port port_layer2_config = self.port.Layer2EthIISet() port_layer2_config.MacSet(self.port_mac_address) # configure the IP addressing on the port port_layer3_config = self.port.Layer3IPv4Set() if type(self.port_ip_address ) is str and self.port_ip_address == 'dhcp': # DHCP is configured on the DHCP protocol dhcp_protocol = port_layer3_config.ProtocolDhcpGet() dhcp_protocol.Perform() else: # Static addressing port_layer3_config.IpSet(self.port_ip_address[0]) port_layer3_config.NetmaskSet(self.port_ip_address[1]) port_layer3_config.GatewaySet(self.port_ip_address[2]) print("Created port", self.port.DescriptionGet())
def cleanup(self): instance = ByteBlower.InstanceGet() # Cleanup if self.meetingpoint is not None: instance.MeetingPointRemove(self.meetingpoint) if self.server is not None: instance.ServerRemove(self.server)
def run(self): instance = ByteBlower.InstanceGet() assert isinstance(instance, ByteBlower) # Connect to the meetingpoint self.meetingpoint = instance.MeetingPointAdd(self.meetingpoint_address) # If no WirelessEndpoint UUID was given, search an available one. if self.wireless_endpoint_uuid is None: self.wireless_endpoint_uuid = self.select_an_wireless_endpoint_uuid( ) if self.wireless_endpoint_uuid is None: print("The MeetingPoint has no available Wireless Endpoints.") print("Aborting the example.") return # Get the WirelessEndpoint device # We don't need to lock the Wireless Endpoint to get the # polling results. self.wireless_endpoint = self.meetingpoint.DeviceGet( self.wireless_endpoint_uuid) device_info = self.wireless_endpoint.DeviceInfoGet() print("Using wireless endpoint", device_info.GivenNameGet()) network_info = device_info.NetworkInfoGet() interfaces = network_info.InterfaceGet() network_interface = None for network_interface in interfaces: if network_interface.DisplayNameGet() == self.wireless_interface: break if network_interface is None: print("ERROR: could not find the specified interface") return 1 headers = ('"SSID"', '"BSSID"', '"Channel"', '"RSSI (dBm)"', '"Tx Rate (bps)"') results = [] for _ in range(self.duration_s): # Synchronize the local API object with the values # cached in the MeetingPoint network_info.Refresh() # Collect the results and print them out. result = ("\"" + network_interface.WiFiSsidGet() + "\"", "\"" + network_interface.WiFiBssidGet() + "\"", network_interface.WiFiChannelGet(), network_interface.WiFiRssiGet(), network_interface.WiFiTxRateGet()) print(network_interface.DisplayNameGet(), result) results.append(result) time.sleep(1) instance.MeetingPointRemove(self.meetingpoint)
def cleanup(self): for bb_port in self.client_bb_ports: self.server.PortDestroy(bb_port) if self.server_bb_port: self.server.PortDestroy(self.server_bb_port) self.server_bb_port = None # Disconnect from the ByteBlower server if self.server: ByteBlower.InstanceGet().ServerRemove(self.server) self.server = None
def cleanup(self): instance = ByteBlower.InstanceGet() # Cleanup for wireless_endpoint in self.wireless_endpoints: wireless_endpoint.Lock(False) if self.meetingpoint is not None: instance.MeetingPointRemove(self.meetingpoint) if self.server is not None: instance.ServerRemove(self.server)
def cleanup(self): """Clean up the created objects""" byteblower_instance = ByteBlower.InstanceGet() if self.port_1: self.server.PortDestroy(self.port_1) self.port_1 = None if self.port_2: self.server.PortDestroy(self.port_2) self.port_2 = None if self.server is not None: byteblower_instance.ServerRemove(self.server) self.server = None
def run(self): instance = ByteBlower.InstanceGet() assert isinstance(instance, ByteBlower) # Connect to the meetingpoint self.meetingpoint = instance.MeetingPointAdd(self.meetingpoint_address) # If no WirelessEndpoint UUID was given, search an available one. if self.wireless_endpoint_uuid is None: self.wireless_endpoint_uuid = self.select_wireless_endpoint_uuid() # Get the WirelessEndpoint device self.wireless_endpoint = self.meetingpoint.DeviceGet( self.wireless_endpoint_uuid) device_info = self.wireless_endpoint.DeviceInfoGet() print("Using wireless endpoint", device_info.GivenNameGet()) duration_scenario = 5000000000 self.wireless_endpoint.ScenarioDurationSet(duration_scenario) # Make sure we are the only users for the wireless endpoint self.wireless_endpoint.Lock(True) # Upload the configuration to the wireless endpoint self.wireless_endpoint.Prepare() from time import sleep # starting the wireless endpoint starttime_posix = self.wireless_endpoint.Start() # Current POSIX timestamp on the meetingpoint current_time_posix = self.meetingpoint.TimestampGet() time_to_wait_ns = starttime_posix - current_time_posix # Wait 200 ms longer, to make sure the wireless endpoint has started. time_to_wait_ns += 200000000 print("Waiting for", time_to_wait_ns / 1000000000.0, "to start the wireless endpoint") sleep(time_to_wait_ns / 1000000000.0) print("wireless endpoint will be running for", duration_scenario / 1000000000.0, "seconds") print("Waiting for the test to finish") sleep(duration_scenario / 1000000000.0) self.wireless_endpoint.Lock(False)
def __exit__(self, *args, **kwargs): instance = ByteBlower.InstanceGet() if self.wireless_endpoint is not None: self.wireless_endpoint.Lock(False) if self.meetingpoint is not None: instance.MeetingPointRemove(self.meetingpoint) self.meetingpoint = None if self.port is not None: self.server.PortDestroy(self.port) self.port = None if self.server is not None: instance.ServerRemove(self.server) self.server = None
def __enter__(self): instance = ByteBlower.InstanceGet() # Connect to the server self.server = instance.ServerAdd(self.server_address) # create and configure the port. self.port = self.server.PortCreate(self.server_interface) # configure the MAC address on the port port_layer2_config = self.port.Layer2EthIISet() port_layer2_config.MacSet(self.port_mac_address) # configure the IP addressing on the port port_layer3_config = self.port.Layer3IPv4Set() if type(self.port_ip_address) is str and self.port_ip_address == 'dhcp': # DHCP is configured on the DHCP protocol dhcp_protocol = port_layer3_config.ProtocolDhcpGet() dhcp_protocol.Perform() else: # Static addressing port_layer3_config.IpSet(self.port_ip_address[0]) port_layer3_config.NetmaskSet(self.port_ip_address[1]) port_layer3_config.GatewaySet(self.port_ip_address[2]) print("Created port", self.port.DescriptionGet()) # Connect to the meetingpoint self.meetingpoint = instance.MeetingPointAdd(self.meetingpoint_address) # If no WirelessEndpoint UUID was given, search an available one. if self.wireless_endpoint_uuid is None: self.wireless_endpoint_uuid = self.select_wireless_endpoint_uuid() # Get the WirelessEndpoint device self.wireless_endpoint = self.meetingpoint.DeviceGet(self.wireless_endpoint_uuid) print("Using wireless endpoint", self.wireless_endpoint.DescriptionGet()) # Now we have the correct information to start configuring the flow. # Claim the wireless endpoint for ourselves. This means that nobody # but us can use this device. self.wireless_endpoint.Lock(True) return self
def inspect_trunk(server, trunkbase=''): """ Inspect a trunk-interface of a server to detect connected modems """ byteblower_instance = ByteBlower.InstanceGet() server = byteblower_instance.ServerAdd(server) ports = [] for an_bb_interface in server.InterfaceNamesGet(): if not an_bb_interface.startswith(trunkbase): continue port = server.PortCreate(an_bb_interface) port_l2 = port.Layer2EthIISet() port_l2.MacSet(a_mac_address()) port_l3 = port.Layer3IPv4Set() port_l3.ProtocolDhcpGet().PerformAsync() ports.append(port) responding_ports = [] for a_port in ports: try: l3 = a_port.Layer3IPv4Get() dhcp = l3.ProtocolDhcpGet() dhcp.Perform() l3.ResolveAsync(l3.GatewayGet()) responding_ports.append(a_port) except DHCPFailed: server.PortDestroy(a_port) for a_port in responding_ports: l3 = a_port.Layer3IPv4Get() gateway_addr = l3.GatewayGet() try: mac_gw = l3.Resolve(gateway_addr) vendor_string = lookup_vendor_name(mac_gw) result_format = "%s, %s, %s, %s" print(result_format % (a_port.InterfaceNameGet(), l3.IpGet(), mac_gw, vendor_string)) except AddressResolutionFailed: pass server.PortDestroy(a_port)
def main(server_address, src_interface, dst_interface, speed_mbps=999): byteblower_instance = ByteBlower.InstanceGet() server = None try: server = byteblower_instance.ServerAdd(server_address) src = create_port(server, src_interface) dst = create_port(server, dst_interface) a_mbit = 1e6 n_req, fps, rx_echo, rx_replies = test_connection( src, dst, speed_mbps * a_mbit) summary_txt = """ Send out %d Ping requests at %d Mbit/s (%.2f requests a second) %d (%.1f %% ) were received at the destination. %d (%.1f %% ) were answered at the source. """ % (n_req, speed_mbps, fps, rx_echo, (100. * rx_echo) / n_req, rx_replies, (100. * rx_replies) / n_req) print(summary_txt) finally: if server is not None: byteblower_instance.ServerRemove(server)
def run(self): instance = ByteBlower.InstanceGet() assert isinstance(instance, ByteBlower) self.__setup_byteblower_port() http_server = self.__setup_http_server() # Connect to the meetingpoint self.meetingpoint = instance.MeetingPointAdd(self.meetingpoint_address) # Get the maximum of devices allowed by the license, so we can limit # the number of devices we lock. byteblower_license = self.meetingpoint.ServiceInfoGet().LicenseGet() max_devices_allowed = byteblower_license.NumberOfWirelessEndpointsGet() # If no WirelessEndpoint UUID was given, search an available one. if not self.wireless_endpoint_uuids: self.wireless_endpoint_uuids = self.select_wireless_endpoint_uuids( ) # Limit the number of wireless endpoints to the number we fetched earlier. if len(self.wireless_endpoint_uuids) > max_devices_allowed: first_devices = self.wireless_endpoint_uuids[:max_devices_allowed] self.wireless_endpoint_uuids = first_devices # Get the WirelessEndpoint devices self.wireless_endpoints = [ self.meetingpoint.DeviceGet(uuid) for uuid in self.wireless_endpoint_uuids ] print("Using wireless endpoints:") for wireless_endpoint in self.wireless_endpoints: print(wireless_endpoint.DescriptionGet()) # Now we have the correct information to start configuring the flows. for wireless_endpoint in self.wireless_endpoints: # Claim the wireless endpoint for ourselves. This means that # nobody but us can use this device. print("Locking device", wireless_endpoint.DeviceIdentifierGet()) try: wireless_endpoint.Lock(True) except ConfigError as e: print("Could not lock!", e.getMessage(), file=sys.stderr) raise for wireless_endpoint in self.wireless_endpoints: self.__setup_http_client(wireless_endpoint, http_server) # now the flows are configured and the HTTP server is listening, # start the wireless endpoints. # Add all the wireless endpoint into a WirelessEndpointList. # Our API currently doesn't allow passing a pure python-list. all_wireless_endpoints = WirelessEndpointList() for wireless_endpoint in self.wireless_endpoints: all_wireless_endpoints.append(wireless_endpoint) # Send the Scenario to all wireless endpoints # Sending the scenario per device would take at least the number of # Wireless Endpoints in seconds, since they beat only once per second. # Using this technique they get their scenario in the next 2 heartbeats. print("Preparing the devices") self.meetingpoint.DevicesPrepare(all_wireless_endpoints) # Now we will start the wireless endpoints at once. # As with prepare, sending the start using the meetingpoint is a lot # faster than starting them one by one. In fact it is the only way # to get them started in a coordinated way. # The meetingpoint will return the timestamp when the devices will # start. starttime_ns = self.meetingpoint.DevicesStart(all_wireless_endpoints) now_ns = self.meetingpoint.TimestampGet() time_to_wait_ns = starttime_ns - now_ns time_to_wait = datetime.timedelta(microseconds=time_to_wait_ns / 1000) print("Waiting for", time_to_wait.total_seconds(), "seconds for the devices to start.") time.sleep(time_to_wait.total_seconds()) print("Devices started.") # We need to wait for the devices to become available again # This indicates that the scenarios are finished. still_running = True while still_running: time.sleep(1) still_running = False running_devices = 0 for wireless_endpoint in self.wireless_endpoints: allowed_statusses = [ DeviceStatus.Reserved, DeviceStatus.Available ] # The wireless Endpoint is running a test when it is # - Armed # - Running # If the device is Available or Reserved (= Available + Locked) # the device is not running a test. if wireless_endpoint.StatusGet() not in allowed_statusses: still_running = True running_devices += 1 print(running_devices, "running,", len(http_server.ClientIdentifiersGet()), "clients connected") print("All devices finished.") # Wireless Endpoint has returned. Collect and process the results. # It was a new HTTP server. There will thus be only 1 client. client_idents = http_server.ClientIdentifiersGet() if len(client_idents) == 0: print("Nothing connected") sys.exit(-1) # save the results to CSV, this allows further analysis afterwards collected_results = self.collect_results(http_server) return collected_results
def run(self): byteblower_instance = ByteBlower.InstanceGet() print("Connecting to ByteBlower server %s..." % self.server_address) self.server = byteblower_instance.ServerAdd(self.server_address) print("Creating ports") # Do check the provision_port code. The vlan has # a small impact there. self.port_1 = self.provision_port(self.port_1_config) self.port_2 = self.provision_port(self.port_2_config) # Creating the stream where we'll sent the traffic from. # Most is the same as the basic IPv4 example. stream = self.port_1.TxStreamAdd() stream.NumberOfFramesSet(self.number_of_frames) stream.InterFrameGapSet(self.interframegap_ns) frame = stream.FrameAdd() # Collect the basic addressing info for the Tx side. # VLAN id handled lower in the code. src_ip = self.port_1_config['ip_address'] src_mac = self.port_1.Layer2EthIIGet().MacGet() dst_ip = self.port_2_config['ip_address'] dst_mac = self.port_1.Layer3IPv4Get().Resolve(dst_ip) frame_size = 512 udp_src = 4096 udp_dest = 4096 payload = 'a' * (frame_size - 42) from scapy.layers.inet import UDP, IP, Ether from scapy.all import Raw # We will need to add a VLAN layer in the frame to transmit. # In scapy Vlans are represented in the Dot1Q class. from scapy.all import Dot1Q udp_payload = Raw(payload.encode('ascii', 'strict')) udp_header = UDP(dport=udp_dest, sport=udp_src) ip_header = IP(src=src_ip, dst=dst_ip) eth_header = Ether(src=src_mac, dst=dst_mac) # A stream will always send the packet just as configured. # When the Tx ByteBlower port has a VLAN, we need to add it to frame to # be sent. The following lines are the only difference compared to # the basic IPv4 example. if 'vlan' in self.port_1_config: vlan_id = self.port_1_config['vlan'] vlan_header = Dot1Q(vlan=vlan_id) scapy_frame = eth_header / vlan_header / ip_header / udp_header / udp_payload else: scapy_frame = eth_header / ip_header / udp_header / udp_payload # As noted above, the remainder of the stream config is the same again. frame_content = bytearray(bytes(scapy_frame)) hexbytes = ''.join((format(b, "02x") for b in frame_content)) frame.BytesSet(hexbytes) # create a trigger to count the number of received frames. # Similar to the stream we will need to make a slight modification # for the Vlan layer. trigger = self.port_2.RxTriggerBasicAdd() # The BPF filter on a trigger is promiscous: it will be applied to all # traffic that arrives at the Physical interface. # # When we expect to receive packets with a VLAN, we need to add # this element to the filter. if 'vlan' in self.port_2_config: rx_vlan_id = str(self.port_2_config['vlan']) bpf_filter = "vlan {} and ip dst {} and udp port {}".format( rx_vlan_id, dst_ip, udp_dest) else: bpf_filter = "ip dst {} and udp port {}".format(dst_ip, udp_dest) trigger.FilterSet(bpf_filter) # The above filter was the last change necessary in this method. # The remainder, result gathering and cleanup is the same. # VLAN info will be list in the port description below. print("Current ByteBlower configuration:") print("port1:", self.port_1.DescriptionGet()) print("port2:", self.port_2.DescriptionGet()) print("Starting traffic") trigger.ResultClear() stream_history = stream.ResultHistoryGet() trigger_history = trigger.ResultHistoryGet() duration_ns = self.interframegap_ns * self.number_of_frames duration_s = duration_ns / 1000000000 + 1 # Running the test. No difference here. # For more info on specific methods, do look into # the API specification (http:\\api.byteblower.com) # or the ipv4.py example. stream.Start() for iteration in range(1, int(duration_s)): sleep(1) stream_history.Refresh() trigger_history.Refresh() last_interval_tx = stream_history.IntervalLatestGet() last_interval_rx = trigger_history.IntervalLatestGet() print("Sent {TX} frames, received {RX} frames".format( TX=last_interval_tx.PacketCountGet(), RX=last_interval_rx.PacketCountGet())) print("Done sending traffic (time elapsed)") print("Waiting for a second") sleep(1) # Collect and show the results. stream_result = stream.ResultGet() trigger_result = trigger.ResultGet() stream_result.Refresh() print("Stream result:", stream_result.DescriptionGet()) trigger_result.Refresh() print("Trigger result:", trigger_result.DescriptionGet()) tx_frames = stream_result.PacketCountGet() rx_frames = trigger_result.PacketCountGet() print("Sent {TX} frames, received {RX} frames".format( TX=tx_frames, RX=rx_frames)) return [tx_frames, rx_frames]
def run(self): instance = ByteBlower.InstanceGet() assert isinstance(instance, ByteBlower) # Connect to the meetingpoint self.meetingpoint = instance.MeetingPointAdd(self.meetingpoint_address) # If no WirelessEndpoint UUID was given, search for any available one. if self.wireless_endpoint_uuid is None: self.wireless_endpoint_uuid = self.select_wireless_endpoint_uuid() # Get the WirelessEndpoint device self.wireless_endpoint = self.meetingpoint.DeviceGet( self.wireless_endpoint_uuid) device_info = self.wireless_endpoint.DeviceInfoGet() logging.info("Using wireless endpoint %s", device_info.GivenNameGet()) # The network monitor is part of scenario. self.wireless_endpoint.Lock(True) scenario_duration_ns = int(self.duration.total_seconds() * 1000000000) self.wireless_endpoint.ScenarioDurationSet(scenario_duration_ns) # Add the monitor to the scenario. # The Wi-Fi statistics are captured as soon as the scenario starts. monitor = device_info.NetworkInfoMonitorAdd() # We want to have history samples every interval_duration seconds. # The Wireless Endpoint will take new snapshot every # interval_duration_ns. interval_duration_s = self.interval_duration.total_seconds() interval_duration_ns = int(interval_duration_s * 1e9) monitor_history = monitor.ResultHistoryGet() monitor_history.SamplingIntervalDurationSet(interval_duration_ns) # Start the test-run. logging.info("Starting the wireless endpoint") self.wireless_endpoint.Prepare() start_time = self.wireless_endpoint.Start() # Wait for the device to start logging.info('Waiting for the wireless endpoint to start') current_time = self.meetingpoint.TimestampGet() time_to_sleep = (start_time - current_time) / 1000000000 time.sleep(int(time_to_sleep)) # Wait for the test to finish logging.info('Waiting for the wireless endpoint to finish the test') time.sleep(self.duration.total_seconds()) # Wait for the device to start beating again. # Default heartbeat interval is 1 seconds, so lets wait for 2 beats logging.info('Waiting for the wireless endpoint to be communicating ' 'with the server') time.sleep(2) # Get the results on the wireless endpoint logging.info('Fetching the results') self.wireless_endpoint.ResultGet() logging.info('Parsing the results') monitor_history.Refresh() # Collect the results from the NetworkInfoMonitor headers = ('Time', 'SSID', 'BSSID', 'Channel', 'RSSI (dBm)', 'Tx Rate (bps)"') logging.info(" ".join(headers)) # Looping over the collected results. for sample in monitor_history.IntervalGet(): # The moment when this sample was taken. timestamp = sample.TimestampGet() # Each sample from the interval includes a list of all # interfaces active at the point in time. interfaces = sample.InterfaceGet() for network_interface in interfaces: # The results for this interface at this moment. is_connected_to_wifi = network_interface.WiFiSsidGet() != "" if is_connected_to_wifi: logging.info("%d %s %s %s %d %d %d", timestamp, network_interface.DisplayNameGet(), network_interface.WiFiSsidGet(), network_interface.WiFiBssidGet(), network_interface.WiFiChannelGet(), network_interface.WiFiRssiGet(), network_interface.WiFiTxRateGet()) return self.collect_results(monitor_history)
def cleanup(self): instance = ByteBlower.InstanceGet() if self.meetingpoint is not None: instance.MeetingPointRemove(self.meetingpoint)
def run(self): # duration of the samples taken. (nanoseconds) sample_duration = 1000000000 # number of samples to take: # ( test_duration / sample_duration) is just enough, so we are doubling # this so we have more than enough sample_count = int(2 * (self.duration / sample_duration)) instance = ByteBlower.InstanceGet() # Connect to the server self.server = instance.ServerAdd(self.server_address) # create and configure the port. self.port = self.server.PortCreate(self.server_interface) # configure the MAC address on the port port_layer2_config = self.port.Layer2EthIISet() port_layer2_config.MacSet(self.port_mac_address) # configure the IP addressing on the port port_layer3_config = self.port.Layer3IPv4Set() if type(self.port_ip_address) is str and self.port_ip_address == 'dhcp': # DHCP is configured on the DHCP protocol dhcp_protocol = port_layer3_config.ProtocolDhcpGet() dhcp_protocol.Perform() else: # Static addressing port_layer3_config.IpSet(self.port_ip_address[0]) port_layer3_config.NetmaskSet(self.port_ip_address[1]) port_layer3_config.GatewaySet(self.port_ip_address[2]) print("Created port", self.port.DescriptionGet()) # Connect to the meetingpoint self.meetingpoint = instance.MeetingPointAdd(self.meetingpoint_address) # If no WirelessEndpoint UUID was given, search an available one. if self.wireless_endpoint_uuid is None: self.wireless_endpoint_uuid = self.select_wireless_endpoint_uuid() # Get the WirelessEndpoint device self.wireless_endpoint = self.meetingpoint.DeviceGet(self.wireless_endpoint_uuid) print("Using wireless endpoint", self.wireless_endpoint.DescriptionGet()) # Now we have the correct information to start configuring the flow. # Claim the wireless endpoint for ourselves. This means that nobody # but us can use this device. self.wireless_endpoint.Lock(True) # Configure the HTTP server, running on the ByteBlower port. http_server = self.port.ProtocolHttpServerAdd() if self.port_tcp_port is None: self.port_tcp_port = random.randint(10000, 40000) # Configure the TCP port on which the HTTP server wll listen http_server.PortSet(self.port_tcp_port) # Configure the receive window. http_server.ReceiveWindowScalingEnable(True) http_server.ReceiveWindowScalingValueSet(7) # Tell the ByteBlower to sample every sample_duration and keep up to # sample_count samples (see top of this function) http_server.HistorySamplingIntervalDurationSet(sample_duration) http_server.HistorySamplingBufferLengthSet(sample_count) # A HTTP server will not listen for new connections as long it is not # started. You can compare it to e.g. Apache or nginx, it won't accept # new connections as long the daemon is not started. http_server.Start() print("HTTP server configuration:", http_server.DescriptionGet()) # Configure the client. http_client = self.wireless_endpoint.ProtocolHttpClientAdd() # Configure the remote endpoint to which it must connect. # This is the IP address and port of the HTTP server configured above http_client.RemoteAddressSet(self.port.Layer3IPv4Get().IpGet()) http_client.RemotePortSet(self.port_tcp_port) http_client.RequestDurationSet(self.duration) http_client.RequestInitialTimeToWaitSet(0) # What will we do? HTTP Get or HTTP PUT? http_client.HttpMethodSet(self.http_method) http_client.TypeOfServiceSet(self.tos) print("HTTP client configuration:", http_client.DescriptionGet()) # Add a NetworkInfoMonitor, to monitor the RSSI over time : device_info = self.wireless_endpoint.DeviceInfoGet() self.network_info_monitor = device_info.NetworkInfoMonitorAdd() # Send the scenario to the wireless endpoint self.wireless_endpoint.Prepare() # Start the wireless endpoint. # Actually, the function will return earlier, since the MeetingPoint # schedules the start some time in the future, to make sure all # devices start at the same time. self.wireless_endpoint.Start() # Wait until the device returns. # As long the device is running, the device will be in # - DeviceStatus_Starting # - DeviceStatus_Running # As soon the device has finished the test, it will return to # 'DeviceStatus_Reserved', since we have a Lock on the device. status = self.wireless_endpoint.StatusGet() start_moment = datetime.datetime.now() while status != DeviceStatus.Reserved: time.sleep(1) status = self.wireless_endpoint.StatusGet() now = datetime.datetime.now() print(str(now), ":: Running for", str(now - start_moment), "::", http_server.ClientIdentifiersGet().size(), "client(s) connected") # Wireless Endpoint has returned. Collect and process the results. # Fetch the results from the wireless endpoint, they will be stored # at the MeetingPoint, we will fetch the results in a following step. self.wireless_endpoint.ResultGet() # Fetch the results of our created NetworkInfoMonitor network_info_history = self.network_info_monitor.ResultHistoryGet() network_info_history.Refresh() # Fetch the results of our HTTP Server. client_idents = http_server.ClientIdentifiersGet() if len(client_idents) == 0: print("Nothing connected") sys.exit(-1) client_identifier = client_idents[0] http_session = http_server.HttpSessionInfoGet(client_identifier) http_hist = http_session.ResultHistoryGet() http_hist.Refresh() # Now we have all results available in our API, we can process them. # We will store results in a list, containing dicts # { 'timestamp': ... , 'SSID': ... , 'BSSID': ... , 'throughput': ... results = [] interval_snapshots = network_info_history.IntervalGet() for network_info_interval in interval_snapshots: # Find the corresponding HTTP snapshot timestamp = network_info_interval.TimestampGet() try: http_interval = http_hist.IntervalGetByTime(timestamp) # Get the average througput for this interval # type is byteblowerll.byteblower.DataRate rate = http_interval.AverageDataSpeedGet() rate_bps = rate.bitrate() except ConfigError as e: print("Couldn't fetch Throughput snapshot for timestamp", timestamp) print("Number of NetworkInfo snapshots:", len(interval_snapshots)) print("Number of HTTP snapshots:", http_hist.IntervalLengthGet()) print("ConfigError:", e.what()) rate_bps = 0 # Get the interfaces stored in this interval interfaces = network_info_interval.InterfaceGet() # Find the WiFi Interface network_interface = self.find_wifi_interface(interfaces) result = { 'timestamp': timestamp, 'throughput': int(rate_bps), # Default values 'SSID': 'Unknown', 'BSSID': 'Unknown', 'RSSI': -127 } if network_interface is None: print("WARNING: No WiFi interface found to query on timestamp", timestamp) else: result.update({ 'SSID': network_interface.WiFiSsidGet(), 'BSSID': network_interface.WiFiBssidGet(), 'RSSI': int(network_interface.WiFiRssiGet()), }) results.append(result) self.server.PortDestroy(self.port) self.wireless_endpoint.Lock(False) return results
def run(self): instance = ByteBlower.InstanceGet() assert isinstance(instance, ByteBlower) # Connect to the server self.server = instance.ServerAdd(self.server_address) # create and configure the port. self.port = self.server.PortCreate(self.server_interface) # configure the MAC address on the port port_layer2_config = self.port.Layer2EthIISet() port_layer2_config.MacSet(self.port_mac_address) # configure the IP addressing on the port port_layer3_config = self.port.Layer3IPv6Set() if (type(self.port_ip_address) is str and self.port_ip_address.lower() == 'dhcp'): # DHCP is configured on the DHCP protocol dhcp_protocol = port_layer3_config.ProtocolDhcpGet() dhcp_protocol.Perform() elif (type(self.port_ip_address) is str and self.port_ip_address.lower() == 'slaac'): # wait for stateless autoconfiguration to complete port_layer3_config.StatelessAutoconfiguration() else: # Static addressing address = self.port_ip_address[0] prefixlength = self.port_ip_address[1] ip = "{}/{}".format(address, prefixlength) port_layer3_config.IpManualAdd(ip) print("Created port", self.port.DescriptionGet()) # Connect to the meetingpoint self.meetingpoint = instance.MeetingPointAdd(self.meetingpoint_address) # If no WirelessEndpoint UUID was given, search an available one. if self.wireless_endpoint_uuid is None: self.wireless_endpoint_uuid = self.select_wireless_endpoint_uuid() # Get the WirelessEndpoint device self.wireless_endpoint = self.meetingpoint.DeviceGet( self.wireless_endpoint_uuid) print("Using wireless endpoint", self.wireless_endpoint.DescriptionGet()) # Now we have the correct information to start configuring the flow. # The ByteBlower port will transmit frames to the wireless endpoint, # This means we need to create a 'stream' on the ByteBlower port and # a Trigger on the WirelessEndpoint stream = self.wireless_endpoint.TxStreamAdd() stream.InterFrameGapSet(self.interframe_gap_nanoseconds) stream.NumberOfFramesSet(self.number_of_frames) # a stream needs to send some data, so lets create a frame # For the frame, we need: # - The destination IP address (The IP address of the ByteBlower port) # - The source and destination UDP ports # (we configured this on top of this script) # - a payload to transmit. port_layer3_config = self.port.Layer3IPv6Get() ipv6_addresses = port_layer3_config.IpLinkLocalGet() if self.port_ip_address == "dhcp": ipv6_addresses = port_layer3_config.IpDhcpGet() elif self.port_ip_address == "slaac": ipv6_addresses = port_layer3_config.IpStatelessGet() elif isinstance(self.port_ip_address, list): ipv6_addresses = port_layer3_config.IpManualGet() port_ipv6 = None for ipv6_address in ipv6_addresses: port_ipv6 = ipv6_address.split("/")[0] payload = 'a' * (self.frame_size - 42) scapy_udp_payload = Raw(payload.encode('ascii', 'strict')) payload_array = bytearray(bytes(scapy_udp_payload)) # The ByteBlower API expects an 'str' as input for the # frame.PayloadSet() method, we need to convert the bytearray hexbytes = ''.join((format(b, "02x") for b in payload_array)) frame = stream.FrameAdd() frame.PayloadSet(hexbytes) stream.DestinationAddressSet(port_ipv6) stream.DestinationPortSet(self.udp_dstport) stream.SourcePortSet(self.udp_srcport) # The trigger on the WirelessEndpoint counts received frames # We need # - the source UDP port # - the destination UDP port # - the destination IP address trigger = self.port.RxTriggerBasicAdd() # Trigger on a ByteBlower port uses BPF # Note: We could generate a more effective filter which will only # trigger the traffic, but for demo purposes and taking NAT into # account, we just keep it simple. bpf = "ip6 host {} and udp port {}".format(port_ipv6, self.udp_dstport) trigger.FilterSet(bpf) # Now all configuration is made print(stream.DescriptionGet()) print(trigger.DescriptionGet()) # Make sure we are the only users for the wireless endpoint self.wireless_endpoint.Lock(True) # Upload the configuration to the wireless endpoint self.wireless_endpoint.Prepare() from time import sleep # POSIX timestamp in nanoseconds when the wireless endpoint will start starttime_posix = self.wireless_endpoint.Start() # Current POSIX timestamp on the meetingpoint current_time_posix = self.meetingpoint.TimestampGet() time_to_wait_ns = starttime_posix - current_time_posix # Wait 200 ms longer, to make sure the wireless endpoint has started. time_to_wait_ns += 200000000 print("Waiting for", time_to_wait_ns / 1000000000.0, "to start the port") sleep(time_to_wait_ns / 1000000000.0) duration_ns = self.interframe_gap_nanoseconds * self.number_of_frames duration_ns += 1000000000 print("Port will transmit for", duration_ns / 1000000000.0, "seconds") self.port.Start() print("Waiting for the test to finish") sleep(duration_ns / 1000000000.0) # get the results from the wireless endpoint self.wireless_endpoint.ResultGet() self.wireless_endpoint.Lock(False) tx_result = stream.ResultGet() tx_result.Refresh() rx_result = trigger.ResultGet() rx_result.Refresh() print("Transmitted", tx_result.PacketCountGet(), "packets") print("Received ", rx_result.PacketCountGet(), "packets") return { 'tx': tx_result.PacketCountGet(), 'rx': rx_result.PacketCountGet() }
def run(self): byteblower_instance = ByteBlower.InstanceGet() print("Connecting to ByteBlower server %s..." % self.server_address) self.server = byteblower_instance.ServerAdd(self.server_address) # Create the port which will be the HTTP server (port_1) print("Creating TX port") self.port = self.server.PortCreate(self.server_interface) # configure the MAC address on the port port_layer2_config = self.port.Layer2EthIISet() port_layer2_config.MacSet(self.port_mac_address) # configure the IP addressing on the port port_layer3_config = self.port.Layer3IPv4Set() if (type(self.port_ip_address) is str and self.port_ip_address == 'dhcp'): # DHCP is configured on the DHCP protocol dhcp_protocol = port_layer3_config.ProtocolDhcpGet() dhcp_protocol.Perform() else: # Static addressing port_layer3_config.IpSet(self.port_ip_address[0]) port_layer3_config.NetmaskSet(self.port_ip_address[1]) port_layer3_config.GatewaySet(self.port_ip_address[2]) # Connect to the meetingpoint self.meetingpoint = byteblower_instance.MeetingPointAdd(self.meetingpoint_address) # If no WirelessEndpoint UUID was given, search an available one. if self.wireless_endpoint_uuid is None: self.wireless_endpoint_uuid = self.select_wireless_endpoint_uuid() # Get the WirelessEndpoint device self.wireless_endpoint = self.meetingpoint.DeviceGet(self.wireless_endpoint_uuid) print("Using wireless endpoint", self.wireless_endpoint.DescriptionGet()) # the destination MAC is the MAC address of the destination port if # the destination port is in the same subnet as the source port, # otherwise it will be the MAC address of the gateway. # ByteBlower has a function to resolve the correct MAC address in # the Layer3 configuration object network_info = self.wireless_endpoint.DeviceInfoGet().NetworkInfoGet() wireless_endpoint_ipv4 = network_info.IPv4Get() port_mac = self.port.Layer2EthIIGet().MacGet() port_layer3_config = self.port.Layer3IPv4Get() port_ipv4 = port_layer3_config.IpGet() # destination MAC must be resolved, since we do not know whether # the wireless endpoint is available on the local LAN destination_mac = port_layer3_config.Resolve(wireless_endpoint_ipv4) payload = 'a' * (self.frame_size - 42) duration_ns = self.interframe_gap_nanoseconds * self.number_of_frames # Add 2 seconds of rollout, so frames in transit can be counted too duration_ns += 2 * 1000 * 1000 * 1000 # create a latency-enabled trigger. A trigger is an object which # receives data. The Basic trigger just count packets, # a LatencyBasic trigger analyzes the timestamps embedded in the # received frame. latency_trigger = self.wireless_endpoint.RxLatencyBasicAdd() # configure the trigger latency_trigger.DurationSet(duration_ns) latency_trigger.FilterUdpSourcePortSet(self.udp_srcport) latency_trigger.FilterUdpDestinationPortSet(self.udp_dstport) latency_trigger.FilterSourceAddressSet(port_ipv4) stream = self.port.TxStreamAdd() stream.InterFrameGapSet(self.interframe_gap_nanoseconds) stream.NumberOfFramesSet(self.number_of_frames) from scapy.layers.inet import UDP, IP, Ether from scapy.all import Raw udp_payload = Raw(payload.encode('ascii', 'strict')) udp_header = UDP(dport=self.udp_dstport, sport=self.udp_srcport, chksum=0) ip_header = IP(src=port_ipv4, dst=wireless_endpoint_ipv4) eth_header = Ether(src=port_mac, dst=destination_mac) scapy_frame = eth_header / ip_header / udp_header / udp_payload frame_content = bytearray(bytes(scapy_frame)) # The ByteBlower API expects an 'str' as input for the # frame.BytesSet() method, we need to convert the bytearray hexbytes = ''.join((format(b, "02x") for b in frame_content)) # Since a stream transmits frames, we need to tell the stream which # frames we want to transmit frame = stream.FrameAdd() frame.BytesSet(hexbytes) # Enable latency for this frame. The frame frame contents will be # altered so it contains a timestamp. frame_tag = frame.FrameTagTimeGet() frame_tag.Enable(True) # Make sure we are the only users for the wireless endpoint self.wireless_endpoint.Lock(True) # Upload the configuration to the wireless endpoint self.wireless_endpoint.Prepare() # print the configuration # This makes it easy to review what we have done until now print("Current ByteBlower configuration:") print("port:", self.port.DescriptionGet()) print("wireless endpoint:", self.wireless_endpoint.DescriptionGet()) # start the traffic, clear the latency trigger. Triggers are active # as soon they are created, so we may want to clear the data it already # has collected. print("Starting traffic") latency_trigger.ResultClear() duration_ns = self.interframe_gap_nanoseconds * self.number_of_frames from time import sleep # POSIX timestamp in nanoseconds when the wireless endpoint will start starttime_posix = self.wireless_endpoint.Start() # Current POSIX timestamp on the meetingpoint current_time_posix = self.meetingpoint.TimestampGet() time_to_wait_ns = starttime_posix - current_time_posix # Wait 200 ms longer, to make sure the wireless endpoint has started. time_to_wait_ns += 200000000 print("Waiting for", time_to_wait_ns / 1000000000.0, "to start the port") sleep(time_to_wait_ns / 1000000000.0) stream.Start() print("Waiting for the test to finish") sleep(duration_ns / 1000000000.0) print("Done sending traffic (time elapsed)") # Waiting for a second after the stream is finished. # This has the advantage that frames that were transmitted but were # not received yet, can be processed by the server print("Waiting for a second") sleep(1) # During the test itself we queried the interval counters, there are # also cumulative counters. The last cumulative counter available in # the history is also available as the Result self.wireless_endpoint.ResultGet() stream_result = stream.ResultGet() latency_result = latency_trigger.ResultGet() stream_result.Refresh() latency_result.Refresh() tx_frames = stream_result.PacketCountGet() rx_frames = latency_result.PacketCountGet() latency_min = 0 latency_max = 0 latency_avg = 0 jitter = 0 if latency_result.PacketCountValidGet() > 0: latency_min = latency_result.LatencyMinimumGet() latency_avg = latency_result.LatencyAverageGet() latency_max = latency_result.LatencyMaximumGet() jitter = latency_result.JitterGet() print("Sent {TX} frames, received {RX} frames".format(TX=tx_frames, RX=rx_frames)) print("Latency (Average, minimum, maximum, jitter): {AVG}ns, {MIN}ns, {MAX}ns, {JIT}ns".format( AVG=latency_avg, MIN=latency_min, MAX=latency_max, JIT=jitter )) # It is considered good practice to clean up your objects. This tells the ByteBlower server it can # clean up its resources. self.server.PortDestroy(self.port) self.wireless_endpoint.Lock(False) return [tx_frames, rx_frames, latency_min, latency_avg, latency_max, jitter]
def run(self): byteblower_instance = ByteBlower.InstanceGet() print("Connecting to ByteBlower server %s..." % self.server_address) self.server = byteblower_instance.ServerAdd(self.server_address) # Create the port which will be the HTTP server (port_1) print("Creating TX port") self.port_1 = self.provision_port(self.port_1_config) print("Creating RX port") # Create the port which will be the HTTP client (port_2) self.port_2 = self.provision_port(self.port_2_config) # now create the stream. # A stream transmits frames on the port on which it is created. stream = self.port_1.TxStreamAdd() # set the number of frames to transmit stream.NumberOfFramesSet(self.number_of_frames) # set the speed of the transmission stream.InterFrameGapSet(self.interframegap_ns) # Since a stream transmits frames, we need to tell the stream which # frames we want to transmit frame = stream.FrameAdd() # collect the frame header info. We need to provide the # Layer2 (ethernet) and Layer3 (IPv4) addresses. src_ip = self.port_1_config['ip_address'] src_mac = self.port_1.Layer2EthIIGet().MacGet() dst_ip = self.port_2_config['ip_address'] # the destination MAC is the MAC address of the destination port if # the destination port is in the same subnet as the source port, # otherwise it will be the MAC address of the gateway. # ByteBlower has a function to resolve the correct MAC address in # the Layer3 configuration object dst_mac = self.port_1.Layer3IPv6Get().Resolve(dst_ip) frame_size = 512 udp_src = 4096 udp_dest = 4096 payload = 'a' * (frame_size - 42) from scapy.layers.inet6 import UDP, IPv6, Ether from scapy.all import Raw udp_payload = Raw(payload.encode('ascii', 'strict')) udp_header = UDP(dport=udp_dest, sport=udp_src) ip_header = IPv6(src=src_ip, dst=dst_ip) eth_header = Ether(src=src_mac, dst=dst_mac) scapy_frame = eth_header / ip_header / udp_header / udp_payload frame_content = bytearray(bytes(scapy_frame)) # The ByteBlower API expects an 'str' as input for the # frame.BytesSet() method, we need to convert the bytearray hex_bytes = ''.join((format(b, "02x") for b in frame_content)) frame.BytesSet(hex_bytes) # Create a trigger. A trigger is an object which receives data. # The Basic trigger just count packets trigger = self.port_2.RxTriggerBasicAdd() # Every trigger needs to know on which frames it will work. # The default filter is no filter, so it will analyze every frame, # which is not what we want here. # We will filter on the destination IP and the destination UDP port bpf_filter = "ip6 dst {} and udp port {}".format(dst_ip, udp_dest) trigger.FilterSet(bpf_filter) # print the configuration, this makes it easy to review what we have # done until now print("Current ByteBlower configuration:") print("port1:", self.port_1.DescriptionGet()) print("port2:", self.port_2.DescriptionGet()) # Start the traffic and clear the trigger. # Triggers are active as soon they are created, so we may want to clear # the data it already has collected. print("Starting traffic") trigger.ResultClear() stream_history = stream.ResultHistoryGet() trigger_history = trigger.ResultHistoryGet() duration_ns = self.interframegap_ns * self.number_of_frames duration_s = duration_ns / 1000000000 + 1 stream.Start() # duration_s is a float, so we need to cast it to an integer first for iteration in range(1, int(duration_s)): # sleep one second sleep(1) # Refresh the history, the ByteBlower server will create interval # and cumulative results every second (by default). # The Refresh method will synchronize the server data with # the client. stream_history.Refresh() trigger_history.Refresh() last_interval_tx = stream_history.IntervalLatestGet() last_interval_rx = trigger_history.IntervalLatestGet() print("Sent {TX} frames, received {RX} frames".format( TX=last_interval_tx.PacketCountGet(), RX=last_interval_rx.PacketCountGet())) print("Done sending traffic (time elapsed)") # Waiting for a second after the stream is finished. # This has the advantage that frames that were transmitted but not # received yet, can be processed by the server print("Waiting for a second") sleep(1) # During the test itself we queried the interval counters, there are # also cumulative counters. The last cumulative counter available in # the history is also available as the Result stream_result = stream.ResultGet() trigger_result = trigger.ResultGet() stream_result.Refresh() print("Stream result:", stream_result.DescriptionGet()) trigger_result.Refresh() print("Trigger result:", trigger_result.DescriptionGet()) tx_frames = stream_result.PacketCountGet() rx_frames = trigger_result.PacketCountGet() print("Sent {TX} frames, received {RX} frames".format(TX=tx_frames, RX=rx_frames)) return [tx_frames, rx_frames]
def run(self): byteblower_instance = ByteBlower.InstanceGet() print("Connecting to ByteBlower server %s..." % self.server_address) self.server = byteblower_instance.ServerAdd(self.server_address) # Create the port which will be the HTTP server (port_1) print("Creating HTTP Server port") self.server_bb_port = self.provision_port(self.server_bb_port_config) print("Creating HTTP Client port") # Create the port which will be the HTTP client (port_2) self.client_bb_port = self.provision_port(self.client_bb_port_config) http_server_ip_address = self.server_bb_port_config['ip_address'] # create a HTTP server http_server = self.server_bb_port.ProtocolHttpServerAdd() server_tcp_port = self.server_bb_port_config['tcp_listen_port'] http_server.PortSet(server_tcp_port) # The HTTP Server still needs to be started explicitly. # You'll notice a difference for the HTTP Clients. http_server.Start() # This section differs from the basic TCP example. # We will create multiple clients onto the same the ByteBlowerPort. http_clients = [] # We'll use the max_duration for the stop condition further in # the script. max_duration = 0 # Configure each client one-by-one. # This part is the same as the basic TCP example. for client_config in self.http_client_configs: # create a new HTTP Client and configure it. # This part is the same for 1 or multiple ones. # # You can configure multiple clients to connect to the # the same server. You can even mix different HTTP Methods. http_client = self.client_bb_port.ProtocolHttpClientAdd() http_client.RemoteAddressSet(http_server_ip_address) http_client.RemotePortSet(server_tcp_port) http_client.HttpMethodSet(client_config['http_method']) http_client.RequestDurationSet(client_config['duration']) # The client configured duration is in nanoseconds, we want to keep # the max_duration as simple as 'seconds', so convert the value. client_duration_s = client_config['duration'] / 1e9 max_duration = max(max_duration, client_duration_s) # The RequestStartType is the main configuration difference # Between 2 TCP clients and multiple ones. Rather than starting # the client directly, we'll schedule when to start. http_client.RequestStartTypeSet(RequestStartType.Scheduled) http_clients.append(http_client) print("Server port:", self.server_bb_port.DescriptionGet()) print("Client port:", self.client_bb_port.DescriptionGet()) # This is another difference with the basic TCP example. # The Start method on a ByteBlower Port starts all scheduled traffic # types. This example this means all configured HTTPClients. self.client_bb_port.Start() # Unlike before we now have several HTTPClients running together. # This makes determining when the scenario is finished more # complex. # Below we show two different stop conditions: # 1. a time based one. (required) # 2. a client based one. (optional) # # Always use the time stop-condition. This provides a guaranteed # end in case when the flows can't connect. # # A little bit of extra_time gives the HTTPClients some time extra # to make the actual connection. extra_time = 2 start_moment = time.time() time_elapsed = 0 while time_elapsed <= (extra_time + max_duration): time.sleep(1) time_elapsed = time.time() - start_moment print('%.2fs :: Waiting for clients to finish.' % time_elapsed) # Below is the second type of stop condition, a client based one. any_client_running = False # Consider a client finished when the state is either: # - Finished # - Error finished_states = [ HTTPRequestStatus.Error, HTTPRequestStatus.Finished ] for http_client in http_clients: # Update the local API object with the with the info on the # ByteBlowerServer. http_client.Refresh() # Check the status. status = http_client.RequestStatusGet() this_client_running = status not in finished_states any_client_running = any_client_running or this_client_running # all clients finished? No need to wait any longer. if not any_client_running: break # Stop the HTTP Server. # This step is optional but has the advantage of stopping traffic # to/from the HTTP Clients http_server.Stop() server_number_of_clients = len(http_server.ClientIdentifiersGet()) print("") print("HTTP Server info ") print("-" * 10) print("Connected clients : {} ".format(server_number_of_clients)) print("") print("HTTP Client info ") print("-" * 10) # Process each of the clients. results = [] for client in http_clients: results.append(self.process_http_client(client)) return results
config = { 'meetingpoint': 'byteblower-tutorial-1300.lab.byteblower.excentis.com' } def device_status_to_str(state): """ Convert the value to an actual name. """ for (name, val) in DeviceStatus.__dict__.items(): if val == state: return name api = ByteBlower.InstanceGet() meetingPoint = api.MeetingPointAdd(config['meetingpoint']) def list_devices(): """ List Wireless Endpoint devices. Returns the results as a list of dictionaries. """ devices_list = [] for dev in meetingPoint.DeviceListGet(): devices_list.append({ 'uuid': dev.DeviceIdentifierGet(), 'name': dev.DeviceInfoGet().GivenNameGet(), 'state': device_status_to_str(dev.StatusGet()) })
def run(self): # duration of the samples taken. (nanoseconds) sample_duration = 100000000 # number of samples to take: # ( test_duration / sample_duration) is just enough, so we are doubling # this so we have more than enough sample_count = int(math.ceil(2 * (self.duration / sample_duration))) instance = ByteBlower.InstanceGet() assert isinstance(instance, ByteBlower) # Connect to the server self.server = instance.ServerAdd(self.server_address) # create and configure the port. self.port = self.server.PortCreate(self.server_interface) # configure the MAC address on the port port_layer2_config = self.port.Layer2EthIISet() port_layer2_config.MacSet(self.port_mac_address) # configure the IP addressing on the port port_layer3_config = self.port.Layer3IPv6Set() if (type(self.port_ip_address) is str and self.port_ip_address.lower() == 'dhcp'): # DHCP is configured on the DHCP protocol dhcp_protocol = port_layer3_config.ProtocolDhcpGet() dhcp_protocol.Perform() elif (type(self.port_ip_address) is str and self.port_ip_address.lower() == 'slaac'): # wait for stateless autoconfiguration to complete port_layer3_config.StatelessAutoconfiguration() else: # Static addressing address = self.port_ip_address[0] prefixlength = self.port_ip_address[1] ip = "{}/{}".format(address, prefixlength) port_layer3_config.IpManualAdd(ip) print("Created port", self.port.DescriptionGet()) # Connect to the meetingpoint self.meetingpoint = instance.MeetingPointAdd(self.meetingpoint_address) # If no WirelessEndpoint UUID was given, search an available one. if self.wireless_endpoint_uuid is None: self.wireless_endpoint_uuid = self.select_wireless_endpoint_uuid() # Get the WirelessEndpoint device self.wireless_endpoint = self.meetingpoint.DeviceGet( self.wireless_endpoint_uuid) print("Using wireless endpoint", self.wireless_endpoint.DescriptionGet()) # Now we have the correct information to start configuring the flow. # Claim the wireless endpoint for ourselves. This means that nobody # but us can use this device. self.wireless_endpoint.Lock(True) # Configure the HTTP server, running on the ByteBlower port. http_server = self.port.ProtocolHttpServerAdd() if self.port_tcp_port is None: self.port_tcp_port = random.randint(10000, 40000) # Configure the TCP port on which the HTTP server wll listen http_server.PortSet(self.port_tcp_port) # Configure the receive window. http_server.ReceiveWindowScalingEnable(True) http_server.ReceiveWindowScalingValueSet(7) # Tell the ByteBlower to sample every sample_duration and keep up to # sample_count samples (see top of this function) http_server.HistorySamplingIntervalDurationSet(sample_duration) http_server.HistorySamplingBufferLengthSet(sample_count) # A HTTP server will not listen for new connections as long it is not # started. You can compare it to e.g. Apache or nginx, it won't accept # new connections as long the daemon is not started. http_server.Start() print("HTTP server configuration:", http_server.DescriptionGet()) # Configure the client. http_client = self.wireless_endpoint.ProtocolHttpClientAdd() # Configure the remote endpoint to which it must connect. # This is the IP address and port of the HTTP server configured above port_layer3_config = self.port.Layer3IPv6Get() ipv6_addresses = port_layer3_config.IpLinkLocalGet() if self.port_ip_address == "dhcp": ipv6_addresses = port_layer3_config.IpDhcpGet() elif self.port_ip_address == "slaac": ipv6_addresses = port_layer3_config.IpStatelessGet() elif isinstance(self.port_ip_address, list): ipv6_addresses = port_layer3_config.IpManualGet() address = None for ipv6_address in ipv6_addresses: address = ipv6_address.split("/")[0] http_client.RemoteAddressSet(address) http_client.RemotePortSet(self.port_tcp_port) http_client.RequestDurationSet(self.duration) http_client.RequestInitialTimeToWaitSet(0) # What will we do? HTTP Get or HTTP PUT? http_client.HttpMethodSet(self.http_method) http_client.TypeOfServiceSet(self.tos) print("HTTP client configuration:", http_client.DescriptionGet()) try: self.wireless_endpoint.Prepare() self.wireless_endpoint.Start() except Exception as e: print("Error couldn't start the WE") print(e.message) sys.exit(-1) # Wait until the device returns. # As long the device is running, the device will be in # - DeviceStatus_Starting # - DeviceStatus_Running # As soon the device has finished the test, it will return to # 'DeviceStatus_Reserved', since we have a Lock on the device. status = self.wireless_endpoint.StatusGet() start_moment = datetime.datetime.now() while status != DeviceStatus.Reserved: time.sleep(1) status = self.wireless_endpoint.StatusGet() now = datetime.datetime.now() print(str(now), ":: Running for", str(now - start_moment), "::", http_server.ClientIdentifiersGet().size(), "client(s) connected") # Wireless Endpoint has returned. Collect and process the results. # It was a new HTTP server. There will thus be only 1 client. client_idents = http_server.ClientIdentifiersGet() if len(client_idents) == 0: print("Nothing connected") sys.exit(-1) first = client_idents[0] http_session = http_server.HttpSessionInfoGet(first) http_hist = http_session.ResultHistoryGet() http_hist.Refresh() # save the results to CSV, this allows further analysis afterwards collected_results = self.collect_results(http_hist) cumulative_result = http_hist.CumulativeLatestGet() mbit_s = cumulative_result.AverageDataSpeedGet().MbpsGet() print("Average throughput", mbit_s, "Mbps") print("Removing the server") self.port.ProtocolHttpServerRemove(http_server) print("Removing the client") self.wireless_endpoint.ProtocolHttpClientRemove(http_client) # Cleanup self.wireless_endpoint.Lock(False) return collected_results
def run(self): instance = ByteBlower.InstanceGet() assert isinstance(instance, ByteBlower) # Connect to the server self.server = instance.ServerAdd(self.server_address) # create and configure the port. self.port = self.server.PortCreate(self.server_interface) # configure the MAC address on the port port_layer2_config = self.port.Layer2EthIISet() port_layer2_config.MacSet(self.port_mac_address) # configure the IP addressing on the port port_layer3_config = self.port.Layer3IPv6Set() if (type(self.port_ip_address) is str and self.port_ip_address.lower() == 'dhcp'): # DHCP is configured on the DHCP protocol dhcp_protocol = port_layer3_config.ProtocolDhcpGet() dhcp_protocol.Perform() elif (type(self.port_ip_address) is str and self.port_ip_address.lower() == 'slaac'): # wait for stateless autoconfiguration to complete port_layer3_config.StatelessAutoconfiguration() else: # Static addressing address = self.port_ip_address[0] prefixlength = self.port_ip_address[1] ip = "{}/{}".format(address, prefixlength) port_layer3_config.IpManualAdd(ip) print("Created port", self.port.DescriptionGet()) # Connect to the meetingpoint self.meetingpoint = instance.MeetingPointAdd(self.meetingpoint_address) # If no WirelessEndpoint UUID was given, search an available one. if self.wireless_endpoint_uuid is None: self.wireless_endpoint_uuid = self.select_wireless_endpoint_uuid() # Get the WirelessEndpoint device self.wireless_endpoint = self.meetingpoint.DeviceGet( self.wireless_endpoint_uuid) print("Using wireless endpoint", self.wireless_endpoint.DescriptionGet()) # Now we have the correct information to start configuring the flow. # The ByteBlower port will transmit frames to the wireless endpoint, # This means we need to create a 'stream' on the ByteBlower port # and a Trigger on the WirelessEndpoint stream = self.port.TxStreamAdd() stream.InterFrameGapSet(self.interframe_gap_nanoseconds) stream.NumberOfFramesSet(self.number_of_frames) # a stream needs to send some data, so lets create a frame # For the frame, we need: # - The source MAC address (MAC address of the ByteBlower port # in our case) # - The destination MAC address. This can be the MAC address of the # WirelessEndpoint, a router, ... This will resolved later on. # - The source IP address (The IP address of the ByteBlower port) # - The destination IP address (The IP address of the WirelessEndpoint) # - The source and destination UDP ports (we configured this on top of # this script) # - a payload to transmit. port_mac = self.port.Layer2EthIIGet().MacGet() port_layer3_config = self.port.Layer3IPv6Get() ipv6_addresses = port_layer3_config.IpLinkLocalGet() if self.port_ip_address == "dhcp": ipv6_addresses = port_layer3_config.IpDhcpGet() elif self.port_ip_address == "slaac": ipv6_addresses = port_layer3_config.IpStatelessGet() elif isinstance(self.port_ip_address, list): ipv6_addresses = port_layer3_config.IpManualGet() port_ipv6 = None for ipv6_address in ipv6_addresses: port_ipv6 = ipv6_address.split("/")[0] # destination MAC must be resolved, since we do not know whether the WE # is available on the local LAN destination_mac = None wireless_endpoint_ipv6 = None all_we_addresses = self.select_wireless_endpoint_addresses() for address in all_we_addresses: wireless_endpoint_ipv6 = address.split('/')[0] try: destination_mac = port_layer3_config.Resolve( wireless_endpoint_ipv6) break except: pass payload = 'a' * (self.frame_size - 42) from scapy.layers.inet6 import UDP, IPv6, Ether from scapy.all import Raw udp_payload = Raw(payload.encode('ascii', 'strict')) udp_header = UDP(dport=self.udp_dstport, sport=self.udp_srcport) ip_header = IPv6(src=port_ipv6, dst=wireless_endpoint_ipv6) eth_header = Ether(src=port_mac, dst=destination_mac) scapy_frame = eth_header / ip_header / udp_header / udp_payload frame_content = bytearray(bytes(scapy_frame)) # The ByteBlower API expects an 'str' as input for the # frame.BytesSet() method, we need to convert the bytearray hexbytes = ''.join((format(b, "02x") for b in frame_content)) frame = stream.FrameAdd() frame.BytesSet(hexbytes) # The trigger on the WirelessEndpoint counts received frames # We need # - the source UDP port # - the destination UDP port # - the originating IP address # - the duration of the session. This can be calculated from the # stream settings as # interframegap (nanoseconds/frame) * number of frames (frames) # some fixed rollout can be added too trigger = self.wireless_endpoint.RxTriggerBasicAdd() # Add 2 seconds of rollout, so frames in transit can be counted too duration_ns = self.interframe_gap_nanoseconds * self.number_of_frames duration_ns += 2000000000 trigger.DurationSet(duration_ns) trigger.FilterUdpSourcePortSet(self.udp_srcport) trigger.FilterUdpDestinationPortSet(self.udp_dstport) trigger.FilterSourceAddressSet(port_ipv6) # Now all configuration is made print(stream.DescriptionGet()) print(trigger.DescriptionGet()) # Make sure we are the only users for the wireless endpoint self.wireless_endpoint.Lock(True) # Upload the configuration to the wireless endpoint self.wireless_endpoint.Prepare() from time import sleep # POSIX timestamp in nanoseconds when the wireless endpoint will start starttime_posix = self.wireless_endpoint.Start() # Current POSIX timestamp on the meetingpoint current_time_posix = self.meetingpoint.TimestampGet() time_to_wait_ns = starttime_posix - current_time_posix # Wait 200 ms longer, to make sure the wireless endpoint has started. time_to_wait_ns += 200000000 print("Waiting for", time_to_wait_ns / 1000000000.0, "to start the port") sleep(time_to_wait_ns / 1000000000.0) print("Port will transmit for", duration_ns / 1000000000.0, "seconds") self.port.Start() print("Waiting for the test to finish") sleep(duration_ns / 1000000000.0) # get the results from the wireless endpoint self.wireless_endpoint.ResultGet() self.wireless_endpoint.Lock(False) tx_result = stream.ResultGet() tx_result.Refresh() rx_result = trigger.ResultGet() rx_result.Refresh() print("Transmitted", tx_result.PacketCountGet(), "packets") print("Received ", rx_result.PacketCountGet(), "packets") return { 'tx': tx_result.PacketCountGet(), 'rx': rx_result.PacketCountGet() }
def run(self): instance = ByteBlower.InstanceGet() assert isinstance(instance, ByteBlower) # Connect to the server self.server = instance.ServerAdd(self.server_address) # create and configure the port. self.port = self.server.PortCreate(self.server_interface) # configure the MAC address on the port port_layer2_config = self.port.Layer2EthIISet() port_layer2_config.MacSet(self.port_mac_address) # configure the IP addressing on the port port_layer3_config = self.port.Layer3IPv4Set() if (type(self.port_ip_address) is str and self.port_ip_address == 'dhcp'): # DHCP is configured on the DHCP protocol dhcp_protocol = port_layer3_config.ProtocolDhcpGet() dhcp_protocol.Perform() else: # Static addressing port_layer3_config.IpSet(self.port_ip_address[0]) port_layer3_config.NetmaskSet(self.port_ip_address[1]) port_layer3_config.GatewaySet(self.port_ip_address[2]) print("Created port", self.port.DescriptionGet()) # Connect to the meetingpoint self.meetingpoint = instance.MeetingPointAdd(self.meetingpoint_address) # If no WirelessEndpoint UUID was given, search an available one. if self.wireless_endpoint_uuid is None: self.wireless_endpoint_uuid = self.select_wireless_endpoint_uuid() # Get the WirelessEndpoint device self.wireless_endpoint = self.meetingpoint.DeviceGet( self.wireless_endpoint_uuid) print("Using wireless endpoint", self.wireless_endpoint.DescriptionGet()) # The wireless endpoint device info device_info = self.wireless_endpoint.DeviceInfoGet() # Now we have the correct information to start configuring the flow. # The ByteBlower port will transmit frames to the wireless endpoint, # This means we need to create a 'stream' on the ByteBlower port # and a Trigger on the WirelessEndpoint stream = self.wireless_endpoint.TxStreamAdd() stream.InterFrameGapSet(self.interframe_gap_nanoseconds) number_of_frames = int(self.duration / self.interframe_gap_nanoseconds) stream.NumberOfFramesSet(number_of_frames) # a stream needs to send some data, so lets create a frame # For the frame, we need: # - The destination IP address (The IP address of the ByteBlower port) # - The source and destination UDP ports (we configured this on top of # this script) # - a payload to transmit. port_layer3_config = self.port.Layer3IPv4Get() port_ipv4 = port_layer3_config.IpGet() payload = 'a' * (self.frame_size - 42) scapy_udp_payload = Raw(payload.encode('ascii', 'strict')) payload_array = bytearray(bytes(scapy_udp_payload)) # The ByteBlower API expects an 'str' as input for the # frame.BytesSet() method, we need to convert the bytearray hexbytes = ''.join((format(b, "02x") for b in payload_array)) frame = stream.FrameAdd() frame.PayloadSet(hexbytes) stream.DestinationAddressSet(port_ipv4) stream.DestinationPortSet(self.udp_dstport) stream.SourcePortSet(self.udp_srcport) # The trigger on the WirelessEndpoint counts received frames # We need # - the source UDP port # - the destination UDP port # - the destination IP address trigger = self.port.RxTriggerBasicAdd() # Trigger on a ByteBlower port uses BPF # Note: We could generate a more effective filter which will only # trigger the traffic, but for demo purposes and taking NAT into # account, we just keep it simple. bpf = "ip host %s and udp port %d" % (port_ipv4, self.udp_dstport) trigger.FilterSet(bpf) # We also want the network information over time, # so we can compare the RSSI vs the Loss monitor = device_info.NetworkInfoMonitorAdd() # Now all configuration is made print(stream.DescriptionGet()) print(trigger.DescriptionGet()) print(monitor.DescriptionGet()) # Make sure we are the only users for the wireless endpoint self.wireless_endpoint.Lock(True) # Upload the configuration to the wireless endpoint self.wireless_endpoint.Prepare() from time import sleep # POSIX timestamp in nanoseconds when the wireless endpoint will start starttime_posix = self.wireless_endpoint.Start() # Current POSIX timestamp on the meetingpoint current_time_posix = self.meetingpoint.TimestampGet() time_to_wait_ns = starttime_posix - current_time_posix # Wait 200 ms longer, to make sure the wireless endpoint has started. time_to_wait_ns += 200000000 print("Waiting for", time_to_wait_ns / 1000000000.0, "to start the port") sleep(time_to_wait_ns / 1000000000.0) duration_ns = self.duration + 1000000000 print("Port will transmit for", duration_ns / 1000000000.0, "seconds") self.port.Start() print("Waiting for the test to finish") for i in range(int(duration_ns / 1000000000)): # Refresh the stream results stream.ResultHistoryGet().Refresh() # Refresh the trigger results trigger.ResultHistoryGet().Refresh() self.wireless_endpoint.Refresh() status = self.wireless_endpoint.StatusGet() if status in [DeviceStatus.Reserved, DeviceStatus.Unavailable]: break sleep(1) print("Wait for the device to beat") # Usually one second sleep(1) # get the results from the wireless endpoint self.wireless_endpoint.ResultGet() self.wireless_endpoint.Lock(False) stream_history = stream.ResultHistoryGet() stream_history.Refresh() trigger_history = trigger.ResultHistoryGet() trigger_history.Refresh() monitor_history = monitor.ResultHistoryGet() monitor_history.Refresh() results = [] for network_info_interval in monitor_history.IntervalGet(): timestamp = network_info_interval.TimestampGet() network_interfaces = network_info_interval.InterfaceGet() network_interface = self.find_wifi_interface(network_interfaces) result = { 'timestamp': timestamp, 'rssi': -127, 'ssid': '', 'bssid': '', 'tx_frames': 0, 'rx_frames': 0, 'loss': 0, 'throughput': 0 } if network_interface is not None: result['rssi'] = network_interface.WiFiRssiGet() result['ssid'] = network_interface.WiFiSsidGet() result['bssid'] = network_interface.WiFiBssidGet() try: stream_interval = stream_history.IntervalGetByTime(timestamp) result['tx_frames'] = stream_interval.PacketCountGet() except ConfigError as e: print("ERROR: Could not get result for stream on timestamp", timestamp, ":", str(e)) try: trigger_interval = trigger_history.IntervalGetByTime(timestamp) result['rx_frames'] = trigger_interval.PacketCountGet() throughput = self.frame_size * result['rx_frames'] * 8 result['throughput'] = throughput except ConfigError as e: print("ERROR: Could not get result for trigger on timestamp", timestamp, ":", str(e)) if result['tx_frames'] != 0: lost_frames = result['tx_frames'] - result['rx_frames'] loss = lost_frames * 100.0 / result['tx_frames'] result['loss'] = loss results.append(result) return results
def run(self): instance = ByteBlower.InstanceGet() assert isinstance(instance, ByteBlower) # Connect to the server self.server = instance.ServerAdd(self.server_address) # create and configure the port. self.port = self.server.PortCreate(self.server_interface) # configure the MAC address on the port port_layer2_config = self.port.Layer2EthIISet() port_layer2_config.MacSet(self.port_mac_address) # configure the IP addressing on the port port_layer3_config = self.port.Layer3IPv4Set() if type(self.port_ip_address ) is str and self.port_ip_address == "dhcp": # DHCP is configured on the DHCP protocol dhcp_protocol = port_layer3_config.ProtocolDhcpGet() dhcp_protocol.Perform() else: # Static addressing port_layer3_config.IpSet(self.port_ip_address[0]) port_layer3_config.NetmaskSet(self.port_ip_address[1]) port_layer3_config.GatewaySet(self.port_ip_address[2]) print("Created port", self.port.DescriptionGet()) # Connect to the meetingpoint self.meetingpoint = instance.MeetingPointAdd(self.meetingpoint_address) # If no WirelessEndpoint UUID was given, search an available one. if self.wireless_endpoint_uuid is None: self.wireless_endpoint_uuid = self.select_wireless_endpoint_uuid() # Get the WirelessEndpoint device self.wireless_endpoint = self.meetingpoint.DeviceGet( self.wireless_endpoint_uuid) self.wireless_endpoint.Lock(True) device_info = self.wireless_endpoint.DeviceInfoGet() # The network monitor is part of scenario. self.wireless_endpoint.Lock(True) # Add the monitor to the scenario. # The Wi-Fi statistics are captured as soon as the scenario starts. monitor = device_info.NetworkInfoMonitorAdd() traffic_flows = [] for traffic_config in self.traffic: traffic_type = traffic_config["type"] if "tcp" == traffic_type: traffic_flows.append( TCPTraffic(self.wireless_endpoint, self.port, traffic_config)) elif "udp" == traffic_type and "up" == traffic_config["direction"]: traffic_flows.append( UDPTrafficUp(self.wireless_endpoint, self.port, traffic_config)) elif "udp" == traffic_type and "down" == traffic_config[ "direction"]: traffic_flows.append( UDPTrafficDown(self.wireless_endpoint, self.port, traffic_config)) try: self.wireless_endpoint.Prepare() starttime = self.wireless_endpoint.Start() wait_time_ns = starttime - self.meetingpoint.TimestampGet() time.sleep(max(0, wait_time_ns / 1e9)) except Exception as e: print("Error couldn't start the WE") print(str(e)) sys.exit(-1) print("Starting the ByteBlower") self.port.Start() # Wait until the device returns. # As long the device is running, the device will be in # - DeviceStatus_Starting # - DeviceStatus_Running # As soon the device has finished the test, it will return to # 'DeviceStatus_Reserved', since we have a Lock on the device. status = self.wireless_endpoint.StatusGet() start_moment = datetime.datetime.now() while status != DeviceStatus.Reserved: time.sleep(1) status = self.wireless_endpoint.StatusGet() now = datetime.datetime.now() # Wireless Endpoint has returned. Collect and process the results. self.wireless_endpoint.ResultGet() traffic_results = [] for config, flow in zip(self.traffic, traffic_flows): flow_result = flow.gather_results() flow_result["config"] = config traffic_results.append(flow_result) monitor_history = monitor.ResultHistoryGet() monitor_history.Refresh() monitor_results = [] for sample in monitor_history.IntervalGet(): current_sample = {"timestamp": sample.TimestampGet()} nics = [] for network_interface in sample.InterfaceGet(): current = { "name": network_interface.DisplayNameGet(), "Ssid": network_interface.WiFiSsidGet(), "BSSID": network_interface.WiFiBssidGet(), "Channel": network_interface.WiFiChannelGet(), "RSSI": network_interface.WiFiRssiGet(), "TxRate": network_interface.WiFiTxRateGet(), } nics.append(current) current_sample["interfaces"] = nics monitor_results.append(current_sample) # Cleanup self.server.PortDestroy(self.port) self.wireless_endpoint.Lock(False) return {"traffic": traffic_results, "networkinfo": monitor_results}