]> git.ipfire.org Git - thirdparty/hostap.git/blame - tests/hwsim/hostapd.py
HE: MCS size is always a minimum of 4 bytes
[thirdparty/hostap.git] / tests / hwsim / hostapd.py
CommitLineData
b8cd4c54 1# Python class for controlling hostapd
02a4ac0f 2# Copyright (c) 2013-2019, Jouni Malinen <j@w1.fi>
b8cd4c54
JM
3#
4# This software may be distributed under the terms of the BSD license.
5# See README for more details.
6
7import os
8import time
9import logging
bfe375ec
JM
10import binascii
11import struct
b8cd4c54 12import wpaspy
8ce4855b 13import remotehost
9cd6f4c0 14import utils
7fd9fbc2 15import subprocess
b8cd4c54 16
c9aa4308 17logger = logging.getLogger()
b8cd4c54 18hapd_ctrl = '/var/run/hostapd'
8c87f65f 19hapd_global = '/var/run/hostapd-global'
b8cd4c54 20
bfe375ec 21def mac2tuple(mac):
fab49f61 22 return struct.unpack('6B', binascii.unhexlify(mac.replace(':', '')))
bfe375ec 23
b8cd4c54 24class HostapdGlobal:
02a4ac0f 25 def __init__(self, apdev=None, global_ctrl_override=None):
625bf744
JD
26 try:
27 hostname = apdev['hostname']
28 port = apdev['port']
29 except:
30 hostname = None
31 port = 8878
8ce4855b 32 self.host = remotehost.Host(hostname)
cb73f7e8
JD
33 self.hostname = hostname
34 self.port = port
35 if hostname is None:
02a4ac0f
JM
36 global_ctrl = hapd_global
37 if global_ctrl_override:
38 global_ctrl = global_ctrl_override
39 self.ctrl = wpaspy.Ctrl(global_ctrl)
40 self.mon = wpaspy.Ctrl(global_ctrl)
d4944fad 41 self.dbg = ""
cb73f7e8
JD
42 else:
43 self.ctrl = wpaspy.Ctrl(hostname, port)
44 self.mon = wpaspy.Ctrl(hostname, port)
d4944fad 45 self.dbg = hostname + "/" + str(port)
41a256ec
AN
46 self.mon.attach()
47
e9f2d54f 48 def cmd_execute(self, cmd_array, shell=False):
7fd9fbc2 49 if self.hostname is None:
e9f2d54f
JM
50 if shell:
51 cmd = ' '.join(cmd_array)
52 else:
53 cmd = cmd_array
7fd9fbc2 54 proc = subprocess.Popen(cmd, stderr=subprocess.STDOUT,
e9f2d54f 55 stdout=subprocess.PIPE, shell=shell)
7fd9fbc2
JA
56 out = proc.communicate()[0]
57 ret = proc.returncode
45b0b88f 58 return ret, out.decode()
7fd9fbc2
JA
59 else:
60 return self.host.execute(cmd_array)
61
d4944fad
JD
62 def request(self, cmd, timeout=10):
63 logger.debug(self.dbg + ": CTRL(global): " + cmd)
64 return self.ctrl.request(cmd, timeout)
41a256ec
AN
65
66 def wait_event(self, events, timeout):
67 start = os.times()[4]
68 while True:
69 while self.mon.pending():
70 ev = self.mon.recv()
d4944fad 71 logger.debug(self.dbg + "(global): " + ev)
41a256ec
AN
72 for event in events:
73 if event in ev:
74 return ev
75 now = os.times()[4]
76 remaining = start + timeout - now
77 if remaining <= 0:
78 break
79 if not self.mon.pending(timeout=remaining):
80 break
81 return None
b8cd4c54 82
08763216
JM
83 def add(self, ifname, driver=None):
84 cmd = "ADD " + ifname + " " + hapd_ctrl
85 if driver:
86 cmd += " " + driver
d4944fad 87 res = self.request(cmd)
a8b8da11 88 if "OK" not in res:
b8cd4c54
JM
89 raise Exception("Could not add hostapd interface " + ifname)
90
77990cd7 91 def add_iface(self, ifname, confname):
d4944fad 92 res = self.request("ADD " + ifname + " config=" + confname)
a8b8da11 93 if "OK" not in res:
77990cd7
JM
94 raise Exception("Could not add hostapd interface")
95
a6333977 96 def add_bss(self, phy, confname, ignore_error=False):
d4944fad 97 res = self.request("ADD bss_config=" + phy + ":" + confname)
a8b8da11 98 if "OK" not in res:
a6333977
JM
99 if not ignore_error:
100 raise Exception("Could not add hostapd BSS")
101
b8cd4c54 102 def remove(self, ifname):
d4944fad 103 self.request("REMOVE " + ifname, timeout=30)
b8cd4c54 104
75428961 105 def relog(self):
d4944fad 106 self.request("RELOG")
75428961 107
f8949f5f 108 def flush(self):
d4944fad 109 self.request("FLUSH")
f8949f5f 110
4d48d44c
JD
111 def get_ctrl_iface_port(self, ifname):
112 if self.hostname is None:
113 return None
114
d4944fad 115 res = self.request("INTERFACES ctrl")
4d48d44c
JD
116 lines = res.splitlines()
117 found = False
118 for line in lines:
119 words = line.split()
120 if words[0] == ifname:
121 found = True
122 break
123 if not found:
124 raise Exception("Could not find UDP port for " + ifname)
125 res = line.find("ctrl_iface=udp:")
126 if res == -1:
127 raise Exception("Wrong ctrl_interface format")
128 words = line.split(":")
129 return int(words[1])
b8cd4c54 130
e3b36d42
JD
131 def terminate(self):
132 self.mon.detach()
133 self.mon.close()
134 self.mon = None
135 self.ctrl.terminate()
136 self.ctrl = None
137
b8cd4c54 138class Hostapd:
cb73f7e8 139 def __init__(self, ifname, bssidx=0, hostname=None, port=8877):
e2f3f023 140 self.hostname = hostname
8ce4855b 141 self.host = remotehost.Host(hostname, ifname)
b8cd4c54 142 self.ifname = ifname
cb73f7e8
JD
143 if hostname is None:
144 self.ctrl = wpaspy.Ctrl(os.path.join(hapd_ctrl, ifname))
145 self.mon = wpaspy.Ctrl(os.path.join(hapd_ctrl, ifname))
d4944fad 146 self.dbg = ifname
cb73f7e8
JD
147 else:
148 self.ctrl = wpaspy.Ctrl(hostname, port)
149 self.mon = wpaspy.Ctrl(hostname, port)
d4944fad 150 self.dbg = hostname + "/" + ifname
b47750be 151 self.mon.attach()
f6420942 152 self.bssid = None
54cf411f 153 self.bssidx = bssidx
f6420942 154
e9f2d54f 155 def cmd_execute(self, cmd_array, shell=False):
7fd9fbc2 156 if self.hostname is None:
e9f2d54f
JM
157 if shell:
158 cmd = ' '.join(cmd_array)
159 else:
160 cmd = cmd_array
7fd9fbc2 161 proc = subprocess.Popen(cmd, stderr=subprocess.STDOUT,
e9f2d54f 162 stdout=subprocess.PIPE, shell=shell)
7fd9fbc2
JA
163 out = proc.communicate()[0]
164 ret = proc.returncode
45b0b88f 165 return ret, out.decode()
7fd9fbc2
JA
166 else:
167 return self.host.execute(cmd_array)
168
e3b36d42
JD
169 def close_ctrl(self):
170 if self.mon is not None:
171 self.mon.detach()
172 self.mon.close()
173 self.mon = None
174 self.ctrl.close()
175 self.ctrl = None
176
f6420942
JM
177 def own_addr(self):
178 if self.bssid is None:
54cf411f 179 self.bssid = self.get_status_field('bssid[%d]' % self.bssidx)
f6420942 180 return self.bssid
b8cd4c54
JM
181
182 def request(self, cmd):
d4944fad 183 logger.debug(self.dbg + ": CTRL: " + cmd)
b8cd4c54
JM
184 return self.ctrl.request(cmd)
185
186 def ping(self):
187 return "PONG" in self.request("PING")
188
189 def set(self, field, value):
a8b8da11 190 if "OK" not in self.request("SET " + field + " " + value):
b8cd4c54
JM
191 raise Exception("Failed to set hostapd parameter " + field)
192
193 def set_defaults(self):
194 self.set("driver", "nl80211")
195 self.set("hw_mode", "g")
196 self.set("channel", "1")
197 self.set("ieee80211n", "1")
789b9f1d
JM
198 self.set("logger_stdout", "-1")
199 self.set("logger_stdout_level", "0")
b8cd4c54
JM
200
201 def set_open(self, ssid):
202 self.set_defaults()
203 self.set("ssid", ssid)
204
205 def set_wpa2_psk(self, ssid, passphrase):
206 self.set_defaults()
207 self.set("ssid", ssid)
208 self.set("wpa_passphrase", passphrase)
209 self.set("wpa", "2")
210 self.set("wpa_key_mgmt", "WPA-PSK")
211 self.set("rsn_pairwise", "CCMP")
212
e492837b
JM
213 def set_wpa_psk(self, ssid, passphrase):
214 self.set_defaults()
215 self.set("ssid", ssid)
216 self.set("wpa_passphrase", passphrase)
217 self.set("wpa", "1")
218 self.set("wpa_key_mgmt", "WPA-PSK")
219 self.set("wpa_pairwise", "TKIP")
220
221 def set_wpa_psk_mixed(self, ssid, passphrase):
222 self.set_defaults()
223 self.set("ssid", ssid)
224 self.set("wpa_passphrase", passphrase)
225 self.set("wpa", "3")
226 self.set("wpa_key_mgmt", "WPA-PSK")
227 self.set("wpa_pairwise", "TKIP")
228 self.set("rsn_pairwise", "CCMP")
229
0165c4be
JM
230 def set_wep(self, ssid, key):
231 self.set_defaults()
232 self.set("ssid", ssid)
233 self.set("wep_key0", key)
234
b8cd4c54 235 def enable(self):
a8b8da11 236 if "OK" not in self.request("ENABLE"):
b8cd4c54
JM
237 raise Exception("Failed to enable hostapd interface " + self.ifname)
238
239 def disable(self):
a8b8da11 240 if "OK" not in self.request("DISABLE"):
b8cd4c54 241 raise Exception("Failed to disable hostapd interface " + self.ifname)
e259d186 242
b47750be
JM
243 def dump_monitor(self):
244 while self.mon.pending():
245 ev = self.mon.recv()
d4944fad 246 logger.debug(self.dbg + ": " + ev)
b47750be
JM
247
248 def wait_event(self, events, timeout):
d1fb06c9
JM
249 if not isinstance(events, list):
250 raise Exception("Hostapd.wait_event() called with incorrect events argument type")
36408936
JM
251 start = os.times()[4]
252 while True:
b47750be
JM
253 while self.mon.pending():
254 ev = self.mon.recv()
d4944fad 255 logger.debug(self.dbg + ": " + ev)
b47750be
JM
256 for event in events:
257 if event in ev:
258 return ev
36408936
JM
259 now = os.times()[4]
260 remaining = start + timeout - now
261 if remaining <= 0:
262 break
263 if not self.mon.pending(timeout=remaining):
264 break
b47750be
JM
265 return None
266
938c6e7b 267 def wait_sta(self, addr=None, timeout=2):
c4a9610e 268 ev = self.wait_event(["AP-STA-CONNECT"], timeout=timeout)
938c6e7b
JM
269 if ev is None:
270 raise Exception("AP did not report STA connection")
271 if addr and addr not in ev:
272 raise Exception("Unexpected STA address in connection event: " + ev)
273
b47750be
JM
274 def get_status(self):
275 res = self.request("STATUS")
276 lines = res.splitlines()
277 vals = dict()
278 for l in lines:
fab49f61 279 [name, value] = l.split('=', 1)
b47750be
JM
280 vals[name] = value
281 return vals
282
283 def get_status_field(self, field):
284 vals = self.get_status()
285 if field in vals:
286 return vals[field]
287 return None
288
a36158be
JM
289 def get_driver_status(self):
290 res = self.request("STATUS-DRIVER")
291 lines = res.splitlines()
292 vals = dict()
293 for l in lines:
fab49f61 294 [name, value] = l.split('=', 1)
a36158be
JM
295 vals[name] = value
296 return vals
297
298 def get_driver_status_field(self, field):
299 vals = self.get_driver_status()
300 if field in vals:
301 return vals[field]
302 return None
303
65038313
JM
304 def get_config(self):
305 res = self.request("GET_CONFIG")
306 lines = res.splitlines()
307 vals = dict()
308 for l in lines:
fab49f61 309 [name, value] = l.split('=', 1)
65038313
JM
310 vals[name] = value
311 return vals
312
bfe375ec
JM
313 def mgmt_rx(self, timeout=5):
314 ev = self.wait_event(["MGMT-RX"], timeout=timeout)
315 if ev is None:
316 return None
317 msg = {}
318 frame = binascii.unhexlify(ev.split(' ')[1])
319 msg['frame'] = frame
320
321 hdr = struct.unpack('<HH6B6B6BH', frame[0:24])
322 msg['fc'] = hdr[0]
323 msg['subtype'] = (hdr[0] >> 4) & 0xf
324 hdr = hdr[1:]
325 msg['duration'] = hdr[0]
326 hdr = hdr[1:]
327 msg['da'] = "%02x:%02x:%02x:%02x:%02x:%02x" % hdr[0:6]
328 hdr = hdr[6:]
329 msg['sa'] = "%02x:%02x:%02x:%02x:%02x:%02x" % hdr[0:6]
330 hdr = hdr[6:]
331 msg['bssid'] = "%02x:%02x:%02x:%02x:%02x:%02x" % hdr[0:6]
332 hdr = hdr[6:]
333 msg['seq_ctrl'] = hdr[0]
334 msg['payload'] = frame[24:]
335
336 return msg
337
338 def mgmt_tx(self, msg):
339 t = (msg['fc'], 0) + mac2tuple(msg['da']) + mac2tuple(msg['sa']) + mac2tuple(msg['bssid']) + (0,)
340 hdr = struct.pack('<HH6B6B6BH', *t)
7ab74770
MH
341 res = self.request("MGMT_TX " + binascii.hexlify(hdr + msg['payload']).decode())
342 if "OK" not in res:
0851a180 343 raise Exception("MGMT_TX command to hostapd failed")
bfe375ec 344
cce26eb4
JM
345 def get_sta(self, addr, info=None, next=False):
346 cmd = "STA-NEXT " if next else "STA "
347 if addr is None:
348 res = self.request("STA-FIRST")
349 elif info:
350 res = self.request(cmd + addr + " " + info)
5dec879d 351 else:
cce26eb4 352 res = self.request(cmd + addr)
6435799b
JM
353 lines = res.splitlines()
354 vals = dict()
355 first = True
356 for l in lines:
2496adf0 357 if first and '=' not in l:
6435799b
JM
358 vals['addr'] = l
359 first = False
360 else:
fab49f61 361 [name, value] = l.split('=', 1)
6435799b
JM
362 vals[name] = value
363 return vals
364
4fcee244
JM
365 def get_mib(self, param=None):
366 if param:
367 res = self.request("MIB " + param)
368 else:
369 res = self.request("MIB")
7fd15145
JM
370 lines = res.splitlines()
371 vals = dict()
372 for l in lines:
4fcee244
JM
373 name_val = l.split('=', 1)
374 if len(name_val) > 1:
375 vals[name_val[0]] = name_val[1]
7fd15145
JM
376 return vals
377
865fa1e9
JM
378 def get_pmksa(self, addr):
379 res = self.request("PMKSA")
380 lines = res.splitlines()
381 for l in lines:
382 if addr not in l:
383 continue
384 vals = dict()
fab49f61 385 [index, aa, pmkid, expiration, opportunistic] = l.split(' ')
865fa1e9
JM
386 vals['index'] = index
387 vals['pmkid'] = pmkid
388 vals['expiration'] = expiration
389 vals['opportunistic'] = opportunistic
390 return vals
391 return None
392
0422d06b
JM
393 def dpp_qr_code(self, uri):
394 res = self.request("DPP_QR_CODE " + uri)
395 if "FAIL" in res:
396 raise Exception("Failed to parse QR Code URI")
397 return int(res)
a5387062
JM
398
399 def dpp_bootstrap_gen(self, type="qrcode", chan=None, mac=None, info=None,
400 curve=None, key=None):
401 cmd = "DPP_BOOTSTRAP_GEN type=" + type
402 if chan:
403 cmd += " chan=" + chan
404 if mac:
405 if mac is True:
406 mac = self.own_addr()
407 cmd += " mac=" + mac.replace(':', '')
408 if info:
409 cmd += " info=" + info
410 if curve:
411 cmd += " curve=" + curve
412 if key:
413 cmd += " key=" + key
414 res = self.request(cmd)
415 if "FAIL" in res:
416 raise Exception("Failed to generate bootstrapping info")
417 return int(res)
0422d06b 418
7e009100
JM
419 def dpp_listen(self, freq, netrole=None, qr=None, role=None):
420 cmd = "DPP_LISTEN " + str(freq)
421 if netrole:
422 cmd += " netrole=" + netrole
423 if qr:
424 cmd += " qr=" + qr
425 if role:
426 cmd += " role=" + role
427 if "OK" not in self.request(cmd):
428 raise Exception("Failed to start listen operation")
429
5725b3e3
JM
430 def dpp_auth_init(self, peer=None, uri=None, conf=None, configurator=None,
431 extra=None, own=None, role=None, neg_freq=None,
432 ssid=None, passphrase=None, expect_fail=False):
433 cmd = "DPP_AUTH_INIT"
434 if peer is None:
435 peer = self.dpp_qr_code(uri)
436 cmd += " peer=%d" % peer
437 if own is not None:
438 cmd += " own=%d" % own
439 if role:
440 cmd += " role=" + role
441 if extra:
442 cmd += " " + extra
443 if conf:
444 cmd += " conf=" + conf
445 if configurator is not None:
446 cmd += " configurator=%d" % configurator
447 if neg_freq:
448 cmd += " neg_freq=%d" % neg_freq
449 if ssid:
450 cmd += " ssid=" + binascii.hexlify(ssid.encode()).decode()
451 if passphrase:
452 cmd += " pass=" + binascii.hexlify(passphrase.encode()).decode()
453 res = self.request(cmd)
454 if expect_fail:
455 if "FAIL" not in res:
456 raise Exception("DPP authentication started unexpectedly")
457 return
458 if "OK" not in res:
459 raise Exception("Failed to initiate DPP Authentication")
460
6d196e59
JM
461 def dpp_pkex_init(self, identifier, code, role=None, key=None, curve=None,
462 extra=None, use_id=None):
463 if use_id is None:
464 id1 = self.dpp_bootstrap_gen(type="pkex", key=key, curve=curve)
465 else:
466 id1 = use_id
467 cmd = "own=%d " % id1
468 if identifier:
469 cmd += "identifier=%s " % identifier
470 cmd += "init=1 "
471 if role:
472 cmd += "role=%s " % role
473 if extra:
474 cmd += extra + " "
475 cmd += "code=%s" % code
476 res = self.request("DPP_PKEX_ADD " + cmd)
477 if "FAIL" in res:
478 raise Exception("Failed to set PKEX data (initiator)")
479 return id1
480
481 def dpp_pkex_resp(self, freq, identifier, code, key=None, curve=None,
482 listen_role=None):
483 id0 = self.dpp_bootstrap_gen(type="pkex", key=key, curve=curve)
484 cmd = "own=%d " % id0
485 if identifier:
486 cmd += "identifier=%s " % identifier
487 cmd += "code=%s" % code
488 res = self.request("DPP_PKEX_ADD " + cmd)
489 if "FAIL" in res:
490 raise Exception("Failed to set PKEX data (responder)")
491 self.dpp_listen(freq, role=listen_role)
492
e105110f
JM
493 def dpp_configurator_add(self, curve=None, key=None):
494 cmd = "DPP_CONFIGURATOR_ADD"
495 if curve:
496 cmd += " curve=" + curve
497 if key:
498 cmd += " key=" + key
499 res = self.request(cmd)
500 if "FAIL" in res:
501 raise Exception("Failed to add configurator")
502 return int(res)
503
504 def dpp_configurator_remove(self, conf_id):
505 res = self.request("DPP_CONFIGURATOR_REMOVE %d" % conf_id)
506 if "OK" not in res:
507 raise Exception("DPP_CONFIGURATOR_REMOVE failed")
508
431802df
JM
509 def note(self, txt):
510 self.request("NOTE " + txt)
511
02a4ac0f 512def add_ap(apdev, params, wait_enabled=True, no_enable=False, timeout=30,
e374def2 513 global_ctrl_override=None, driver=False):
78b83193
JD
514 if isinstance(apdev, dict):
515 ifname = apdev['ifname']
516 try:
517 hostname = apdev['hostname']
518 port = apdev['port']
519 logger.info("Starting AP " + hostname + "/" + port + " " + ifname)
520 except:
521 logger.info("Starting AP " + ifname)
522 hostname = None
523 port = 8878
524 else:
525 ifname = apdev
526 logger.info("Starting AP " + ifname + " (old add_ap argument type)")
527 hostname = None
528 port = 8878
02a4ac0f
JM
529 hapd_global = HostapdGlobal(apdev,
530 global_ctrl_override=global_ctrl_override)
e259d186 531 hapd_global.remove(ifname)
e374def2 532 hapd_global.add(ifname, driver=driver)
4d48d44c
JD
533 port = hapd_global.get_ctrl_iface_port(ifname)
534 hapd = Hostapd(ifname, hostname=hostname, port=port)
e259d186
JM
535 if not hapd.ping():
536 raise Exception("Could not ping hostapd")
537 hapd.set_defaults()
fab49f61
JM
538 fields = ["ssid", "wpa_passphrase", "nas_identifier", "wpa_key_mgmt",
539 "wpa",
540 "wpa_pairwise", "rsn_pairwise", "auth_server_addr",
541 "acct_server_addr", "osu_server_uri"]
e259d186
JM
542 for field in fields:
543 if field in params:
544 hapd.set(field, params[field])
fab49f61 545 for f, v in list(params.items()):
93a06242
JM
546 if f in fields:
547 continue
548 if isinstance(v, list):
549 for val in v:
550 hapd.set(f, val)
551 else:
552 hapd.set(f, v)
138ec97e
JM
553 if no_enable:
554 return hapd
e259d186 555 hapd.enable()
629dbdd3 556 if wait_enabled:
57ff37d0 557 ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=timeout)
629dbdd3
JM
558 if ev is None:
559 raise Exception("AP startup timed out")
f8ad9dc2
JM
560 if "AP-ENABLED" not in ev:
561 raise Exception("AP startup failed")
b47750be 562 return hapd
e259d186 563
9cd6f4c0
JD
564def add_bss(apdev, ifname, confname, ignore_error=False):
565 phy = utils.get_phy(apdev)
566 try:
567 hostname = apdev['hostname']
568 port = apdev['port']
569 logger.info("Starting BSS " + hostname + "/" + port + " phy=" + phy + " ifname=" + ifname)
570 except:
571 logger.info("Starting BSS phy=" + phy + " ifname=" + ifname)
572 hostname = None
573 port = 8878
625bf744 574 hapd_global = HostapdGlobal(apdev)
a6333977 575 hapd_global.add_bss(phy, confname, ignore_error)
4d48d44c
JD
576 port = hapd_global.get_ctrl_iface_port(ifname)
577 hapd = Hostapd(ifname, hostname=hostname, port=port)
a6333977
JM
578 if not hapd.ping():
579 raise Exception("Could not ping hostapd")
fb1a7dcc 580 return hapd
a6333977 581
29444a08
JD
582def add_iface(apdev, confname):
583 ifname = apdev['ifname']
584 try:
585 hostname = apdev['hostname']
586 port = apdev['port']
587 logger.info("Starting interface " + hostname + "/" + port + " " + ifname)
588 except:
589 logger.info("Starting interface " + ifname)
590 hostname = None
591 port = 8878
625bf744 592 hapd_global = HostapdGlobal(apdev)
77990cd7 593 hapd_global.add_iface(ifname, confname)
4d48d44c
JD
594 port = hapd_global.get_ctrl_iface_port(ifname)
595 hapd = Hostapd(ifname, hostname=hostname, port=port)
77990cd7
JM
596 if not hapd.ping():
597 raise Exception("Could not ping hostapd")
fb1a7dcc 598 return hapd
77990cd7 599
c92ee957
JD
600def remove_bss(apdev, ifname=None):
601 if ifname == None:
602 ifname = apdev['ifname']
603 try:
604 hostname = apdev['hostname']
605 port = apdev['port']
606 logger.info("Removing BSS " + hostname + "/" + port + " " + ifname)
607 except:
608 logger.info("Removing BSS " + ifname)
625bf744 609 hapd_global = HostapdGlobal(apdev)
a6333977
JM
610 hapd_global.remove(ifname)
611
369f712a
JD
612def terminate(apdev):
613 try:
614 hostname = apdev['hostname']
615 port = apdev['port']
625bf744 616 logger.info("Terminating hostapd " + hostname + "/" + port)
369f712a 617 except:
369f712a 618 logger.info("Terminating hostapd")
625bf744 619 hapd_global = HostapdGlobal(apdev)
e3b36d42
JD
620 hapd_global.terminate()
621
e259d186 622def wpa2_params(ssid=None, passphrase=None):
fab49f61
JM
623 params = {"wpa": "2",
624 "wpa_key_mgmt": "WPA-PSK",
625 "rsn_pairwise": "CCMP"}
e259d186
JM
626 if ssid:
627 params["ssid"] = ssid
628 if passphrase:
629 params["wpa_passphrase"] = passphrase
630 return params
631
632def wpa_params(ssid=None, passphrase=None):
fab49f61
JM
633 params = {"wpa": "1",
634 "wpa_key_mgmt": "WPA-PSK",
635 "wpa_pairwise": "TKIP"}
e259d186
JM
636 if ssid:
637 params["ssid"] = ssid
638 if passphrase:
639 params["wpa_passphrase"] = passphrase
640 return params
641
642def wpa_mixed_params(ssid=None, passphrase=None):
fab49f61
JM
643 params = {"wpa": "3",
644 "wpa_key_mgmt": "WPA-PSK",
645 "wpa_pairwise": "TKIP",
646 "rsn_pairwise": "CCMP"}
e259d186
JM
647 if ssid:
648 params["ssid"] = ssid
649 if passphrase:
650 params["wpa_passphrase"] = passphrase
651 return params
9626962d
JM
652
653def radius_params():
fab49f61
JM
654 params = {"auth_server_addr": "127.0.0.1",
655 "auth_server_port": "1812",
656 "auth_server_shared_secret": "radius",
657 "nas_identifier": "nas.w1.fi"}
9626962d
JM
658 return params
659
71390dc8
JM
660def wpa_eap_params(ssid=None):
661 params = radius_params()
662 params["wpa"] = "1"
663 params["wpa_key_mgmt"] = "WPA-EAP"
664 params["wpa_pairwise"] = "TKIP"
665 params["ieee8021x"] = "1"
666 if ssid:
667 params["ssid"] = ssid
668 return params
669
9626962d
JM
670def wpa2_eap_params(ssid=None):
671 params = radius_params()
672 params["wpa"] = "2"
673 params["wpa_key_mgmt"] = "WPA-EAP"
674 params["rsn_pairwise"] = "CCMP"
675 params["ieee8021x"] = "1"
676 if ssid:
677 params["ssid"] = ssid
678 return params
c0ca24fc
JD
679
680def b_only_params(channel="1", ssid=None, country=None):
fab49f61
JM
681 params = {"hw_mode": "b",
682 "channel": channel}
c0ca24fc
JD
683 if ssid:
684 params["ssid"] = ssid
685 if country:
686 params["country_code"] = country
687 return params
688
689def g_only_params(channel="1", ssid=None, country=None):
fab49f61
JM
690 params = {"hw_mode": "g",
691 "channel": channel}
c0ca24fc
JD
692 if ssid:
693 params["ssid"] = ssid
694 if country:
695 params["country_code"] = country
696 return params
697
698def a_only_params(channel="36", ssid=None, country=None):
fab49f61
JM
699 params = {"hw_mode": "a",
700 "channel": channel}
c0ca24fc
JD
701 if ssid:
702 params["ssid"] = ssid
703 if country:
704 params["country_code"] = country
705 return params
706
707def ht20_params(channel="1", ssid=None, country=None):
fab49f61
JM
708 params = {"ieee80211n": "1",
709 "channel": channel,
710 "hw_mode": "g"}
c0ca24fc
JD
711 if int(channel) > 14:
712 params["hw_mode"] = "a"
713 if ssid:
714 params["ssid"] = ssid
715 if country:
716 params["country_code"] = country
717 return params
718
719def ht40_plus_params(channel="1", ssid=None, country=None):
720 params = ht20_params(channel, ssid, country)
721 params['ht_capab'] = "[HT40+]"
722 return params
723
724def ht40_minus_params(channel="1", ssid=None, country=None):
725 params = ht20_params(channel, ssid, country)
726 params['ht_capab'] = "[HT40-]"
727 return params
7fd9fbc2 728
e9f2d54f 729def cmd_execute(apdev, cmd, shell=False):
7fd9fbc2 730 hapd_global = HostapdGlobal(apdev)
e9f2d54f 731 return hapd_global.cmd_execute(cmd, shell=shell)