1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
|
#!/bin/sh
# wifichoice.sh by Stefan Tomanek (stefan@pico.ruhr.de)
# http://localhost.ruhr.de/~stefan/interfaces/
#
# Wifichoice selects the proper configuration profile for your WLAN
# interface by scanning for the right environment.
# To achieve this, it can either scan for the correct access point
# or ESSID, or try to associate with the configured network.
#
# Configuration is done in a central way via /etc/network/interfaces:
#
# mapping wlan0
# script /usr/local/sbin/ifichoice.sh
# map default: none
# map timeout: 2
#
# Timeout is the number of seconds the script waits after a test
# association for the device to settle, and default is the profile
# that shoud be loaded is if no known surrounding is detected.
#
# The test parameters are defined in the profiles themselves:
#
# iface home inet dhcp
# wireless yes
# wireless_mode managed
# wireless_key open 1234567890ABCDEF1234567890
# wireless_essid mywifinet
# wifichoice ap 00:12:34:56:78:9A
#
# Since your access point does not not broadcast its ESSID,
# and/or your card does not support "iwlist scan", wifichoice tries to
# associate with the network, using the supplied config, and then checks
# whether the network is managed by the right access point.
#
# If you can identify the network by its broadcasted ESSID or AP, you can
# also try to scan for it. Just add a line like this to your profile:
#
# wifichoice scan essid mywifinet
#
# Wifichoice then invokes a scan for neighbouring access points, and
# identifies those that serve the requested ESSID. It is also possible
# to scan for a specific access point address, this is useful if the AP
# does not transmit its ESSID:
#
# wifichoice scan ap 00:12:34:56:78:9A
# Which physical interface do we operate on?
IFACE=$1
# How long do we wait for the interface to settle?
TIMEOUT=2
# What is the default profile?
DEFAULT=""
DEBUG=0
# Paths to files
ENI=/etc/network/interfaces
IWCONFIG=/sbin/iwconfig
IFCONFIG=/sbin/ifconfig
IWLIST=/sbin/iwlist
IWGETID=/sbin/iwgetid
readConfig() {
while read L <&0; do
OPTION="$(echo $L | cut -d: -f1)"
VALUE="$(echo $L | cut -d ' ' -f2)"
if [ "$OPTION" = "default" ]; then
DEFAULT=$VALUE
elif [ "$OPTION" = "timeout" ]; then
TIMEOUT=$VALUE
elif [ "$OPTION" = "debug" ]; then
DEBUG=$VALUE
fi
done
debugMSG "Debug output is enabled"
debugMSG "Timout is $TIMEOUT seconds"
debugMSG "Default profile is $DEFAULT"
}
reset() {
IF="$1"
CONF="mode managed enc off ap auto essid auto"
$IWCONFIG $IF $CONF
$IFCONFIG $IF down
}
config() {
IF="$1"
reset $IF
CONF="$2"
debugMSG "Trying wireless configuration: $CONF";
$IWCONFIG $IF $CONF
$IFCONFIG $IF up
sleep $TIMEOUT
}
checkAP() {
IF="$1"
AP="$2"
[ "$($IWGETID $IF -ra)" = "$AP" ]
}
scanESSID() {
IF="$1"
ESSID="$2"
FOUND=0
# certain PC-Cards need this
$IFCONFIG $IF up
$IWLIST $IF scan | egrep -q '^[[:space:]]*ESSID:"'$ESSID'"$' && FOUND=1
$IFCONFIG $IF down
[ $FOUND -eq 1 ]
}
scanAP() {
IF="$1"
AP="$2"
FOUND=0
$IFCONFIG $IF up
$IWLIST $IF scan | egrep -q '^[[:space:]]*Cell [[:digit:]]+ - Address: '$AP'$' && FOUND=1
$IFCONFIG $IF down
[ $FOUND -eq 1 ]
}
debugMSG() {
if [ $DEBUG -eq 1 ]; then echo "$*" >&2 ; fi
}
checkProfile() {
FOUND=0
if [ "$METHOD" = "ap" ]; then
debugMSG "Trying to associate with $PROFILE"
AP="$(echo $TEST | cut -d ' ' -f 2)"
config $IFACE "$CONFIG"
checkAP $IFACE $AP && FOUND=1
elif [ "$METHOD" = "scan" ]; then
debugMSG "Scanning for $PROFILE"
# What are we scanning for?
# We support essid and ap
FOR="$(echo $TEST | cut -d ' ' -f 2)"
VAL="$(echo $TEST | cut -d ' ' -f 3)"
if [ "$FOR" = "essid" ]; then
debugMSG "Scanning for essid $VAL"
scanESSID $IFACE $VAL && FOUND=1
elif [ "$FOR" = "ap" ]; then
debugMSG "Scanning for access point $VAL"
scanAP $IFACE $VAL && FOUND=1
fi
fi
if [ $FOUND -eq 1 ]; then
debugMSG "Success!"
echo $PROFILE >&3
fi
[ $FOUND -eq 1 ]
}
# Kill STDOUT
exec 3>&1 1>/dev/null
readConfig
PROFILE=""
CONFIG=""
FOUND=0
TEST=""
METHOD=""
sed 's/^[[:space:]]*//; s/#.*$//g' $ENI | while read LINE; do
if echo $LINE | egrep -q '^iface [[:alnum:]]+'; then
# new profile started, check for past profile
if [ "$PROFILE" ] && [ "$TEST" ]; then
checkProfile $PROFILE $TEST $METHOD && break;
fi
# reset vars
PROFILE="$(echo $LINE | cut -d " " -f 2)"
CONFIG=""
TEST=""
METHOD=""
elif echo $LINE | egrep -q '^wireless(_|-)([[:alnum:]])+'; then
CMD="$(echo $LINE | sed 's/^wireless\(_\|-\)//')"
CONFIG="$CONFIG$CMD "
elif echo $LINE | egrep -q '^wifichoice'; then
TEST="$(echo $LINE | cut -d ' ' -f 2-)"
METHOD="$(echo $TEST | cut -d ' ' -f 1)"
reset $IFACE
fi
done
reset $IFACE
|