3 # Author: Martin Matusiak <numerodix@gmail.com>
4 # Licensed under the GNU Public License, version 3.
9 from conf
import config
13 from sdict
import sdict
19 def read_iface(iface_name
):
20 fields
= sdict(); info
= sdict()
21 fields
.ip
= "inet addr:([0-9.]+)"
23 output
= procs
.run("%s %s" % (config
.ifconfig
, iface_name
))
24 for key
in fields
.keys():
25 info
[key
] = regex
.find1(fields
[key
], output
)
28 def has_ip(iface_name
):
29 invalid_range
= "169.254."
30 info
= read_iface(iface_name
)
31 if info
.up
and info
.ip
and not regex
.matches(invalid_range
, info
.ip
):
34 def iface_up(iface_name
, ip
=None):
36 if ip
: ip_str
= "inet %s" % ip
37 info
= read_iface(iface_name
)
39 procs
.run("%s %s %s up" % (config
.ifconfig
, iface_name
, ip_str
))
41 def iface_down(iface_name
):
42 info
= read_iface(iface_name
)
44 procs
.run("%s %s inet 0.0.0.0 down" % (config
.ifconfig
, iface_name
))
49 def request_ip(iface_name
):
51 procs
.kill_by_name(config
.dhcpcd
)
52 procs
.kill_by_name(config
.dhclient
)
54 for i
in config
.interfaces
:
55 if i
.interface
!= iface_name
: iface_down(i
.interface
)
58 if config
.dhcpcd
[0] == '/':
59 procs
.run("%s -d -t5 %s" % (config
.dhcpcd
, iface_name
))
61 procs
.run("%s %s 2>&1" % (config
.dhclient
, iface_name
))
62 return has_ip(iface_name
)
67 def wire_connected(iface_name
):
69 output
= procs
.run("%s %s" % (config
.mii_tool
, iface_name
))
70 link
= regex
.matches("link ok", output
)
71 if output
and link
: return iface_name
77 IE: (?P<wpa_ver>.*%s.*)\s+
78 Group Cipher : (?P<group_cipher>[^\s]+)\s+
79 Pairwise Ciphers \(.\) : (?P<pairwise_ciphers>.+)\s+
80 Authentication Suites \(.\) : (?P<auth_suites>.+)\s*
81 (?P<preauth>Preauthentication Supported)*
83 wpa
= regex
.replaceall("\n", "", wpa
)
84 wpa_subfields
= ['wpa_ver', 'group_cipher', 'pairwise_ciphers', 'auth_suites', 'preauth']
86 def read_wifi(iface_name
):
87 fields
= sdict(); info
= sdict()
88 fields
.assoc
= "(IEEE 802.11)"
89 fields
.mode
= "Mode:([^\s]+)"
90 fields
.essid
= "ESSID:\"(.*?)\""
91 fields
.bssid
= "Access Point: ([^\s]+)"
92 fields
.key
= "Encryption key:([^\s]+)"
93 output
= procs
.run("%s %s" % (config
.iwconfig
, iface_name
))
94 for key
in fields
.keys():
95 info
[key
] = regex
.find1(fields
[key
], output
)
96 if info
.mode
: info
.mode
= info
.mode
.lower()
99 def setup_wifi(iface_name
, network
=None):
102 extra
+= "ap %s " % network
.bssid
103 extra
+= "essid \"%s\" " % network
.essid
105 key
= "s:%s" % network
.key
106 if not network
.key
: key
= "off"
107 extra
+= "key %s " % key
109 procs
.run("%s %s mode managed %s" % (config
.iwconfig
, iface_name
, extra
))
112 deadline
= time
.time()+1.5
113 while deadline
> time
.time():
114 info
= read_wifi(iface_name
)
115 if info
.assoc
: return True
119 def normal_scan(iface_name
):
121 deadline
= time
.time()+3
123 if time
.time() > deadline
: break
124 output
+= regex
.replaceall("^.+\n" , "", single_scan(iface_name
))
128 def single_scan(iface_name
):
129 procs
.kill_by_name(config
.iwlist
)
131 setup_wifi(iface_name
)
132 return procs
.run("%s %s scan" % (config
.iwlist
, iface_name
))
134 def read_scan(scan_data
):
136 config
.scan_count
+= 1
139 return config
.live_networks
142 blocks
= scan_data
.split("Cell")[1:]
145 fields
.bssid
= "Address: ([^\s]*)"
146 fields
.essid
= "ESSID:\"(.*?)\""
147 fields
.channel
= "Channel:([^\s]*)"
148 fields
.encrypted
= "Encryption key:(on)"
149 fields
.bitrate
= "Bit Rates:((?:[0-9.]* [Mbs;/]*\s*)*)"
150 fields
.quality
= "Quality=([0-9]+/[0-9]+)"
151 fields
.signal
= "Signal level=([^\s]* dBm)"
152 fields
.noise
= "Noise level=([^\s]* dBm)"
153 fields
.beacon
= "Last beacon: ([^\s]*ms)"
157 for key
in fields
.keys():
158 s
= regex
.find1(fields
[key
], block
)
159 if s
and s
.strip(): net
[key
] = s
.strip()
161 # special handling for bitrate
162 bitrates
= regex
.findall(fields
.bitrate
, block
)
164 bitrates
= " ".join(bitrates
)
165 bitrates
= regex
.findall('[0-9.]+', bitrates
)
166 bitrates
= map(float, bitrates
)
167 bitrates
= sorted(bitrates
)
168 bitrate
= bitrates
[-1]
169 bitrate
= (int(bitrate
) == float(bitrate
)
170 and int(bitrate
) or float(bitrate
))
171 net
.bitrate
= "%s Mb/s" % bitrate
173 # convert quality into percentage
175 st
= net
.quality
.split('/')
178 num
, den
= int(num
), int(den
)
179 net
.quality
= "%s%%" % int( 100 * num
/ den
)
181 # extract wpa details
182 fields
.wpa
= wpa
% "WPA Version"
183 fields
.wpa2
= wpa
% "WPA2 Version"
184 for field
in ['wpa', 'wpa2']:
185 m
= regex
.find(fields
[field
], block
)
188 for subfield
in wpa_subfields
:
189 wpa_info
[subfield
] = m
.group(subfield
)
190 net
[field
] = wpa_info
192 # shorthand security value for display
193 if net
.wpa
and net
.wpa2
: net
.sec
= 'wpa/wpa2'
194 elif net
.wpa
: net
.sec
= 'wpa'
195 elif net
.wpa2
: net
.sec
= 'wpa2'
196 elif net
.encrypted
and net
.encrypted
== "on":
200 net
.last
= time
.time()
202 config
.live_networks
= config
.live_networks
.merge1(net
, 'bssid')
207 if 'freq' not in net
:
210 net
.freq
= int(net
.freq
) + 1
212 config
.live_networks
.set_with('bssid', net
.bssid
, bump_freq
)
214 config
.live_networks
= opts
.post_negate_nets(config
.live_networks
, 'essid')
215 return config
.live_networks
218 if __name__
== "__main__":
221 #print config.networks
222 #print has_ip("eth1")
223 #print wire_connected("eth0")
225 # print display_live_networks(read_scan(normal_scan("eth1")), field='sec')
227 # print display_live_networks(read_scan(None))
231 nets
= read_scan(single_scan("wlan0"))
232 # nets = [n for n in nets if 'sec' not in n]
233 print ui
.display_live_networks(nets
, column
=3)
235 #print request_ip("eth1")
236 #print read_iface("eth1")
239 #print read_wifi("eth1")