Slightly updated - the "die" error catchers didn't always do what I expected, so gone for now. Otherwise this has been behaving well. Whit --- cut --- #!/usr/local/bin/perl # checkroutes.pl version 0.05, 18 Feb. 2002, whit@transpect.com # changed from 0.04: (1) removed disfunctional "die" statements # (2) added double check that for extra "default" # Extends stock Nano-Howto setup with upstream route accessibility checking # See http://www.linuxvirtualserver.org/~julian/nano.txt and patches at # http://www.linuxvirtualserver.org/~julian/#routes # (if not using Julian's patchs, remove "proto static" occurrences below) # Run from cron (set with "crontab -e") # example: "0-59/2 * * * * /path/to/checkroutes.pl" runs this every 2 minutes # Best IPs to test may be last IPs at ISP before routing out to Net # If perl not at /usr/local/bin/perl change first line to point to it # Before running install Net::Ping from http://freeware.roobik.com/netping/ # (untar, cd to directory, "perl Makefile.PL; make; make install") use Net::Ping; # User settings # _____________ $ip = "/usr/sbin/ip"; # Location of "ip" on system $gw1 = ""; # Gateway 1 IP $dev1 = ""; # Device (e.g., eth1) $tip1 = ""; # Upstream IP to test $src1 = ""; # Source address for outgoing packets $wei1 = ""; # Weight $gw2 = ""; # Gateway 2 IP $dev2 = ""; # Device (e.g., eth2) $tip2 = ""; # Upstream IP to test $src2 = ""; # Source address for outgoing packets $wei2 = ""; # Weight $tab = "222"; # Table to set routes in $logfile = "/var/log/checkroutes.log"; # File to log messages to # create timestamp for log # ________________________ sub TimeStamp { # subroutine to create a "nice" looking timestamp # that doesn't rely on the system's 'date' command my @days = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat'); my @months = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep', 'Oct','Nov','Dec'); my ($sec,$min,$hour,$dom,$mon,$year,$wday,$yday,$isd) = localtime(time); my $timestamp = sprintf("%3s %3s %02d %4d %02d:%02d:%02d", $days[$wday], $months[$mon], $dom, $year+1900, $hour, $min, $sec); return $timestamp; } # be sure routes are set via appropriate gateways to test IPs # ___________________________________________________________ $checkro = `$ip ro ls`; if (!($checkro =~ /$tip1/)) { system ("$ip ro add to $tip1 via $gw1 src $src1 proto static"); } if (!($checkro =~ /$tip2/)) { system ("$ip ro add to $tip2 via $gw2 src $src2 proto static"); } # test if $gw1 and/or $gw2 currently in table $tab # ________________________________________________ $checkgw = qx/$ip ro ls tab $tab/; if ($checkgw =~ /$gw1/) { $check1 = 1; } else { $check1 = 0; } if ($checkgw =~ /$gw2/) { $check2 = 1; } else { $check2 = 0; } # ping the test IPs $tip1 and $tip2 # _________________________________ $p = Net::Ping->new("icmp"); if ($p->ping($tip1)) { $live1 = 1; } else { $live1 = 0; } $p->close(); $p = Net::Ping->new("icmp"); if ($p->ping($tip2)) { $live2 = 1; } else { $live2 = 0; } $p->close(); # If the current default in table $tab does not match the ping results then # if only one route's test IP is pingable change the default to that route # or if both test IPs are pingable change the default to use both # or if neither test IPs are pingable change the default to use both # (might as well continue to try them, if we're not going anywhere anyway) # _________________________________________________________________________ if (($check1 != $live1)||($check2 != $live2)) { if ((($live1 == 1)&&($live2 == 1))||(($live1 == 0)&&($live2 == 0))) { system ("$ip ro ap default tab $tab proto static nexthop via $gw1 dev $dev1 weight $wei1 nexthop via $gw2 dev $dev2 weight $wei2"); } elsif (($live1 == 1)&&($live2 == 0)) { system ("$ip ro ap default tab $tab proto static via $gw1 dev $dev1"); } elsif (($live1 == 0)&&($live2 == 1)) { system ("$ip ro ap default tab $tab proto static via $gw2 dev $dev2"); } else { die ("value out of bounds\n"); } system ("$ip ro del default tab $tab"); system ("$ip ro flush cache"); } # log # ___ if (($live1 == 1)&&($live2 == 1)) { $log = "both UP"; } elsif (($live1 == 0)&&($live2 == 0)) { $log = "both DOWN (set UP)"; } elsif (($live1 == 1)&&($live2 == 0)) { $log = "$gw1 up, $gw2 DOWN"; } elsif (($live1 == 0)&&($live2 == 1)) { $log = "$gw2 up, $gw1 DOWN"; } open(LOG, ">>$logfile"); print LOG &TimeStamp . " - $log\n"; close(LOG); # double check that only one default is set # _________________________________________ $checkdup = qx/$ip ro ls tab $tab/; if ($checkdup =~ /default.*default/s) { system ("$ip ro del default tab $tab"); }