#!/bin/bash
#
# Wireless Access Point Scanning and Manipulation 0.1
#
#	Copyright (c) Bryan Biedenkapp <gatekeep@circlesoftus.org>
#
#

RES_COL=40
MOVE_TO_COL="echo -en \\033[${RES_COL}G"
SETBACKGROUND_NORMAL="echo -en \\033[0;37;0m"
SETBACKGROUND_BLUE="echo -en \\033[0;37;44m"
SETCOLOR_NORMAL="echo -en \\033[0;37;44m"
SETCOLOR_BRIGHT="echo -en \\033[1;37;44m"
SETCOLOR_GREEN="echo -en \\033[1;32;44m"
SETCOLOR_RED="echo -en \\033[1;31;44m"
SETCOLOR_SPECIAL_RED="echo -en \\033[1;33;41m"
SETCOLOR_YELLOW="echo -en \\033[1;33;44m"

WIRELESS_DEVICE=$1

TRUE=1
FALSE=0

if [ ! $1 ]
then
    #unset WIRELESS_DEVICE
    echo ""
fi

## INTERNAL FUNCTIONS ##
function displayDevice
{
    echo -n $"Using Wireless Device:"
    $MOVE_TO_COL
    echo -n $"[ "
    $SETCOLOR_GREEN
    echo -n ${WIRELESS_DEVICE}
    $SETCOLOR_NORMAL
    echo -n $" ]"
    echo
}    

function getinput
{
    unset GETINPUT
    while [ "$GETINPUT" == '' ]
    do {
	echo -n "$1"
	read GETINPUT
    }
    done
}

## PROGRAM FUNCTIONS ##
function printVersion
{
    echo "Wireless Access Point Scanning and Manipulation - Version 0.1"
    echo "	Copyright (c) Bryan Biedenkapp <gatekeep@circlesoftus.org>"
    echo
    $SETCOLOR_YELLOW
    #echo "Please note that the author is not responsible for any actions that"
    #echo "you take while using this program. USE AT YOUR OWN RISK!"
    echo "Type 'help' for commands listing or 'quit' to exit"
    $SETCOLOR_NORMAL
}

function printHeader
{
    $SETBACKGROUND_BLUE
    clear
    printVersion
    echo
    displayDevice
    echo
}

function printHelp
{
    printVersion
    echo
    $SETCOLOR_BRIGHT
    echo "[HELP]"
    $SETCOLOR_NORMAL
    echo "Wireless Commands:"
    echo -n $"	scan, scan loop, \"s\" or \"l\""
    $MOVE_TO_COL
    echo "- Perform a Access Point scan [Non/Loop]"
    echo -n $"	connect or \"c\""
    $MOVE_TO_COL
    echo "- Connect to a specific Access Point"
    echo -n $"	disconnect or \"d\""
    $MOVE_TO_COL
    echo "- Disconnect from a specific Access Point"
    echo -n $"	interface or \"i\""
    $MOVE_TO_COL
    echo "- Displays network interface information"
    echo -n $"	channel or \"chan\""
    $MOVE_TO_COL
    echo "- Change the network cards operating frequency/channel"
    echo -n $"	txpower or \"t\""
    $MOVE_TO_COL
    echo "- Change transmission power (TX Power)"
    echo -n $"	sensitivity or \"sens\""
    $MOVE_TO_COL
    echo "- Change the network card sensitivity"
    echo -n $"	mode or \"m\""
    $MOVE_TO_COL
    echo "- Change the network card mode"
    echo -n $"	getchannel"
    $MOVE_TO_COL
    echo "- Get the current operating channel"
    echo -n $"	getbitrate"
    $MOVE_TO_COL
    echo "- Get the current operating bitrate"
    echo
    echo "Network Commands:"
    echo -n $"	traceroute or \"t\""
    $MOVE_TO_COL
    echo "- Perform a traceroute to a specific IP address or hostname"
    echo -n $"	ping or \"p\""
    $MOVE_TO_COL
    echo "- Perform a ping to a specific IP address or hostname"
    echo
    echo "General Commands:"
    echo -n $"	clear"
    $MOVE_TO_COL
    echo "- Clear console"
    echo -n $"	help, \"h\" or \"?\""
    $MOVE_TO_COL
    echo "- Display this message"    
    echo -n $"	ver"
    $MOVE_TO_COL
    echo "- Display the version information"
    echo -n $"	quit"
    $MOVE_TO_COL
    echo "- Terminate the program"
    echo
}

function performScan
{
    $SETCOLOR_RED
    echo "Performing Wireless Access Point Scan..."
    $SETCOLOR_NORMAL
    /sbin/ifconfig ${WIRELESS_DEVICE} up
    /sbin/iwlist ${WIRELESS_DEVICE} scan
}

function performLoopScan
{
    unset GETINPUT
    while [ ${TRUE} ]
    do {
	
        while [ "$GETINPUT" == '' ]
        do {
            clear
	    printVersion
	    echo
            $SETCOLOR_SPECIAL_RED
	    $MOVE_TO_COL
            echo "Performing Wireless Access Point (Loop) Scan..."
	    $MOVE_TO_COL
            echo "      Press q and then <enter> to stop...      "
    	    $SETCOLOR_NORMAL
	    $MOVE_TO_COL
	    echo -n $"      - Using Wireless Device: [ "
	    $SETCOLOR_GREEN
	    echo -n ${WIRELESS_DEVICE}
	    $SETCOLOR_NORMAL
    	    echo -n $" ]"
	    echo
	    
            /sbin/iwlist ${WIRELESS_DEVICE} scan

    	    read -st4 GETINPUT
	}
	done
	
	if [ "$GETINPUT" = "q" ]
	then
    	    clear
    	    $SETCOLOR_YELLOW
    	    echo "Please run a normal scan to precisely find any Access Points!"
	    $SETCOLOR_NORMAL
	    return 0;
	fi
	
    }
    done
    
    return 1;
}

function printInterface
{
    $SETCOLOR_BRIGHT
    echo "Network Interface Information:"
    $SETCOLOR_NORMAL
    /sbin/ifconfig ${WIRELESS_DEVICE}
    $SETCOLOR_BRIGHT
    echo "Wireless Interface Information:"
    $SETCOLOR_NORMAL
    /sbin/iwconfig ${WIRELESS_DEVICE}
}

function setChannel
{
    echo "Set the operating frequency or channel in the device. Value below 1000 are the channel number,"
    echo "value over this is the frequency in Hz. You must append the suffix k, M or G to the value (for"
    echo "example, "2.46G" for 2.46 GHz frequency), or add enough '0'. Channels are usually numbered"
    echo "starting at 1. Depending on regulations, some frequencies/channels may not be available."
    echo
    /sbin/iwlist ${WIRELESS_DEVICE} channel
    echo -n $"Enter the new channel number [or specify it in Hz](or \"stop\" to cancel): "
    
    unset GETINPUT
    while [ "$GETINPUT" = '' ]
    do {
	getinput
    }
    done
    echo

    if [ "$GETINPUT" = 'stop' ]
    then
	return 0;
    fi
    
    /sbin/iwconfig ${WIRELESS_DEVICE} channel "$GETINPUT"
    /sbin/iwconfig ${WIRELESS_DEVICE} commit
}


function setTXPower
{
    echo "For cards supporting multiple transmit powers, set the transmit power in dBm. If W is the power in"
    echo "Watt, the power in dBm is P = 30  +  10.log(W). If the value is postfixed by mW, it will be automatically"
    echo "converted to dBm. In addition, on and off enable and disable the radio, and auto and fixed enable and"
    echo "disable power control (if those features are available)."
    echo
    /sbin/iwlist ${WIRELESS_DEVICE} txpower
    echo "Enter the new TX (Transmission) power [in dBm]"
    echo -n $"(or \"auto\" for automatic power, or \"off\" for no power, or \"stop\" to cancel): "
    
    unset GETINPUT
    while [ "$GETINPUT" = '' ]
    do {
	getinput
    }
    done
    echo

    if [ "$GETINPUT" = 'stop' ]
    then
	return 0;
    fi
    
    /sbin/iwconfig ${WIRELESS_DEVICE} txpower "$GETINPUT"
    /sbin/iwconfig ${WIRELESS_DEVICE} commit
}

function setSensitivity
{
    echo "Set the sensitivity threshold. This is the lowest signal level for which we attempt a packet reception,"
    echo "signal lower than this are not received. This is used to avoid receiving background noise, so you"
    echo "should set it according to the average noise level. Positive values are assumed to be the raw value"
    echo "used by the hardware or a percentage, negative values are assumed to be dBm."
    echo
    echo "With some hardware, this parameter also control the defer threshold (lowest signal level for which"
    echo "we consider the channel busy) and the handover threshold (lowest signal level where we stay associated"
    echo "with the current access point)."
    echo
    echo -n $"Enter the new sensitivity level [in dBm](or type \"stop\" to cancel): "
    
    unset GETINPUT
    while [ "$GETINPUT" = '' ]
    do {
	getinput
    }
    done
    echo

    if [ "$GETINPUT" = 'stop' ]
    then
	return 0;
    fi
    
    /sbin/iwconfig ${WIRELESS_DEVICE} sens "$GETINPUT"
    /sbin/iwconfig ${WIRELESS_DEVICE} commit
}

function setMode
{
    echo "Set the operating mode of the device, which depends on the network topology. The mode can be Ad-hoc"
    echo "(network composed of only one cell and without Access Point), Managed (node connects to a network"
    echo "composed of many Access Points, with roaming), Master (the node is the synchronisation  master"
    echo "or act as an Access Point), Repeater (the node forward packets between other wireless nodes),"
    echo "Secondary (the node act as a backup master/repeater), Monitor (the node act as a passive"
    echo "monitor and only receives packets) or Auto."
    echo
    echo -n $"Enter the network mode (Ad-hoc/Managed/Master/Repeater/Monitor/Auto or type \"stop\" to cancel): "
    
    unset GETINPUT
    while [ "$GETINPUT" = '' ]
    do {
	getinput
    }
    done
    echo

    if [ "$GETINPUT" = 'stop' ]
    then
	return 0;
    fi
    
    /sbin/iwconfig ${WIRELESS_DEVICE} mode "$GETINPUT"
    /sbin/iwconfig ${WIRELESS_DEVICE} commit
}

function setHWMAC
{
    echo "Set the hardware address of this interface, if the device driver supports this operation."
    echo
    /sbin/ifconfig ${WIRELESS_DEVICE}
    echo -n $"Enter the new network MAC (or type \"stop\" to cancel): "
    
    unset GETINPUT
    while [ "$GETINPUT" = '' ]
    do {
	getinput
    }
    done
    echo

    if [ "$GETINPUT" = 'stop' ]
    then
	return 0;
    fi
    
    /sbin/ifconfig ${WIRELESS_DEVICE} hw ether "$GETINPUT"
}

function doDisconnect
{
    $SETCOLOR_RED
    echo "Performing Wireless Access Point Disconnect..."
    $SETCOLOR_NORMAL
    #/sbin/dhclient -r ${WIRELESS_DEVICE} 2>&1 | cat /dev/null
    /sbin/ifconfig ${WIRELESS_DEVICE} down
    /sbin/iwconfig ${WIRELESS_DEVICE} essid off
    /sbin/iwconfig ${WIRELESS_DEVICE} commit
    echo
    printInterface
    echo
}

function doConnect
{
    performScan
    echo -n $"What is the ESSID of the Access Point you wish to connect to (or type \"none\" to cancel)? "
    
    unset GETINPUT
    while [ "$GETINPUT" = '' ]
    do {
	getinput
    }
    done
    echo
    
    if [ "$GETINPUT" = 'none' ]
    then
	return 0;
    fi
    
    doDisconnect
    echo
    $SETCOLOR_RED
    echo "Performing Wireless Access Point Connection..."
    $SETCOLOR_NORMAL
    /sbin/iwconfig ${WIRELESS_DEVICE} essid "$GETINPUT"
    /sbin/iwconfig ${WIRELESS_DEVICE} commit
    /sbin/ifconfig ${WIRELESS_DEVICE} up
    echo
    printInterface
    echo
    $SETCOLOR_BRIGHT
    echo "DHCP Client Information:"
    $SETCOLOR_NORMAL
    udhcpc -n -i ${WIRELESS_DEVICE}
    #/sbin/dhclient ${WIRELESS_DEVICE}
    echo
}

function doTraceroute
{
    echo -n $"Destination host IP or name (or type \"stop\" to cancel)? "
    
    unset GETINPUT
    while [ "$GETINPUT" = '' ]
    do {
	getinput
    }
    done
    echo
    
    if [ "$GETINPUT" = 'stop' ]
    then
	return 0;
    fi

    $SETCOLOR_RED
    echo "Performing Traceroute..."
    $SETCOLOR_NORMAL
    /bin/traceroute -i ${WIRELESS_DEVICE} -In "$GETINPUT"
    echo
}

function doPing
{
    echo -n $"Destination host IP or name (or type \"stop\" to cancel)? "
    
    unset GETINPUT
    while [ "$GETINPUT" = '' ]
    do {
	getinput
    }
    done
    echo
    
    if [ "$GETINPUT" = 'stop' ]
    then
	return 0;
    fi

    $SETCOLOR_RED
    echo "Performing Ping..."
    $SETCOLOR_NORMAL
    /bin/ping -I ${WIRELESS_DEVICE} -c 10 -nv "$GETINPUT"
    echo
}

if [ ! ${WIRELESS_DEVICE} ]
then
    echo "Usage: wlscan <wireless interface>"
    echo "	- Wireless device was not specified!"
    echo "      - Assuming wlan0 as wireless interface"
    WIRELESS_DEVICE=wlan0
    #exit 1;
fi

/sbin/ifconfig ${WIRELESS_DEVICE} up

#----------------------
# Start program proper
#
printHeader

while [ ${TRUE} ]
do {
    $SETCOLOR_YELLOW
    echo -n $"${WIRELESS_DEVICE}"
    $SETCOLOR_GREEN
    echo -n $"@wirelessCOM > "
    $SETCOLOR_NORMAL
    
    unset GETINPUT
    while [ "$GETINPUT" = '' ]
    do {
	getinput
	
	if [ "$GETINPUT" = "scan" ] ||
	   [ "$GETINPUT" = "s"    ]
	then
	    performScan
	elif [ "$GETINPUT" = "scan loop"  ] ||
	     [ "$GETINPUT" = "l"	  ]
	then
	    performLoopScan
	elif [ "$GETINPUT" = "connect" ] ||
	     [ "$GETINPUT" = "c"       ]
	then
	    doConnect
	elif [ "$GETINPUT" = "disconnect" ] ||
	     [ "$GETINPUT" = "d"       ]
	then
	    doDisconnect
	elif [ "$GETINPUT" = "interface" ] ||
	     [ "$GETINPUT" = "i"       ]
	then
	    printInterface
	elif [ "$GETINPUT" = "channel" ] ||
	     [ "$GETINPUT" = "chan"    ]
	then
	    setChannel
	elif [ "$GETINPUT" = "txpower" ] ||
	     [ "$GETINPUT" = "t"       ]
	then
	    setTXPower
	elif [ "$GETINPUT" = "sensitivity" ] ||
	     [ "$GETINPUT" = "sens"        ]
	then
	    setSensitivity
	elif [ "$GETINPUT" = "mode" ] ||
	     [ "$GETINPUT" = "m"    ]
	then
	    setMode
	elif [ "$GETINPUT" = "getchannel" ]
	then
	    /sbin/iwlist ${WIRELESS_DEVICE} channel
	elif [ "$GETINPUT" = "getbitrate" ]
	then
	    /sbin/iwlist ${WIRELESS_DEVICE} bitrate
	elif [ "$GETINPUT" = "traceroute" ] ||
	     [ "$GETINPUT" = "t"          ]
	then
	    doTraceroute
	elif [ "$GETINPUT" = "ping" ] ||
	     [ "$GETINPUT" = "p"    ]
	then
	    doPing
	elif [ "$GETINPUT" = "clear" ]
	then
	    clear
	elif [ "$GETINPUT" = "help" ] ||
	     [ "$GETINPUT" = "h"    ] ||
	     [ "$GETINPUT" = "?"    ]
	then
	    printHelp
	elif [ "$GETINPUT" = "ver"  ]
	then
	    printVersion
	elif [ "$GETINPUT" = "internal_DISPif" ]
	then
	    displayDevice
	elif [ "$GETINPUT" = "internal_chMAC" ]
	then
	    setHWMAC
	elif [ "$GETINPUT" = "quit" ] ||
	     [ "$GETINPUT" = "q"    ]
	then
	    $SETBACKGROUND_NORMAL
	    clear
	    reset
	    clear
	    exit 0;
	else
	    echo "!!! Unreconized Command !!!"
	fi
    }
    done
}
done
