#!/bin/bash # Scriptname: network-discovery # Intention: Try to find some kind of network connection providing a link to # the internet. For this a list of wired interfaces is checked first. # Afterwards a list of wireless devices is checked whereas a list of # provided ESSIDs is prefered for the connection. # Optionally the script also tries to connect to whatever ESSID it can find # to get a connection (-> ESSID 'any' ). # Version: 0.1 (3.11.2007) # 0.2 (5.11.2007) # - added several sleeps # - implemented 5 retries to get the interface up with ifconfig $IF up # - added a complete shutdown of all involved network interfaces at startup to get a clean start ##################### # open improvements # ##################### # FIXME Log error/status messages via syslog --> logger # FIXME Trying DHCP on a network without DHCP takes an awfully long time until it aborts # FIXME Think of something better to test network connectivity # FIXME Add generic VPN support # FIXME check if the tun module is loaded when using VPN # FIXME Check if all used tools are installed before starting anything # FIXME Add static configuration support # FIXME Check output of dhclient for what really happened # success + received ip: # DHCPACK from 192.168.0.2 # bound to 192.168.0.245 -- renewal in 1636 seconds. # no success: # No DHCPOFFERS received. # FIXME dhclient processes stay in background after trying to get an ip unsuccessfully (-> quick solution: killall at the end of the file) # FIXME hidden ESSIDs are not reconized (-> fix: first set the adapter's ESSID then scan for it) #################### # global variables # #################### # config for wired network interface IF_WIRED_LIST="eth0" # config for wireless network interface IF_WIRELESS_LIST="ath0" #IF_WIRELESS_ESSID_LIST="FAU-VPN HOME any" # adding 'any' to the list also tries to connect through other WLANs in range IF_WIRELESS_ESSID_LIST="FAU-VPN HOME" # adding 'any' to the list also tries to connect through other WLANs in range # OpenVPN config for FAU-VPN FAU_VPN_PATH="/root/scripts/network/RRZE" # set delimiter to \n #IFS="\n" IFS=" " ############# # functions # ############# # test routine for network/internet setup function check_network_connection { echo -ne "\t\tChecking for a working internet connection ... " host -W1 google.com 1>/dev/null 2>&1 EXIT_STATUS=$? if ( test $EXIT_STATUS = 127 ) then # command not found echo -ne "error\n\t\tCommand 'host' was not found.\nExiting.\n" exit 127 fi if ( test $EXIT_STATUS = 1 ) then # no connectivity -> do nothing echo -ne "none found.\n" fi if ( test $EXIT_STATUS = 0 ) then # YEEHA! - got a connection echo -ne "OK\n\nSuccess.\n" exit 0 fi } ########## # script # ########## # do a pre-check #echo -ne "--> Pre-check\n\to connectivity\n" #check_network_connection; # FIXME # shutdown all network related stuff for IF in $IF_WIRED_LIST do ifconfig $IF down 1>/dev/null 2>&1 done for IF in $IF_WIRELESS_LIST do ifconfig $IF down 1>/dev/null 2>&1 done killall dhclient 1>/dev/null 2>&1 killall openvpn 1>/dev/null 2>&1 ###### WIRED INTERFACES echo -ne "\n### WIRED INTERFACES ###\n" for IF_WIRED in $IF_WIRED_LIST do # check cable connections first echo -ne "\n--> Trying interface ${IF_WIRED} ...\n" # check if interface exists echo -ne "\to existence\n" if !( test -e /sys/class/net/${IF_WIRED} ) then # interface does not exist -> skip echo -ne "\t\tInterface ${IF_WIRED} not found- skipping\n" continue fi echo -ne "\t\tOK\n" # check interface state (up/down) echo -ne "\to state\n" IF_OPERSTATE=`cat /sys/class/net/${IF_WIRED}/operstate` echo -ne "\t\t/sys/class/net/${IF_WIRED}/operstate: ${IF_OPERSTATE}\n" if ( test "${IF_OPERSTATE}" = "down" ) then # interface is down echo -ne "\t\tTrying to 'ifconfig ${IF_WIRED} up' ... " for i in 1 2 3 4 5 do echo -ne "#${i} " ifconfig ${IF_WIRED} up 1>/dev/null 2>&1 sleep 1 IF_OPERSTATE=`cat /sys/class/net/${IF_WIRED}/operstate` if ( test "${IF_OPERSTATE}" != "down" ) then break fi ifconfig ${IF_WIRED} down 1>/dev/null 2>&1 done if ( test "${IF_OPERSTATE}" = "down" ) then # trying to bring up the interface didn't work -> skip echo -ne "still down - skipping\n" ifconfig ${IF_WIRED} down continue fi echo -ne "OK\n" fi echo -ne "\t\tOK\n" # check if the interface is actually connected to a network echo -ne "\to carrier\n" IF_CARRIER=`cat /sys/class/net/${IF_WIRED}/carrier` EXIT_STATUS=$? if ( test $EXIT_STATUS != 0 ) then # if the interface is down reading from /sys/class/net/${IF_WIRED}/carrier results in an error echo -ne "\t\tThis is weird. Could not read /sys/class/net/${IF_WIRED}/carrier - skipping\n" continue fi echo -ne "\t\t/sys/class/net/${IF_WIRED}/carrier: ${IF_CARRIER}\n" if ( test $IF_CARRIER = 0 ) then # device is not connected to a network echo -ne "\t\tInterface ${IF_WIRED} is not connected to a network - skipping\n" ifconfig ${IF_WIRED} down continue fi echo -ne "\t\tOK\n" # try to setup a working network connection echo -ne "\to setup\n" # try to setup the interface through DHCP echo -ne "\t\tTrying 'dhclient ${IF_WIRED}' ... " dhclient ${IF_WIRED} 1>/dev/null 2>&1 EXIT_STATUS=$? if ( test $EXIT_STATUS = 0 ) then echo -ne "OK\n" else echo -ne "error (code ${EXIT_STATUS}) - skipping\n" continue fi check_network_connection; # FIXME # if we get to this point there was no connection found so we shut down the tried interface again ifconfig ${IF_WIRED} down killall dhclient done ###### WIRELESS INTERFACES echo -ne "\n### WIRELESS INTERFACES ###\n" for IF_WIRELESS in $IF_WIRELESS_LIST do echo -ne "\n--> Trying interface ${IF_WIRELESS} ...\n" # check if interface exists echo -ne "\to existence\n" if !( test -e /sys/class/net/${IF_WIRELESS} ) then # interface does not exist -> skip echo -ne "\t\tInterface ${IF_WIRELESS} not found - skipping\n" continue fi echo -ne "\t\tOK\n" # check interface state (up/down) echo -ne "\to state\n" IF_OPERSTATE=`cat /sys/class/net/${IF_WIRELESS}/operstate` echo -ne "\t\t/sys/class/net/${IF_WIRELESS}/operstate: ${IF_OPERSTATE}\n" if ( test "${IF_OPERSTATE}" = "down" ) then # interface is down echo -ne "\t\tTrying to 'ifconfig ${IF_WIRELESS} up' ... " for i in 1 2 3 4 5 do echo -ne "#${i} " ifconfig ${IF_WIRELESS} up 1>/dev/null 2>&1 sleep 1 IF_OPERSTATE=`cat /sys/class/net/${IF_WIRELESS}/operstate` if ( test "${IF_OPERSTATE}" != "down" ) then break fi ifconfig ${IF_WIRELESS} down 1>/dev/null 2>&1 done IF_OPERSTATE=`cat /sys/class/net/${IF_WIRELESS}/operstate` if ( test "${IF_OPERSTATE}" = "down" ) then # trying to bring up the interface didn't work -> skip echo -ne "still down - skipping\n" continue fi echo -ne "OK\n" fi echo -ne "\t\tOK\n" # get list of available unique ESSIDs echo -ne "\to Scan\n" echo -ne "\t\tScanning ... " ESSID_LIST=`iwlist ath0 scan | grep ESSID | awk -F '"' '{print $2}' | tr '\n' ' ' 2>/dev/null` sleep 2 EXIT_STATUS=$? if ( test $EXIT_STATUS = 0 ) then echo -ne "OK\n" else echo -ne "error (code ${EXIT_STATUS}) - skipping\n" continue fi IF_WIRELESS_ESSIDs_IN_RANGE="" for i in $ESSID_LIST do DUPLICATE_FOUND=0 for j in $IF_WIRELESS_ESSIDs_IN_RANGE do if ( test "$i" = "$j" ) then DUPLICATE_FOUND=1 break fi done if ( test $DUPLICATE_FOUND = 0 ) then if ( test "$IF_WIRELESS_ESSIDs_IN_RANGE" = "") then IF_WIRELESS_ESSIDs_IN_RANGE="${i}" else IF_WIRELESS_ESSIDs_IN_RANGE="${IF_WIRELESS_ESSIDs_IN_RANGE} ${i}" fi fi done echo -ne "\t\tFound unique ESSIDs: '${IF_WIRELESS_ESSIDs_IN_RANGE}'\n" echo -ne "\n" # try to find valid ESSIDs in range echo -ne "\t\tLooking for valid ESSIDs ...\n" TRY_UNKNOWN_ESSIDs=0 IF_WIRELESS_ESSID_CHECKLIST="" for IF_WIRELESS_ESSID in $IF_WIRELESS_ESSID_LIST do # set a flag if checking unknown ESSIDs is desired if ( test "$IF_WIRELESS_ESSID" = "any" ) then TRY_UNKNOWN_ESSIDs=1 continue fi echo -ne "\t\tChecking ESSID '${IF_WIRELESS_ESSID}' ... " IS_IN_RANGE=0 for i in $IF_WIRELESS_ESSIDs_IN_RANGE do if ( test "$i" = "$IF_WIRELESS_ESSID" ) then IS_IN_RANGE=1 break fi done if ( test $IS_IN_RANGE = 1 ) then # add found valid ESSID to the 'to-check' - list if ( test "$IF_WIRELESS_ESSID_CHECKLIST" = "" ) then IF_WIRELESS_ESSID_CHECKLIST="$IF_WIRELESS_ESSID" else IF_WIRELESS_ESSID_CHECKLIST="$IF_WIRELESS_ESSID_CHECKLIST $IF_WIRELESS_ESSID" fi echo -ne "OK\n" else echo -ne "not in range\n" fi done echo -ne "\n" if ( test "$IF_WIRELESS_ESSID_CHECKLIST" = "" ) then echo -ne "\t\tNo valid ESSID in range of this interface" if ( test $TRY_UNKNOWN_ESSIDs = 0 ) then echo -ne " - skipping\n" continue else echo -ne " - trying unknown ESSIDs\n" # add all other ESSIDs in range after the valid ESSIDs to the 'to-check' - list for i in $IF_WIRELESS_ESSIDs_IN_RANGE do for j in $IF_WIRELESS_ESSID_CHECKLIST do if ( test "$i" = "$j" ) then continue 2 fi done if ( test "$IF_WIRELESS_ESSID_CHECKLIST" = "" ) then IF_WIRELESS_ESSID_CHECKLIST="$i" else IF_WIRELESS_ESSID_CHECKLIST="$IF_WIRELESS_ESSID_CHECKLIST $i" fi done fi fi # try to setup a working network connection with one of the found ESSIDs echo -ne "\to setup\n" for ESSID in $IF_WIRELESS_ESSID_CHECKLIST do # configure interface for ESSID echo -ne "\t\tSwitching interface to ESSID '${ESSID}' ... " iwconfig ${IF_WIRELESS} essid ${ESSID} EXIT_STATUS=$? sleep 2 if ( test $EXIT_STATUS = 0 ) then echo -ne "OK\n" else echo -ne "error (code ${EXIT_STATUS}) - skipping\n" continue 2 fi # try to setup the interface through DHCP echo -ne "\t\tTrying 'dhclient ${IF_WIRELESS}' ... " dhclient ${IF_WIRELESS} 1>/dev/null 2>&1 EXIT_STATUS=$? if ( test $EXIT_STATUS = 0 ) then echo -ne "OK\n" else echo -ne "error (code ${EXIT_STATUS}) - skipping\n" continue fi # FIXME # connect through FAU's OpenVPN tunnel if ( test "$ESSID" = "FAU-VPN" ) then echo -ne "\t\tConnecting through FAU's OpenVPN tunnel ... " PWD=`pwd` cd $FAU_VPN_PATH openvpn --config RRZE-full-tunnel.ovpn --auth-user-pass secret --daemon FAU-VPN 1>/dev/null 2>&1 EXIT_STATUS=$? cd $PWD if ( test $EXIT_STATUS = 0 ) then echo -ne "OK\n" else echo -ne "error (code ${EXIT_STATUS}) - skipping\n" continue 2 fi fi check_network_connection; echo -ne "\n" done done # unsuccessful exit killall dhclient # FIXME echo -ne "\nGiving up.\n" exit 1