blob: bfb9491a78e8ceeca4a7f77093217c7c38661420 [file] [log] [blame]
# Copyright 2017 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import logging
import time
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros.network import tcpdump_analyzer
from autotest_lib.server.cros.network import hostap_config
from autotest_lib.server.cros.network import wifi_cell_test_base
class RandomMACAddressTestBase(wifi_cell_test_base.WiFiCellTestBase):
"""An abstract base class for MAC address randomization tests in WiFi cells.
MAC address randomization tests will test the ability of the DUT to
successfully randomize the MAC address it sends in probe requests when
such a feature is supported and configured, and that it does not do so
otherwise.
"""
# Approximate number of seconds to perform a full scan.
REQUEST_SCAN_DELAY = 5
# Default number of shill scans to run.
DEFAULT_NUM_SCANS = 5
def initialize(self, host):
"""Generate the HostapConfig used by the AP."""
self._ap_config = hostap_config.HostapConfig(channel=1)
def warmup(self, host, raw_cmdline_args, additional_params=None):
super(RandomMACAddressTestBase, self).warmup(
host, raw_cmdline_args, additional_params)
self.context.configure(self._ap_config)
def start_capture(self):
"""
Start packet capture.
"""
logging.debug('Starting packet capture')
self.context.capture_host.start_capture(
self._ap_config.frequency,
width_type=self._ap_config.packet_capture_mode)
def request_scans(self, num_scans=DEFAULT_NUM_SCANS):
"""
Helper to request a few scans with the configured randomization.
@param num_scans: The number of scans to perform.
"""
for _ in range(num_scans):
# Request scan through shill rather than iw because iw won't
# set the random MAC flag in the scan request netlink packet.
self.context.client.shill.request_scan()
time.sleep(self.REQUEST_SCAN_DELAY)
def _frame_matches_ssid(self, frame):
# Empty string is a wildcard SSID.
return frame.ssid == '' or frame.ssid == self.context.router.get_ssid()
def stop_capture_and_get_probe_requests(self):
"""
Stop packet capture and return probe requests from the DUT.
have the hardware MAC address.
"""
logging.debug('Stopping packet capture')
results = self.context.capture_host.stop_capture()
if len(results) != 1:
raise error.TestError('Expected to generate one packet '
'capture but got %d captures instead.',
len(results))
logging.debug('Analyzing packet capture...')
# Get all the frames in chronological order.
frames = tcpdump_analyzer.get_frames(
results[0].local_pcap_path,
tcpdump_analyzer.WLAN_PROBE_REQ_ACCEPTOR, reject_bad_fcs=True,
reject_low_signal=True)
return [frame for frame in frames if self._frame_matches_ssid(frame)]