Hi,
I use very frequently the wireless to connect to different nets and I
have a script for personal use which probably (??) could be useful for
some of you. At least some of the misc people I know asked me to post
this here.
I also have seen/read a lot of critics to obsd for not having a couple
of tools for doing such things. I hope this helps obsd a bit (???).
In any case, I hope I don't overwhelm your inbox with unwished spam. I
am sure that a lot of you have already done something similar...
This script is thought to help you find the different available
connections (named "beams" for historical reasons) where you happen to
be when you execute it. It will display them in the following order:
1- "Public" connections (i.e. without wep key)
2- "Secured" connections (i.e. with wep)
They are also shown in order according to the strength of the signal
and then you're prompted to choose the number of the beam you wish to
connect to. Of course, if a wep password is required, you will be
asked for it. Afterwards it'll connect to it.
Please note that you will have to modify the script to
a- select your IFACE (in my case iwi0)
b- select your LANG (in my case "catala", but "english" is also available)
ah, so... author? Let's say... an "anonymous donor to the public domain" ;)
A big thank you to everybody and in this occasion especially to Damien
for his great work.
Cheers,
Pau
--------------------------------------------------------
#!/bin/sh
#
#
# wifiprobe ver 0.1
#
# Copyright (c) 2007 anonymous donor to the public domain
#
# BSD license and disclaimers apply.
#
# Do not change to zsh; it will break. There are subtle differences.
#
# This script should be installed with execute permissions, and
# be invoked by name.
#
# Developed under and for OpenBSD 4.1 9/2007
#
#-------------------------------------------------------------------------
#
# helper functions
#
#-------------------------------------------------------------------------
function parseit
{
local therest
shift 1
beamname=$1
shift 1
therest=$*
IFS=" "
set $therest
shift 4
sigstrength=$1
shift 1
}
function readprobe
{
#
# this was not as easy to write as it looks
#
local Foo
while read Foo
do
IFS=" "
if echo $Foo | grep -q \" ; then
IFS="\""
fi
parseit $Foo
beam[nbeam]=${beamname}
strength[nbeam]=${sigstrength%dB}
# printf "%4d\t%-32s\t%s\t%s\n" $nbeam "${beam[$nbeam]}"
$sigstrength ${strength[nbeam]}
nbeam=$(($nbeam+1))
done
}
function sortandprint
{
typeset tempnm
typeset tempst
typeset -i i
typeset -i j
typeset -i inc
typeset -i n
typeset -i s
s=$1
n=$2
# s is offset in arrays where sort starts
# n is number of items to sort
# In other words, sort elements $s to $s + $n
#
# Implement a Shell sort. In ksh. Painful. All the write-only jive-notation
# of perl, none of the functionality.
#
if [ $n -eq 0 ]; then
echo $MSG9
return
fi
inc=$(($n/2))
while [ $inc -gt 0 ]
do
i=$inc
while [ $i -lt $n ]
do
j=$i
tempst=${strength[$(($i+$s))]}
tempnm=${beam[$(($i+$s))]}
#
# to change the sense of the sort, change the second test.
# use -lt for biggest first, -gt for smallest first.
#
while [[ $j -ge $inc && ${strength[$(($j+$s-$inc))]} -lt $tempst ]]
do
strength[$(($j+$s))]=${strength[$(($j+$s-$inc))]}
beam[$(($j+$s))]=${beam[$(($j+$s-$inc))]}
j=$(($j-$inc))
done
strength[$(($j+$s))]=$tempst
beam[$(($j+$s))]=$tempnm
i=$(($i+1))
done
if [ $inc -eq 2 ]; then
inc=1
else
inc=$(($inc/2))
fi
done
i=$s
while [ $i -lt $(($n+$s)) ]
do
printf "%4d %-32s\t%3d dB\n" $(($i+1)) "${beam[$i]}" ${strength[$i]}
i=$(($i+1))
done
}
cleanup ()
{
if [ -t 0 -a -t 1 ]; then
stty sane
fi
rm -f ${TMPPROBE}
exit
}
#-------------------------------------------------------------------------
#
# "main" part of the script
#
#-------------------------------------------------------------------------
LANG="catala"
progname=`basename $0`
if [ X$LANG = X"english" ]; then
MSG1="$progname: Wireless access selection for device:"
MSG2="Available public beams"
MSG3="Available secured beams"
MSG4="$progname: no wireless beams found"
MSG5="choice out of range"
MSG6="try again"
MSG7="public access beam selected"
MSG8="$progname: not interactive and no public beams"
MSG9="none probed"
MSG10="usage: $progname [interface_name]"
CHOOSEPROMPT="Select beam> "
PASSPROMPT="Password for"
elif [ X$LANG = X"catala" ] ; then
MSG1="$progname: Dispositu de xarxa sense fil:"
MSG2="Xarxes obertes disponibles"
MSG3="Xarxes tancades detectades"
MSG4="$progname: No hi ha cap xarxa disponible"
MSG5="La xarxa que has triat no es troba en la llista"
MSG6="mira de fer-ho una altra vegada..."
MSG7="Has triat una xarxa oberta"
MSG8="$progname: No interactiu, i no hi ha d'obertes"
MSG9="no n'has avaluat cap"
MSG10="Com fer-ho servir: $progname [nom_dispositiu]"
CHOOSEPROMPT="Tria la xarxa> "
PASSPROMPT="Mot de pas per a"
fi
IFACE=iwi0
if [ $# -gt 0 ]; then
IFACE=$1
shift 1
if [ $# -gt 0 ]; then
echo Extra arguments: $@ 1>&2
echo $MSG10 1>&2
exit 1
fi
fi
TMPPROBE=`mktemp -t ${IFACE}.XXXXXXXX`
# only half-hearted efforts to rm this file are made.
testing=false
#testing=true
if [ X$testing = Xtrue ]; then
# hacks for development use by author
# exho="echo dummy command: "
# PROBECMD="cat /home/mass/play/weasel"
# SUDO=""
# SUDO="Pseudo-SUDO"
else
exho=""
SUDO="sudo"
PROBECMD="${SUDO} ifconfig -M ${IFACE}"
fi
trap cleanup EXIT INT PIPE
typeset -i nbeam=0
typeset -i private=0
# one can get more clever than this, one might involve PAGER
# one might involve LESS
# not this one, though
if [ -t 0 -a -t 1 ]; then
mypager=more
else
mypager=cat
fi
# generate a menu
# Do this even for batch use, to log results during, say, boot/rc
#
# if this script is used in another script and output is not
# wanted, then invoke it with >/dev/null and perhaps 2>/dev/null
# That is the True Path
#
# The parsing done by the sed/grep pipe is not robust at all.
# It is possible that a recipe for bouillabaise might pass muster
# as output sufficiently parseable to attempt to configure a device
# later on. The "correct" way to do this job is with a compiled
# program, modelled on ifconfig, that gathers this information from
# ioctl(2) calls on the device. (see routines getinfo() et al in
# the sources for ifconfig.) Parsing output not intended for
# human reading is a path to later madness. This script is twice
# as long as it might be, if the need to parse and later accomodate
# device "nwids" with embedded blanks did not exist.
#
echo $MSG1 ${IFACE}
echo
echo $MSG2
echo "-----------------------------------------------------------------"
eval $PROBECMD | sed "s/^[[:space:]]*//g" | grep ^nwid | grep -v
privacy > ${TMPPROBE}
readprobe < ${TMPPROBE}
sortandprint 0 $nbeam > ${TMPPROBE}
eval ${mypager} ${TMPPROBE}
# for obscure reasons of scoping, do not "simplify" the preceding
# two lines by discarding the temp file and putting readprobe on the
# end of the pipe.
#
# Put no function in a pipe (wrecks scope)
#
# the dividing point between public and private:
private=${nbeam}
echo
echo $MSG3
echo "-----------------------------------------------------------------"
eval $PROBECMD | sed "s/^[[:space:]]*//g" | grep ^nwid | grep privacy
>${TMPPROBE}
readprobe < ${TMPPROBE}
sortandprint $private $(($nbeam-$private)) > ${TMPPROBE}
eval ${mypager} ${TMPPROBE}
# the "if" establishes whether stdin and stdout are ttys.
# This is not flawless, of course, but tends to guess whether
# an operator is present.
# It would be better if a variable asserting batchness were present
# on the command line or in the environment.
typeset -i choice=-1
if [ $nbeam -eq 0 ] ; then
echo $MSG4 1>&2
cleanup
fi
if [ -t 0 -a -t 1 ]; then
while [ 0 ]
do
read choice?"$CHOOSEPROMPT"
if [ $choice -eq 0 ] ; then
break
elif [ $choice -gt $nbeam ] ; then
echo $MSG5 $choice
echo $MSG6
else
break
fi
done
if [ $choice -eq 0 ] ; then
cleanup
fi
#
# decrement choice to accommodate zero-based arrays
#
choice=$(($choice-1))
if [ $choice -ge $private ] ; then
stty -echo
read pass?"$PASSPROMPT ${beam[$choice]}> "
stty echo
echo
# this leaks the password to stdout when exho=echo. Big deal?
eval ${exho} ${SUDO} ifconfig ${IFACE} nwid \"${beam[$choice]}\" \
nwkey \"${pass}\"
else
echo $MSG7 ${beam[$choice]}
eval ${exho} ${SUDO} ifconfig ${IFACE} nwid \"${beam[$choice]}\" \
-nwkey down
fi
else # non-interactive: configure the first (strongest) public beam
if [ $private -eq 0 ] ; then
echo $MSG8 1>&2
cleanup
else
choice=1
eval ${exho} ${SUDO} ifconfig ${IFACE} nwid \"${beam[$choice]}\" \
-nwkey down 1>&2
fi
fi
eval ${exho} ${SUDO} dhclient ${IFACE}
cleanup