Annotation of badi/public_scripts/switchgate/switchgate, revision 1.1
1.1 ! adi 1: #!/bin/bash
! 2:
! 3: # switchhgate 0.0.3
! 4: # (c) 2005 under GPL by Adrian Zaugg
! 5:
! 6: # switchgate pings a set of hosts to determine the state of the internet connectivity. If
! 7: # the connection is down, it can change the default gateway to an alternative gateway.
! 8:
! 9: ## Settings
! 10: #
! 11:
! 12: # Where the config files reside
! 13: CONFIG_PATH="/etc/switchgate"
! 14:
! 15: # Path where to find dhcp information file from switchgate-helper,
! 16: # the dhclient-exit-hook helper program
! 17: DHCP_TMP_DIR=/tmp/switchgate
! 18:
! 19: # Host set to ping. A file containing IP addresses, each on a single line.
! 20: # Do not include any local hosts, list only hosts located behind your gateways.
! 21: HOSTSET_FILE="$CONFIG_PATH/hostset"
! 22:
! 23: # The file defining fixed and dynamic gateway preference
! 24: GATEWAYS_FILE="$CONFIG_PATH/gateways"
! 25:
! 26: # path to fping
! 27: PING=/usr/sbin/fping
! 28:
! 29: # answer of fping to reachable hosts
! 30: ALIVE_ANSWER="is alive"
! 31:
! 32: # set to an empty string to avoid debug output
! 33: # to "low" for a few output and to anything else
! 34: # for verbose output
! 35: DEBUG=
! 36:
! 37:
! 38: # -------- Do not edit below this line --------
! 39:
! 40: PINGARGS="-A -p25 -t100"
! 41:
! 42:
! 43: ## Function declarations
! 44: #
! 45:
! 46: # Read gateways from file
! 47: function readgwlist {
! 48: if [ -f "$GATEWAYS_FILE" ]; then
! 49: # Ordered list of all gateways in file. Highest preference has entry with index 0, which
! 50: # is your standard default gateway.
! 51: # dhcp[.ethX] means dhcp supplied gateways in file $CONFIG_PATH/dhcp.ethX
! 52: number_of_gws=0
! 53: if [ -n "$DEBUG" -a "$DEBUG" != "low" ]; then
! 54: echo "Reading config file $GATEWAYS_FILE..."
! 55: fi
! 56:
! 57: allgates=`grep -ve "^[ ]*[\#]\+.*$" "$GATEWAYS_FILE" | xargs`
! 58: for gate in $allgates; do
! 59: if [[ $(echo "$gate" | grep -c -e "^[:space:]*dhcp\..*$") -eq 1 && \
! 60: -f "$CONFIG_PATH/$gate" ]]; then
! 61: # Read dhcp supplied gate for a specific interface
! 62: alldhcpgates=`grep -e "^[^\#].*$" "$CONFIG_PATH/$gate" | xargs`
! 63: elif [[ $(echo "$gate" | grep -c -e "^[:space:]*dhcp[:space:]*$") -eq 1 ]]; then
! 64: # Read all dhcp files
! 65: alldhcpgates=""
! 66: for dhcpfile in $(echo -n $(ls -1 $DHCP_TMP_DIR/dhcp* 2>/dev/null)); do
! 67: alldhcpgates="$alldhcpgates `grep -e "^[^\#].*$" "$dhcpfile" | xargs`"
! 68: done
! 69: else
! 70: # it's a fixed gateway
! 71: addgw="$gate"
! 72: debug_msg="fixed"
! 73: addgateway
! 74: fi
! 75:
! 76: for dhcpgate in $alldhcpgates; do
! 77: addgw="$dhcpgate"
! 78: debug_msg="$gate"
! 79: addgateway
! 80: done
! 81: unset alldhcpgates
! 82: done
! 83: fi
! 84:
! 85: if [ "$number_of_gws" -eq 0 ]; then
! 86: echo "No gateways configured. Please edit $GATEWAYS_FILE."
! 87: exit 1
! 88: elif [[ "$number_of_gws" -eq 1 && ! -z $DEBUG ]]; then
! 89: echo "Only 1 gateway configured. No fallback switching possible."
! 90: else
! 91: if [[ -n "$DEBUG" && "$DEBUG" != "low" ]]; then
! 92: echo "... $number_of_gws gateway(s) found."
! 93: fi
! 94: fi
! 95: }
! 96:
! 97: # add a gateway to the array of all gateways to possibly switch to
! 98: function addgateway {
! 99: addgw=$(echo "$addgw" | tr -d ' ')
! 100: # check no duplicate addition is performed
! 101: if [ $(echo "${GW[*]}" | grep -c "$addgw") -eq 0 ]; then
! 102: GW[$number_of_gws]=$addgw
! 103: if [[ -n "$DEBUG" && "$DEBUG" != "low" ]]; then
! 104: echo -e "\tGateway $number_of_gws: $addgw ($debug_msg)"
! 105: fi
! 106: let "number_of_gws += 1"
! 107: fi
! 108: unset addgw
! 109: }
! 110:
! 111: # If one host of the HOSTSET_FILE responds, the conncetion is considered up.
! 112: function checkconnection {
! 113: UP=""
! 114: if [ `$PING $PINGARGS < "$HOSTSET_FILE" 2> /dev/null | grep -c "$ALIVE_ANSWER"` -gt 0 ]; then
! 115: UP=true
! 116: fi
! 117: if [ -n "$DEBUG" ]; then
! 118: if [ -n "$UP" ]; then
! 119: echo "The connection is up."
! 120: else
! 121: echo "The connection is down."
! 122: fi
! 123: fi
! 124: }
! 125:
! 126: # Is a certain gateway reachable?
! 127: function checkgw {
! 128: if [ `$PING $PINGARGS "$NEWGW" 2> /dev/null | grep -c "$ALIVE_ANSWER"` -gt 0 ]; then
! 129: if [ -n "$DEBUG" ]; then
! 130: echo "$NEWGW is reachable."
! 131: fi
! 132: else
! 133: if [ -n "$DEBUG" ]; then
! 134: echo "$NEWGW is not reachable."
! 135: fi
! 136: NEWGW=""
! 137: fi
! 138: }
! 139:
! 140: function getcurrentgw {
! 141: iproute_default_gw_txt="$(ip route show scope global)"
! 142: if [ `echo $iproute_default_gw_txt | grep -c default` -gt 1 ]; then
! 143: echo "No support for multiple default gateways. Exiting."
! 144: exit 1
! 145: else
! 146: iproute_default_gw_txt="$(echo "$iproute_default_gw_txt" | grep "default via")"
! 147: fi
! 148: if [ -z "$iproute_default_gw_txt" ]; then
! 149: # no default gateway currently set, set to the highest index, to land on GW0
! 150: CURRENTGW_ID=0
! 151: CURRENTGW=${GW[$CURRENTGW_ID]}
! 152: CURRENTGW_DEV="unknown"
! 153: echo "No default gateway currently set. Setting it now to $CURRENTGW."
! 154: ip route add default via $CURRENTGW
! 155: else
! 156: CURRENTGW=`echo $iproute_default_gw_txt | sed "s/^default via \(\([0-9]\+\.\?\)\{4\}\).*\$/\1/"`
! 157: CURRENTGW_DEV=`echo $iproute_default_gw_txt | sed "s/^default via .* dev \(eth[0-9]\+\).*\$/\1/"`
! 158: fi
! 159:
! 160: # get index of current gateway
! 161: index=-1
! 162: for NEWGW in ${GW[*]}; do
! 163: let "index += 1"
! 164: if [ "$CURRENTGW" = "$NEWGW" ]; then
! 165: CURRENTGW_ID=$index
! 166: break
! 167: fi
! 168: done
! 169: if [ -z "$CURRENTGW_ID" ]; then
! 170: echo "The current gateway ($CURRENTGW) is not in the list of available gateways."
! 171: echo "Please edit $GATEWAYS_FILE to correct."
! 172: exit 1
! 173: fi
! 174: if [ "$DEBUG" = "low" ]; then
! 175: echo "Default gateway detected: $CURRENTGW ($CURRENTGW_ID) on dev $CURRENTGW_DEV"
! 176: fi
! 177: }
! 178:
! 179: # Set NEWGW and NEWGW_ID to the next gateway from GW[]
! 180: function getnextgw {
! 181: if [ -z "$NEWGW_ID" ]; then
! 182: if [ -z "$CURRENTGW_ID" ]; then
! 183: getcurrentgw
! 184: NEWGW_ID=$CURRENTGW_ID
! 185: else
! 186: NEWGW_ID=-1
! 187: fi
! 188: fi
! 189: NEWGW_ID=$[ $NEWGW_ID + 1 ]
! 190: if [ "$NEWGW_ID" -ge "${#GW[*]}" ]; then
! 191: NEWGW_ID=0
! 192: fi
! 193: NEWGW=${GW[$NEWGW_ID]}
! 194: }
! 195:
! 196: # Set $NEWGW to the next working gateway
! 197: function getnewgw {
! 198: getnextgw
! 199: # Check wheter all gateways are already tested and failed
! 200: if [ "$NEWGW_ID" -eq "$CURRENTGW_ID" ]; then
! 201: if [ -n "$DEBUG" ]; then
! 202: echo "All gateways tried."
! 203: fi
! 204: NEWGW=""
! 205: NEWGW_ID=""
! 206: else
! 207: if [ -n "$DEBUG" ]; then
! 208: echo -n "Trying $NEWGW..."
! 209: fi
! 210: savegw=$NEWGW
! 211: checkgw
! 212: if [ -z "$NEWGW" ]; then
! 213: if [ -n "$DEBUG" ]; then
! 214: echo "No luck. Trying next..."
! 215: fi
! 216: NEWGW=$savegw
! 217: getnewgw
! 218: else
! 219: if [ -n "$DEBUG" ]; then
! 220: echo "Successfully found a new gateway, it's $NEWGW."
! 221: fi
! 222: fi
! 223: fi
! 224: }
! 225:
! 226: function switchgw {
! 227: getnewgw
! 228: if [ -n "$NEWGW" ]; then
! 229: if [ "$DEBUG" = "low" ]; then
! 230: echo -n "Switching default gateway now to $NEWGW ($NEWGW_ID)..."
! 231: fi
! 232:
! 233: iproute_msg="$(ip route change default via $NEWGW 2>&1 )"
! 234: iproute_exit=$?
! 235:
! 236: # generate some traffic to take effect
! 237: sleep 1
! 238: GARBAGE=`$PING -q -c 5 -t100 -p50 -A -f $HOSTSET_FILE 2> /dev/null`
! 239: sleep 1
! 240:
! 241: if [ "$DEBUG" = "low" ]; then
! 242: echo "done."
! 243: fi
! 244:
! 245: checkconnection
! 246: if [ -z "$UP" ]; then
! 247: if [ "$DEBUG" = "low" ]; then
! 248: echo -n "$NEWGW ($NEWGW_ID) is not working, switching back to $CURRENTGW ($CURRENTGW_ID)..."
! 249: fi
! 250: ip route change default via $CURRENTGW
! 251: if [ "$DEBUG" = "low" ]; then
! 252: echo "done."
! 253: fi
! 254: switchgw
! 255: elif [ "$iproute_exit" -eq 0 ]; then
! 256: CURRENTGW=$NEWGW
! 257: CURRENTGW_ID=$NEWGW_ID
! 258: else
! 259: echo "Failure from iproute: $iproute_msg"
! 260: echo "However, the connection is working. Continue as if nothing."
! 261: fi
! 262: else
! 263: if [ "$DEBUG" = "low" ]; then
! 264: echo "Not switching."
! 265: fi
! 266: fi
! 267: }
! 268:
! 269:
! 270: ## MAIN
! 271: #
! 272:
! 273: # Parse writeable dir request (hidden feature)
! 274: if [ "$1" = "-C" ]; then
! 275: echo "$DHCP_TMP_DIR"
! 276: exit 0
! 277: fi
! 278:
! 279: # Parse debug switch (another hidden feature)
! 280: if [ "$1" = "-d" ]; then
! 281: if [ "$2" != "low" ]; then
! 282: echo "Debug mode on."
! 283: DEBUG="choke"
! 284: else
! 285: #echo "Info mode on."
! 286: DEBUG="low"
! 287: fi
! 288: fi
! 289:
! 290: # Get all gateways, we can forward traffic
! 291: readgwlist
! 292:
! 293: # Parse query for current gw (yet another hidden feature)
! 294: if [ "$1" = "-q" ]; then
! 295: DEBUG=
! 296: getcurrentgw
! 297: echo "$CURRENTGW"
! 298: exit 0
! 299: fi
! 300:
! 301: # get current gw
! 302: getcurrentgw
! 303:
! 304: # check wether host set file is around
! 305: if [ ! -e $HOSTSET_FILE ]; then
! 306: echo "No host list found! File $HOSTSET_FILE not found."
! 307: exit 1
! 308: fi
! 309:
! 310: # check connection
! 311: checkconnection
! 312:
! 313: # If the connection is down, change to the nextgw
! 314: if [ -z "$UP" ]; then
! 315: # Some more information of down reason: Diagnose wheter the current gateway is alive
! 316: NEWGW=$CURRENTGW
! 317: checkgw
! 318: if [ -z "$NEWGW" ]; then
! 319: echo "Gateway $CURRENTGW is down."
! 320: else
! 321: echo "No connection through gateway $CURRENTGW."
! 322: fi
! 323:
! 324: NEWGW_ID=$CURRENTGW_ID
! 325: switchgw
! 326:
! 327: else
! 328: # If the current gateway is not the standard default gateway, try if the connection
! 329: # through the standard default gateway is back
! 330: if [ "$CURRENTGW_ID" != 0 ]; then
! 331: if [ "$DEBUG" = "low" ]; then
! 332: echo "Not operating on standard default gateway (${GW[0]}). Trying to change."
! 333: fi
! 334: NEWGW_ID=""
! 335: switchgw
! 336: else
! 337: # normal operation
! 338: if [[ -n "$DEBUG" && "$DEBUG" != "low" ]]; then
! 339: echo "Normal operation on standard default gateway $CURRENTGW ($CURRENTGW_ID)."
! 340: fi
! 341: fi
! 342: fi
! 343:
! 344: if [ "$DEBUG" = "low" ]; then
! 345: echo
! 346: echo "Default Gateway: $CURRENTGW ($CURRENTGW_ID)"
! 347: echo
! 348: fi
! 349: exit 0
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>