Discovering initng was great, really sped up booting. But it needed a 2.6.12+ kernel and I was on 2.6.8. Undaunted I installed Debian’s stock 2.6.16-1-686 kernel, which then broke all my wireless stuff.
Niavely thinking there must be an elegant way to do my set up I spent ages on google looking for advice. What I wanted is simple(ish):
- I use my laptop at home and at work. I have a wireless card that I can plug in when I need it.
- When it’s plugged in, I want the computer to connect (using a WPA PSK) to the available network, so I can just get on using it.
But what I found was that all the applications seem to be in a bit of a state of change, and getting them to play together is a challenge. Here’s my understanding, in case it’s useful. Or you may want to nip to the bottom of the page where I link to other pages I found useful.
Kernel level: wireless extentions (wext) and ndiswrapper
As I’m using ndiswrapper (deb. package 1.16-1), each time I change kernel, I need to recompile and install this module. There are lots of pages explaining how to do this.
- download source, userspace utils and kernel headers
- compile and install
- download WinXp/2k driver and (for my DLINK DWL-G650+ card).
- associate the new module with the wireless interface so it’s loaded when needed:
ie:
$ apt-get ndiswrapper-source ndiswrapper-utils-1.8 linux-headers-2.6.16-1-686
$ cd /usr/src; tar -xjf ndiswrapper-source.tar.bz2 ; cd modules/ndiswrapper
$ make distclean;make ; make install
$ ndiswrapper-1.8 -i GPLUS.inf
$ echo "alias wlan0 ndiswrapper" >/etc/modprobe.d/ndiswrapper
The pitfalls here are:
- Stupidly, I thought the .inf file was all that mattered. It isn’t. you need the .sys file too, which (I suppose) is the actual binary driver.
- the kernel driver is ndiswrapper (without it no lights on card, no joy), but the wireless extentions (wext) play a big part where I didn’t know they existed before (see below).
wpa_supplicant
This is the software that uses the card to associate with, then connect to wireless access points. It used to run as a system service daemon but now it’s fired up if needed according to /etc/network/interfaces stanzas. Here I explain how mine now works, not the miriad of other possibilities I tried before finding what did work!
$ apt-get install wpa_supplicant # I installed v. 0.4.8-4
Then my /etc/wpa_supplicant.conf file is:
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=0
eapol_version=1
ap_scan=1
fast_reauth=1
network={
ssid="smiles"
priority=9
key_mgmt=WPA-PSK
psk="oooh incredibly secret hex key..."
group=TKIP
proto=WPA
}
network={
ssid="peopleplanet"
priority=5
proto=WPA
key_mgmt=WPA-PSK
group=TKIP
psk="oooh another incredibly secret hex key..."
}
And my /etc/default/wpasupplicant (no _ ) is:
ENABLED=1
OPTIONS="-D wext -c /etc/wpa_supplicant.conf -Bw"
Note the -D wext bit which says use wext driver. I used to use ndiswrapper but now it only works specifying wext.
And I made this script to figure out where I am (there are others but this works):
#!/usr/bin/perl -w
use strict;
sleep 1; # give the computer time to realise there's a card...
die ("Must be called for wlan0") if ($#ARGV != 0 || $ARGV[0] ne 'wlan0' ) ;
my $iface = $ARGV[0]; # always wlan0 !
my %known = qw/
00:11:95:94:AA:A0 home
00:E0:98:E3:94:C6 work /;
my @networks = ();
my %tmpnet = ();
# pipe output of scan to me
open FH, ">>/home/rich/wlanthing.log";
print FH `date`, "\n\tScan full log:\n\t-------------\n";
my $fail=0;
open SCAN, "iwlist wlan0 scan 2>>/home/rich/wlanerr|" or $fail=1;
if ( $fail )
{ print FH "failed to open scan thingy.\n" ;
print FH $_ while (<SCAN>);
exit();
}
while (<SCAN>)
{
print FH "\t\t$_";
chomp;
if ( /^\s+Cell \d+ - Address: (.*)$/ )
{
# start of new network
# push any existing network onto @networks.
push @networks, {%tmpnet} unless ( %tmpnet eq "0" );
# print "new network. There are now " . @networks . " networks\n";
# clear network hash
%tmpnet = ('address',$1);
}
elsif ( /ESSID:"(.*)"/ ) { $tmpnet{'essid'}=$1 }
elsif ( /Encryption key:(.*)/ ) { $tmpnet{'encryption'}=$1 }
elsif ( /Quality(.*)/ ) { $tmpnet{'quality'}=$1 }
}
push @networks, {%tmpnet} unless ( %tmpnet eq "0" );
close SCAN;
my $net;
print FH "\n\tScan results:\n\t-------------\n";
#my $selected='rome';
my $selected='home';
my $netcount=1;
foreach $net ( @networks )
{
print FH "\tNetwork ", $netcount++, "\n";
print FH "\t\t$_ :" . $net->{$_} , "\n" foreach ( keys %{$net} ) ;
#or: print "\t$_ :" . $$net{$_}," \n" ;
#or: print "\t$_ :" . ${$net}{$_}," \n" ;
# $net is a pointer to a hash
if ( defined $known{$net->{'address'}} )
{
$selected = $known{$net->{'address'}};
print FH "\t\t**Recognised address, using ",
$net->{'essid'}," ".
$known{$net->{'address'}}, "**\n";
last;
}
else {print FH "\t\tUnknown network.\n" }
}
print $iface, '-', $selected, "\n";
print FH "\n\tOutput to ifup: ",$iface, '-', $selected, "\n\n";
close FH;
Set up /etc/network/interfaces
Mine is:
# Used by ifup(8) and ifdown(8). See the interfaces(5) manpage or
# /usr/share/doc/ifupdown/examples for more information.
mapping wlan0
script /home/rich/bin/wlanthing.pl
iface eth0 inet static
netmask 255.255.255.0
address 192.168.254.200
gateway 192.168.254.253
auto lo
iface lo inet loopback
address 127.0.0.1
allow-hotplug wlan0-home
iface wlan0-home inet static
address 192.168.1.3
netmask 255.255.255.0
gateway 192.168.1.1
wpa-ssid smiles
wpa-conf /etc/wpa_supplicant.conf
allow-hotplug wlan0-work
iface wlan0-work inet static
wpa-ssid peopleplanet
wpa-conf /etc/wpa_supplicant.conf
address 192.168.254.200
netmask 255.255.255.0
gateway 192.168.254.253
Set up ifplugd
V. confusing, but udev fires etc/hotplug.d/net/ifplugd.hotplug which in turn starts a ifplugd for the interface. Ifplugd usually has to detect when a network cable is plugged in, and configure the device accordingly. With wireless it’s different. For my set up the only thing that seems reliable is to look for whether the interface exists or not, ie. yes when the card is plugged in, no when it’s not.
So my /etc/default/ifplugd is:
INTERFACES="eth0 wlan0"
HOTPLUG_INTERFACES="all"
ARGS="-q -f -u0 -d2 -w -I"
ARGS_wlan0="-m iff -M -u2 -d0 -I -w"
SUSPEND_ACTION="stop"
How it all fits together
- Plug card in
- udev fires up ifplugd
- ifplugd realises there’s a wireless card in, and calls ifup wlan0
- ifup runs the mapping script for wlan
- the mapping script above looks at the output of iwlist wlan0 scan and figures out which of the access points’ Mac addresses it knows, and spits out something like “wlan0-home”.
- ifup realises from the wpa-… stanzas in /e/n/i under wlan0-home that wpa_supplicant is needed and starts it for that interface with the default options, before configuring the interface.
- wpa_supplicant connects to the access point (this probably happens before the interface can be up’ed but I really don’t know).
Non-solutions
guessnet seemed really neat: you put it as your mapping script and then with one line per network chunk in /e/n/i you can identify your wireless network by the mac address of your access point. But this relies upon a connection being already made, which means wpa_supplicant must have done it’s thing, which it can’t have because it’s not started until the network is chosen… I tried making a hotplug script to launch wpa supplicant first. Seemed a good idea since with the set up I have above, wpa supplicant will chose the available access point and connect to it (like roaming). This means that guessnet could…guess. However, it proved unreliable and everything on t’interweb seemed to say that wpa_supplicant should give up it’s roaming dreams and just focus on connecting with the security stuff. So I gave up on it too, which meant giving up on guessnet.
Then there’s wapraomd which seems simple enough, firing up scripts with the same name as the mac addresses of APs, or ESSIDs. Sounds great, but the debian version in Etch (testing) is broken (hotplug scripts points to wrong directory for hotplug.functions), which didn’t give me confidence and I couldn’t for the life of me figure out how it would work with ifplugd.
So I gave up and went back to my homespun script (which as you’ll see has loads of debugging logging in it!)
Pages I found useful
- Debian Administration page
- Emailed how-to
- wpa stuff you can put in /e/n/i
- wireless tools
- wpa supplicant homepage (actually I didn’t find this v. helpful at all!)
network-manager also seems interesting.
For what regards wpa_supplicant I still can't get it working, and I'm still stuck with wep.
The problem here is that we have a lot of eterogeneous systems that try to collaborate, and a well defined framework to establish how things should work has yet to be defined.
http://diabetes-20.pyhigle.info
http://google.com
http://excellent-credit-card.blogspot.com
http://mentax.zostura.cn
