def test_sta_dynamic_random_mac_addr_scan_keep_oui(dev, apdev): """Dynamically added wpa_supplicant interface and random MAC address for scan (keep OUI)""" params = hostapd.wpa2_params(ssid="sta-dynamic", passphrase="12345678") hapd = hostapd.add_ap(apdev[0]['ifname'], params) wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') wpas.interface_add("wlan5") addr0 = wpas.get_driver_status_field("addr") wpas.request("SET preassoc_mac_addr 2") wpas.request("SET rand_addr_lifetime 0") id = wpas.connect("sta-dynamic", psk="12345678", scan_freq="2412") addr1 = wpas.get_driver_status_field("addr") if addr0 != addr1: raise Exception("Random MAC address used unexpectedly")
def test_sta_dynamic_ext_mac_addr_change(dev, apdev): """Dynamically added wpa_supplicant interface with external MAC address change""" params = hostapd.wpa2_params(ssid="sta-dynamic", passphrase="12345678") hapd = hostapd.add_ap(apdev[0], params) logger.info("Create a dynamic wpa_supplicant interface and connect") wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') wpas.interface_add("wlan5") wpas.connect("sta-dynamic", psk="12345678", scan_freq="2412") hwsim_utils.test_connectivity(wpas, hapd) subprocess.call(['ifconfig', wpas.ifname, 'down']) wpas.wait_disconnected(timeout=10) if wpas.get_status_field("wpa_state") != "INTERFACE_DISABLED": raise Exception("Unexpected wpa_state") prev_addr = wpas.p2p_interface_addr() new_addr = '02:11:22:33:44:55' try: subprocess.call( ['ip', 'link', 'set', 'dev', wpas.ifname, 'address', new_addr]) subprocess.call(['ifconfig', wpas.ifname, 'up']) wpas.wait_connected(timeout=15, error="Reconnection not reported") if wpas.get_driver_status_field('addr') != new_addr: raise Exception("Address change not reported") hwsim_utils.test_connectivity(wpas, hapd) sta = hapd.get_sta(new_addr) if sta['addr'] != new_addr: raise Exception("STA association with new address not found") finally: subprocess.call(['ifconfig', wpas.ifname, 'down']) subprocess.call( ['ip', 'link', 'set', 'dev', wpas.ifname, 'address', prev_addr]) subprocess.call(['ifconfig', wpas.ifname, 'up'])
def test_cfg80211_tx_frame(dev, apdev, params): """cfg80211 offchannel TX frame command""" dev[0].p2p_start_go(freq='2412') go = WpaSupplicant(dev[0].group_ifname) frame = binascii.unhexlify("d0000000020000000100" + go.own_addr().replace(':', '') + "02000000010000000409506f9a090001dd5e506f9a0902020025080401001f0502006414060500585804510b0906000200000000000b1000585804510b0102030405060708090a0b0d1d000200000000000108000000000000000000101100084465766963652041110500585804510bdd190050f204104a0001101012000200011049000600372a000120") ifindex = int(go.get_driver_status_field("ifindex")) res = nl80211_frame(go, ifindex, frame, freq=2422, duration=500, offchannel_tx_ok=True) time.sleep(0.1) # note: Uncommenting this seems to remove the incorrect channel issue #nl80211_frame_wait_cancel(dev[0], ifindex, res[nl80211_attr['COOKIE']]) # note: this Action frame ends up getting sent incorrectly on 2422 MHz nl80211_frame(go, ifindex, frame, freq=2412) time.sleep(1.5) # note: also the Deauthenticate frame sent by the GO going down ends up # being transmitted incorrectly on 2422 MHz. del go out = run_tshark(os.path.join(params['logdir'], "hwsim0.pcapng"), "wlan.fc.type_subtype == 13", ["radiotap.channel.freq"]) if out is not None: freq = out.splitlines() if len(freq) != 2: raise Exception("Unexpected number of Action frames (%d)" % len(freq)) if freq[0] != "2422": raise Exception("First Action frame on unexpected channel: %s MHz" % freq[0]) if freq[1] != "2412": raise Exception("Second Action frame on unexpected channel: %s MHz" % freq[1])
def test_sta_dynamic_ext_mac_addr_change(dev, apdev): """Dynamically added wpa_supplicant interface with external MAC address change""" params = hostapd.wpa2_params(ssid="sta-dynamic", passphrase="12345678") hapd = hostapd.add_ap(apdev[0], params) logger.info("Create a dynamic wpa_supplicant interface and connect") wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') wpas.interface_add("wlan5") wpas.connect("sta-dynamic", psk="12345678", scan_freq="2412") hwsim_utils.test_connectivity(wpas, hapd) subprocess.call(['ifconfig', wpas.ifname, 'down']) wpas.wait_disconnected(timeout=10) if wpas.get_status_field("wpa_state") != "INTERFACE_DISABLED": raise Exception("Unexpected wpa_state") prev_addr = wpas.p2p_interface_addr() new_addr = '02:11:22:33:44:55' try: subprocess.call(['ip', 'link', 'set', 'dev', wpas.ifname, 'address', new_addr]) subprocess.call(['ifconfig', wpas.ifname, 'up']) wpas.wait_connected(timeout=15, error="Reconnection not reported") if wpas.get_driver_status_field('addr') != new_addr: raise Exception("Address change not reported") hwsim_utils.test_connectivity(wpas, hapd) sta = hapd.get_sta(new_addr) if sta['addr'] != new_addr: raise Exception("STA association with new address not found") finally: subprocess.call(['ifconfig', wpas.ifname, 'down']) subprocess.call(['ip', 'link', 'set', 'dev', wpas.ifname, 'address', prev_addr]) subprocess.call(['ifconfig', wpas.ifname, 'up'])
def test_cfg80211_tx_frame(dev, apdev, params): """cfg80211 offchannel TX frame command""" dev[0].p2p_start_go(freq='2412') go = WpaSupplicant(dev[0].group_ifname) frame = binascii.unhexlify("d0000000020000000100" + go.own_addr().translate(None, ':') + "02000000010000000409506f9a090001dd5e506f9a0902020025080401001f0502006414060500585804510b0906000200000000000b1000585804510b0102030405060708090a0b0d1d000200000000000108000000000000000000101100084465766963652041110500585804510bdd190050f204104a0001101012000200011049000600372a000120") ifindex = int(go.get_driver_status_field("ifindex")) res = nl80211_frame(go, ifindex, frame, freq=2422, duration=500, offchannel_tx_ok=True) time.sleep(0.1) # note: Uncommenting this seems to remove the incorrect channel issue #nl80211_frame_wait_cancel(dev[0], ifindex, res[nl80211_attr['COOKIE']]) # note: this Action frame ends up getting sent incorrectly on 2422 MHz nl80211_frame(go, ifindex, frame, freq=2412) time.sleep(1.5) # note: also the Deauthenticate frame sent by the GO going down ends up # being transmitted incorrectly on 2422 MHz. del go out = run_tshark(os.path.join(params['logdir'], "hwsim0.pcapng"), "wlan.fc.type_subtype == 13", ["radiotap.channel.freq"]) if out is not None: freq = out.splitlines() if len(freq) != 2: raise Exception("Unexpected number of Action frames (%d)" % len(freq)) if freq[0] != "2422": raise Exception("First Action frame on unexpected channel: %s MHz" % freq[0]) if freq[1] != "2412": raise Exception("Second Action frame on unexpected channel: %s MHz" % freq[1])
def test_sta_dynamic_random_mac_addr_keep_oui(dev, apdev): """Dynamically added wpa_supplicant interface and random MAC address (keep OUI)""" params = hostapd.wpa2_params(ssid="sta-dynamic", passphrase="12345678") hapd = hostapd.add_ap(apdev[0]['ifname'], params) wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') wpas.interface_add("wlan5") addr0 = wpas.get_driver_status_field("addr") wpas.request("SET preassoc_mac_addr 2") wpas.request("SET rand_addr_lifetime 0") id = wpas.connect("sta-dynamic", psk="12345678", mac_addr="2", scan_freq="2412") addr1 = wpas.get_driver_status_field("addr") if addr0 == addr1: raise Exception("Random MAC address not used") if addr1[3:8] != addr0[3:8]: raise Exception("OUI was not kept") sta = hapd.get_sta(addr0) if sta['addr'] != "FAIL": raise Exception("Unexpected STA association with permanent address") sta = hapd.get_sta(addr1) if sta['addr'] != addr1: raise Exception("STA association with random address not found") wpas.request("DISCONNECT") wpas.connect_network(id) addr2 = wpas.get_driver_status_field("addr") if addr1 != addr2: raise Exception("Random MAC address changed unexpectedly") wpas.remove_network(id) id = wpas.connect("sta-dynamic", psk="12345678", mac_addr="2", scan_freq="2412") addr2 = wpas.get_driver_status_field("addr") if addr1 == addr2: raise Exception("Random MAC address did not change") if addr2[3:8] != addr0[3:8]: raise Exception("OUI was not kept")
def run_macsec_psk_ns(dev, apdev, params): try: subprocess.check_call([ "ip", "link", "add", "veth0", "type", "veth", "peer", "name", "veth1" ]) except subprocess.CalledProcessError: raise HwsimSkip("veth not supported (kernel CONFIG_VETH)") prefix = "macsec_psk_ns" conffile = os.path.join(params['logdir'], prefix + ".conf") pidfile = os.path.join(params['logdir'], prefix + ".pid") logfile0 = os.path.join(params['logdir'], prefix + ".veth0.log") logfile1 = os.path.join(params['logdir'], prefix + ".veth1.log") cap_veth0 = os.path.join(params['logdir'], prefix + ".veth0.pcap") cap_veth1 = os.path.join(params['logdir'], prefix + ".veth1.pcap") cap_macsec0 = os.path.join(params['logdir'], prefix + ".macsec0.pcap") cap_macsec1 = os.path.join(params['logdir'], prefix + ".macsec1.pcap") for i in range(2): try: subprocess.check_call(["ip", "netns", "add", "ns%d" % i]) except subprocess.CalledProcessError: raise HwsimSkip( "network namespace not supported (kernel CONFIG_NAMESPACES, CONFIG_NET_NS)" ) subprocess.check_call( ["ip", "link", "set", "veth%d" % i, "netns", "ns%d" % i]) subprocess.check_call([ "ip", "netns", "exec", "ns%d" % i, "ip", "link", "set", "dev", "veth%d" % i, "up" ]) cmd = {} cmd[0] = WlantestCapture('veth0', cap_veth0, netns='ns0') cmd[1] = WlantestCapture('veth1', cap_veth1, netns='ns1') write_conf(conffile + '0') write_conf(conffile + '1', mka_priority=100) prg = os.path.join(params['logdir'], 'alt-wpa_supplicant/wpa_supplicant/wpa_supplicant') if not os.path.exists(prg): prg = '../../wpa_supplicant/wpa_supplicant' arg = [ "ip", "netns", "exec", "ns0", prg, '-BdddtKW', '-P', pidfile + '0', '-f', logfile0, '-g', '/tmp/wpas-veth0', '-Dmacsec_linux', '-c', conffile + '0', '-i', "veth0" ] logger.info("Start wpa_supplicant: " + str(arg)) try: subprocess.check_call(arg) except subprocess.CalledProcessError: raise HwsimSkip( "macsec supported (wpa_supplicant CONFIG_MACSEC, CONFIG_DRIVER_MACSEC_LINUX; kernel CONFIG_MACSEC)" ) if os.path.exists("wpa_supplicant-macsec2"): logger.info( "Use alternative wpa_supplicant binary for one of the macsec devices" ) prg = "wpa_supplicant-macsec2" arg = [ "ip", "netns", "exec", "ns1", prg, '-BdddtKW', '-P', pidfile + '1', '-f', logfile1, '-g', '/tmp/wpas-veth1', '-Dmacsec_linux', '-c', conffile + '1', '-i', "veth1" ] logger.info("Start wpa_supplicant: " + str(arg)) subprocess.check_call(arg) wpas0 = WpaSupplicant('veth0', '/tmp/wpas-veth0') wpas1 = WpaSupplicant('veth1', '/tmp/wpas-veth1') log_ip_macsec_ns() log_ip_link_ns() logger.info("wpas0 STATUS:\n" + wpas0.request("STATUS")) logger.info("wpas1 STATUS:\n" + wpas1.request("STATUS")) logger.info("wpas0 STATUS-DRIVER:\n" + wpas0.request("STATUS-DRIVER")) logger.info("wpas1 STATUS-DRIVER:\n" + wpas1.request("STATUS-DRIVER")) for i in range(10): macsec_ifname0 = wpas0.get_driver_status_field("parent_ifname") macsec_ifname1 = wpas1.get_driver_status_field("parent_ifname") if "Number of Keys" in wpas0.request("STATUS"): key_tx0 = int(wpas0.get_status_field("Number of Keys Distributed")) key_rx0 = int(wpas0.get_status_field("Number of Keys Received")) else: key_tx0 = 0 key_rx0 = 0 if "Number of Keys" in wpas1.request("STATUS"): key_tx1 = int(wpas1.get_status_field("Number of Keys Distributed")) key_rx1 = int(wpas1.get_status_field("Number of Keys Received")) else: key_tx1 = 0 key_rx1 = 0 if key_rx0 > 0 and key_tx1 > 0: break time.sleep(1) cmd[2] = WlantestCapture(macsec_ifname0, cap_macsec0, netns='ns0') cmd[3] = WlantestCapture(macsec_ifname1, cap_macsec1, netns='ns0') time.sleep(0.5) logger.info("wpas0 STATUS:\n" + wpas0.request("STATUS")) logger.info("wpas1 STATUS:\n" + wpas1.request("STATUS")) log_ip_macsec_ns() hwsim_utils.test_connectivity(wpas0, wpas1, ifname1=macsec_ifname0, ifname2=macsec_ifname1, send_len=1400) log_ip_macsec_ns() subprocess.check_call([ 'ip', 'netns', 'exec', 'ns0', 'ip', 'addr', 'add', '192.168.248.17/30', 'dev', macsec_ifname0 ]) subprocess.check_call([ 'ip', 'netns', 'exec', 'ns1', 'ip', 'addr', 'add', '192.168.248.18/30', 'dev', macsec_ifname1 ]) c = subprocess.Popen( ['ip', 'netns', 'exec', 'ns0', 'ping', '-c', '2', '192.168.248.18'], stdout=subprocess.PIPE) res = c.stdout.read().decode() c.stdout.close() logger.info("ping:\n" + res) if "2 packets transmitted, 2 received" not in res: raise Exception("ping did not work") wpas0.close_monitor() wpas0.request("TERMINATE") wpas0.close_control() del wpas0 wpas1.close_monitor() wpas1.request("TERMINATE") wpas1.close_control() del wpas1 time.sleep(1) for i in range(len(cmd)): cmd[i].close()
def run_macsec_psk_ns(dev, apdev, params): try: subprocess.check_call(["ip", "link", "add", "veth0", "type", "veth", "peer", "name", "veth1"]) except subprocess.CalledProcessError: raise HwsimSkip("veth not supported (kernel CONFIG_VETH)") prefix = "macsec_psk_ns" conffile = os.path.join(params['logdir'], prefix + ".conf") pidfile = os.path.join(params['logdir'], prefix + ".pid") logfile0 = os.path.join(params['logdir'], prefix + ".veth0.log") logfile1 = os.path.join(params['logdir'], prefix + ".veth1.log") cap_veth0 = os.path.join(params['logdir'], prefix + ".veth0.pcap") cap_veth1 = os.path.join(params['logdir'], prefix + ".veth1.pcap") cap_macsec0 = os.path.join(params['logdir'], prefix + ".macsec0.pcap") cap_macsec1 = os.path.join(params['logdir'], prefix + ".macsec1.pcap") for i in range(2): try: subprocess.check_call(["ip", "netns", "add", "ns%d" % i]) except subprocess.CalledProcessError: raise HwsimSkip("network namespace not supported (kernel CONFIG_NAMESPACES, CONFIG_NET_NS)") subprocess.check_call(["ip", "link", "set", "veth%d" % i, "netns", "ns%d" %i]) subprocess.check_call(["ip", "netns", "exec", "ns%d" % i, "ip", "link", "set", "dev", "veth%d" % i, "up"]) cmd = {} cmd[0] = subprocess.Popen(['ip', 'netns', 'exec', 'ns0', 'tcpdump', '-p', '-U', '-i', 'veth0', '-w', cap_veth0, '-s', '2000', '--immediate-mode'], stderr=open('/dev/null', 'w')) cmd[1] = subprocess.Popen(['ip', 'netns', 'exec', 'ns1', 'tcpdump', '-p', '-U', '-i', 'veth1', '-w', cap_veth1, '-s', '2000', '--immediate-mode'], stderr=open('/dev/null', 'w')) write_conf(conffile + '0') write_conf(conffile + '1', mka_priority=100) prg = os.path.join(params['logdir'], 'alt-wpa_supplicant/wpa_supplicant/wpa_supplicant') if not os.path.exists(prg): prg = '../../wpa_supplicant/wpa_supplicant' arg = ["ip", "netns", "exec", "ns0", prg, '-BdddtKW', '-P', pidfile + '0', '-f', logfile0, '-g', '/tmp/wpas-veth0', '-Dmacsec_linux', '-c', conffile + '0', '-i', "veth0"] logger.info("Start wpa_supplicant: " + str(arg)) try: subprocess.check_call(arg) except subprocess.CalledProcessError: raise HwsimSkip("macsec supported (wpa_supplicant CONFIG_MACSEC, CONFIG_DRIVER_MACSEC_LINUX; kernel CONFIG_MACSEC)") if os.path.exists("wpa_supplicant-macsec2"): logger.info("Use alternative wpa_supplicant binary for one of the macsec devices") prg = "wpa_supplicant-macsec2" arg = ["ip", "netns", "exec", "ns1", prg, '-BdddtKW', '-P', pidfile + '1', '-f', logfile1, '-g', '/tmp/wpas-veth1', '-Dmacsec_linux', '-c', conffile + '1', '-i', "veth1"] logger.info("Start wpa_supplicant: " + str(arg)) subprocess.check_call(arg) wpas0 = WpaSupplicant('veth0', '/tmp/wpas-veth0') wpas1 = WpaSupplicant('veth1', '/tmp/wpas-veth1') log_ip_macsec_ns() log_ip_link_ns() logger.info("wpas0 STATUS:\n" + wpas0.request("STATUS")) logger.info("wpas1 STATUS:\n" + wpas1.request("STATUS")) logger.info("wpas0 STATUS-DRIVER:\n" + wpas0.request("STATUS-DRIVER")) logger.info("wpas1 STATUS-DRIVER:\n" + wpas1.request("STATUS-DRIVER")) macsec_ifname0 = wpas0.get_driver_status_field("parent_ifname") macsec_ifname1 = wpas1.get_driver_status_field("parent_ifname") for i in range(10): key_tx0 = int(wpas0.get_status_field("Number of Keys Distributed")) key_rx0 = int(wpas0.get_status_field("Number of Keys Received")) key_tx1 = int(wpas1.get_status_field("Number of Keys Distributed")) key_rx1 = int(wpas1.get_status_field("Number of Keys Received")) if key_rx0 > 0 and key_tx1 > 0: break time.sleep(1) cmd[2] = subprocess.Popen(['ip', 'netns', 'exec', 'ns0', 'tcpdump', '-p', '-U', '-i', macsec_ifname0, '-w', cap_macsec0, '-s', '2000', '--immediate-mode'], stderr=open('/dev/null', 'w')) cmd[3] = subprocess.Popen(['ip', 'netns', 'exec', 'ns0', 'tcpdump', '-p', '-U', '-i', macsec_ifname1, '-w', cap_macsec1, '-s', '2000', '--immediate-mode'], stderr=open('/dev/null', 'w')) time.sleep(0.5) logger.info("wpas0 STATUS:\n" + wpas0.request("STATUS")) logger.info("wpas1 STATUS:\n" + wpas1.request("STATUS")) log_ip_macsec_ns() hwsim_utils.test_connectivity(wpas0, wpas1, ifname1=macsec_ifname0, ifname2=macsec_ifname1, send_len=1400) log_ip_macsec_ns() subprocess.check_call(['ip', 'netns', 'exec', 'ns0', 'ip', 'addr', 'add', '192.168.248.17/30', 'dev', macsec_ifname0]) subprocess.check_call(['ip', 'netns', 'exec', 'ns1', 'ip', 'addr', 'add', '192.168.248.18/30', 'dev', macsec_ifname1]) c = subprocess.Popen(['ip', 'netns', 'exec', 'ns0', 'ping', '-c', '2', '192.168.248.18'], stdout=subprocess.PIPE) res = c.stdout.read().decode() c.stdout.close() logger.info("ping:\n" + res) if "2 packets transmitted, 2 received" not in res: raise Exception("ping did not work") wpas0.close_monitor() wpas0.request("TERMINATE") wpas0.close_control() del wpas0 wpas1.close_monitor() wpas1.request("TERMINATE") wpas1.close_control() del wpas1 time.sleep(1) for i in range(len(cmd)): cmd[i].terminate()