--- badi/public_scripts/switchgate/switchgate 2009/04/24 00:12:49 1.1 +++ badi/public_scripts/switchgate/switchgate 2010/01/09 04:25:42 1.5 @@ -16,6 +16,10 @@ CONFIG_PATH="/etc/switchgate" # the dhclient-exit-hook helper program DHCP_TMP_DIR=/tmp/switchgate +# eMail address to send alert messages, if not operating on the +# standard default gateway +ALERT_EMAIL="adi@ente.limmat.ch" + # Host set to ping. A file containing IP addresses, each on a single line. # Do not include any local hosts, list only hosts located behind your gateways. HOSTSET_FILE="$CONFIG_PATH/hostset" @@ -24,7 +28,7 @@ HOSTSET_FILE="$CONFIG_PATH/hostset" GATEWAYS_FILE="$CONFIG_PATH/gateways" # path to fping -PING=/usr/sbin/fping +PING=/usr/bin/fping # answer of fping to reachable hosts ALIVE_ANSWER="is alive" @@ -32,7 +36,7 @@ ALIVE_ANSWER="is alive" # set to an empty string to avoid debug output # to "low" for a few output and to anything else # for verbose output -DEBUG= +DEBUG=low # -------- Do not edit below this line -------- @@ -43,6 +47,61 @@ PINGARGS="-A -p25 -t100" ## Function declarations # +# parse commandline switches +function parse_commandline { + + # check rest + while [ "$#" -gt 0 ]; do + + case "$1" in + + -d|--debug) + # debug switch (another hidden feature) + shift + if [ "$1" != "low" ]; then + DEBUG="choke" + echo "Debug mode on." + else + #echo "Info mode on." + DEBUG="low" + shift + fi + ;; + + -C) + # Parse writeable dir request (hidden feature) + echo "$DHCP_TMP_DIR" + exit 0 + ;; + + -q|--query) + # Parse query for current gw (yet another hidden feature) + shift + parse_commandline "$@" + getcurrentgw + echo "$CURRENTGW" + exit 0 + ;; + + -s|--set) + # Set gateway to number n (yet another hidden feature) + shift + set_to_gw="$1" + shift + parse_commandline "$@" + set_gw + exit 0 + ;; + + *) + echo "Invalid argument \"$1\"." + exit 1 + ;; + + esac + done +} + # Read gateways from file function readgwlist { if [ -f "$GATEWAYS_FILE" ]; then @@ -81,7 +140,7 @@ function readgwlist { unset alldhcpgates done fi - + if [ "$number_of_gws" -eq 0 ]; then echo "No gateways configured. Please edit $GATEWAYS_FILE." exit 1 @@ -117,7 +176,7 @@ function checkconnection { if [ -n "$DEBUG" ]; then if [ -n "$UP" ]; then echo "The connection is up." - else + else echo "The connection is down." fi fi @@ -130,13 +189,14 @@ function checkgw { echo "$NEWGW is reachable." fi else - if [ -n "$DEBUG" ]; then + if [ -n "$DEBUG" ]; then echo "$NEWGW is not reachable." fi NEWGW="" fi } +# Get the current default gateway (or set it, if there was none set) function getcurrentgw { iproute_default_gw_txt="$(ip route show scope global)" if [ `echo $iproute_default_gw_txt | grep -c default` -gt 1 ]; then @@ -144,18 +204,21 @@ function getcurrentgw { exit 1 else iproute_default_gw_txt="$(echo "$iproute_default_gw_txt" | grep "default via")" - fi + fi if [ -z "$iproute_default_gw_txt" ]; then # no default gateway currently set, set to the highest index, to land on GW0 CURRENTGW_ID=0 CURRENTGW=${GW[$CURRENTGW_ID]} - CURRENTGW_DEV="unknown" echo "No default gateway currently set. Setting it now to $CURRENTGW." ip route add default via $CURRENTGW + if [ $? -eq 2 ]; then + echo "Not able to switch default gateway. Is your interface up?" + exit 1 + fi else - CURRENTGW=`echo $iproute_default_gw_txt | sed "s/^default via \(\([0-9]\+\.\?\)\{4\}\).*\$/\1/"` - CURRENTGW_DEV=`echo $iproute_default_gw_txt | sed "s/^default via .* dev \(eth[0-9]\+\).*\$/\1/"` + CURRENTGW=`echo $iproute_default_gw_txt | sed "s/^default via \(\([0-9]\+\.\?\)\{4\}\).*\$/\1/"` fi + CURRENTGW_DEV=`echo $iproute_default_gw_txt | sed "s/^default via .* dev \(eth[0-9]\+\).*\$/\1/"` # get index of current gateway index=-1 @@ -197,7 +260,7 @@ function getnextgw { function getnewgw { getnextgw # Check wheter all gateways are already tested and failed - if [ "$NEWGW_ID" -eq "$CURRENTGW_ID" ]; then + if [[ "$NEWGW_ID" -eq "$CURRENTGW_ID" && -z $set_to_gw ]]; then if [ -n "$DEBUG" ]; then echo "All gateways tried." fi @@ -223,13 +286,40 @@ function getnewgw { fi } +# Switch the gateway to a desired gateway +function set_gw { + + # get name of gateway + if [[ ! "$set_to_gw" =~ ^[0-9]{1,}$ ]]; then + echo "Only positive numbers allowed. Invalid value \"$set_to_gw\"." + exit 1 + fi + + NEWGW=${GW[$set_to_gw]} + if [ -z "$NEWGW" ]; then + echo "The gateway number $set_to_gw is not in the list of available gateways." + echo "Valid gateways are:" + for ((gw=0; gw<${#GW[*]}; gw++)); do + echo -e "\t$gw (${GW[$gw]})" + done + exit 1 + fi + if [ -n "$DEBUG" -a "$DEBUG" != "low" ]; then + echo "Default gateway desired: $NEWGW ($set_to_gw)" + fi + + getcurrentgw + NEWGW_ID=$[ $set_to_gw - 1 ] + switchgw +} + function switchgw { getnewgw if [ -n "$NEWGW" ]; then if [ "$DEBUG" = "low" ]; then echo -n "Switching default gateway now to $NEWGW ($NEWGW_ID)..." - fi - + fi + iproute_msg="$(ip route change default via $NEWGW 2>&1 )" iproute_exit=$? @@ -237,7 +327,7 @@ function switchgw { sleep 1 GARBAGE=`$PING -q -c 5 -t100 -p50 -A -f $HOSTSET_FILE 2> /dev/null` sleep 1 - + if [ "$DEBUG" = "low" ]; then echo "done." fi @@ -270,33 +360,18 @@ function switchgw { ## MAIN # -# Parse writeable dir request (hidden feature) -if [ "$1" = "-C" ]; then - echo "$DHCP_TMP_DIR" - exit 0 -fi -# Parse debug switch (another hidden feature) -if [ "$1" = "-d" ]; then - if [ "$2" != "low" ]; then - echo "Debug mode on." - DEBUG="choke" - else - #echo "Info mode on." - DEBUG="low" - fi +# Check fping existence +if [ ! -x "$PING" ]; then + echo -e "Error: Ping program not executable or not found at $PING.\nPlease configure the full path in $0." + exit 1 fi # Get all gateways, we can forward traffic readgwlist -# Parse query for current gw (yet another hidden feature) -if [ "$1" = "-q" ]; then - DEBUG= - getcurrentgw - echo "$CURRENTGW" - exit 0 -fi +# parse commandline switches +parse_commandline "$@" # get current gw getcurrentgw @@ -317,13 +392,13 @@ if [ -z "$UP" ]; then checkgw if [ -z "$NEWGW" ]; then echo "Gateway $CURRENTGW is down." - else + else echo "No connection through gateway $CURRENTGW." fi - + NEWGW_ID=$CURRENTGW_ID switchgw - + else # If the current gateway is not the standard default gateway, try if the connection # through the standard default gateway is back @@ -341,6 +416,23 @@ else fi fi +# send an eMail if the connection is down or limited +if [ -z "$UP" ]; then + EMAIL_BODY="Switchgate on $(hostname -f) reports: No connection!\n\nTime:\t\t$(date)\nGateway:\t$CURRENTGW ($CURRENTGW_ID)" + EMAIL_SUBJECT="Attention: $(hostname -f) has no connection!" + echo -e "$EMAIL_BODY" | mail -s "$EMAIL_SUBJECT" "$ALERT_EMAIL" + if [[ -n "$DEBUG" && "$DEBUG" != "low" ]]; then + echo "Alert message sent to $ALERT_EMAIL." + fi +elif [ "$CURRENTGW_ID" != 0 ]; then + EMAIL_BODY="Switchgate on $(hostname -f) reports: Not operating on standard default gateway!\n\nTime:\t\t$(date)\nGateway:\t$CURRENTGW ($CURRENTGW_ID)" + EMAIL_SUBJECT="Attention: $(hostname -f) not operating on standard default gateway!" + echo -e "$EMAIL_BODY" | mail -s "$EMAIL_SUBJECT" "$ALERT_EMAIL" + if [[ -n "$DEBUG" && "$DEBUG" != "low" ]]; then + echo "Alert message sent to $ALERT_EMAIL." + fi +fi + if [ "$DEBUG" = "low" ]; then echo echo "Default Gateway: $CURRENTGW ($CURRENTGW_ID)"