add freq
[dumbwifi.git] / network.py
blob1417178fcb69de41c7d5a76bf6d4d46df3efe632
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 if not scan_data:
136 return config.live_networks
138 blocks = scan_data.split("Cell")[1:]
140 fields = sdict()
141 fields.bssid = "Address: ([^\s]*)"
142 fields.essid = "ESSID:\"(.*?)\""
143 fields.channel = "Channel:([^\s]*)"
144 fields.encrypted = "Encryption key:(on)"
145 fields.bitrate = "Bit Rates:((?:[0-9.]* [Mbs;/]*\s*)*)"
146 fields.quality = "Quality=([0-9]+/[0-9]+)"
147 fields.signal = "Signal level=([^\s]* dBm)"
148 fields.noise = "Noise level=([^\s]* dBm)"
149 fields.beacon = "Last beacon: ([^\s]*ms)"
151 for block in blocks:
152 net = sdict()
153 for key in fields.keys():
154 s = regex.find1(fields[key], block)
155 if s and s.strip(): net[key] = s.strip()
157 # special handling for bitrate
158 bitrates = regex.findall(fields.bitrate, block)
159 if bitrates:
160 bitrates = " ".join(bitrates)
161 bitrates = regex.findall('[0-9.]+', bitrates)
162 bitrates = map(float, bitrates)
163 bitrates = sorted(bitrates)
164 bitrate = bitrates[-1]
165 bitrate = (int(bitrate) == float(bitrate)
166 and int(bitrate) or float(bitrate))
167 net.bitrate = "%s Mb/s" % bitrate
169 # convert quality into percentage
170 if net.quality:
171 st = net.quality.split('/')
172 if len(st) == 2:
173 (num, den) = st
174 num, den = int(num), int(den)
175 net.quality = "%s%%" % int( 100 * num / den )
177 # extract wpa details
178 fields.wpa = wpa % "WPA Version"
179 fields.wpa2 = wpa % "WPA2 Version"
180 for field in ['wpa', 'wpa2']:
181 m = regex.find(fields[field], block)
182 if m:
183 wpa_info = sdict()
184 for subfield in wpa_subfields:
185 wpa_info[subfield] = m.group(subfield)
186 net[field] = wpa_info
188 # shorthand security value for display
189 if net.wpa and net.wpa2: net.sec = 'wpa/wpa2'
190 elif net.wpa: net.sec = 'wpa'
191 elif net.wpa2: net.sec = 'wpa2'
192 elif net.encrypted and net.encrypted == "on":
193 net.sec = 'wep'
195 # record time
196 net.seen = time.time()
198 config.live_networks = config.live_networks.merge1(net, 'bssid')
201 # bump net counter
202 def bump_freq(net):
203 if 'freq' not in net:
204 net.freq = 1
205 else:
206 net.freq = int(net.freq) + 1
208 config.live_networks.set_with('bssid', net.bssid, bump_freq)
210 # bump scan counter
211 config.scan_count += 1
213 config.live_networks = opts.post_negate_nets(config.live_networks, 'essid')
214 return config.live_networks
217 if __name__ == "__main__":
218 pass
219 ui.init_config()
220 #print config.networks
221 #print has_ip("eth1")
222 #print wire_connected("eth0")
224 # print display_live_networks(read_scan(normal_scan("eth1")), field='sec')
226 # print display_live_networks(read_scan(None))
228 # curse("eth1",-1)
230 nets = read_scan(single_scan("wlan0"))
231 # nets = [n for n in nets if 'sec' not in n]
232 print ui.display_live_networks(nets, column=3)
234 #print request_ip("eth1")
235 #print read_iface("eth1")
236 #iface_up("eth1")
237 #iface_down("eth1")
238 #print read_wifi("eth1")