Updated to hostap_2_6
[mech_eap.git] / libeap / wpaspy / wpaspy.py
1 #!/usr/bin/python
2 #
3 # wpa_supplicant/hostapd control interface using Python
4 # Copyright (c) 2013, Jouni Malinen <j@w1.fi>
5 #
6 # This software may be distributed under the terms of the BSD license.
7 # See README for more details.
8
9 import os
10 import stat
11 import socket
12 import select
13
14 counter = 0
15
16 class Ctrl:
17     def __init__(self, path, port=9877):
18         global counter
19         self.started = False
20         self.attached = False
21         self.path = path
22         self.port = port
23
24         try:
25             mode = os.stat(path).st_mode
26             if stat.S_ISSOCK(mode):
27                 self.udp = False
28             else:
29                 self.udp = True
30         except:
31             self.udp = True
32
33         if not self.udp:
34             self.s = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
35             self.dest = path
36             self.local = "/tmp/wpa_ctrl_" + str(os.getpid()) + '-' + str(counter)
37             counter += 1
38             self.s.bind(self.local)
39             try:
40                 self.s.connect(self.dest)
41             except Exception, e:
42                 self.s.close()
43                 os.unlink(self.local)
44                 raise
45         else:
46             try:
47                 self.s = None
48                 ai_list = socket.getaddrinfo(path, port, socket.AF_INET,
49                                              socket.SOCK_DGRAM)
50                 for af, socktype, proto, cn, sockaddr in ai_list:
51                     self.sockaddr = sockaddr
52                     break
53                 self.s = socket.socket(af, socktype)
54                 self.s.settimeout(5)
55                 self.s.sendto("GET_COOKIE", sockaddr)
56                 reply, server = self.s.recvfrom(4096)
57                 self.cookie = reply
58                 self.port = port
59             except:
60                 print "connect exception ", path, str(port)
61                 if self.s != None:
62                     self.s.close()
63                 raise
64         self.started = True
65
66     def __del__(self):
67         self.close()
68
69     def close(self):
70         if self.attached:
71             try:
72                 self.detach()
73             except Exception, e:
74                 # Need to ignore this allow the socket to be closed
75                 self.attached = False
76                 pass
77         if self.started:
78             self.s.close()
79             if not self.udp:
80                 os.unlink(self.local)
81             self.started = False
82
83     def request(self, cmd, timeout=10):
84         if self.udp:
85             self.s.sendto(self.cookie + cmd, self.sockaddr)
86         else:
87             self.s.send(cmd)
88         [r, w, e] = select.select([self.s], [], [], timeout)
89         if r:
90             return self.s.recv(4096)
91         raise Exception("Timeout on waiting response")
92
93     def attach(self):
94         if self.attached:
95             return None
96         res = self.request("ATTACH")
97         if "OK" in res:
98             self.attached = True
99             return None
100         raise Exception("ATTACH failed")
101
102     def detach(self):
103         if not self.attached:
104             return None
105         while self.pending():
106             ev = self.recv()
107         res = self.request("DETACH")
108         if "FAIL" not in res:
109             self.attached = False
110             return None
111         raise Exception("DETACH failed")
112
113     def terminate(self):
114         if self.attached:
115             try:
116                 self.detach()
117             except Exception, e:
118                 # Need to ignore this to allow the socket to be closed
119                 self.attached = False
120         self.request("TERMINATE")
121         self.close()
122
123     def pending(self, timeout=0):
124         [r, w, e] = select.select([self.s], [], [], timeout)
125         if r:
126             return True
127         return False
128
129     def recv(self):
130         res = self.s.recv(4096)
131         return res