Permalink
Browse files

Split off useful utilities into netutils 0.1

  • Loading branch information...
1 parent edea0a4 commit 8edb1092af843b2ff414c30349b2e71820f1394a @akkana committed Mar 26, 2012
Showing with 585 additions and 0 deletions.
  1. +133 −0 netutils.html
  2. +452 −0 netutils.py
View
133 netutils.html
@@ -0,0 +1,133 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html><head><title>Python: module netutils</title>
+</head><body bgcolor="#f0f0f8">
+
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
+<tr bgcolor="#7799ee">
+<td valign=bottom>&nbsp;<br>
+<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong>netutils</strong></big></big></font></td
+><td align=right valign=bottom
+><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/akkana/bin/netutils.py">/home/akkana/bin/netutils.py</a></font></td></tr></table>
+ <p><tt>netutils:&nbsp;a&nbsp;set&nbsp;of&nbsp;networking&nbsp;utilities&nbsp;for&nbsp;Python.<br>
+Copyright&nbsp;2010&nbsp;by&nbsp;Akkana&nbsp;Peck&nbsp;&lt;akkana@shallowsky.com&gt;<br>
+&nbsp;...&nbsp;share&nbsp;and&nbsp;enjoy&nbsp;under&nbsp;the&nbsp;GPLv2&nbsp;or&nbsp;(at&nbsp;your&nbsp;option)&nbsp;later.<br>
+&nbsp;<br>
+Provides&nbsp;the&nbsp;following:<br>
+&nbsp;<br>
+Classes:<br>
+&nbsp;&nbsp;<a href="#NetInterface">NetInterface</a>:&nbsp;name,&nbsp;ip,&nbsp;broadcast,&nbsp;netmask,&nbsp;essid,&nbsp;encryption,&nbsp;wireless<br>
+&nbsp;&nbsp;<a href="#AccessPoint">AccessPoint</a>&nbsp;:&nbsp;address,&nbsp;essid,&nbsp;encryption,&nbsp;quality,&nbsp;interface<br>
+&nbsp;&nbsp;<a href="#Route">Route</a>&nbsp;:&nbsp;display&nbsp;or&nbsp;change&nbsp;network&nbsp;routing&nbsp;tables.<br>
+&nbsp;<br>
+Functions&nbsp;outside&nbsp;of&nbsp;classes:<br>
+&nbsp;&nbsp;<a href="#-get_interfaces">get_interfaces</a>(only_up=False):&nbsp;returns&nbsp;a&nbsp;list&nbsp;of&nbsp;all&nbsp;<a href="#NetInterface">NetInterface</a>.<br>
+&nbsp;&nbsp;&nbsp;&nbsp;If&nbsp;only_up,&nbsp;will&nbsp;only&nbsp;return&nbsp;the&nbsp;ones&nbsp;currently&nbsp;marked&nbsp;UP.<br>
+&nbsp;&nbsp;<a href="#-get_wireless_interfaces">get_wireless_interfaces</a>():&nbsp;returns&nbsp;a&nbsp;list&nbsp;of&nbsp;wireless&nbsp;<a href="#NetInterface">NetInterface</a>.<br>
+&nbsp;&nbsp;<a href="#-get_accesspoints">get_accesspoints</a>():&nbsp;returns&nbsp;a&nbsp;list&nbsp;of&nbsp;visible&nbsp;AccessPoints.<br>
+&nbsp;&nbsp;<a href="#-ifdown_all">ifdown_all</a>():&nbsp;take&nbsp;all&nbsp;interfaces&nbsp;down,&nbsp;killing&nbsp;any&nbsp;wpa_supplicant&nbsp;or&nbsp;dhcp<br>
+&nbsp;&nbsp;<a href="#-kill_by_name">kill_by_name</a>(namelist):&nbsp;Kill&nbsp;a&nbsp;any&nbsp;running&nbsp;processes&nbsp;that&nbsp;include&nbsp;any<br>
+&nbsp;&nbsp;&nbsp;&nbsp;of&nbsp;the&nbsp;names&nbsp;in&nbsp;namelist.&nbsp;Return&nbsp;a&nbsp;list&nbsp;of&nbsp;actual&nbsp;process&nbsp;names&nbsp;killed.</tt></p>
+<p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#aa55cc">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
+
+<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
+<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="os.html">os</a><br>
+</td><td width="25%" valign=top><a href="re.html">re</a><br>
+</td><td width="25%" valign=top><a href="subprocess.html">subprocess</a><br>
+</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ee77aa">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
+
+<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
+<td width="100%"><dl>
+<dt><font face="helvetica, arial"><a href="netutils.html#AccessPoint">AccessPoint</a>
+</font></dt><dt><font face="helvetica, arial"><a href="netutils.html#NetInterface">NetInterface</a>
+</font></dt><dt><font face="helvetica, arial"><a href="netutils.html#Route">Route</a>
+</font></dt></dl>
+ <p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ffc8d8">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#000000" face="helvetica, arial"><a name="AccessPoint">class <strong>AccessPoint</strong></a></font></td></tr>
+
+<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
+<td colspan=2><tt>One&nbsp;Cell&nbsp;or&nbsp;<a href="#AccessPoint">AccessPoint</a>&nbsp;from&nbsp;iwlist&nbsp;output<br>&nbsp;</tt></td></tr>
+<tr><td>&nbsp;</td>
+<td width="100%">Methods defined here:<br>
+<dl><dt><a name="AccessPoint-__init__"><strong>__init__</strong></a>(self)</dt></dl>
+
+<dl><dt><a name="AccessPoint-clear"><strong>clear</strong></a>(self)</dt><dd><tt>Clear&nbsp;all&nbsp;parameters</tt></dd></dl>
+
+</td></tr></table> <p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ffc8d8">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#000000" face="helvetica, arial"><a name="NetInterface">class <strong>NetInterface</strong></a></font></td></tr>
+
+<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
+<td colspan=2><tt>A&nbsp;network&nbsp;interface,&nbsp;like&nbsp;eth1&nbsp;or&nbsp;wlan0.<br>&nbsp;</tt></td></tr>
+<tr><td>&nbsp;</td>
+<td width="100%">Methods defined here:<br>
+<dl><dt><a name="NetInterface-__init__"><strong>__init__</strong></a>(self, name)</dt></dl>
+
+<dl><dt><a name="NetInterface-__repr__"><strong>__repr__</strong></a>(self)</dt><dd><tt>Prettyprint&nbsp;a&nbsp;<a href="#NetInterface">NetInterface</a>&nbsp;instance</tt></dd></dl>
+
+<dl><dt><a name="NetInterface-ifconfig_down"><strong>ifconfig_down</strong></a>(self)</dt><dd><tt>Mark&nbsp;the&nbsp;interface&nbsp;DOWN&nbsp;with&nbsp;ifconfig</tt></dd></dl>
+
+<dl><dt><a name="NetInterface-ifconfig_up"><strong>ifconfig_up</strong></a>(self)</dt><dd><tt>Mark&nbsp;the&nbsp;interface&nbsp;UP&nbsp;with&nbsp;ifconfig</tt></dd></dl>
+
+</td></tr></table> <p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ffc8d8">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#000000" face="helvetica, arial"><a name="Route">class <strong>Route</strong></a></font></td></tr>
+
+<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
+<td colspan=2><tt>Network&nbsp;routing&nbsp;table&nbsp;entry:&nbsp;one&nbsp;line&nbsp;from&nbsp;route&nbsp;-n<br>&nbsp;</tt></td></tr>
+<tr><td>&nbsp;</td>
+<td width="100%">Methods defined here:<br>
+<dl><dt><a name="Route-__init__"><strong>__init__</strong></a>(self, *args)</dt><dd><tt>#&nbsp;<a href="#Route">Route</a>(line)<br>
+#&nbsp;<a href="#Route">Route</a>(dest,&nbsp;gateway,&nbsp;iface,&nbsp;mask=None)&nbsp;:</tt></dd></dl>
+
+<dl><dt><a name="Route-__repr__"><strong>__repr__</strong></a>(self)</dt><dd><tt>Return&nbsp;a&nbsp;string&nbsp;representing&nbsp;the&nbsp;route</tt></dd></dl>
+
+<dl><dt><a name="Route-add"><strong>add</strong></a>(self)</dt><dd><tt>Add&nbsp;this&nbsp;route&nbsp;to&nbsp;the&nbsp;routing&nbsp;tables.</tt></dd></dl>
+
+<dl><dt><a name="Route-call_route"><strong>call_route</strong></a>(self, cmd)</dt><dd><tt>Backend&nbsp;routine&nbsp;to&nbsp;call&nbsp;the&nbsp;system&nbsp;route&nbsp;command.<br>
+cmd&nbsp;is&nbsp;either&nbsp;"add"&nbsp;or&nbsp;"delete".<br>
+Users&nbsp;should&nbsp;normally&nbsp;call&nbsp;<a href="#Route-add">add</a>()&nbsp;or&nbsp;<a href="#Route-delete">delete</a>()&nbsp;instead.</tt></dd></dl>
+
+<dl><dt><a name="Route-delete"><strong>delete</strong></a>(self)</dt><dd><tt>Remove&nbsp;this&nbsp;route&nbsp;from&nbsp;the&nbsp;routing&nbsp;tables.</tt></dd></dl>
+
+<dl><dt><a name="Route-init_from_line"><strong>init_from_line</strong></a>(self, line)</dt><dd><tt>init&nbsp;from&nbsp;a&nbsp;line&nbsp;from&nbsp;route&nbsp;-n,&nbsp;such&nbsp;as:<br>
+192.168.1.0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;255.255.255.0&nbsp;&nbsp;&nbsp;U&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;eth0<br>
+default&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;192.168.1.1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0.0.0.0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;wlan0</tt></dd></dl>
+
+<hr>
+Static methods defined here:<br>
+<dl><dt><a name="Route-read_route_table"><strong>read_route_table</strong></a>()</dt><dd><tt>Read&nbsp;the&nbsp;system&nbsp;routing&nbsp;table,&nbsp;returning&nbsp;a&nbsp;list&nbsp;of&nbsp;Routes.</tt></dd></dl>
+
+</td></tr></table></td></tr></table><p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#eeaa77">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
+
+<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
+<td width="100%"><dl><dt><a name="-get_accesspoints"><strong>get_accesspoints</strong></a>()</dt><dd><tt>Return&nbsp;a&nbsp;list&nbsp;of&nbsp;visible&nbsp;wireless&nbsp;accesspoints.</tt></dd></dl>
+ <dl><dt><a name="-get_interfaces"><strong>get_interfaces</strong></a>(only_up<font color="#909090">=False</font>)</dt><dd><tt>Returns&nbsp;a&nbsp;list&nbsp;of&nbsp;NetInterfaces&nbsp;for&nbsp;all&nbsp;eth*,&nbsp;wlan*&nbsp;or&nbsp;mlan*<br>
+interfaces&nbsp;visible&nbsp;from&nbsp;ifconfig.<br>
+Omit&nbsp;lo,&nbsp;vpn,&nbsp;ipv6&nbsp;and&nbsp;other&nbsp;non-physical&nbsp;interfaces.<br>
+If&nbsp;only_up&nbsp;is&nbsp;true,&nbsp;use&nbsp;ifconfig&nbsp;instead&nbsp;if&nbsp;ifconfig&nbsp;-a.</tt></dd></dl>
+ <dl><dt><a name="-get_wireless_interfaces"><strong>get_wireless_interfaces</strong></a>()</dt><dd><tt>Returns&nbsp;a&nbsp;list&nbsp;of&nbsp;wireless&nbsp;interfaces&nbsp;available.</tt></dd></dl>
+ <dl><dt><a name="-ifdown_all"><strong>ifdown_all</strong></a>()</dt><dd><tt>Take&nbsp;all&nbsp;current&nbsp;interfaces&nbsp;down.</tt></dd></dl>
+ <dl><dt><a name="-kill_by_name"><strong>kill_by_name</strong></a>(namelist)</dt><dd><tt>Kills&nbsp;all&nbsp;running&nbsp;processes&nbsp;that&nbsp;start&nbsp;with&nbsp;any&nbsp;of&nbsp;the<br>
+strings&nbsp;in&nbsp;the&nbsp;given&nbsp;name&nbsp;list.</tt></dd></dl>
+</td></tr></table>
+</body></html>
View
452 netutils.py
@@ -0,0 +1,452 @@
+#! /usr/bin/env python
+#
+# Network utilities for Python.
+# Copyright 2010 by Akkana Peck akkana@shallowsky.com
+# ... share and enjoy under the GPLv2 or (at your option) later.
+
+"""netutils: a set of networking utilities for Python.
+Copyright 2010 by Akkana Peck <akkana@shallowsky.com>
+ ... share and enjoy under the GPLv2 or (at your option) later.
+
+Provides the following:
+
+Classes:
+ NetInterface: name, ip, broadcast, netmask, essid, encryption, wireless
+ AccessPoint : address, essid, encryption, quality, interface
+ Route : display or change network routing tables.
+
+Functions outside of classes:
+ get_interfaces(only_up=False): returns a list of all NetInterface.
+ If only_up, will only return the ones currently marked UP.
+ get_wireless_interfaces(): returns a list of wireless NetInterface.
+ get_accesspoints(): returns a list of visible AccessPoints.
+ ifdown_all(): take all interfaces down, killing any wpa_supplicant or dhcp
+ kill_by_name(namelist): Kill a any running processes that include any
+ of the names in namelist. Return a list of actual process names killed.
+"""
+
+import os, subprocess, re
+
+class NetInterface :
+ """A network interface, like eth1 or wlan0."""
+
+ def __init__(self, name) :
+ self.name = name
+ self.ip = ''
+ self.broadcast = ''
+ self.netmask = ''
+ self.essid = ''
+ self.encryption = None
+ self.up = False
+ self.wireless = False
+
+ def __repr__(self) :
+ """Prettyprint a NetInterface instance"""
+ s = 'NetInterface ' + self.name
+ if self.wireless :
+ if self.essid :
+ if self.encryption :
+ s += ' (wireless, essid=%s, %s)' % \
+ (self.essid, self.encryption)
+ else :
+ s += ' (wireless, essid=%s, open)' % self.essid
+ else :
+ s += ' (wireless)'
+ if self.up :
+ s += ' UP'
+ if self.ip :
+ s += ' ip=' + self.ip
+ if self.broadcast :
+ s += ' broadcast=' + self.broadcast
+ if self.netmask :
+ s += ' ip=' + self.netmask
+
+ return s
+
+ def ifconfig_up(self) :
+ """Mark the interface UP with ifconfig"""
+ subprocess.call(["ifconfig", self.name, "up"])
+
+ def ifconfig_down(self) :
+ """Mark the interface DOWN with ifconfig"""
+ subprocess.call(["ifconfig", self.name, "down"])
+
+class AccessPoint :
+ """ One Cell or AccessPoint from iwlist output"""
+
+ def __init__(self) :
+ self.clear()
+
+ def clear(self) :
+ """Clear all parameters"""
+ self.address = ""
+ self.essid = ""
+ self.encryption = ""
+ self.quality = ""
+ self.interface = ""
+ self.mode = ""
+
+class Route :
+ """Network routing table entry: one line from route -n"""
+
+ # Route(line)
+ # Route(dest, gateway, iface, mask=None) :
+ def __init__(self, *args) :
+ if len(args) == 1 :
+ print "init from line", args
+ self.init_from_line(args[0])
+ return
+
+ (self.dest, self.gateway, self.iface) = args
+ if len(args) > 3 :
+ self.mask = args[3]
+
+ def init_from_line(self, line) :
+ """init from a line from route -n, such as:
+192.168.1.0 * 255.255.255.0 U 0 0 0 eth0
+default 192.168.1.1 0.0.0.0 UG 0 0 0 wlan0
+ """
+ # Another place to get this is /proc/net/route.
+
+ words = line.split()
+ if len(words) < 8 :
+ self.dest = None
+ return
+ self.dest = words[0]
+ if self.dest == 'Destination' :
+ self.dest = None
+ return
+ self.gateway = words[1]
+ self.mask = words[2]
+ self.iface = words[7]
+
+ def __repr__(self) :
+ """Return a string representing the route"""
+ return "dest=%-16s gw=%-16s mask=%-16s iface=%s" % (self.dest,
+ self.gateway,
+ self.mask,
+ self.iface)
+
+ def call_route(self, cmd) :
+ """Backend routine to call the system route command.
+cmd is either "add" or "delete".
+Users should normally call add() or delete() instead."""
+ args = [ "route", cmd ]
+
+ # Syntax seems to be different depending whether dest is "default"
+ # or not. The man page is clear as mud and explains nothing.
+ if self.dest == 'default' or self.dest == '0.0.0.0' :
+ # route add default gw 192.168.1.1
+ # route del default gw 192.168.160.1
+ args.append(self.dest)
+ if self.gateway :
+ args.append("gw")
+ args.append(self.gateway)
+ else :
+ # route add -net 192.168.1.0 netmask 255.255.255.0 dev wlan0
+ args.append('-net')
+ args.append(self.dest)
+ if self.gateway :
+ args.append("gw")
+ args.append(self.gateway)
+ if self.mask :
+ args.append("mask")
+ args.append(self.mask)
+ args.append("dev")
+ args.append(self.iface)
+
+ print "Calling:", args
+ subprocess.call(args)
+
+ def add(self) :
+ """Add this route to the routing tables."""
+ self.call_route("add")
+
+ def delete(self) :
+ """Remove this route from the routing tables."""
+ # route del -net 192.168.1.0 netmask 255.255.255.0 dev wlan0
+ self.call_route("del")
+
+ @staticmethod
+ def read_route_table() :
+ """Read the system routing table, returning a list of Routes."""
+ proc = subprocess.Popen('route', shell=False, stdout=subprocess.PIPE)
+ stdout_str = proc.communicate()[0]
+ stdout_list = stdout_str.split('\n')
+
+ rtable = []
+ for line in stdout_list :
+ r = Route(line)
+ if r.dest :
+ rtable.append(r)
+
+ return rtable
+
+def get_interfaces(only_up=False) :
+ """Returns a list of NetInterfaces for all eth*, wlan* or mlan*
+ interfaces visible from ifconfig.
+ Omit lo, vpn, ipv6 and other non-physical interfaces.
+ If only_up is true, use ifconfig instead if ifconfig -a.
+ """
+ if only_up :
+ ifcfg = 'ifconfig'
+ else :
+ ifcfg = '/sbin/ifconfig -a'
+ proc = subprocess.Popen(ifcfg, shell=True, stdout=subprocess.PIPE)
+ stdout_str = proc.communicate()[0]
+ stdout_list = stdout_str.split('\n')
+ ifaces = []
+ cur_iface = None
+ for line in stdout_list :
+ if len(line) == 0 :
+ continue
+ words = line.split()
+ if line[0] != ' ' :
+ # It's a new interface. Should have a line like:
+ # eth0 Link encap:Ethernet HWaddr 00:01:4A:98:F1:51
+ # We only want the encap:Ethernet lines, not others like
+ # loopback, vpn, ipv6 etc.
+ if words[2] == 'encap:Ethernet' :
+ cur_iface = NetInterface(words[0])
+ ifaces.append(cur_iface)
+ else :
+ cur_iface = None
+ else :
+ if not cur_iface :
+ continue
+ if words[0] == 'inet' :
+ # inet addr:192.168.1.6 Bcast:192.168.1.255 Mask:255.255.255.0
+ match = re.search('addr:(\d+\.\d+\.\d+\.\d+)', line)
+ if match :
+ cur_iface.ip = match.group(1)
+ match = re.search('Bcast:(\d+\.\d+\.\d+\.\d+)', line)
+ if match :
+ cur_iface.broadcast = match.group(1)
+ match = re.search('Mask:(\d+\.\d+\.\d+\.\d+)', line)
+ if match :
+ cur_iface.netmask = match.group(1)
+ elif words[0] == 'UP' :
+ cur_iface.up = True
+
+ # Now we have the list of all interfaces. Find out which are wireless:
+ proc = subprocess.Popen('iwconfig', shell=False,
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ # TEMPORARY, FOR TESTING ON DESKTOPS:
+ #proc = subprocess.Popen('cat /home/akkana/iwconfig.out', shell=True,
+ # stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ stdout_str = proc.communicate()[0]
+ stdout_list = stdout_str.split('\n')
+ cur_iface = None
+ for line in stdout_list :
+ # print "line", line
+ if len(line) == 0 :
+ continue
+ if line[0] != ' ' :
+ words = line.split()
+ # print "New interface", words[0]
+ for iface in ifaces :
+ # print "Checking", words[0], "against", iface.name
+ if iface.name == words[0] :
+ # print "It's in the list"
+ cur_iface = iface
+ cur_iface.wireless = True
+ match = re.search('ESSID:"(.*)"', line)
+ if match :
+ cur_iface.essid = match.group(1)
+ # print "And it has essid", iface.essid
+
+ return ifaces
+
+def get_wireless_interfaces() :
+ """Returns a list of wireless interfaces available.
+ """
+ wifaces = []
+ for iface in get_interfaces() :
+ if iface.wireless :
+ wifaces.append(iface)
+ return wifaces
+
+def get_accesspoints() :
+ """Return a list of visible wireless accesspoints."""
+
+ # We can only get accesspoints if a wifi interface is up.
+ wiface = None
+ ifaces = get_interfaces()
+ for iface in ifaces :
+ if iface.wireless and iface.up :
+ wiface = iface
+ break
+ if not wiface and iface.wireless :
+ wiface = iface
+ if not wiface : # No wireless interface on this system
+ return None
+ if not wiface.up :
+ wiface.ifconfig_up()
+ else :
+ wiface = None # nothing to take down later
+
+ proc = subprocess.Popen('iwlist scan 2>/dev/null',
+ shell=True, stdout=subprocess.PIPE)
+ #proc = subprocess.Popen('cat /home/akkana/iwlist.out 2>/dev/null',
+ # shell=True, stdout=subprocess.PIPE, )
+ stdout_str = proc.communicate()[0]
+ stdout_list = stdout_str.split('\n')
+
+ iface = None
+ ap = None
+ aplist=[]
+
+ for line in stdout_list :
+ if len(line) == 0 :
+ continue
+ if not line[0].isspace() :
+ sp = line.find(' ')
+ if sp > 0 :
+ iface = line[:sp]
+ else :
+ iface = line
+ continue
+
+ line=line.strip()
+
+ match = re.search('Cell ', line)
+ if match :
+ ap = AccessPoint()
+ aplist.append(ap)
+ if iface :
+ ap.interface = iface
+
+ match = re.search('ESSID:"(.+)"', line)
+ if match :
+ if match.group(1) == "<hidden>":
+ ap.essid = ''
+ # I have no idea what these \x00\x00\x00\x00\x00 essids are,
+ # but they're quite common, and annoying to see in a UI:
+ elif match.group(1) == "\\x00\\x00\\x00\\x00\\x00":
+ ap.essid = "[null]"
+ else :
+ ap.essid = match.group(1)
+
+ match = re.search('Address: (\S+)', line)
+ if match:
+ ap.address = match.group(1)
+
+ match = re.search('Encryption key:([onf]+)', line)
+ if match:
+ if match.group(1) == "off" :
+ ap.encryption = "open"
+ else :
+ ap.encryption = "WEP" # change later if WPA
+
+ # match = re.search('Protocol:IEEE(.+)', line)
+ # if match:
+ # ap.protocol = match.group(1)
+
+ match = re.search('WPA', line)
+ if match:
+ ap.encryption = "WPA"
+
+ match = re.search('Mode:(.+)', line)
+ if match :
+ ap.mode = match.group(1)
+
+ match = re.search('Quality=([^ ]+) ', line)
+ if match :
+ ap.quality = match.group(1)
+
+ # If we marked an interface up just for this, mark it down again:
+ if wiface :
+ wiface.ifconfig_down()
+
+ return aplist
+
+def ifdown_all() :
+ """Take all current interfaces down.
+ """
+
+ up_ifaces = get_interfaces(True)
+
+ # Kill DHCP and wpa_supplicant.
+ # In theory apparently it's better to stop wpa_supplicant with
+ #os.system('wpa_cli -i %s terminate' % up_iface)
+ # except for the minor problem that it fails because
+ # it can't communicate with wpa_supplicant.
+ print "Killing dhcp processes"
+ kill_by_name(['dhcpcd', 'dhclient'])
+
+ # Kill wpa_supplicant in a separate step,
+ # to make it easier to tell whether it was actually running:
+ print "Killing wpa processes"
+ killed = kill_by_name(['wpa_supplicant'])
+
+ # If wpa_supplicant was one of the killed processes,
+ # then our wireless interface is all messed up now,
+ # and we'll never be able to connect to an open or WEP
+ # network with that interface again.
+ # The only way to fix it seems to be to unload and reload
+ # the wireless card's module. If it's not a module ... oops.
+ # First find the module:
+ if len(killed) >= 1 and len(up_ifaces) > 0 :
+ # Get the first wireless one. Hope there's only one.
+ iface = None
+ for i in up_ifaces :
+ if i.wireless :
+ iface = i
+ break
+ if iface :
+ fp = open("/sys/class/net/" + iface.name + "/device/uevent")
+ # Another way to get this: ethtool -i iface.name
+ line = fp.readline()
+ fp.close()
+ if line[0:7] == "DRIVER=" :
+ module = line[7:].strip()
+ print "Unloading", module, "module"
+ subprocess.call(["modprobe", "-r", module])
+ print "Re-loading", module, "module"
+ subprocess.call(["modprobe", module])
+ else :
+ print "Confusion! Can't find the old wireless interface to reload"
+
+ elif len(killed) == 0 :
+ print "Didn't kill wpa, no no need to reload modules"
+ else :
+ print "Didn't have any UP interfaces"
+
+ # It's apparently better to kill wpa_supplicant while the
+ # interface is still up (which takes it down).
+ # So now, finally, we can take everything down:
+ for iface in up_ifaces :
+ print "Marking", iface.name, "down"
+ iface.ifconfig_down()
+
+def kill_by_name(namelist) :
+ """Kills all running processes that start with any of the
+ strings in the given name list.
+ """
+ PROCDIR = '/proc'
+ killed = []
+ for proc in os.listdir(PROCDIR) :
+ if not proc[0].isdigit() :
+ continue
+ # Race condition: processes can come and go, so we may not be
+ # able to open something just because it was there when we
+ # did the listdir.
+ try :
+ procfp = open(os.path.join(PROCDIR, proc, 'cmdline'))
+ for line in procfp :
+ cmd = os.path.basename(line.split('\0')[0])
+ for name in namelist :
+ if name == cmd[0:len(name)] :
+ killed.append(name)
+ os.kill(int(proc), 9)
+ break # There's only one line anyway
+ procfp.close()
+ except :
+ pass
+ return killed
+
+# main
+if __name__ == "__main__" :
+ for iface in get_interfaces() :
+ print iface
+

0 comments on commit 8edb109

Please sign in to comment.