1#!/usr/bin/env python3.4 2# 3# Copyright 2019 - The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17import itertools 18import pprint 19import queue 20import re 21import time 22 23import acts.base_test 24import acts.signals as signals 25import acts_contrib.test_utils.wifi.wifi_test_utils as wutils 26import acts.utils 27 28from acts import asserts 29from acts.test_decorators import test_tracker_info 30from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G 31from acts_contrib.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G 32from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest 33from scapy.all import * 34from acts.controllers.ap_lib import hostapd_constants 35 36WifiEnums = wutils.WifiEnums 37 38# Default timeout used for reboot, toggle WiFi and Airplane mode, 39# for the system to settle down after the operation. 40DEFAULT_TIMEOUT = 10 41SHORT_TIMEOUT = 5 42 43# Constants for WiFi state change operations. 44FORGET = 1 45TOGGLE = 2 46REBOOT_DUT = 3 47REBOOT_AP = 4 48 49# MAC Randomization setting constants. 50RANDOMIZATION_NONE = 0 51RANDOMIZATION_PERSISTENT = 1 52 53 54class WifiMacRandomizationTest(WifiBaseTest): 55 """Tests for APIs in Android's WifiManager class. 56 57 Test Bed Requirement: 58 * Atleast one Android device and atleast two Access Points. 59 * Several Wi-Fi networks visible to the device. 60 """ 61 62 def setup_class(self): 63 super().setup_class() 64 65 self.dut = self.android_devices[0] 66 self.dut_client = self.android_devices[1] 67 wutils.wifi_test_device_init(self.dut) 68 wutils.wifi_test_device_init(self.dut_client) 69 req_params = ["sta_sta_supported_models", "dbs_supported_models", 70 "support_one_factory_mac_address", "roaming_attn"] 71 opt_param = [ 72 "open_network", "reference_networks", "wep_networks" 73 ] 74 self.unpack_userparams( 75 req_param_names=req_params, opt_param_names=opt_param) 76 77 if not hasattr(self, 'packet_capture'): 78 raise signals.TestFailure("Needs packet_capture attribute to " 79 "support sniffing.") 80 self.configure_packet_capture() 81 82 if "AccessPoint" in self.user_params: 83 self.legacy_configure_ap_and_start(wep_network=True, 84 ap_count=2) 85 elif "OpenWrtAP" in self.user_params: 86 self.configure_openwrt_ap_and_start(open_network=True, 87 wpa_network=True, 88 wep_network=True, 89 mirror_ap=True, 90 ap_count=2) 91 92 asserts.assert_true( 93 len(self.reference_networks) > 0, 94 "Need at least one reference network with psk.") 95 96 # Reboot device to reset factory MAC of wlan1 97 self.dut.reboot() 98 self.dut_client.reboot() 99 time.sleep(DEFAULT_TIMEOUT) 100 wutils.wifi_toggle_state(self.dut, True) 101 wutils.wifi_toggle_state(self.dut_client, True) 102 if self.dut.model in self.support_one_factory_mac_address: 103 self.soft_ap_factory_mac = (self.dut.droid 104 .wifigetFactorymacAddresses()[0]) 105 else: 106 self.soft_ap_factory_mac = self.get_soft_ap_mac_address() 107 self.sta_factory_mac = self.dut.droid.wifigetFactorymacAddresses()[0] 108 109 self.wpapsk_2g = self.reference_networks[0]["2g"] 110 self.wpapsk_5g = self.reference_networks[0]["5g"] 111 self.wep_2g = self.wep_networks[0]["2g"] 112 self.wep_5g = self.wep_networks[0]["5g"] 113 self.open_2g = self.open_network[0]["2g"] 114 self.open_5g = self.open_network[0]["5g"] 115 116 def setup_test(self): 117 super().setup_test() 118 for ad in self.android_devices: 119 ad.droid.wakeLockAcquireBright() 120 ad.droid.wakeUpNow() 121 wutils.wifi_toggle_state(ad, True) 122 123 def teardown_test(self): 124 super().teardown_test() 125 for ad in self.android_devices: 126 ad.droid.wakeLockRelease() 127 ad.droid.goToSleepNow() 128 self.dut.droid.wifiRemoveNetworkSuggestions([]) 129 wutils.reset_wifi(self.dut) 130 wutils.reset_wifi(self.dut_client) 131 132 def teardown_class(self): 133 if "AccessPoint" in self.user_params: 134 del self.user_params["reference_networks"] 135 del self.user_params["open_network"] 136 del self.user_params["wep_networks"] 137 138 139 """Helper Functions""" 140 141 142 def get_randomized_mac(self, network): 143 """Get the randomized MAC address. 144 145 Args: 146 network: dict, network information. 147 148 Returns: 149 The randomized MAC address string for the network. 150 151 """ 152 return self.dut.droid.wifigetRandomizedMacAddress(network) 153 154 def connect_to_network_and_verify_mac_randomization(self, network, 155 status=RANDOMIZATION_PERSISTENT): 156 """Connect to the given network and verify MAC. 157 158 Args: 159 network: dict, the network information. 160 status: int, MAC randomization level. 161 162 Returns: 163 The randomized MAC addresss string. 164 165 """ 166 wutils.connect_to_wifi_network(self.dut, network) 167 return self.verify_mac_randomization(network, status=status) 168 169 def verify_mac_randomization_and_add_to_list(self, network, mac_list): 170 """Connect to a network and populate it's MAC in a reference list, 171 that will be used to verify any repeated MAC addresses. 172 173 Args: 174 network: dict, the network information. 175 mac_list: list of MAC addresss strings. 176 177 """ 178 rand_mac = self.connect_to_network_and_verify_mac_randomization( 179 network) 180 if rand_mac in mac_list: 181 raise signals.TestFailure('A new Randomized MAC was not generated ' 182 ' for this network %s.' % network) 183 mac_list.append(rand_mac) 184 185 def verify_mac_randomization(self, network, status=RANDOMIZATION_PERSISTENT): 186 """Get the various types of MAC addresses for the device and verify. 187 188 Args: 189 network: dict, the network information. 190 status: int, MAC randomization level. 191 192 Returns: 193 The randomized MAC address string for the network. 194 195 """ 196 randomized_mac = self.get_randomized_mac(network) 197 default_mac = self.get_sta_mac_address() 198 self.log.info("Factory MAC = %s\nRandomized MAC = %s\nDefault MAC = %s" % 199 (self.sta_factory_mac, randomized_mac, default_mac)) 200 message = ('Randomized MAC and Factory MAC are the same. ' 201 'Randomized MAC = %s, Factory MAC = %s' % (randomized_mac, self.sta_factory_mac)) 202 asserts.assert_true(randomized_mac != self.sta_factory_mac, message) 203 if status == RANDOMIZATION_NONE: 204 asserts.assert_true(default_mac == self.sta_factory_mac, "Connection is not " 205 "using Factory MAC as the default MAC.") 206 else: 207 message = ('Connection is not using randomized MAC as the default MAC. ' 208 'Randomized MAC = %s, Deafult MAC = %s' % (randomized_mac, default_mac)) 209 asserts.assert_true(default_mac == randomized_mac, message) 210 return randomized_mac 211 212 def check_mac_persistence(self, network, condition): 213 """Check if the MAC is persistent after carrying out specific operations 214 like forget WiFi, toggle WiFi, reboot device and AP. 215 216 Args: 217 network: dict, The network information. 218 condition: int, value to trigger certain operation on the device. 219 220 Raises: 221 TestFaikure is the MAC is not persistent. 222 223 """ 224 rand_mac1 = self.connect_to_network_and_verify_mac_randomization(network) 225 226 if condition == FORGET: 227 wutils.wifi_forget_network(self.dut, network['SSID']) 228 229 elif condition == TOGGLE: 230 wutils.wifi_toggle_state(self.dut, False) 231 wutils.wifi_toggle_state(self.dut, True) 232 233 elif condition == REBOOT_DUT: 234 self.dut.reboot() 235 time.sleep(DEFAULT_TIMEOUT) 236 237 elif condition == REBOOT_AP: 238 wutils.turn_ap_off(self, 1) 239 time.sleep(DEFAULT_TIMEOUT) 240 wutils.turn_ap_on(self, 1) 241 time.sleep(DEFAULT_TIMEOUT) 242 243 rand_mac2 = self.connect_to_network_and_verify_mac_randomization(network) 244 245 if rand_mac1 != rand_mac2: 246 raise signals.TestFailure('Randomized MAC is not persistent after ' 247 'forgetting networ. Old MAC = %s New MAC' 248 ' = %s' % (rand_mac1, rand_mac2)) 249 250 def verify_mac_not_found_in_pcap(self, mac, packets): 251 for pkt in packets: 252 self.log.debug("Packet Summary = %s" % pkt.summary()) 253 if mac in pkt.summary(): 254 raise signals.TestFailure("Caught Factory MAC in packet sniffer" 255 "Packet = %s Device = %s" 256 % (pkt.show(), self.dut)) 257 258 def verify_mac_is_found_in_pcap(self, mac, packets): 259 for pkt in packets: 260 self.log.debug("Packet Summary = %s" % pkt.summary()) 261 if mac in pkt.summary(): 262 return 263 raise signals.TestFailure("Did not find MAC = %s in packet sniffer." 264 "for device %s" % (mac, self.dut)) 265 266 def get_sta_mac_address(self): 267 """Gets the current MAC address being used for client mode.""" 268 out = self.dut.adb.shell("ifconfig wlan0") 269 res = re.match(".* HWaddr (\S+).*", out, re.S) 270 return res.group(1) 271 272 def get_soft_ap_mac_address(self): 273 """Gets the current MAC address being used for SoftAp.""" 274 if self.dut.model in self.sta_sta_supported_models: 275 out = self.dut.adb.shell("ifconfig wlan2") 276 return re.match(".* HWaddr (\S+).*", out, re.S).group(1) 277 if self.dut.model in self.dbs_supported_models: 278 out = self.dut.adb.shell("ifconfig wlan1") 279 return re.match(".* HWaddr (\S+).*", out, re.S).group(1) 280 else: 281 return self.get_sta_mac_address() 282 283 def _add_suggestion_and_verify_mac_randomization(self, network_suggestion): 284 """Add wifi network suggestion and verify MAC randomization. 285 286 Args: 287 network_suggestion: network suggestion to add. 288 289 Returns: 290 Randomized MAC address. 291 """ 292 self.log.info("Adding network suggestion") 293 asserts.assert_true( 294 self.dut.droid.wifiAddNetworkSuggestions([network_suggestion]), 295 "Failed to add suggestions") 296 wutils.start_wifi_connection_scan_and_ensure_network_found( 297 self.dut, network_suggestion[WifiEnums.SSID_KEY]) 298 wutils.wait_for_connect(self.dut, network_suggestion[WifiEnums.SSID_KEY]) 299 default_mac = self.get_sta_mac_address() 300 randomized_mac = self.dut.droid.wifiGetConnectionInfo()["mac_address"] 301 self.log.info("Factory MAC = %s\nRandomized MAC = %s\nDefault MAC = %s" % 302 (self.sta_factory_mac, randomized_mac, default_mac)) 303 asserts.assert_true( 304 default_mac == randomized_mac, 305 "Connection is not using randomized MAC as the default MAC.") 306 return randomized_mac 307 308 def _remove_suggestion_and_verify_disconnect(self, network_suggestion): 309 """Remove wifi network suggestion and verify device disconnects. 310 311 Args: 312 network_suggestion: network suggestion to remove. 313 """ 314 self.dut.log.info("Removing network suggestions") 315 asserts.assert_true( 316 self.dut.droid.wifiRemoveNetworkSuggestions([network_suggestion]), 317 "Failed to remove suggestions") 318 wutils.wait_for_disconnect(self.dut) 319 self.dut.ed.clear_all_events() 320 asserts.assert_false( 321 wutils.wait_for_connect( 322 self.dut, 323 network_suggestion[WifiEnums.SSID_KEY], 324 assert_on_fail=False), 325 "Device should not connect back") 326 327 """Tests""" 328 329 330 @test_tracker_info(uuid="2dd0a05e-a318-45a6-81cd-962e098fa242") 331 def test_set_mac_randomization_to_none(self): 332 self.pcap_procs = wutils.start_pcap( 333 self.packet_capture, 'dual', self.test_name) 334 network = self.wpapsk_2g 335 # Set macRandomizationSetting to RANDOMIZATION_NONE. 336 network["macRand"] = RANDOMIZATION_NONE 337 self.connect_to_network_and_verify_mac_randomization(network, 338 status=RANDOMIZATION_NONE) 339 pcap_fname = '%s_%s.pcap' % \ 340 (self.pcap_procs[hostapd_constants.BAND_2G][1], 341 hostapd_constants.BAND_2G.upper()) 342 time.sleep(SHORT_TIMEOUT) 343 wutils.stop_pcap(self.packet_capture, self.pcap_procs, False) 344 packets = rdpcap(pcap_fname) 345 self.verify_mac_is_found_in_pcap(self.sta_factory_mac, packets) 346 347 @test_tracker_info(uuid="d9e64202-02d5-421a-967c-42e45f1f7f91") 348 def test_mac_randomization_wpapsk(self): 349 """Verify MAC randomization for a WPA network. 350 351 Steps: 352 1. Connect to WPA network. 353 2. Get the Factory, Randomized and Default MACs. 354 3. Verify randomized MAC is the default MAC for the device. 355 356 """ 357 self.connect_to_network_and_verify_mac_randomization(self.wpapsk_2g) 358 359 @test_tracker_info(uuid="b5be7c53-2edf-449e-ba70-a1fb7acf735e") 360 def test_mac_randomization_wep(self): 361 """Verify MAC randomization for a WEP network. 362 363 Steps: 364 1. Connect to WEP network. 365 2. Get the Factory, Randomized and Default MACs. 366 3. Verify randomized MAC is the default MAC for the device. 367 368 """ 369 self.connect_to_network_and_verify_mac_randomization(self.wep_2g) 370 371 @test_tracker_info(uuid="f5347ac0-68d5-4882-a58d-1bd0d575503c") 372 def test_mac_randomization_open(self): 373 """Verify MAC randomization for a open network. 374 375 Steps: 376 1. Connect to open network. 377 2. Get the Factory, Randomized and Default MACs. 378 3. Verify randomized MAC is the default MAC for the device. 379 380 """ 381 self.connect_to_network_and_verify_mac_randomization(self.open_2g) 382 383 @test_tracker_info(uuid="5d260421-2adf-4ace-b281-3d15aec39b2a") 384 def test_persistent_mac_after_forget(self): 385 """Check if MAC is persistent after forgetting/adding a network. 386 387 Steps: 388 1. Connect to WPA network and get the randomized MAC. 389 2. Forget the network. 390 3. Connect to the same network again. 391 4. Verify randomized MAC has not changed. 392 393 """ 394 self.check_mac_persistence(self.wpapsk_2g, FORGET) 395 396 @test_tracker_info(uuid="09d40a93-ead2-45ca-9905-14b05fd79f34") 397 def test_persistent_mac_after_toggle(self): 398 """Check if MAC is persistent after toggling WiFi network. 399 400 Steps: 401 1. Connect to WPA network and get the randomized MAC. 402 2. Turn WiFi ON/OFF. 403 3. Connect to the same network again. 404 4. Verify randomized MAC has not changed. 405 406 """ 407 self.check_mac_persistence(self.wpapsk_2g, TOGGLE) 408 409 @test_tracker_info(uuid="b3aa514f-8562-44e8-bfe0-4ecab9af165b") 410 def test_persistent_mac_after_device_reboot(self): 411 """Check if MAC is persistent after a device reboot. 412 413 Steps: 414 1. Connect to WPA network and get the randomized MAC. 415 2. Reboot DUT. 416 3. Connect to the same network again. 417 4. Verify randomized MAC has not changed. 418 419 """ 420 self.check_mac_persistence(self.wpapsk_2g, REBOOT_DUT) 421 422 # Disable reboot test for debugging purpose. 423 #@test_tracker_info(uuid="82d691a0-22e4-4a3d-9596-e150531fcd34") 424 def persistent_mac_after_ap_reboot(self): 425 """Check if MAC is persistent after AP reboots itself. 426 427 Steps: 428 1. Connect to WPA network and get the randomized MAC. 429 2. Reboot AP(basically restart hostapd in our case). 430 3. Connect to the same network again. 431 4. Verify randomized MAC has not changed. 432 433 """ 434 self.check_mac_persistence(self.wpapsk_2g, REBOOT_AP) 435 436 @test_tracker_info(uuid="e1f33dbc-808c-4e61-8a4a-3a72c1f63c7e") 437 def test_mac_randomization_multiple_networks(self): 438 """Connect to multiple networks and verify same MAC. 439 440 Steps: 441 1. Connect to network A, get randomizd MAC. 442 2. Conenct to network B, get randomized MAC. 443 3. Connect back to network A and verify same MAC. 444 4. Connect back to network B and verify same MAC. 445 446 """ 447 mac_list = list() 448 449 # Connect to two different networks and get randomized MAC addresses. 450 self.verify_mac_randomization_and_add_to_list(self.wpapsk_2g, mac_list) 451 self.verify_mac_randomization_and_add_to_list(self.open_2g, mac_list) 452 453 # Connect to the previous network and check MAC is persistent. 454 mac_wpapsk = self.connect_to_network_and_verify_mac_randomization( 455 self.wpapsk_2g) 456 msg = ('Randomized MAC is not persistent for this network %s. Old MAC = ' 457 '%s \nNew MAC = %s') 458 if mac_wpapsk != mac_list[0]: 459 raise signals.TestFailure(msg % (self.wpapsk_5g, mac_list[0], mac_wpapsk)) 460 mac_open = self.connect_to_network_and_verify_mac_randomization( 461 self.open_2g) 462 if mac_open != mac_list[1]: 463 raise signals.TestFailure(msg %(self.open_5g, mac_list[1], mac_open)) 464 465 @test_tracker_info(uuid="edb5a0e5-7f3b-4147-b1d3-48ad7ad9799e") 466 def test_mac_randomization_different_APs(self): 467 """Verify randomization using two different APs. 468 469 Steps: 470 1. Connect to network A on AP1, get the randomized MAC. 471 2. Connect to network B on AP2, get the randomized MAC. 472 3. Veirfy the two MACs are different. 473 474 """ 475 ap1 = self.wpapsk_2g 476 ap2 = self.reference_networks[1]["5g"] 477 mac_ap1 = self.connect_to_network_and_verify_mac_randomization(ap1) 478 mac_ap2 = self.connect_to_network_and_verify_mac_randomization(ap2) 479 if mac_ap1 == mac_ap2: 480 raise signals.TestFailure("Same MAC address was generated for both " 481 "APs: %s" % mac_ap1) 482 483 @test_tracker_info(uuid="b815e9ce-bccd-4fc3-9774-1e1bc123a2a8") 484 def test_mac_randomization_ap_sta(self): 485 """Bring up STA and softAP and verify MAC randomization. 486 487 Steps: 488 1. Connect to a network and get randomized MAC. 489 2. Bring up softAP on the DUT. 490 3. Connect to softAP network on the client and get MAC. 491 4. Verify AP and STA use different randomized MACs. 492 5. Find the channel of the SoftAp network. 493 6. Configure sniffer on that channel. 494 7. Verify the factory MAC is not leaked. 495 496 """ 497 wutils.set_wifi_country_code(self.dut, wutils.WifiEnums.CountryCode.US) 498 wutils.set_wifi_country_code(self.dut_client, wutils.WifiEnums.CountryCode.US) 499 mac_sta = self.connect_to_network_and_verify_mac_randomization( 500 self.wpapsk_2g) 501 softap = wutils.start_softap_and_verify(self, WIFI_CONFIG_APBAND_2G) 502 wutils.connect_to_wifi_network(self.dut_client, softap) 503 softap_info = self.dut_client.droid.wifiGetConnectionInfo() 504 mac_ap = softap_info['mac_address'] 505 if mac_sta == mac_ap: 506 raise signals.TestFailure("Same MAC address was used for both " 507 "AP and STA: %s" % mac_sta) 508 509 # Verify SoftAp MAC is randomized 510 softap_mac = self.get_soft_ap_mac_address() 511 message = ('Randomized SoftAp MAC and Factory SoftAp MAC are the same. ' 512 'Randomized SoftAp MAC = %s, Factory SoftAp MAC = %s' 513 % (softap_mac, self.soft_ap_factory_mac)) 514 asserts.assert_true(softap_mac != self.soft_ap_factory_mac, message) 515 516 softap_channel = hostapd_constants.CHANNEL_MAP[softap_info['frequency']] 517 self.log.info("softap_channel = %s\n" % (softap_channel)) 518 result = self.packet_capture.configure_monitor_mode( 519 hostapd_constants.BAND_2G, softap_channel) 520 if not result: 521 raise ValueError("Failed to configure channel for 2G band") 522 self.pcap_procs = wutils.start_pcap( 523 self.packet_capture, 'dual', self.test_name) 524 # re-connect to the softAp network after sniffer is started 525 wutils.connect_to_wifi_network(self.dut_client, self.wpapsk_2g) 526 wutils.connect_to_wifi_network(self.dut_client, softap) 527 time.sleep(SHORT_TIMEOUT) 528 wutils.stop_pcap(self.packet_capture, self.pcap_procs, False) 529 pcap_fname = '%s_%s.pcap' % \ 530 (self.pcap_procs[hostapd_constants.BAND_2G][1], 531 hostapd_constants.BAND_2G.upper()) 532 packets = rdpcap(pcap_fname) 533 self.verify_mac_not_found_in_pcap(self.soft_ap_factory_mac, packets) 534 self.verify_mac_not_found_in_pcap(self.sta_factory_mac, packets) 535 self.verify_mac_is_found_in_pcap(softap_mac, packets) 536 self.verify_mac_is_found_in_pcap(self.get_sta_mac_address(), packets) 537 538 @test_tracker_info(uuid="3ca3f911-29f1-41fb-b836-4d25eac1669f") 539 def test_roaming_mac_randomization(self): 540 """test MAC randomization in the roaming scenario. 541 542 Steps: 543 1. Connect to network A on AP1, get randomized MAC. 544 2. Set AP1 to MAX attenuation so that we roam to AP2. 545 3. Wait for device to roam to AP2 and get randomized MAC. 546 4. Veirfy that the device uses same AMC for both APs. 547 548 """ 549 AP1_network = self.reference_networks[0]["5g"] 550 AP2_network = self.reference_networks[1]["5g"] 551 if "OpenWrtAP" in self.user_params: 552 AP1_network["bssid"] = self.bssid_map[0]["5g"][AP1_network["SSID"]] 553 AP2_network["bssid"] = self.bssid_map[1]["5g"][AP2_network["SSID"]] 554 wutils.set_attns(self.attenuators, "AP1_on_AP2_off", self.roaming_attn) 555 mac_before_roam = self.connect_to_network_and_verify_mac_randomization( 556 AP1_network) 557 wutils.trigger_roaming_and_validate(self.dut, self.attenuators, 558 "AP1_off_AP2_on", AP2_network, self.roaming_attn) 559 mac_after_roam = self.get_randomized_mac(AP2_network) 560 if mac_after_roam != mac_before_roam: 561 raise signals.TestFailure("Randomized MAC address changed after " 562 "roaming from AP1 to AP2.\nMAC before roam = %s\nMAC after " 563 "roam = %s" %(mac_before_roam, mac_after_roam)) 564 wutils.trigger_roaming_and_validate(self.dut, self.attenuators, 565 "AP1_on_AP2_off", AP1_network, self.roaming_attn) 566 mac_after_roam = self.get_randomized_mac(AP1_network) 567 if mac_after_roam != mac_before_roam: 568 raise signals.TestFailure("Randomized MAC address changed after " 569 "roaming from AP1 to AP2.\nMAC before roam = %s\nMAC after " 570 "roam = %s" %(mac_before_roam, mac_after_roam)) 571 572 @test_tracker_info(uuid="17b12f1a-7c62-4188-b5a5-52d7a0bb7849") 573 def test_check_mac_sta_with_link_probe(self): 574 """Test to ensure Factory MAC is not exposed, using sniffer data. 575 576 Steps: 577 1. Configure and start the sniffer on 5GHz band. 578 2. Connect to 5GHz network. 579 3. Send link probes. 580 4. Stop the sniffer. 581 5. Invoke scapy to read the .pcap file. 582 6. Read each packet summary and make sure Factory MAC is not used. 583 584 """ 585 self.pcap_procs = wutils.start_pcap( 586 self.packet_capture, 'dual', self.test_name) 587 time.sleep(SHORT_TIMEOUT) 588 network = self.wpapsk_5g 589 rand_mac = self.connect_to_network_and_verify_mac_randomization(network) 590 pcap_fname_bflink = '%s_%s.pcap' % \ 591 (self.pcap_procs[hostapd_constants.BAND_5G][1], 592 hostapd_constants.BAND_5G.upper()) 593 wutils.stop_pcap(self.packet_capture, self.pcap_procs, False) 594 time.sleep(SHORT_TIMEOUT) 595 packets_bflink = rdpcap(pcap_fname_bflink) 596 self.verify_mac_not_found_in_pcap(self.sta_factory_mac, packets_bflink) 597 self.verify_mac_is_found_in_pcap(rand_mac, packets_bflink) 598 self.pcap_procs = wutils.start_pcap( 599 self.packet_capture, 'dual', self.test_name) 600 time.sleep(SHORT_TIMEOUT) 601 wutils.send_link_probes(self.dut, 3, 3) 602 pcap_fname = '%s_%s.pcap' % \ 603 (self.pcap_procs[hostapd_constants.BAND_5G][1], 604 hostapd_constants.BAND_5G.upper()) 605 wutils.stop_pcap(self.packet_capture, self.pcap_procs, False) 606 time.sleep(SHORT_TIMEOUT) 607 packets = rdpcap(pcap_fname) 608 self.verify_mac_not_found_in_pcap(self.sta_factory_mac, packets) 609 self.verify_mac_is_found_in_pcap(rand_mac, packets) 610 611 @test_tracker_info(uuid="1c2cc0fd-a340-40c4-b679-6acc5f526451") 612 def test_check_mac_in_wifi_scan(self): 613 """Test to ensure Factory MAC is not exposed, in Wi-Fi scans 614 615 Steps: 616 1. Configure and start the sniffer on both bands. 617 2. Perform a full scan. 618 3. Stop the sniffer. 619 4. Invoke scapy to read the .pcap file. 620 5. Read each packet summary and make sure Factory MAC is not used. 621 622 """ 623 self.pcap_procs = wutils.start_pcap( 624 self.packet_capture, 'dual', self.test_name) 625 wutils.start_wifi_connection_scan(self.dut) 626 time.sleep(SHORT_TIMEOUT) 627 wutils.stop_pcap(self.packet_capture, self.pcap_procs, False) 628 pcap_fname = '%s_%s.pcap' % \ 629 (self.pcap_procs[hostapd_constants.BAND_2G][1], 630 hostapd_constants.BAND_2G.upper()) 631 packets = rdpcap(pcap_fname) 632 self.verify_mac_not_found_in_pcap(self.sta_factory_mac, packets) 633 634 @test_tracker_info(uuid="7714d31f-bb08-4f29-b246-0ce1398a3c03") 635 def test_mac_randomization_for_network_suggestion(self): 636 """Add network suggestion and verify MAC randomization. 637 638 Steps: 639 1. Add a network suggestion and verify device connects to it. 640 2. Verify the device uses randomized MAC address for this network. 641 """ 642 network_suggestion = self.reference_networks[0]["5g"] 643 self._add_suggestion_and_verify_mac_randomization(network_suggestion) 644 645 @test_tracker_info(uuid="144ad0b4-b79d-4b1d-a8a9-3c612a76c32c") 646 def test_enhanced_mac_randomization_for_network_suggestion(self): 647 """Test enhanced MAC randomization. 648 649 Steps: 650 1. Add a network suggestion with enhanced mac randomization enabled. 651 2. Connect to the network and verify the MAC address is random. 652 3. Remove the suggestion network and add it back. 653 4. Connect to the network. Verify the MAC address is random and 654 different from the randomized MAC observed in step 2. 655 """ 656 asserts.skip_if(not self.dut.droid.isSdkAtLeastS(), 657 "This feature is only supported on S and later.") 658 659 network_suggestion = self.reference_networks[0]["5g"] 660 network_suggestion["enhancedMacRandomizationEnabled"] = True 661 662 # add network suggestion with enhanced mac randomization 663 randomized_mac1 = self._add_suggestion_and_verify_mac_randomization( 664 network_suggestion) 665 666 # remove network suggestion and verify no connection 667 self._remove_suggestion_and_verify_disconnect(network_suggestion) 668 669 # add network suggestion and verify device connects back 670 randomized_mac2 = self._add_suggestion_and_verify_mac_randomization( 671 network_suggestion) 672 673 # verify both randomized mac addrs are different 674 asserts.assert_true(randomized_mac1 != randomized_mac2, 675 "Randomized MAC addresses are same.") 676