nullpointer
[dumbwifi.git] / network.py
blob553c0ba4989ff82f53e72e62f5ddc123d9e848eb
1 #!/usr/bin/env python
3 # Author: Martin Matusiak <numerodix@gmail.com>
4 # Licensed under the GNU Public License, version 3.
6 import re
7 import time
9 from conf import config
10 import opts
11 import procs
12 import regex
13 from sdict import sdict
14 import ui
17 # Interface status
19 def read_iface(iface_name):
20 fields = sdict(); info = sdict()
21 fields.ip = "inet addr:([0-9.]+)"
22 fields.up = "(UP)"
23 output = procs.run("%s %s" % (config.ifconfig, iface_name))
24 for key in fields.keys():
25 info[key] = regex.find1(fields[key], output)
26 return info
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):
32 return info.ip
34 def iface_up(iface_name, ip=None):
35 ip_str = ""
36 if ip: ip_str = "inet %s" % ip
37 info = read_iface(iface_name)
38 if not info.up:
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)
43 if info.up:
44 procs.run("%s %s inet 0.0.0.0 down" % (config.ifconfig, iface_name))
47 # DHCP
49 def request_ip(iface_name):
50 if config.dhcpcd:
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)
56 iface_up(iface_name)
58 if config.dhcpcd[0] == '/':
59 procs.run("%s -d -t5 %s" % (config.dhcpcd, iface_name))
60 else:
61 procs.run("%s %s 2>&1" % (config.dhclient, iface_name))
62 return has_ip(iface_name)
65 # Wired network
67 def wire_connected(iface_name):
68 iface_up(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
74 # Wireless network
76 wpa="""
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)*
82 """
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()
97 return info
99 def setup_wifi(iface_name, network=None):
100 extra = ""
101 if network:
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))
111 if network:
112 deadline = time.time()+1.5
113 while deadline > time.time():
114 info = read_wifi(iface_name)
115 if info.assoc: return True
116 time.sleep(0.75)
117 return False
119 def normal_scan(iface_name):
120 output = ""
121 deadline = time.time()+3
122 while 1:
123 if time.time() > deadline: break
124 output += regex.replaceall("^.+\n" , "", single_scan(iface_name))
125 time.sleep(0.5)
126 return output
128 def single_scan(iface_name):
129 procs.kill_by_name(config.iwlist)
130 iface_up(iface_name)
131 setup_wifi(iface_name)
132 return procs.run("%s %s scan" % (config.iwlist, iface_name))
134 def read_scan(scan_data):
135 # bump scan counter
136 config.scan_count += 1
138 if not scan_data:
139 return config.live_networks
142 blocks = scan_data.split("Cell")[1:]
144 fields = sdict()
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)"
155 for block in blocks:
156 net = sdict()
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)
163 if bitrates:
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
174 if net.quality:
175 st = net.quality.split('/')
176 if len(st) == 2:
177 (num, den) = st
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)
186 if m:
187 wpa_info = sdict()
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":
197 net.sec = 'wep'
199 # record time
200 net.last = time.time()
202 config.live_networks = config.live_networks.merge1(net, 'bssid')
205 # bump net counter
206 def bump_freq(net):
207 if 'freq' not in net:
208 net.freq = 1
209 else:
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__":
219 pass
220 ui.init_config()
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))
229 # curse("eth1",-1)
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")
237 #iface_up("eth1")
238 #iface_down("eth1")
239 #print read_wifi("eth1")