| #!/usr/bin/env python3.4 |
| # |
| # Copyright 2019 - The Android Open Source Project |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| import itertools |
| import re |
| import time |
| |
| import acts.base_test |
| import acts.signals as signals |
| import acts_contrib.test_utils.wifi.wifi_test_utils as wutils |
| import acts.utils |
| |
| from acts import asserts |
| from acts.test_decorators import test_tracker_info |
| from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_2G |
| from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_5G |
| from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest |
| from scapy.all import * |
| from acts.controllers.ap_lib import hostapd_constants |
| |
| WifiEnums = wutils.WifiEnums |
| |
| # Default timeout used for reboot, toggle WiFi and Airplane mode, |
| # for the system to settle down after the operation. |
| DEFAULT_TIMEOUT = 10 |
| SHORT_TIMEOUT = 5 |
| |
| # Constants for WiFi state change operations. |
| FORGET = 1 |
| TOGGLE = 2 |
| REBOOT_DUT = 3 |
| REBOOT_AP = 4 |
| |
| # MAC Randomization setting constants. |
| RANDOMIZATION_NONE = 0 |
| RANDOMIZATION_PERSISTENT = 1 |
| |
| |
| class WifiMacRandomizationTest(WifiBaseTest): |
| """Tests for APIs in Android's WifiManager class. |
| |
| Test Bed Requirement: |
| * Atleast one Android device and atleast two Access Points. |
| * Several Wi-Fi networks visible to the device. |
| """ |
| |
| def setup_class(self): |
| super().setup_class() |
| |
| self.dut = self.android_devices[0] |
| self.dut_client = self.android_devices[1] |
| wutils.wifi_test_device_init(self.dut) |
| wutils.wifi_test_device_init(self.dut_client) |
| req_params = [ |
| "sta_sta_supported_models", "dbs_supported_models", |
| "support_one_factory_mac_address", "roaming_attn" |
| ] |
| opt_param = ["open_network", "reference_networks", "wep_networks"] |
| self.unpack_userparams(req_param_names=req_params, |
| opt_param_names=opt_param) |
| |
| if not hasattr(self, 'packet_capture'): |
| raise signals.TestFailure("Needs packet_capture attribute to " |
| "support sniffing.") |
| self.configure_packet_capture() |
| |
| if "AccessPoint" in self.user_params: |
| self.legacy_configure_ap_and_start(wep_network=True, ap_count=2) |
| elif "OpenWrtAP" in self.user_params: |
| self.configure_openwrt_ap_and_start(open_network=True, |
| wpa_network=True, |
| wep_network=True, |
| mirror_ap=True, |
| ap_count=2) |
| |
| asserts.assert_true( |
| len(self.reference_networks) > 0, |
| "Need at least one reference network with psk.") |
| |
| # Reboot device to reset factory MAC of wlan1 |
| self.dut.reboot() |
| self.dut_client.reboot() |
| time.sleep(DEFAULT_TIMEOUT) |
| wutils.wifi_toggle_state(self.dut, True) |
| wutils.wifi_toggle_state(self.dut_client, True) |
| if self.dut.model in self.support_one_factory_mac_address: |
| self.soft_ap_factory_mac = ( |
| self.dut.droid.wifigetFactorymacAddresses()[0]) |
| else: |
| self.soft_ap_factory_mac = self.get_soft_ap_mac_address() |
| self.sta_factory_mac = self.dut.droid.wifigetFactorymacAddresses()[0] |
| |
| self.wpapsk_2g = self.reference_networks[0]["2g"] |
| self.wpapsk_5g = self.reference_networks[0]["5g"] |
| self.wep_2g = self.wep_networks[0]["2g"] |
| self.wep_5g = self.wep_networks[0]["5g"] |
| self.open_2g = self.open_network[0]["2g"] |
| self.open_5g = self.open_network[0]["5g"] |
| |
| def setup_test(self): |
| super().setup_test() |
| for ad in self.android_devices: |
| ad.droid.wakeLockAcquireBright() |
| ad.droid.wakeUpNow() |
| wutils.wifi_toggle_state(ad, True) |
| |
| def teardown_test(self): |
| super().teardown_test() |
| for ad in self.android_devices: |
| ad.droid.wakeLockRelease() |
| ad.droid.goToSleepNow() |
| self.dut.droid.wifiRemoveNetworkSuggestions([]) |
| wutils.reset_wifi(self.dut) |
| wutils.reset_wifi(self.dut_client) |
| |
| def teardown_class(self): |
| if "AccessPoint" in self.user_params: |
| del self.user_params["reference_networks"] |
| del self.user_params["open_network"] |
| del self.user_params["wep_networks"] |
| |
| """Helper Functions""" |
| |
| def get_randomized_mac(self, network): |
| """Get the randomized MAC address. |
| |
| Args: |
| network: dict, network information. |
| |
| Returns: |
| The randomized MAC address string for the network. |
| |
| """ |
| return self.dut.droid.wifigetRandomizedMacAddress(network) |
| |
| def connect_to_network_and_verify_mac_randomization( |
| self, network, status=RANDOMIZATION_PERSISTENT): |
| """Connect to the given network and verify MAC. |
| |
| Args: |
| network: dict, the network information. |
| status: int, MAC randomization level. |
| |
| Returns: |
| The randomized MAC addresss string. |
| |
| """ |
| wutils.connect_to_wifi_network(self.dut, network) |
| return self.verify_mac_randomization(network, status=status) |
| |
| def verify_mac_randomization_and_add_to_list(self, network, mac_list): |
| """Connect to a network and populate it's MAC in a reference list, |
| that will be used to verify any repeated MAC addresses. |
| |
| Args: |
| network: dict, the network information. |
| mac_list: list of MAC addresss strings. |
| |
| """ |
| rand_mac = self.connect_to_network_and_verify_mac_randomization( |
| network) |
| if rand_mac in mac_list: |
| raise signals.TestFailure('A new Randomized MAC was not generated ' |
| ' for this network %s.' % network) |
| mac_list.append(rand_mac) |
| |
| def verify_mac_randomization(self, |
| network, |
| status=RANDOMIZATION_PERSISTENT): |
| """Get the various types of MAC addresses for the device and verify. |
| |
| Args: |
| network: dict, the network information. |
| status: int, MAC randomization level. |
| |
| Returns: |
| The randomized MAC address string for the network. |
| |
| """ |
| randomized_mac = self.get_randomized_mac(network) |
| default_mac = self.get_sta_mac_address() |
| self.log.info( |
| "Factory MAC = %s\nRandomized MAC = %s\nDefault MAC = %s" % |
| (self.sta_factory_mac, randomized_mac, default_mac)) |
| message = ('Randomized MAC and Factory MAC are the same. ' |
| 'Randomized MAC = %s, Factory MAC = %s' % |
| (randomized_mac, self.sta_factory_mac)) |
| asserts.assert_true(randomized_mac != self.sta_factory_mac, message) |
| if status == RANDOMIZATION_NONE: |
| asserts.assert_true( |
| default_mac == self.sta_factory_mac, "Connection is not " |
| "using Factory MAC as the default MAC.") |
| else: |
| message = ( |
| 'Connection is not using randomized MAC as the default MAC. ' |
| 'Randomized MAC = %s, Default MAC = %s' % |
| (randomized_mac, default_mac)) |
| asserts.assert_true(default_mac == randomized_mac, message) |
| return randomized_mac |
| |
| def check_mac_persistence(self, network, condition): |
| """Check if the MAC is persistent after carrying out specific operations |
| like forget WiFi, toggle WiFi, reboot device and AP. |
| |
| Args: |
| network: dict, The network information. |
| condition: int, value to trigger certain operation on the device. |
| |
| Raises: |
| TestFaikure is the MAC is not persistent. |
| |
| """ |
| rand_mac1 = self.connect_to_network_and_verify_mac_randomization( |
| network) |
| |
| if condition == FORGET: |
| wutils.wifi_forget_network(self.dut, network['SSID']) |
| |
| elif condition == TOGGLE: |
| wutils.wifi_toggle_state(self.dut, False) |
| wutils.wifi_toggle_state(self.dut, True) |
| |
| elif condition == REBOOT_DUT: |
| self.dut.reboot() |
| time.sleep(DEFAULT_TIMEOUT) |
| |
| elif condition == REBOOT_AP: |
| wutils.turn_ap_off(self, 1) |
| time.sleep(DEFAULT_TIMEOUT) |
| wutils.turn_ap_on(self, 1) |
| time.sleep(DEFAULT_TIMEOUT) |
| |
| rand_mac2 = self.connect_to_network_and_verify_mac_randomization( |
| network) |
| |
| if rand_mac1 != rand_mac2: |
| raise signals.TestFailure('Randomized MAC is not persistent after ' |
| 'forgetting networ. Old MAC = %s New MAC' |
| ' = %s' % (rand_mac1, rand_mac2)) |
| |
| def verify_mac_not_found_in_pcap(self, mac, packets): |
| for pkt in packets: |
| self.log.debug("Packet Summary = %s" % pkt.summary()) |
| if mac in pkt.summary(): |
| raise signals.TestFailure( |
| "Caught Factory MAC in packet sniffer" |
| "Packet = %s Device = %s" % (pkt.show(), self.dut)) |
| |
| def verify_mac_is_found_in_pcap(self, mac, packets): |
| for pkt in packets: |
| self.log.debug("Packet Summary = %s" % pkt.summary()) |
| if mac in pkt.summary(): |
| return |
| raise signals.TestFailure("Did not find MAC = %s in packet sniffer." |
| "for device %s" % (mac, self.dut)) |
| |
| def get_sta_mac_address(self): |
| """Gets the current MAC address being used for client mode.""" |
| out = self.dut.adb.shell("ifconfig wlan0") |
| res = re.match(".* HWaddr (\S+).*", out, re.S) |
| return res.group(1) |
| |
| def get_soft_ap_mac_address(self): |
| """Gets the current MAC address being used for SoftAp.""" |
| if self.dut.model in self.sta_sta_supported_models: |
| out = self.dut.adb.shell("ifconfig wlan2") |
| return re.match(".* HWaddr (\S+).*", out, re.S).group(1) |
| if self.dut.model in self.dbs_supported_models: |
| out = self.dut.adb.shell("ifconfig wlan1") |
| return re.match(".* HWaddr (\S+).*", out, re.S).group(1) |
| else: |
| return self.get_sta_mac_address() |
| |
| def _add_suggestion_and_verify_mac_randomization(self, network_suggestion): |
| """Add wifi network suggestion and verify MAC randomization. |
| |
| Args: |
| network_suggestion: network suggestion to add. |
| |
| Returns: |
| Randomized MAC address. |
| """ |
| self.log.info("Adding network suggestion") |
| asserts.assert_true( |
| self.dut.droid.wifiAddNetworkSuggestions([network_suggestion]), |
| "Failed to add suggestions") |
| wutils.start_wifi_connection_scan_and_ensure_network_found( |
| self.dut, network_suggestion[WifiEnums.SSID_KEY]) |
| wutils.wait_for_connect(self.dut, |
| network_suggestion[WifiEnums.SSID_KEY]) |
| default_mac = self.get_sta_mac_address() |
| randomized_mac = self.dut.droid.wifiGetConnectionInfo()["mac_address"] |
| self.log.info( |
| "Factory MAC = %s\nRandomized MAC = %s\nDefault MAC = %s" % |
| (self.sta_factory_mac, randomized_mac, default_mac)) |
| asserts.assert_true( |
| default_mac == randomized_mac, |
| "Connection is not using randomized MAC as the default MAC.") |
| return randomized_mac |
| |
| def _remove_suggestion_and_verify_disconnect(self, network_suggestion): |
| """Remove wifi network suggestion and verify device disconnects. |
| |
| Args: |
| network_suggestion: network suggestion to remove. |
| """ |
| self.dut.log.info("Removing network suggestions") |
| asserts.assert_true( |
| self.dut.droid.wifiRemoveNetworkSuggestions([network_suggestion]), |
| "Failed to remove suggestions") |
| wutils.wait_for_disconnect(self.dut) |
| self.dut.ed.clear_all_events() |
| asserts.assert_false( |
| wutils.wait_for_connect(self.dut, |
| network_suggestion[WifiEnums.SSID_KEY], |
| assert_on_fail=False), |
| "Device should not connect back") |
| |
| """Tests""" |
| |
| @test_tracker_info(uuid="2dd0a05e-a318-45a6-81cd-962e098fa242") |
| def test_set_mac_randomization_to_none(self): |
| self.pcap_procs = wutils.start_pcap(self.packet_capture, 'dual', |
| self.test_name) |
| network = self.wpapsk_2g |
| # Set macRandomizationSetting to RANDOMIZATION_NONE. |
| network["macRand"] = RANDOMIZATION_NONE |
| self.connect_to_network_and_verify_mac_randomization( |
| network, status=RANDOMIZATION_NONE) |
| pcap_fname = '%s_%s.pcap' % \ |
| (self.pcap_procs[hostapd_constants.BAND_2G][1], |
| hostapd_constants.BAND_2G.upper()) |
| time.sleep(SHORT_TIMEOUT) |
| wutils.stop_pcap(self.packet_capture, self.pcap_procs, False) |
| packets = rdpcap(pcap_fname) |
| self.verify_mac_is_found_in_pcap(self.sta_factory_mac, packets) |
| |
| @test_tracker_info(uuid="d9e64202-02d5-421a-967c-42e45f1f7f91") |
| def test_mac_randomization_wpapsk(self): |
| """Verify MAC randomization for a WPA network. |
| |
| Steps: |
| 1. Connect to WPA network. |
| 2. Get the Factory, Randomized and Default MACs. |
| 3. Verify randomized MAC is the default MAC for the device. |
| |
| """ |
| self.connect_to_network_and_verify_mac_randomization(self.wpapsk_2g) |
| |
| @test_tracker_info(uuid="b5be7c53-2edf-449e-ba70-a1fb7acf735e") |
| def test_mac_randomization_wep(self): |
| """Verify MAC randomization for a WEP network. |
| |
| Steps: |
| 1. Connect to WEP network. |
| 2. Get the Factory, Randomized and Default MACs. |
| 3. Verify randomized MAC is the default MAC for the device. |
| |
| """ |
| self.connect_to_network_and_verify_mac_randomization(self.wep_2g) |
| |
| @test_tracker_info(uuid="f5347ac0-68d5-4882-a58d-1bd0d575503c") |
| def test_mac_randomization_open(self): |
| """Verify MAC randomization for a open network. |
| |
| Steps: |
| 1. Connect to open network. |
| 2. Get the Factory, Randomized and Default MACs. |
| 3. Verify randomized MAC is the default MAC for the device. |
| |
| """ |
| self.connect_to_network_and_verify_mac_randomization(self.open_2g) |
| |
| @test_tracker_info(uuid="5d260421-2adf-4ace-b281-3d15aec39b2a") |
| def test_persistent_mac_after_forget(self): |
| """Check if MAC is persistent after forgetting/adding a network. |
| |
| Steps: |
| 1. Connect to WPA network and get the randomized MAC. |
| 2. Forget the network. |
| 3. Connect to the same network again. |
| 4. Verify randomized MAC has not changed. |
| |
| """ |
| self.check_mac_persistence(self.wpapsk_2g, FORGET) |
| |
| @test_tracker_info(uuid="09d40a93-ead2-45ca-9905-14b05fd79f34") |
| def test_persistent_mac_after_toggle(self): |
| """Check if MAC is persistent after toggling WiFi network. |
| |
| Steps: |
| 1. Connect to WPA network and get the randomized MAC. |
| 2. Turn WiFi ON/OFF. |
| 3. Connect to the same network again. |
| 4. Verify randomized MAC has not changed. |
| |
| """ |
| self.check_mac_persistence(self.wpapsk_2g, TOGGLE) |
| |
| @test_tracker_info(uuid="b3aa514f-8562-44e8-bfe0-4ecab9af165b") |
| def test_persistent_mac_after_device_reboot(self): |
| """Check if MAC is persistent after a device reboot. |
| |
| Steps: |
| 1. Connect to WPA network and get the randomized MAC. |
| 2. Reboot DUT. |
| 3. Connect to the same network again. |
| 4. Verify randomized MAC has not changed. |
| |
| """ |
| self.check_mac_persistence(self.wpapsk_2g, REBOOT_DUT) |
| |
| # Disable reboot test for debugging purpose. |
| #@test_tracker_info(uuid="82d691a0-22e4-4a3d-9596-e150531fcd34") |
| def persistent_mac_after_ap_reboot(self): |
| """Check if MAC is persistent after AP reboots itself. |
| |
| Steps: |
| 1. Connect to WPA network and get the randomized MAC. |
| 2. Reboot AP(basically restart hostapd in our case). |
| 3. Connect to the same network again. |
| 4. Verify randomized MAC has not changed. |
| |
| """ |
| self.check_mac_persistence(self.wpapsk_2g, REBOOT_AP) |
| |
| @test_tracker_info(uuid="e1f33dbc-808c-4e61-8a4a-3a72c1f63c7e") |
| def test_mac_randomization_multiple_networks(self): |
| """Connect to multiple networks and verify same MAC. |
| |
| Steps: |
| 1. Connect to network A, get randomizd MAC. |
| 2. Conenct to network B, get randomized MAC. |
| 3. Connect back to network A and verify same MAC. |
| 4. Connect back to network B and verify same MAC. |
| |
| """ |
| mac_list = list() |
| |
| # Connect to two different networks and get randomized MAC addresses. |
| self.verify_mac_randomization_and_add_to_list(self.wpapsk_2g, mac_list) |
| self.verify_mac_randomization_and_add_to_list(self.open_2g, mac_list) |
| |
| # Connect to the previous network and check MAC is persistent. |
| mac_wpapsk = self.connect_to_network_and_verify_mac_randomization( |
| self.wpapsk_2g) |
| msg = ( |
| 'Randomized MAC is not persistent for this network %s. Old MAC = ' |
| '%s \nNew MAC = %s') |
| if mac_wpapsk != mac_list[0]: |
| raise signals.TestFailure( |
| msg % (self.wpapsk_5g, mac_list[0], mac_wpapsk)) |
| mac_open = self.connect_to_network_and_verify_mac_randomization( |
| self.open_2g) |
| if mac_open != mac_list[1]: |
| raise signals.TestFailure(msg % |
| (self.open_5g, mac_list[1], mac_open)) |
| |
| @test_tracker_info(uuid="edb5a0e5-7f3b-4147-b1d3-48ad7ad9799e") |
| def test_mac_randomization_different_APs(self): |
| """Verify randomization using two different APs. |
| |
| Steps: |
| 1. Connect to network A on AP1, get the randomized MAC. |
| 2. Connect to network B on AP2, get the randomized MAC. |
| 3. Veirfy the two MACs are different. |
| |
| """ |
| ap1 = self.wpapsk_2g |
| ap2 = self.reference_networks[1]["5g"] |
| mac_ap1 = self.connect_to_network_and_verify_mac_randomization(ap1) |
| mac_ap2 = self.connect_to_network_and_verify_mac_randomization(ap2) |
| if mac_ap1 == mac_ap2: |
| raise signals.TestFailure( |
| "Same MAC address was generated for both " |
| "APs: %s" % mac_ap1) |
| |
| @test_tracker_info(uuid="b815e9ce-bccd-4fc3-9774-1e1bc123a2a8") |
| def test_mac_randomization_ap_sta(self): |
| """Bring up STA and softAP and verify MAC randomization. |
| |
| Steps: |
| 1. Connect to a network and get randomized MAC. |
| 2. Bring up softAP on the DUT. |
| 3. Connect to softAP network on the client and get MAC. |
| 4. Verify AP and STA use different randomized MACs. |
| 5. Find the channel of the SoftAp network. |
| 6. Configure sniffer on that channel. |
| 7. Verify the factory MAC is not leaked. |
| |
| """ |
| wutils.set_wifi_country_code(self.dut, wutils.WifiEnums.CountryCode.US) |
| wutils.set_wifi_country_code(self.dut_client, |
| wutils.WifiEnums.CountryCode.US) |
| mac_sta = self.connect_to_network_and_verify_mac_randomization( |
| self.wpapsk_2g) |
| softap = wutils.start_softap_and_verify(self, WIFI_CONFIG_APBAND_2G) |
| wutils.connect_to_wifi_network(self.dut_client, softap) |
| softap_info = self.dut_client.droid.wifiGetConnectionInfo() |
| mac_ap = softap_info['mac_address'] |
| if mac_sta == mac_ap: |
| raise signals.TestFailure("Same MAC address was used for both " |
| "AP and STA: %s" % mac_sta) |
| |
| # Verify SoftAp MAC is randomized |
| softap_mac = self.get_soft_ap_mac_address() |
| message = ( |
| 'Randomized SoftAp MAC and Factory SoftAp MAC are the same. ' |
| 'Randomized SoftAp MAC = %s, Factory SoftAp MAC = %s' % |
| (softap_mac, self.soft_ap_factory_mac)) |
| asserts.assert_true(softap_mac != self.soft_ap_factory_mac, message) |
| |
| softap_channel = hostapd_constants.CHANNEL_MAP[ |
| softap_info['frequency']] |
| self.log.info("softap_channel = %s\n" % (softap_channel)) |
| result = self.packet_capture.configure_monitor_mode( |
| hostapd_constants.BAND_2G, softap_channel) |
| if not result: |
| raise ValueError("Failed to configure channel for 2G band") |
| self.pcap_procs = wutils.start_pcap(self.packet_capture, 'dual', |
| self.test_name) |
| # re-connect to the softAp network after sniffer is started |
| wutils.connect_to_wifi_network(self.dut_client, self.wpapsk_2g) |
| wutils.connect_to_wifi_network(self.dut_client, softap) |
| time.sleep(SHORT_TIMEOUT) |
| wutils.stop_pcap(self.packet_capture, self.pcap_procs, False) |
| pcap_fname = '%s_%s.pcap' % \ |
| (self.pcap_procs[hostapd_constants.BAND_2G][1], |
| hostapd_constants.BAND_2G.upper()) |
| packets = rdpcap(pcap_fname) |
| self.verify_mac_not_found_in_pcap(self.soft_ap_factory_mac, packets) |
| self.verify_mac_not_found_in_pcap(self.sta_factory_mac, packets) |
| self.verify_mac_is_found_in_pcap(softap_mac, packets) |
| self.verify_mac_is_found_in_pcap(self.get_sta_mac_address(), packets) |
| |
| @test_tracker_info(uuid="3ca3f911-29f1-41fb-b836-4d25eac1669f") |
| def test_roaming_mac_randomization(self): |
| """test MAC randomization in the roaming scenario. |
| |
| Steps: |
| 1. Connect to network A on AP1, get randomized MAC. |
| 2. Set AP1 to MAX attenuation so that we roam to AP2. |
| 3. Wait for device to roam to AP2 and get randomized MAC. |
| 4. Veirfy that the device uses same AMC for both APs. |
| |
| """ |
| AP1_network = self.reference_networks[0]["5g"] |
| AP2_network = self.reference_networks[1]["5g"] |
| if "OpenWrtAP" in self.user_params: |
| AP1_network["bssid"] = self.bssid_map[0]["5g"][AP1_network["SSID"]] |
| AP2_network["bssid"] = self.bssid_map[1]["5g"][AP2_network["SSID"]] |
| wutils.set_attns(self.attenuators, "AP1_on_AP2_off", self.roaming_attn) |
| mac_before_roam = self.connect_to_network_and_verify_mac_randomization( |
| AP1_network) |
| wutils.trigger_roaming_and_validate(self.dut, self.attenuators, |
| "AP1_off_AP2_on", AP2_network, |
| self.roaming_attn) |
| mac_after_roam = self.get_randomized_mac(AP2_network) |
| if mac_after_roam != mac_before_roam: |
| raise signals.TestFailure( |
| "Randomized MAC address changed after " |
| "roaming from AP1 to AP2.\nMAC before roam = %s\nMAC after " |
| "roam = %s" % (mac_before_roam, mac_after_roam)) |
| wutils.trigger_roaming_and_validate(self.dut, self.attenuators, |
| "AP1_on_AP2_off", AP1_network, |
| self.roaming_attn) |
| mac_after_roam = self.get_randomized_mac(AP1_network) |
| if mac_after_roam != mac_before_roam: |
| raise signals.TestFailure( |
| "Randomized MAC address changed after " |
| "roaming from AP1 to AP2.\nMAC before roam = %s\nMAC after " |
| "roam = %s" % (mac_before_roam, mac_after_roam)) |
| |
| @test_tracker_info(uuid="17b12f1a-7c62-4188-b5a5-52d7a0bb7849") |
| def test_check_mac_sta_with_link_probe(self): |
| """Test to ensure Factory MAC is not exposed, using sniffer data. |
| |
| Steps: |
| 1. Configure and start the sniffer on 5GHz band. |
| 2. Connect to 5GHz network. |
| 3. Send link probes. |
| 4. Stop the sniffer. |
| 5. Invoke scapy to read the .pcap file. |
| 6. Read each packet summary and make sure Factory MAC is not used. |
| |
| """ |
| self.pcap_procs = wutils.start_pcap(self.packet_capture, 'dual', |
| self.test_name) |
| time.sleep(SHORT_TIMEOUT) |
| network = self.wpapsk_5g |
| rand_mac = self.connect_to_network_and_verify_mac_randomization( |
| network) |
| pcap_fname_bflink = '%s_%s.pcap' % \ |
| (self.pcap_procs[hostapd_constants.BAND_5G][1], |
| hostapd_constants.BAND_5G.upper()) |
| wutils.stop_pcap(self.packet_capture, self.pcap_procs, False) |
| time.sleep(SHORT_TIMEOUT) |
| packets_bflink = rdpcap(pcap_fname_bflink) |
| self.verify_mac_not_found_in_pcap(self.sta_factory_mac, packets_bflink) |
| self.verify_mac_is_found_in_pcap(rand_mac, packets_bflink) |
| self.pcap_procs = wutils.start_pcap(self.packet_capture, 'dual', |
| self.test_name) |
| time.sleep(SHORT_TIMEOUT) |
| wutils.send_link_probes(self.dut, 3, 3) |
| pcap_fname = '%s_%s.pcap' % \ |
| (self.pcap_procs[hostapd_constants.BAND_5G][1], |
| hostapd_constants.BAND_5G.upper()) |
| wutils.stop_pcap(self.packet_capture, self.pcap_procs, False) |
| time.sleep(SHORT_TIMEOUT) |
| packets = rdpcap(pcap_fname) |
| self.verify_mac_not_found_in_pcap(self.sta_factory_mac, packets) |
| self.verify_mac_is_found_in_pcap(rand_mac, packets) |
| |
| @test_tracker_info(uuid="1c2cc0fd-a340-40c4-b679-6acc5f526451") |
| def test_check_mac_in_wifi_scan(self): |
| """Test to ensure Factory MAC is not exposed, in Wi-Fi scans |
| |
| Steps: |
| 1. Configure and start the sniffer on both bands. |
| 2. Perform a full scan. |
| 3. Stop the sniffer. |
| 4. Invoke scapy to read the .pcap file. |
| 5. Read each packet summary and make sure Factory MAC is not used. |
| |
| """ |
| self.pcap_procs = wutils.start_pcap(self.packet_capture, 'dual', |
| self.test_name) |
| wutils.start_wifi_connection_scan(self.dut) |
| time.sleep(SHORT_TIMEOUT) |
| wutils.stop_pcap(self.packet_capture, self.pcap_procs, False) |
| pcap_fname = '%s_%s.pcap' % \ |
| (self.pcap_procs[hostapd_constants.BAND_2G][1], |
| hostapd_constants.BAND_2G.upper()) |
| packets = rdpcap(pcap_fname) |
| self.verify_mac_not_found_in_pcap(self.sta_factory_mac, packets) |
| |
| @test_tracker_info(uuid="7714d31f-bb08-4f29-b246-0ce1398a3c03") |
| def test_mac_randomization_for_network_suggestion(self): |
| """Add network suggestion and verify MAC randomization. |
| |
| Steps: |
| 1. Add a network suggestion and verify device connects to it. |
| 2. Verify the device uses randomized MAC address for this network. |
| """ |
| network_suggestion = self.reference_networks[0]["2g"] |
| self._add_suggestion_and_verify_mac_randomization(network_suggestion) |
| |
| @test_tracker_info(uuid="144ad0b4-b79d-4b1d-a8a9-3c612a76c32c") |
| def test_enhanced_mac_randomization_for_network_suggestion(self): |
| """Test enhanced MAC randomization. |
| |
| Steps: |
| 1. Add a network suggestion with enhanced mac randomization enabled. |
| 2. Connect to the network and verify the MAC address is random. |
| 3. Remove the suggestion network and add it back. |
| 4. Connect to the network. Verify the MAC address is random and |
| different from the randomized MAC observed in step 2. |
| """ |
| asserts.skip_if(not self.dut.droid.isSdkAtLeastS(), |
| "This feature is only supported on S and later.") |
| |
| network_suggestion = self.reference_networks[0]["5g"] |
| network_suggestion["enhancedMacRandomizationEnabled"] = True |
| |
| # add network suggestion with enhanced mac randomization |
| randomized_mac1 = self._add_suggestion_and_verify_mac_randomization( |
| network_suggestion) |
| |
| # remove network suggestion and verify no connection |
| self._remove_suggestion_and_verify_disconnect(network_suggestion) |
| |
| # add network suggestion and verify device connects back |
| randomized_mac2 = self._add_suggestion_and_verify_mac_randomization( |
| network_suggestion) |
| |
| # verify both randomized mac addrs are different |
| asserts.assert_true(randomized_mac1 != randomized_mac2, |
| "Randomized MAC addresses are same.") |