#!/usr/bin/perl # # essid-pick: configure a wireless interface to use one of a prioritized list # of available interfaces. # # Copyright 2004-2005 Patrick Reynolds (reynolds .at. cs duke edu) # # Usage: # essid-pick [ [...]] # For example: # essid-pick wlan0 Home Work CoffeeHouse # # If none of the requested interfaces is available (or if ESSID scanning # fails), essid-pick will fall back on "any," which lets the card choose one. # # If you need extra arguments to iwconfig for a specific network (e.g., # an encryption key), specify them in /etc/essid-pick.conf. All such # arguments will be passed verbatim to iwconfig. For example: # [Home] # key s:abcde # # Debian users: the easiest way to incorporate this script into your # boot process is as a "pre-up" line in /etc/network/interfaces. # For example: # iface wlan0 inet dhcp # pre-up /usr/sbin/essid-pick wlan0 Home Work CoffeeHouse # $proc = "/proc/net/wireless"; $iwlist = "/sbin/iwlist"; $iwconfig = "/sbin/iwconfig"; $conf = "/etc/essid-pick.conf"; if ($#ARGV < 1) { print STDERR "Usage:\n $0 interface essid [essid2 [essid3 [...]]]\n"; exit 1; } $iface = shift; find_interfaces($iface); read_config(); print "Requested APs:"; foreach (@ARGV) { print " $_($found{$_})"; } print "\n"; foreach (@ARGV) { if ($found{$_}) { system("$iwconfig $iface essid \"$_\" $args{$_}"); print "Configuring $iface to use $_:\n"; $args{$_} =~ s/key\s+\S+/key /g; $args{$_} =~ s/enc\s+\S+/enc /g; print " $args{$_}\n"; exit 0; } } print STDERR "None of the requested interfaces was found!\n"; system("$iwconfig $iface essid any"); exit 0; sub find_interfaces { my $iface = shift; print "Available APs for $iface:"; system("ifconfig $iface up"); open(IWLIST, "$iwlist $iface scan 2>&1 |") || die "$iwlist: $!"; while () { chomp; if (/ESSID:\s*"([^"]+)"/) { print " \"$1\""; $found{$1}++; } elsif (/Failed to read scan data/) { print "$iwlist failed here. Blah.\n"; system("$iwconfig $iface essid any"); exit 0; } } print "\n"; close(IWLIST); system("ifconfig $iface down"); } sub read_config { if (!open(CONF, "<$conf")) { print "$0: $conf not found\n"; return; } my $ssid; while () { chomp; s/#.*//; next if /^$/; if (/^\[\s*(.+?)\s*\]$/) { $ssid = $1; } else { $args{$ssid} .= " $_"; } } close(CONF); }