From a2c88a8025b2d76718e862489c37c5252ffc4a67 Mon Sep 17 00:00:00 2001 From: Janusz Dziedzic Date: Fri, 4 Mar 2016 10:20:32 +0100 Subject: [PATCH] wpaspy: Add support for UDP connection hostname and port can now be specified when using wpaspy.Ctrl, so we can connect to remote clients now. This can also be tested using test.py application with ./test.py Signed-off-by: Janusz Dziedzic --- wpaspy/test.py | 23 ++++++++++++++---- wpaspy/wpaspy.py | 62 ++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 67 insertions(+), 18 deletions(-) diff --git a/wpaspy/test.py b/wpaspy/test.py index 493af7a67..9141a8d40 100755 --- a/wpaspy/test.py +++ b/wpaspy/test.py @@ -7,13 +7,23 @@ # See README for more details. import os +import sys import time import wpaspy wpas_ctrl = '/var/run/wpa_supplicant' -def wpas_connect(): +def wpas_connect(host=None, port=9877): ifaces = [] + + if host != None: + try: + wpas = wpaspy.Ctrl(host, port) + return wpas + except: + print "Could not connect to host: ", host + return None + if os.path.isdir(wpas_ctrl): try: ifaces = [os.path.join(wpas_ctrl, i) for i in os.listdir(wpas_ctrl)] @@ -34,15 +44,15 @@ def wpas_connect(): return None -def main(): +def main(host=None, port=9877): print "Testing wpa_supplicant control interface connection" - wpas = wpas_connect() + wpas = wpas_connect(host, port) if wpas is None: return print "Connected to wpa_supplicant" print wpas.request('PING') - mon = wpas_connect() + mon = wpas_connect(host, port) if mon is None: print "Could not open event monitor connection" return @@ -66,4 +76,7 @@ def main(): if __name__ == "__main__": - main() + if len(sys.argv) > 2: + main(host=sys.argv[1], port=int(sys.argv[2])) + else: + main() diff --git a/wpaspy/wpaspy.py b/wpaspy/wpaspy.py index 2f57d74f7..861bee6ee 100644 --- a/wpaspy/wpaspy.py +++ b/wpaspy/wpaspy.py @@ -7,27 +7,59 @@ # See README for more details. import os +import stat import socket import select counter = 0 class Ctrl: - def __init__(self, path): + def __init__(self, path, port=9877): global counter self.started = False self.attached = False - self.s = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM) - self.dest = path - self.local = "/tmp/wpa_ctrl_" + str(os.getpid()) + '-' + str(counter) - counter += 1 - self.s.bind(self.local) + self.path = path + self.port = port + try: - self.s.connect(self.dest) - except Exception, e: - self.s.close() - os.unlink(self.local) - raise + mode = os.stat(path).st_mode + if stat.S_ISSOCK(mode): + self.udp = False + else: + self.udp = True + except: + self.udp = True + + if not self.udp: + self.s = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM) + self.dest = path + self.local = "/tmp/wpa_ctrl_" + str(os.getpid()) + '-' + str(counter) + counter += 1 + self.s.bind(self.local) + try: + self.s.connect(self.dest) + except Exception, e: + self.s.close() + os.unlink(self.local) + raise + else: + try: + ai_list = socket.getaddrinfo(path, port, socket.AF_INET, + socket.SOCK_DGRAM) + for af, socktype, proto, cn, sockaddr in ai_list: + self.sockaddr = sockaddr + break + self.s = socket.socket(af, socktype) + self.s.settimeout(5) + self.s.sendto("GET_COOKIE", sockaddr) + reply, server = self.s.recvfrom(4096) + self.cookie = reply + self.port = port + except: + print "connect exception ", path, str(port) + if self.s != None: + self.s.close() + raise self.started = True def __del__(self): @@ -43,11 +75,15 @@ class Ctrl: pass if self.started: self.s.close() - os.unlink(self.local) + if not self.udp: + os.unlink(self.local) self.started = False def request(self, cmd, timeout=10): - self.s.send(cmd) + if self.udp: + self.s.sendto(self.cookie + cmd, self.sockaddr) + else: + self.s.send(cmd) [r, w, e] = select.select([self.s], [], [], timeout) if r: return self.s.recv(4096)