Manual (open) wireless network configuration is simple:
iwconfig (iface)
dhclient (iface)
... except that you need to parse `iwlist (iface)
Here is a really shoddy script that replaces NetworkManager with a trivial interactive loop to attempt to connect to one of the detected AP.
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
szym / Oct 2009
NetworkManager is not good enough when the APs are half-broken
(e.g., don't associate, don't give DHCP leases or don't route).
This is a really shoddy script that replaces NetworkManager.
"""
from os import popen, system
class WifiSelector:
def __init__(self, iface):
# test iface first
if(system("ls /sys/class/net/%s/wireless >/dev/null" % iface) != 0):
raise Exception("%s is not wireless" % iface)
self.iface = iface
self.aps = []
def scan(self):
""" iwlist <iface> scan
parse output and store in aps
"""
aps = []
cur = None
for l in popen("iwlist %s scan" % self.iface):
l = l.strip()
if (not l):
continue
if (l.startswith('Cell')):
if (cur != None):
aps.append(cur)
keys = [ 'essid','mode','chan','key','q','sig','noise','last' ]
cur = dict([(x, '???') for x in keys])
cur['ap'] = l.split()[4]
if (cur == None):
continue
if (l.startswith('ESSID')):
cur['essid'] = l.split(':')[1]
if (l.startswith('Mode')):
cur['mode'] = l.split(':')[1]
if (l.startswith('Channel')):
cur['chan'] = int(l.split(':')[1])
if (l.startswith('Encryption')):
cur['key'] = l.split(':')[1]
if (l.startswith('Quality')):
# Quality=15/100 Signal level:-84 dBm Noise level=-90 dBm
ls = l.replace(':', ' ').replace('/', ' ').replace('=', ' ').split()
cur['q'] = int(ls[1])
cur['sig'] = int(ls[5])
#cur['noise'] = int(ls[9])
if (l.startswith('Extra: Last beacon:')):
#Extra: Last beacon: 1888ms ago
cur['last'] = int(l.split()[3][:-2])
self.aps = aps
def show(self):
""" pretty print aps
"""
for i, ap in enumerate(self.aps):
print i, "%(mode)-6s %(key)-3s %(q)2d %(essid)-30s %(chan)4s %(ap)s %(last)5d" % ap
def sortq(self):
""" sort aps by quality
"""
self.aps.sort(key=lambda d: d['q'], reverse=True)
def refresh(self):
self.scan()
self.sortq()
self.show()
def select(self, i):
""" attempt to associate with aps[i]
"""
ap = self.aps[i]
system("iwconfig wlan0 essid %(essid)s ap %(ap)s" % ap)
system("dhclient %s" % self.iface)
def kill_nm(self):
if (system("/etc/init.d/network-manager status") == 0):
system("/etc/init.d/network-manager stop")
system("ifconfig %s up" % self.iface)
def main(args):
from sys import stderr
if (len(args) > 1 and args[1] == '-h'):
print >> stderr, "Usage: %s <iface>" % args[0]
return -1
if len(args) < 2:
iface = 'wlan0'
else:
iface = args[1]
ws = WifiSelector(iface)
ws.kill_nm()
ws.refresh()
while(True):
try:
which = int(raw_input('select (<0 refresh): '))
except:
break
if (which >= 0 and which < len(ws.aps)):
ws.select(which)
else:
ws.refresh()
if (__name__ == '__main__'):
from sys import argv
main(argv)
I need to figure out a better way to post small source code online. Any recommendations?
ReplyDelete