def ensure_unique_mac(self, net_dev): """Ensure MAC address of |net_dev| meets uniqueness requirements. The Linux kernel does not allow multiple APs with the same BSSID on the same PHY (at least, with some drivers). Hence, we want to ensure that the DEVs for a PHY have unique MAC addresses. Note that we do not attempt to make the MACs unique across PHYs, because some tests deliberately create such scenarios. @param net_dev NetDev to uniquify. """ if net_dev.if_type == 'monitor': return our_ifname = net_dev.if_name our_phy = net_dev.phy our_mac = interface.Interface(our_ifname, self.host).mac_address sibling_devs = [ dev for dev in self._interfaces if (dev.phy == our_phy and dev.if_name != our_ifname and dev.if_type != 'monitor') ] sibling_macs = (interface.Interface(sib_dev.if_name, self.host).mac_address for sib_dev in sibling_devs) if our_mac in sibling_macs: self.configure_interface_mac(our_ifname, self._get_unique_mac())
def run_once(self): time.sleep(self._init_delay) self._suspender = power_suspend.Suspender( self.resultsdir, method=self._method, suspend_state=self._suspend_state) # Find the interface which is used for most communication. # We assume the interface connects to the gateway and has the lowest # metric. if self._check_connection: interface_choices = {} with open('/proc/net/route') as fh: for line in fh: fields = line.strip().split() if fields[1] != '00000000' or not int(fields[3], 16) & 2: continue interface_choices[fields[0]] = fields[6] iface = interface.Interface(min(interface_choices)) while not self._done(): time.sleep(self._min_resume + random.randint(0, self._max_resume_window)) # Check the network interface to the caller is still available if self._check_connection: # Give a 10 second window for the network to come back. try: utils.poll_for_condition(iface.is_link_operational, desc='Link is operational') except utils.TimeoutError: logging.error('Link to the server gone, reboot') utils.system('reboot') self._suspender.suspend(random.randint(0, 3) + self._min_suspend)
def check_mtu_config(self, mtu): """Check that the ipconfig and interface in the client has correct MTU. @param mtu int expected MTU value. """ proxy = shill_proxy.ShillProxy() device = proxy.find_object( 'Device', {'Name': self.ethernet_pair.peer_interface_name}) if device is None: raise error.TestFail('Device was not found.') device_properties = device.GetProperties(utf8_strings=True) ipconfig_path = device_properties['IPConfigs'][0] ipconfig = proxy.get_dbus_object('org.chromium.flimflam.IPConfig', ipconfig_path) ipconfig_properties = ipconfig.GetProperties(utf8_strings=True) ipconfig_mtu = ipconfig_properties['Mtu'] if ipconfig_mtu != mtu: raise error.TestFail('Shill MTU %d does not match expected %d.' % (ipconfig_mtu, mtu)) interface_mtu = interface.Interface( self.ethernet_pair.peer_interface_name).mtu if interface_mtu != mtu: raise error.TestFail('Interface MTU %d does not match ' 'expected %d.' % (interface_mtu, ipconfig_mtu))
def local_peer_mac_address(self): """Get the MAC address of the peer interface. @return string MAC address of the peer interface. """ iface = interface.Interface(self.station_instances[0].interface, self.router) return iface.mac_address
def get_hostapd_mac(self, ap_num): """Return the MAC address of an AP in the test. @param ap_num int index of local server to read the MAC address from. @return string MAC address like 00:11:22:33:44:55. """ interface_name = self.get_hostapd_interface(ap_num) ap_interface = interface.Interface(interface_name, self.host) return ap_interface.mac_address
def clone_mac_address(self, src_dev=None, dst_dev=None): """Copy the MAC address from one interface to another. @param src_dev string name of device to copy address from. @param dst_dev string name of device to copy address to. """ self.configure_interface_mac( dst_dev, interface.Interface(src_dev, self.host).mac_address)
def _get_default_network_interface(self): interface_choices = {} with open('/proc/net/route') as fh: for line in fh: fields = line.strip().split() if fields[1] != '00000000' or not int(fields[3], 16) & 2: continue interface_choices[fields[0]] = int(fields[6]) if not interface_choices: return None return interface.Interface( min(interface_choices, key=interface_choices.get))
def get_host_ip(): """Get the IP address of the host running containers on lxcbr*. This function gets the IP address on network interface lxcbr*. The assumption is that lxc uses the network interface started with "lxcbr". @return: IP address of the host running containers. """ # The kernel publishes symlinks to various network devices in /sys. result = utils.run('ls /sys/class/net', ignore_status=True) # filter out empty strings interface_names = [x for x in result.stdout.split() if x] lxc_network = None for name in interface_names: if name.startswith('lxcbr'): lxc_network = name break if not lxc_network: raise error.ContainerError('Failed to find network interface used by ' 'lxc. All existing interfaces are: %s' % interface_names) netif = interface.Interface(lxc_network) return netif.ipv4_address
def run_once(self): """Test main loop""" # full_revision looks like "3.4.0". full_revision = utils.system_output('uname -r') # base_revision looks like "3.4". base_revision = '.'.join(full_revision.split('.')[:2]) logging.info('Kernel base is %s', base_revision) found_devices = 0 for device in self.DEVICES: net_if = interface.Interface(device) device_description = net_if.device_description if not device_description: continue device_name, module_path = device_description logging.info('Device name %s, module path %s', device_name, module_path) if not device_name in self.EXPECTED_DRIVER: raise error.TestFail('Unexpected device name %s' % device_name) if not base_revision in self.EXPECTED_DRIVER[device_name]: raise error.TestNAError('Unexpected base kernel revision %s ' 'with device name %s' % (base_revision, device_name)) expected_driver = self.EXPECTED_DRIVER[device_name][base_revision] if module_path != expected_driver: raise error.TestFail( 'Unexpected driver for %s/%s; ' 'got %s but expected %s' % (base_revision, device_name, module_path, expected_driver)) found_devices += 1 if not found_devices: raise error.TestNAError('Found no recognized wireless devices?')
def run_once(self): """Test main loop""" # full_revision looks like "3.4.0". full_revision = utils.system_output('uname -r') # base_revision looks like "3.4". base_revision = '.'.join(full_revision.split('.')[:2]) logging.info('Kernel base is %s', base_revision) proxy = shill_proxy.ShillProxy() device_obj = proxy.find_object('Device', {'Type': proxy.TECHNOLOGY_WIFI}) if device_obj is None: raise error.TestNAError('Found no recognized wireless device') device = device_obj.GetProperties()['Interface'] net_if = interface.Interface(device) device_description = net_if.device_description if not device_description: raise error.TestFail('Device %s is not supported' % device) device_name, module_path = device_description logging.info('Device name %s, module path %s', device_name, module_path) if not device_name in self.EXPECTED_DRIVER: raise error.TestFail('Unexpected device name %s' % device_name) if not base_revision in self.EXPECTED_DRIVER[device_name]: raise error.TestNAError( 'Unexpected base kernel revision %s with device name %s' % (base_revision, device_name)) expected_driver = self.EXPECTED_DRIVER[device_name][base_revision] if module_path != expected_driver: raise error.TestFail( 'Unexpected driver for %s/%s; got %s but expected %s' % (base_revision, device_name, module_path, expected_driver))
def run_once(self, host): helper = privet_helper.PrivetHelper(host=host) logging.info('Looking for privet bootstrapping network from DUT.') scan_interface = self._router.get_wlanif(2437, 'managed') self._router.host.run('%s link set %s up' % (self._router.cmd_ip, scan_interface)) start_time = time.time() privet_bss = None while time.time() - start_time < PRIVET_AP_STARTUP_TIMEOUT_SECONDS: bss_list = self._router.iw_runner.scan(scan_interface) for bss in bss_list or []: if helper.is_softap_ssid(bss.ssid): privet_bss = bss if privet_bss is None: raise error.TestFail('Device did not start soft AP in time.') self._router.release_interface(scan_interface) # Get the netblock of the interface running the AP. dut_iw_runner = iw_runner.IwRunner(remote_host=host) devs = dut_iw_runner.list_interfaces(desired_if_type='AP') if not devs: raise error.TestFail('No AP devices on DUT?') ap_interface = interface.Interface(devs[0].if_name, host=host) ap_netblock = netblock.from_addr(ap_interface.ipv4_address_and_prefix) # Set up an AP on the router in the 5Ghz range with WPA2 security. wpa_config = xmlrpc_security_types.WPAConfig( psk=PASSPHRASE, wpa_mode=xmlrpc_security_types.WPAConfig.MODE_PURE_WPA2, wpa2_ciphers=[xmlrpc_security_types.WPAConfig.CIPHER_CCMP]) router_conf = hostap_config.HostapConfig( frequency=5240, security_config=wpa_config, mode=hostap_config.HostapConfig.MODE_11N_PURE) self._router.hostap_configure(router_conf) # Connect the other interface on the router to the AP on the client # at a hardcoded IP address. self._router.configure_managed_station( privet_bss.ssid, privet_bss.frequency, ap_netblock.get_addr_in_block(200)) station_interface = self._router.get_station_interface(instance=0) logging.debug('Set up station on %s', station_interface) self._router.ping(ping_runner.PingConfig(ap_netblock.addr, count=3)) logging.info('Looking for privet webserver in mDNS records.') start_time = time.time() while time.time() - start_time < PRIVET_MDNS_RECORD_TIMEOUT_SECONDS: all_records = avahi_utils.avahi_browse(host=self._router.host) records = [record for record in all_records if (record.interface == station_interface and record.record_type == '_privet._tcp')] if records: break time.sleep(POLLING_PERIOD) if not records: raise error.TestFail('Did not find privet mDNS records in time.') if len(records) > 1: raise error.TestFail('Should not see multiple privet records.') privet_record = records[0] # TODO(wiley) pull the HTTPs port number out of the /info API. helper = privet_helper.PrivetdHelper( host=self._router.host, hostname=privet_record.address, http_port=int(privet_record.port)) helper.ping_server() # Now configure the client with WiFi credentials. auth_token = helper.privet_auth() ssid = self._router.get_ssid() data = helper.setup_add_wifi_credentials(ssid, PASSPHRASE) helper.setup_start(data, auth_token) logging.info('Waiting for DUT to connect to router network.') start_time = time.time() # Wait for the DUT to take down the AP. while time.time() - start_time < PRIVET_CONNECT_TIMEOUT_SECONDS: if not dut_iw_runner.list_interfaces(desired_if_type='AP'): break time.sleep(POLLING_PERIOD) else: raise error.TestFail('Timeout waiting for DUT to take down AP.') # But we should be able to ping the client from the router's AP. while time.time() - start_time < PRIVET_CONNECT_TIMEOUT_SECONDS: if dut_iw_runner.list_interfaces(desired_if_type='managed'): break time.sleep(POLLING_PERIOD) else: raise error.TestFail('Timeout waiting for DUT managerd interface.') while time.time() - start_time < PRIVET_CONNECT_TIMEOUT_SECONDS: devs = dut_iw_runner.list_interfaces(desired_if_type='managed') if devs: managed_interface = interface.Interface(devs[0].if_name, host=host) # Check if we have an IP yet. if managed_interface.ipv4_address_and_prefix: break time.sleep(POLLING_PERIOD) else: raise error.TestFail('Timeout waiting for DUT managerd interface.') managed_netblock = netblock.from_addr( managed_interface.ipv4_address_and_prefix) while time.time() - start_time < PRIVET_CONNECT_TIMEOUT_SECONDS: PING_COUNT = 3 result = self._router.ping( ping_runner.PingConfig(managed_netblock.addr, ignore_result=True, count=PING_COUNT)) if result.received == PING_COUNT: break time.sleep(POLLING_PERIOD) else: raise error.TestFail('Timeout before ping was successful.') # And buffet should think it is online as well. helper = privet_helper.PrivetdHelper( host=host, hostname=managed_netblock.addr, http_port=int(privet_record.port)) helper.ping_server() if not helper.wifi_setup_was_successful(ssid, auth_token): raise error.TestFail('Device claims to be offline, but is online.')
def _interface_exists(self, interface_name): """ Returns True iff we found an interface with name |interface_name|. """ return interface.Interface(interface_name, host=self._host).exists
def peer_interface_mac(self): """@return string MAC address of the peer interface.""" return interface.Interface(self._peer_interface_name).mac_address
def interface_mac(self): """@return string MAC address of the interface.""" return interface.Interface(self.interface_name).mac_address
def peer_interface_subnet_mask(self): """@return string IPv4 subnet mask of the peer interface.""" return interface.Interface(self.peer_interface_name).ipv4_subnet_mask
def interface_prefix(self): """@return int IPv4 prefix length.""" return interface.Interface(self.interface_name).ipv4_prefix
def peer_interface_ip(self): """@return string IPv4 address of the peer interface.""" return interface.Interface(self.peer_interface_name).ipv4_address
def __init__(self, interface_name): self._interface = interface.Interface(interface_name) self._socket = None
def __init__(self, client_host, result_dir, use_wpa_cli): """ Construct a WiFiClient. @param client_host host object representing a remote host. @param result_dir string directory to store test logs/packet caps. @param use_wpa_cli bool True if we want to use |wpa_cli| commands for Android testing. """ super(WiFiClient, self).__init__(client_host, 'client', inherit_interfaces=True) self._command_ip = 'ip' self._command_iptables = 'iptables' self._command_ping6 = 'ping6' self._command_wpa_cli = 'wpa_cli' self._machine_id = None self._result_dir = result_dir self._conductive = None self._client_hostname = client_host.hostname if self.host.get_os_type() == adb_host.OS_TYPE_ANDROID and use_wpa_cli: # Look up the WiFi device (and its MAC) on the client. devs = self.iw_runner.list_interfaces(desired_if_type='managed') devs = [dev for dev in devs if dev.if_name not in self.WIFI_IF_BLACKLIST] if not devs: raise error.TestFail('No wlan devices found on %s.' % self.host.hostname) if len(devs) > 1: logging.warning('Warning, found multiple WiFi devices on ' '%s: %r', self.host.hostname, devs) self._wifi_if = devs[0].if_name self._shill_proxy = wpa_cli_proxy.WpaCliProxy( self.host, self._wifi_if) self._wpa_cli_proxy = self._shill_proxy else: self._shill_proxy = get_xmlrpc_proxy(self.host) interfaces = self._shill_proxy.list_controlled_wifi_interfaces() if not interfaces: logging.debug('No interfaces managed by shill. Rebooting host') self.host.reboot() raise error.TestError('No interfaces managed by shill on %s' % self.host.hostname) self._wifi_if = interfaces[0] self._wpa_cli_proxy = wpa_cli_proxy.WpaCliProxy( self.host, self._wifi_if) self._raise_logging_level() self._interface = interface.Interface(self._wifi_if, host=self.host) logging.debug('WiFi interface is: %r', self._interface.device_description) self._firewall_rules = [] # Turn off powersave mode by default. self.powersave_switch(False) # All tests that use this object assume the interface starts enabled. self.set_device_enabled(self._wifi_if, True) # Invoke the |capabilities| property defined in the parent |Linuxsystem| # to workaround the lazy loading of the capabilities cache and supported # frequency list. This is needed for tests that may need access to these # when the DUT is unreachable (for ex: suspended). self.capabilities
def _is_test_iface_running(self): """Checks whether the test interface is running.""" return interface.Interface(BACKCHANNEL_IFACE_NAME).is_link_operational()