update
[dumbwifi.git] / network.py
blob93f6bc9d3bbfcfc424fc8ab82ddb7d300062853c
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.replaceall('\n', ' ', bitrates)
162 bitrates = regex.replaceall('[ ]{2,}', ' ', bitrates)
163 bitrates = regex.findall('[0-9.]+', bitrates)
164 bitrates = map(float, bitrates)
165 bitrates = sorted(bitrates)
166 bitrate = bitrates[-1]
167 bitrate = (int(bitrate) == float(bitrate)
168 and int(bitrate) or float(bitrate))
169 net.bitrate = "%s Mb/s" % bitrate
171 # convert quality into percentage
172 if net.quality:
173 st = net.quality.split('/')
174 if len(st) == 2:
175 (num, den) = st
176 num, den = int(num), int(den)
177 net.quality = "%s%%" % int( 100 * num / den )
179 # extract wpa details
180 fields.wpa = wpa % "WPA Version"
181 fields.wpa2 = wpa % "WPA2 Version"
182 for field in ['wpa', 'wpa2']:
183 m = regex.find(fields[field], block)
184 if m:
185 wpa_info = sdict()
186 for subfield in wpa_subfields:
187 wpa_info[subfield] = m.group(subfield)
188 net[field] = wpa_info
190 # shorthand security value for display
191 if net.wpa and net.wpa2: net.sec = 'wpa/wpa2'
192 elif net.wpa: net.sec = 'wpa'
193 elif net.wpa2: net.sec = 'wpa2'
194 elif net.encrypted and net.encrypted == "on":
195 net.sec = 'wep'
197 config.live_networks = config.live_networks.merge1(net, 'bssid')
198 config.live_networks = opts.post_negate_nets(config.live_networks, 'essid')
199 return config.live_networks
202 if __name__ == "__main__":
203 pass
204 ui.init_config()
205 #print config.networks
206 #print has_ip("eth1")
207 #print wire_connected("eth0")
209 # print display_live_networks(read_scan(normal_scan("eth1")), field='sec')
211 # print display_live_networks(read_scan(None))
213 # curse("eth1",-1)
215 nets = read_scan(single_scan("wlan0"))
216 # nets = [n for n in nets if 'sec' not in n]
217 print ui.display_live_networks(nets, column=3)
219 #print request_ip("eth1")
220 #print read_iface("eth1")
221 #iface_up("eth1")
222 #iface_down("eth1")
223 #print read_wifi("eth1")