Skip to content

Commit

Permalink
Support both old and new ifconfig output formats;
Browse files Browse the repository at this point in the history
better reliability for open wi-fi 802.11b connections;
monitor success of starting dhcp client;
don't run ifup twice on debian;
rename 'add' option to 'multi';
better method documentation.
  • Loading branch information
akkana committed Mar 26, 2012
1 parent 192f538 commit bbe664c
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 79 deletions.
57 changes: 41 additions & 16 deletions netscheme
@@ -1,6 +1,7 @@
#! /usr/bin/env python
#
# Copyright 2010 by Akkana Peck akkana@shallowsky.com
# Network scheme-setting tool, version 1.4.
# Copyright 2010-2012 by Akkana Peck akkana@shallowsky.com
# ... share and enjoy under the GPLv2 or (at your option) later.
#

Expand Down Expand Up @@ -93,7 +94,7 @@ class NetScheme :
return s

def dump(self, filename=None) :
print "dump(", filename, ")"
print 'dump(', filename, ')'
if filename == None :
filename = homedirfile(".netscheme")
print "Appending new scheme to", filename
Expand All @@ -111,6 +112,7 @@ class NetScheme :
up_ifaces = netutils.get_interfaces(True)
for i in up_ifaces :
print "Taking", i, "down with ifdown"
i.ifconfig_down()
subprocess.call(["ifdown", i.name])

if add :
Expand Down Expand Up @@ -143,7 +145,6 @@ auto %s""" % (iface.name)

print "Encryption:", self.encryption
if self.encryption == "wpa" or self.encryption == "wpa2" :
print "It's WPA"
if self.essid :
print >>fp, "wpa-ssid", self.essid
if self.key :
Expand Down Expand Up @@ -186,8 +187,8 @@ auto %s""" % (iface.name)
if self.essid :
iwargs.append("essid")
iwargs.append(self.essid)
#iwargs.append("mode")
#iwargs.append("managed")
iwargs.append("mode")
iwargs.append("managed")
if accesspoint and accesspoint.address :
iwargs.append("ap")
iwargs.append(accesspoint.address)
Expand All @@ -197,11 +198,16 @@ auto %s""" % (iface.name)
else :
iwargs.append("key")
iwargs.append("off")
iwargs.append("enc")
iwargs.append("off")
#iwargs.append("enc")
#iwargs.append("off")
iwargs.append("channel")
iwargs.append("auto")
print "Calling", iwargs
subprocess.call(iwargs)

print "Called iwconfig: now it says"
os.system("iwconfig")

elif self.encryption == "wpa" :
tempfp = tempfile.NamedTemporaryFile(prefix="wpasup",
delete=False)
Expand All @@ -215,19 +221,22 @@ key_mgmt=WPA-PSK
psk="%s"
}""" % (self.essid, self.key)
tempfp.close()
print "Starting wpa_supplicant"
subprocess.Popen(["wpa_supplicant", "wpa_supplicant",
"-Dwext", "-i", iface.name, "-c", tempname])
# Is 1 second long enough for wpa_supplicant to open the file?
# 2 might be safer. What a drag.
time.sleep(2)
print "removing tmp file"
os.unlink(tempname)

if self.dhcp :
print "Getting dhcp"
subprocess.call(["dhcpcd", "-G", "-C", "resolv.conf", iface.name])
#subprocess.call(["dhclient", "-v", iface.name])
try :
subprocess.check_call(["dhcpcd", "-G", "-C", "resolv.conf",
iface.name])
#subprocess.call(["dhclient", "-v", iface.name])
except subprocess.CalledProcessError, e :
print "DHCP failed, error", e.returncode
iface.ifconfig_down()

else :
if not self.ip :
Expand Down Expand Up @@ -256,6 +265,7 @@ psk="%s"
# find the first wireless interface
for i in all :
print "Trying interface", i.name
if i.wireless: print i.name, "is wireless"
# The clause from hell. What this does is:
# - If the scheme has an encryption setting (including "open")
# then it's a wireless scheme and needs a wireless interface.
Expand Down Expand Up @@ -307,8 +317,17 @@ psk="%s"
# Mark the interface up (and call ifup too, if applicable)
subprocess.call(["ifconfig", iface.name, "up"])

# This somehow ends up being the second time it's called.
# So don't do that!
if is_deb :
subprocess.call(["ifup", iface.name])
# At one point I thought it was a good idea to call ifup
# explicitly. But at least with some cards, ifup associates
# with the accesspoint and calls DHCP -- all of which is
# about to be done again from service networking restart.
# And calling it the second time can fail (e.g. for Broadcom
# BCM4313 where the driver needs to be reloaded before
# each association).
#subprocess.call(["ifup", iface.name])
subprocess.call(["service", "networking", "restart"])

# Try to make the routing tables sane:
Expand All @@ -323,7 +342,6 @@ psk="%s"
if r.dest == 'default' or r.dest == '0.0.0.0' :
defaults.append(r)
print "Default route:", r
print "============"
if len(defaults) > 1 :
wired_route = None
# Find the first wired route
Expand Down Expand Up @@ -415,6 +433,10 @@ def find_and_set_scheme(newscheme, add=False) :
scheme.set_scheme(add)
return

# XXX TO DO: use python soundex module if available
# to see if there's a similarly named scheme --
# for instance, "Coffee Bean" instead of "coffeebean".

print "No scheme named", newscheme

aplist = netutils.get_accesspoints()
Expand All @@ -435,6 +457,8 @@ def find_and_set_scheme(newscheme, add=False) :
if ans == 'y' or ans == 'Y' :
scheme.dump()

return

#
# A couple of default schemes:
#
Expand Down Expand Up @@ -472,9 +496,9 @@ if __name__ == "__main__" :
default=False,
help="Reset the connection without changing scheme")
parser.add_option("-m", "--multi",
action="store_true", dest="add",
action="store_true", dest="multi",
default=False,
help="Add a new interface without bringing down current one")
help="Multiple interfaces: add a new interface without bringing down current one")
parser.add_option("-s", "--save",
action="store_true", dest="save_new_scheme",
default=False,
Expand Down Expand Up @@ -511,6 +535,7 @@ if __name__ == "__main__" :
newscheme.interface = config.get(scheme, 'interface')
Schemes.append(newscheme)

# Schemes are read, options are read, time to do stuff.
if (options.list_schemes) :
list_schemes()
elif (options.list_accesspoints) :
Expand All @@ -521,6 +546,6 @@ if __name__ == "__main__" :
#print parser.usage
print_current_scheme()
else :
find_and_set_scheme(args[0], options.add)
find_and_set_scheme(args[0], options.multi)
except KeyboardInterrupt :
print "Interrupt"
67 changes: 29 additions & 38 deletions netutils.html
@@ -1,33 +1,20 @@

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><title>Python: module netutils-1.3</title>
<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><a href="netutils-1.html"><font color="#ffffff">netutils-1</font></a>.3</strong></big></big></font></td
<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/web/software/netscheme/netutils-1.3.py">/home/akkana/web/software/netscheme/netutils-1.3.py</a></font></td></tr></table>
><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>
Provides&nbsp;classes&nbsp;and&nbsp;functions&nbsp;to&nbsp;allow&nbsp;finding&nbsp;a&nbsp;wireless&nbsp;interface,<br>
querying&nbsp;for&nbsp;accesspoints,&nbsp;or&nbsp;establishing&nbsp;a&nbsp;connection.</tt></p>
<p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#aa55cc">
Expand All @@ -47,16 +34,16 @@

<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-1.3.html#AccessPoint">AccessPoint</a>
</font></dt><dt><font face="helvetica, arial"><a href="netutils-1.3.html#Connection">Connection</a>
<dt><font face="helvetica, arial"><a href="netutils.html#AccessPoint">AccessPoint</a>
</font></dt><dt><font face="helvetica, arial"><a href="netutils.html#Connection">Connection</a>
</font></dt><dd>
<dl>
<dt><font face="helvetica, arial"><a href="netutils-1.3.html#DebianConnection">DebianConnection</a>
</font></dt><dt><font face="helvetica, arial"><a href="netutils-1.3.html#ManualConnection">ManualConnection</a>
<dt><font face="helvetica, arial"><a href="netutils.html#DebianConnection">DebianConnection</a>
</font></dt><dt><font face="helvetica, arial"><a href="netutils.html#ManualConnection">ManualConnection</a>
</font></dt></dl>
</dd>
<dt><font face="helvetica, arial"><a href="netutils-1.3.html#NetInterface">NetInterface</a>
</font></dt><dt><font face="helvetica, arial"><a href="netutils-1.3.html#Route">Route</a>
<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">
Expand All @@ -65,7 +52,7 @@
<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>
<td colspan=2><tt>One&nbsp;Cell&nbsp;or&nbsp;wireless&nbsp;access&nbsp;point&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>
Expand All @@ -78,17 +65,23 @@
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#000000" face="helvetica, arial"><a name="Connection">class <strong>Connection</strong></a></font></td></tr>

<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
<td colspan=2><tt>Make&nbsp;a&nbsp;connection.&nbsp;Subclass&nbsp;this&nbsp;with&nbsp;details&nbsp;of&nbsp;how&nbsp;the<br>
connection&nbsp;will&nbsp;actually&nbsp;be&nbsp;made.<br>&nbsp;</tt></td></tr>
<tr><td>&nbsp;</td>
<td width="100%">Methods defined here:<br>
<dl><dt><a name="Connection-__init__"><strong>__init__</strong></a>(self, iface<font color="#909090">=None</font>)</dt></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="DebianConnection">class <strong>DebianConnection</strong></a>(<a href="netutils-1.3.html#Connection">Connection</a>)</font></td></tr>
<font color="#000000" face="helvetica, arial"><a name="DebianConnection">class <strong>DebianConnection</strong></a>(<a href="netutils.html#Connection">Connection</a>)</font></td></tr>

<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
<td colspan=2><tt>Make&nbsp;a&nbsp;connection&nbsp;on&nbsp;a&nbsp;Debian&nbsp;system,&nbsp;using&nbsp;/etc/network/interfaces<br>
and&nbsp;service&nbsp;network&nbsp;restart&nbsp;(along&nbsp;with&nbsp;other&nbsp;helpers).<br>&nbsp;</tt></td></tr>
<tr><td>&nbsp;</td>
<td width="100%">Methods defined here:<br>
<dl><dt><a name="DebianConnection-__init__"><strong>__init__</strong></a>(self, iface<font color="#909090">=None</font>)</dt></dl>

Expand All @@ -101,9 +94,14 @@
<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="ManualConnection">class <strong>ManualConnection</strong></a>(<a href="netutils-1.3.html#Connection">Connection</a>)</font></td></tr>
<font color="#000000" face="helvetica, arial"><a name="ManualConnection">class <strong>ManualConnection</strong></a>(<a href="netutils.html#Connection">Connection</a>)</font></td></tr>

<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
<td colspan=2><tt>Make&nbsp;a&nbsp;connection&nbsp;by&nbsp;calling&nbsp;explicit&nbsp;programs&nbsp;like&nbsp;ifconfig,<br>
iwconfig,&nbsp;wpasupplicant,&nbsp;etc.&nbsp;In&nbsp;theory&nbsp;should&nbsp;work&nbsp;on&nbsp;any<br>
Linux&nbsp;machine,&nbsp;but&nbsp;some&nbsp;distros&nbsp;(especially&nbsp;Debian&nbsp;derivatives)<br>
may&nbsp;not&nbsp;work&nbsp;well&nbsp;and&nbsp;may&nbsp;need&nbsp;their&nbsp;own&nbsp;connection&nbsp;type.<br>&nbsp;</tt></td></tr>
<tr><td>&nbsp;</td>
<td width="100%">Methods defined here:<br>
<dl><dt><a name="ManualConnection-__init__"><strong>__init__</strong></a>(self, iface<font color="#909090">=None</font>)</dt></dl>

Expand Down Expand Up @@ -179,12 +177,5 @@
<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><p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#55aa55">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>

<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><strong>__warningregistry__</strong> = {("Parent module 'netutils-1' not found while handling absolute import", &lt;type 'exceptions.RuntimeWarning'&gt;, 28): True}</td></tr></table>
</td></tr></table>
</body></html>

0 comments on commit bbe664c

Please sign in to comment.