#!/usr/bin/perl

use Socket;
use Net::Ping;
use Getopt::Std;
use Mail::Sendmail;
use Sys::Hostname;
use Luca::Logger;


$SIG{'INT'}  = 'IGNORE';
$SIG{'QUIT'} = 'IGNORE';
$SIG{'ILL'}  = 'IGNORE';
$SIG{'TRAP'}  = 'IGNORE';
$SIG{'ABRT'}  = 'IGNORE';
$SIG{'BUS'}  = 'IGNORE';
$SIG{'FPE'}  = 'IGNORE';
$SIG{'USR1'}  = write_route;
$SIG{'SEGV'}  = 'IGNORE';
$SIG{'USR2'}  = 'IGNORE';
$SIG{'PIPE'}  = 'IGNORE';
$SIG{'ALRM'}  = 'IGNORE';
#$SIG{'TERM'}  = 'IGNORE';
$SIG{'CHLD'} = 'IGNORE';
$SIG{'CONT'}  = 'IGNORE';
$SIG{'STOP'}  = 'IGNORE';

getopts('f:l:d:h');

my(%CFG,$routesmaxindex,$pidfile);
my $host = hostname;
$application="Dynaroute-multi";
my $log;
my $ipcmd=`which ip`;
chomp($ipcmd);
my $grep=`which grep`;
chomp($grep);
$routesmaxindex=0;
chomp($ip);

$cfgfile="/etc/sysconfig/dynaroute/dynaroute-multi.conf";
$cfgfile=$opt_f if defined($opt_f);
$logfile="/var/log/dynaroute-multi.log";
$logfile=$opt_l if defined($opt_l);

$log = Logger->new(
                   logfile => $logfile,
                   application => $application,
                  );
my %ISP;


##########Configuration Reader##########
sub _init_
{
  $|=1;
  $log->log("Reading Configuration");
  undef(%ISP);
  undef(@hosts);
  open(CFG,"<$cfgfile");#||_log_("CANNOT OPEN $cfgfile");
  while(<CFG>)
  {
   chomp;
   my($pre,$post);
   next if /[<>]+/;
   next if /^#/;
   ($pre,$post)=split('=');
   if ($pre =~ /instdir/)
      {
       ($CFG{'instdir'})=($post=~ /([^";]+)/);
       $log->log ("Installation dir is " . $CFG{'instdir'});
      }

   if ($pre =~ /pidfile/)
      {
       ($CFG{'pidfile'})=($post=~ /([^";]+)/);
       $log->log ("Pidfile is " . $CFG{'pidfile'});
      }

   if ($pre =~ /tmp_routefile/)
      {
       ($CFG{'tmp_routefile'})=($post=~ /([^";]+)/);
      }

   if ($pre =~ /icqaddr/)
      {
       ($icqaddr)=($post=~ /([^'";]+)/);
       #_log_ ("Icq alert for $icqaddr");
      }

   if ($pre =~ /mailto/)
      {
       ($CFG{'mailto'})=($post=~ /([^'";]+)/);
       $log->to($CFG{'mailto'});
       $log->log ("Mail alert for " . $CFG{'mailto'});
      }

   if ($pre =~ /mailfrom/)
      {
       ($CFG{'mailfrom'})=($post=~ /([^'";]+)/);
       $log->from($CFG{'mailfrom'});
       $log->log ("Mail alert from " . $CFG{'mailfrom'});
      }

   if ($pre =~ /subject/)
      {
       ($CFG{'subject'})=($post=~ /([^'";]+)/);
       $log->subject($CFG{'subject'});
       $log->log ("Mail alert subject " . $CFG{'subject'});
      }

   if ($pre =~ /sleepsecond/)
      {
       ($sleepsecond)=($post=~ /([^";]+)/);
       #_log_ ("Sleep time is $sleepsecond");
      }

   if ($pre =~ /snmpflag/)
      {
       ($snmpflag)=($post=~ /([^";]+)/);
       #_log_ ("Snmp Alert Enabled") if($snmpflag);
      }

   if ($pre =~ /isp/)
      {
        my(@isp,$tm);
       ($tm)=($post=~ /([^";]+)/);
        @isp=split(/\|/,$tm);
        #print "tm $tm\n";
        foreach $isp (@isp)
         {
          #print "ISP $isp\n";
          @fld=();
          @fld=split(/:/,$isp);
          $ISP{$fld[0]}={
                        'device' => $fld[1],
                        'rtnam' => $fld[2],
                        'name' => $fld[3],
                        'endpoint' => $fld[4],
                        'upscript' =>$fld[5],
                        'downscript' => $fld[6]
                      };
          #print "$fld[0] -- $ISP{$fld[0]}{'downscript'} -- $ISP{$fld[0]}{'upscript'}\n";
          $routesmaxindex++;
        }

      }
  }
  close(CFG);
}

sub setroutes
{
        foreach(keys(%ISP))
        {
                `$ipcmd route replace $ISP{$_}->{'endpoint'} via $_ dev $ISP{$_}->{'device'}`;
                $log->log("$ipcmd route replace $ISP{$_}->{'endpoint'} via $_ dev $ISP{$_}->{'device'}");
        }
}

sub write_route
{
 open(ROUTE,">$CFG{'tmp_routefile'}");
 print ROUTE "$running_dev";
 close(ROUTE);
}




#############Get routing status####
sub setstatus
{
 my(%STATE);
 my $pinghost = Net::Ping->new("icmp");
 foreach (keys(%ISP))
  {
   $STATE{$_}=$pinghost->ping($ISP{$_}->{'endpoint'});
  }
 return %STATE;
}
#############Search for activeindex####


##############################MAIN PROGRAM############################
$SIG{'HUP'} = '_init_';

_init_;

open (PID,">$CFG{'pidfile'}");
print PID "$$";
close (PID);

setroutes;

$log->log ("Starting Main Loop");
my @keys,%STATE;
@keys=keys(%ISP);
%STATE=setstatus;

while(1)
{
   my($pinghost,$pinged,%activeroutes);
   $pinghost = Net::Ping->new("icmp");
   foreach $router (@keys)
        {

                #`$ipcmd route replace $ISP{$_}->{'endpoint'} via $ISP{$_}->{'endpoint'} dev $ISP{$_}->{'device'}`;
                #print "testing router $ISP{$router}->{'endpoint'} ....\n";
                if($pinghost->ping($ISP{$router}->{'endpoint'}))
                  {
                    if(!$STATE{$router})
                        {
                          $log->log("$ISP{$router}->{'name'} went up, enabling...");
                          $res=`$CFG{'instdir'}/$ISP{$router}->{'upscript'}`;
                          chomp($res);
                          $log->log("...enabled  $ISP{$router}->{'name'} (Result command was $res)");
                          $log->icq_mail ("Going up $ISP{$router}->{'name'} - Command $res");
                          $STATE{$router}=1;
                        }
                  }
                else
                  {
                    if($STATE{$router})
                        {
                          $log->log("$ISP{$router}->{'name'} went down, disabling...");
                          $res=`$CFG{'instdir'}/$ISP{$router}->{'downscript'}`;
                          chomp($res);
                          $log->log("...disabled $ISP{$router}->{'name'} (Result command was $res)");
                          $log->icq_mail ("Going down $ISP{$router}->{'name'} - Command $res");
                          $STATE{$router}=0;
                        }
                  }

        }

  sleep($sleepsecond);
}

