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