#! /bin/sh
# getwifi
# handles the joining of a wireless network
#
# (c)Joshua D. Abraham
set -o posix
VERSION=0.1.4
# Display debugging information
DEBUG=0
############################################################
# Configs #
############################################################
ENV=${ENV:-/usr/bin/env}
IWCONFIG=${IWCONFIG:-/sbin/iwconfig}
IWLIST=${IWLIST:-/sbin/iwlist}
DHCP_CLIENT=${DHCP_CLIENT:-/sbin/dhclient}
DHCP_LEASE=${DHCP_LEASE:-/var/lib/dhcp3/dhclient.leases}
IFCONFIG=${IFCONFIG:-/sbin/ifconfig}
ROUTE=${ROUTE:-/sbin/route}
CAT=${CAT:-/bin/cat}
TR=${TR:-/usr/bin/tr}
CONFIG_FILE=${CONFIG_FILE:-/etc/getwifi.conf}
INPUT=$*
PROG=`basename $0`
############################################################
#load deps into array
############################################################
DEPS=($IWCONFIG $IWLIST $DHCP_CLIENT $IFCONFIG $IFCONFIG \
$ROUTE $CAT $TR)
DEPLEN=${DEPS[@]}
############################################################
# display version #
############################################################
version() {
echo "version $VERSION"
exit 0
}
############################################################
# display proper usage #
############################################################
usage() {
echo " usage: $PROG [options]"
echo " "
echo " -f --file FILE Config file to be used"
echo " -h --help Show the help message"
echo " -i --interactive Interactive mode"
echo " -s --scan Scan for wireless networks"
echo " -v --version Show the version"
# echo " start"
# echo " stop"
# echo " restart "
echo " "
exit 0
}
############################################################
# scan for wireless essid's #
############################################################
scan() {
echo -n "Input device to scan: "
read DEVICE
toLower $DEVICE
DEVICE=$LOWER
$IWLIST $DEVICE scanning | awk '/ESSID/'
exit 0
}
############################################################
# checks to make sure a valid ip address is passed #
############################################################
validip(){
addr=$1
ONE=$(echo $1 2> /dev/null | cut -f 1 -d '.')
TWO=$(echo $1 2> /dev/null| cut -f 2 -d '.')
THREE=$(echo $1 2> /dev/null | cut -f 3 -d '.')
FOUR=$(echo $1 2> /dev/null| cut -f 4 -d '.')
TMP=`! echo $addr 2> /dev/null | egrep '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$'`
if test "$TMP" = "" ; then
return 1
fi
for i in $ONE $TWO $THREE $FOUR; do
if [ ! $i -ge 0 -o ! $i -le 255 ]; then
return 0
fi
done
}
############################################################
# dynamic loading of configs from user #
############################################################
interactive() {
echo -n "Type of Connection use(precedence|highsig): "
read CONNECT
toLower $CONNECT
CONNECT=$LOWER
if test "$CONNECT" != "precedence" -a "$CONNECT" \
!= "highsig" ; then
echo "Bad input for type of connection"
interactive
fi
echo -n "Input device to use: "
read DEVICE
toLower $DEVICE
DEVICE=$LOWER
echo "Your device is: $DEVICE"
# TODO added checking for a IPv4 address and SUBnet
echo -n "Input type of connection (dhcp/static): "
read TYPE
toLower $TYPE
TYPE=$LOWER
echo -n "Are your configurations similiar (yes/no): "
yesORno
if [ $? -eq 3 ] ; then
echo "bad input for type of configuration"
interactive
fi
SIMI=$YESNO
echo "Your device is: $DEVICE"
if test "$TYPE" != "dhcp" ; then
echo -n "Input type connection IP Address to use: "
read IP
validip $IP
if [ "$?" -eq 1 ] ; then
echo "Improper IP Address"
interactive
fi
echo -n "Input type connection Subnet to use: "
read SUB
validip $SUB
if [ "$?" -eq 1 ] ; then
echo "Improper Subnet Mask"
interactive
fi
echo -n "Input type connection Gateway to use: "
read GW
validip $GW
if [ "$?" -eq 1 ] ; then
echo "Improper Gateway Address"
interactive
fi
echo "Your connection is with a Static IP"
echo "IP Address: $IP"
echo "Subnet: $SUB"
echo "Gateway: $GW"
else
echo "Your connection is with a DHCP using client $DHCP_CLIENT"
echo -n "Is this the proper client? (yes/no): "
yesORno
YESNO=$?
if [ $? -eq 1 ] ; then
echo "Enter the DHCP client"
read DHCP_CLIENT
toLower $DHCP_CLIENT
DHCP_CLIENT=$LOWER
fi
fi
echo -n "Is all the information correct (yes/no): "
yesORno
TEST=$?
if [ $TEST -eq 1 ] ; then
interactive
elif [ $TEST -eq 2 ] ; then
#elif test "$VERIFY" = "y" -o "$VERIFY" = "yes" ; then
properconfig $CONNECT $DEVICE $SIMI $TYPE $IP $SUB $GW
echo "$?"
PROPCONF=$?
# if $TMP is 0 we are connecting with dhcp
# if $TMP is 1 we are connecting with static ip
if [ "$PROPCONF" -eq 0 -o "$PROPCONF" -eq 1 ] ; then
wire[0]="$CONNECT"
wire[1]="$DEVICE"
wire[2]="$SIMI"
wire[3]="$TYPE"
if [ "$PROPCONF" -eq 1 ] ; then
if test "$TYPE" = "static"
then
wire[4]="$IP"
wire[5]="$SUB"
wire[6]="$GW"
fi
else
continue
fi
else
echo "improper arguments"
exit 1
fi
else
echo "Bad Input to verify"
exit 1
fi
}
############################################################
# handles option of yes or no #
# returns 1 for no #
# return 2 for yes #
# return 3 for everything else #
############################################################
yesORno() {
#TMP=$1
#echo "$TMP"
read YESNO
toLower $YESNO
YESNO=$LOWER
if test "$YESNO" = "n" -o "$YESNO" = "no" ; then
return 1
elif test "$YESNO" = "y" -o "$YESNO" = "yes" ; then
return 2
else
return 3
fi
}
############################################################
# converts passed string from any case to lower case #
############################################################
toLower() {
local l=$1
LOWER=`echo $l | $TR A-Z a-z`
}
############################################################
# start monitoring to make sure the wireless card is #
# connected #
# TODO start working on a service to start #
############################################################
#startservice() {
#
# echo "start service"
# while [ true ]
# do
# loadconfig
# done
#}
############################################################
# stop monitoring to make sure the wireless card is #
# connected #
# TODO startworking on a service to stop #
############################################################
#stopservice() {
# echo "stop service"
# exit 0
#}
############################################################
# handles input from the user #
############################################################
input() {
case "$INPUT" in
-f|--file)
CONFIG_FILE=$2
checkdeps
;;
-h|--help)
usage
;;
-i|--interactive)
checkdeps
interactive
;;
-s|--scan)
checkdeps
scan
;;
-v|--version)
version
;;
* )
checkdeps
loadconfig
;;
esac
#while getopts hifv: opt ; do
# case $opt in
# h) usage
# ;;
# i) checkdeps
# interactive
# ;;
# f ) checkdeps
## #CONFIG_FILE=$OPTARG
## loadconfig
# ;;
# v ) version;;
# * ) checkdeps
# loadconfig;;
# esac
# done
# shift `expr $OPTIND - 1`
#
#if [ $# -ne 1 ]; then
# usage
#fi
#exit 0
#}
# start)
# startservice
## ;;
# stop )
# stopservice
# ;;
# restart)
# $0 stop
# sleep 1
# $0 start
# ;;
# esac
# done
#shift $(($OPTIND - 1 ))
}
############################################################
# handles input from the user in the configuration file #
# TODO BUG: check if var is already assigned #
# TODO Error Checking: check if IP address is valid #
############################################################
loadconfig() {
PASS=0
# check is config exists
if [ -e $CONFIG_FILE ] ; then
$CAT $CONFIG_FILE 1>/dev/null 2> /dev/null
while [ "$line" != "####" ] ; do
read line # Reads from $Filename, rather than stdin.
NAME=$(echo $line | awk '{print $1}')
# TODO BUG check if var is already assigned
if test "$NAME" = "DEVICE" ; then
local DEVICE=$(echo $line | awk '{print $3}')
toLower $DEVICE
DEVICE=$LOWER
((PASS++ ))
continue
elif test "$NAME" = "TYPE" ; then
local TYPE=$(echo $line | awk '{print $3}')
toLower $TYPE
TYPE=$LOWER
((PASS++ ))
continue
elif test "$NAME" = "IP" ; then
local IP=$(echo $line | awk '{print $3}')
validip $IP
if [ "$?" -eq 1 ] ; then
echo "Improper IP Address"
exit 1
fi
((PASS++ ))
continue
elif test "$NAME" = "SUBNET" ; then
local SUB=$(echo $line | awk '{print $3}')
validip $SUB
if [ "$?" -eq 1 ] ; then
echo "Improper Subnet Mask"
exit 1
fi
((PASS++ ))
continue
elif test "$NAME" = "GATEWAY" ; then
local GW=$(echo $line | awk '{print $3}')
validip $GW
if [ "$?" -eq 1 ] ; then
echo "Improper Gateway"
exit 1
fi
((PASS++ ))
continue
elif test "$NAME" = "CONNECT" ; then
local CONNECT=$(echo $line | awk '{print $3}')
toLower $CONNECT
CONNECT=$LOWER
if [ "$CONNECT" = "precedence" -o "$CONNECT" = "highsig" ] ; then
((PASS++ ))
continue
else
echo "CONNECT variable not set to (\"precedence\"||\"highsig\")"
exit 1
fi
#handles type of configuration
elif test "$NAME" = "SIMILAR" ; then
local SIMI=$(echo $line | awk '{print $3}' )
toLower $SIMI
SIMI=$LOWER
if [ "$SIMI" = "yes" -o "$SIMI" = "no" ] ; then
((PASS++ ))
continue
else
echo "SIMILAR variable not set to (\"yes\"|\"no\")"
exit 1
fi
#if all the head config parameters are defined execute parts
elif [ "$PASS" -eq 4 -o "$PASS" -gt 4 ] ; then
#assign output of fucntion to $tmp
properconfig $CONNECT $DEVICE $SIMI $TYPE $IP $SUB $GW
TMP=$?
# if $TMP is 0 we are connecting with dhcp
# if $TMP is 1 we are connecting with static ip
if [ "$TMP" -eq 1 -o "$TMP" -eq 2 ] ; then
wire[0]="$CONNECT"
wire[1]="$DEVICE"
wire[2]="$SIMI"
wire[3]="$TYPE"
if [ "$TMP" -eq 2 ] ; then
if test "$TYPE" = "static" ; then
wire[4]="$IP"
wire[5]="$SUB"
wire[6]="$GW"
fi
else
continue
fi
fi
else
continue
fi
done <$CONFIG_FILE # Redirects stdin to file $Filename.
else
echo "no config"
fi
}
############################################################
# determines if configuration is dhcp or static #
############################################################
properconfig() {
if test "$4" = "dhcp" ; then
if [ "$1" != "" ] || [ "$2" != "" ] || [ "$3" != "" ] || \
[ "$4" !="" ] ; then
return 1
else
return -1
fi
elif test "$4" = "static" ; then
if [ "$1" != "" ] || [ "$2" != "" ] || [ "$3" != "" ] || \
[ "$4" != "" ] || [ "$5" != "" ] || [ "$6" != "" ] || \
[ "$7" != "" ] ; then
return 2
else
return -1
fi
else
return -1
fi
return -1
}
############################################################
## handles nonsimiliar configuration file #
# TODO not implemented yet #
############################################################
nonsimiliar() {
echo "Not Implemented"
exit 0
CONNECT=$1
DEVICE=$2
TYPE=$3
echo "Connetion is: $CONNECT"
echo "Wireless device is: $DEVICE"
echo "Type of connection is: $TYPE"
if [ "$TYPE" != "dhcp" ] ; then
TYPE=$3
SUBNET=$4
fi
echo "handling non similiar"
exit 0
}
############################################################
# connect with dhcp using specified dhcp client #
############################################################
dhcp() {
DEVICE=$1
echo "Connection with DHCP"
while [ -e "$DHCP_LEASE" ]
do
echo "removing lease"
rm -f "$DHCP_LEASE"
done
exec $DHCP_CLIENT $DEVICE
if [ $? -eq 0 ] ; then
echo "connected with dhcp"
exit 0
else
echo "timeout"
fi
return 1
}
############################################################
# connect with a static ip using specified address #
# information #
############################################################
static(){
IP=$1
SUB=$2
GW=$3
echo "Connection with a Static IP"
if [ -e "$DHCP_LEASE" ] ; then
echo "removing lease"
rm -f "$DHCP_LEASE"
fi
$IFCONFIG $DEVICE down 1> /dev/null
$ROUTE del default 2> /dev/null 1>/dev/null
$IFCONFIG $DEVICE $IP 1> /dev/null
if [ $? -eq 0 ] ; then
echo -n "Static ip setup ..."
$ROUTE add default gw $GW > /dev/null
if [ $? -eq 0 ] ; then
echo "done"
elif [ $? -eq 7 ] ; then
echo "route already made"
echo "done"
else
$ROUTE del default > /dev/null
echo "retrying"
static $1 $2 $3
fi
else
echo "Unable to assign IP $IP to $DEVICE"
exit 1
fi
}
############################################################
# awk's version of head #
# only prints first line #
############################################################
awkhead(){
awk 'NR==1 {print;exit}'
}
############################################################
# awk's version of tail #
# only prints last line #
############################################################
awktail() {
awk 'END{print}'
}
############################################################
# checks that there is a signal on the given essid #
# TODO Feature add all the autentication arguements #
# TODO Add WPA #
# TODO Add WEP #
# TODO handle other options #
############################################################
checksig () {
# device essid
# ${wire[1]} ${ESSIDary[2]}
DEVICE=$1
ESSID=$2
KEY=$3
echo "checking signal on $ESSID"
if test $DEBUG -eq 1 ; then
echo "device is $DEVICE"
echo "key is $KEY"
fi
#command="$IWCONFIG $DEVICE essid \"$ESSID\""
$IWCONFIG $DEVICE key $KEY && sleep 1
if [ $? != 0 ] ; then
echo "Problem with seting WEP $KEY set on $DEVICE"
return 1
else
echo "wep key set to $KEY"
fi
$IWCONFIG $DEVICE essid $ESSID && sleep 1
if [ $? != 0 ] ; then
echo "Problem with $IWCONFIG connection to $ESSID on $DEVICE"
return 1
else
if test $DEBUG -eq 1 ; then
echo "changed"
fi
fi
SIGNAL=$("$CAT" /proc/net/wireless | awktail | awk '{print $3}')
if test $DEBUG -eq 1 ; then
echo "signal is $SIGNAL"
fi
if [ "$SIGNAL" -eq 100 ] ; then
SSID_TOJOIN=$("$IWCONFIG" "$DEVICE" | awkhead | awk '{print $4}' )
if test $DEBUG -eq 1 ; then
echo "ssid is: $ESSID"
echo "tojoin is: $SSID_TOJOIN"
fi
if [ "$SSID_TOJOIN" = "ESSID:\"$ESSID\"" ] ; then
return 0
else
return 1
fi
else
echo "not high enough"
return 1
fi
}
############################################################
# returns the signal of the essid passed #
############################################################
storesig() {
# device essid
# ${wire[1]} ${ESSIDary[2]}
local DEVICE=$1
local ESSID=$2
if test "$DEBUG" -eq 1 ; then
echo "checking signal on $ESSID"
echo "device is $DEVICE"
echo "essid is $ESSID"
fi
$IW `$DEVICE` essid `$ESSID` && sleep 1
SIGNAL=$($CAT /proc/net/wireless | awktail | awk '{print $3}')
echo "signal is $SIGINAL"
return $SIGNAL
}
############################################################
# determines if your card can handle multiple signals and #
# signal switching #
# example: ndiswrapper cards #
############################################################
highsigcard (){
DEVICE=$1
ESSID=$1
CHANGESIG=$($IWLIST $DEVICE scanning | awk '/Quality/' | awk '{print $1}')
if test $CHANGESIG = "Quality:0/100" ; then
return 1
else
return 0
fi
}
############################################################
# checks the dependencies #
# 1) critical checking for all specific deps that are used #
# 2) must be installed for running script #
# 3) anal checking or this is a boot floppy #
############################################################
checkdeps() {
echo -n "Checking for readability of /proc/net/wireless ... "
if [ -r /proc/net/wireless ] ; then
echo "Passed"
else
echo -e "Failled! /proc/net/wireless not readable"
exit 1
fi
echo -n "Checking for root privs ... "
if [ `whoami` = "root" ] ; then
echo "Passed"
else
echo -e "Failed! you need root privs"
exit 1
fi
#echo -n "Checking for OS ..."
#if test `uname -s` != "Linux" ; then
# echo "Operating System not yet supported"
# echo "Please contact Joshua Abraham if you would like to \
# work on porting $PROG"
# else
# echo "Passed"
# fi
x=0
for x in "${DEPS[@]}" ; do
echo -n "Checking for "$x" ... "
which $x 1> /dev/null 2> /dev/null
if [ $? != 0 ] ; then
echo "Failed! "$x" not found"
exit 1
else
echo "Passed"
#((x++))
fi
done
}
############################################################
# connect to wireless networks based on precedence #
############################################################
precedence() {
NUM=0
PROFILE=0
if test "$DEBUG" -eq 1 ; then
echo "Wire[0] Connection type is: ${wire[0]}"
echo "Wire[1] Device is: ${wire[1]}"
echo "Wire[2] Similar Connection : ${wire[2]}"
echo "Wire[3] TYPE of Connection is: ${wire[3]}"
echo "Wire[4] IP is: ${wire[4]}"
echo "Wire[5] SUBNET is: ${wire[5]}"
echo "Wire[6] GATEWAY is: ${wire[6]}"
fi
if test "${wire[2]}" = "yes" ; then #similiar config
while [ "$line" != "#end" ] ; do
cat $CONFIG_FILE 1>/dev/null 2> /dev/null
read line
CONFIGvar=$(echo $line | awk '{print $1}')
if test "$CONFIGvar" = "#PROFILE" -o "$PROFILE" -eq 1 ; then
PROFILE=1
if test "$CONFIGvar" = "KEY" ;then
KEYary[OPTIONS]=$(echo $line | awk '{print $3}')
((OPTIONS++ ))
continue
elif test "$CONFIGvar" = "ESSID" ; then
ESSIDary[$NUM]=$(echo $line | awk '{print $3}')
if test -z ${KEYary[$OPTIONS]}
then
KEYary[OPTIONS]=off
fi
checksig ${wire[1]} ${ESSIDary[$NUM]} ${KEYary[$OPTION]}
if [ $? -eq 0 ] ; then
((NUM++ ))
if test ${wire[3]} = "dhcp" ; then
ID=$($IWCONFIG $DEVICE | head -n 1 \
| awk '{print $4}' )
if test "$ID" = "ESSID:\"$ESSID\"" ; then
echo "real signal"
dhcp ${wire[1]} ${ESSIDary[$NUM]}
if [ $? -eq 0 ] ; then
echo "connected properly"
fi
else
continue
fi
else
#call for a static [ip] [sub] [gw]
static ${wire[4]} ${wire[5]} ${wire[6]}
if [ $? -eq 0 ] ; then
echo "connected properly"
exit 0
fi
fi
fi
else
continue
fi
else
continue
fi
done <$CONFIG_FILE # Redirects stdin to file $Filename.
elif test "${wire[2]}" = "no" ; then # non similiar config
echo "non similiar"
echo "this is not supported yet"
else
echo "what is wire[2]?"
fi
}
############################################################
# connect to wireless networks based on highest signal #
# strength #
############################################################
highsig(){
echo "Not Implemented"
exit 0
# echo "checking highest sigs"
# NUM=0
# if test "${wire[2]}" = "yes" #similiar config
# then
# while [ "$line" != "#end" ]
# do
# cat $CONFIG_FILE 1>/dev/null 2> /dev/null
# read line
# CONFIGvar=$(echo $line | awk '{print $1}')
#
# if test "$CONFIGvar" = "ESSID"
# then
# ESSIDary[$NUM]=$(echo $line | awk '{print $3}')
# checksig ${wire[1]} ${ESSIDary[$NUM]}
# if [ $? -eq 0 ]
# then
# SIGNALary[$NUM]=$(storesig ${wire[1]} ${ESSIDary[$NUM]})
# echo "signal strenth for ${ESSIDary[$NUM]} is: ${SIGNALary[$NUM]}"
# highsigcard ${wire[1]}
# if [ $? -eq 0 ]
# then
# echo "everything is look good"
# else
# echo "looks like your card can't connect best on higest"
# echo "sig strength"
# exit 1
# fi
# else
# echo "no signal"
# fi
# fi
# done <$CONFIG_FILE # Redirects stdin to file $Filename.
# elif test "${wire[2]}" = "no" #non-similiar config
# then
# echo "non similiar config"
# continue
# else
# echo "what is wire[2]?"
# fi
}
###########################################################
###################### MAIN ###########################
###########################################################
NUM=0
input
if test "${wire[0]}" = "precedence" ; then
precedence
elif test "${wire[0]}" = "highsig" ; then
highsig
fi