#!/usr/bin/perl 

#ModulePurpose: Find IP links with TM, Stats, LSM enabled 
#ModuleName: identify_SS7oIP_apps 


# links with IP:ETHERNET should only have:
#  CT BOTH 16 1
#  ILM BOTH 16 1
#  PA BOTH 16 1
#  p7ctf BOTH 16 1

# Problems Report
#  --- 56 incorrect SS7oIP apps -08.20.2009 
#  type:IP  link:FTW302<00>LENXKSSP2AD LS Stats TM
#  type:IP  link:FTW302<01>LENXKSSP2AD LS Stats TM
#  type:IP  link:FTW302<02>LENXKSSP2AD LS Stats TM
#  type:IP  link:FTW302<03>LENXKSSP2AD LS Stats TM

#Details Report
#  --- 56 incorrect SS7oIP apps -08.20.2009 
#  type:IP link:FTW302<>LENXKSSP1AD type:IP:ETHERNET link:FTW302<03>LENXKSSP1AD CT ILM PA p7ctf
#  type:IP link:FTW302<>LENXKSSP1AD type:IP:ETHERNET link:FTW302<06>LENXKSSP1AD CT ILM PA p7ctf
#  type:IP link:FTW302<>LENXKSSP1AD type:IP:ETHERNET link:FTW302<07>LENXKSSP1AD CT ILM PA p7ctf
#  type:IP link:FTW302<>LENXKSSP2AD type:IP:ETHERNET link:FTW302<00>LENXKSSP2AD CT ILM LS PA Stats TM p7ctf
#  type:IP link:FTW302<>LENXKSSP2AD type:IP:ETHERNET link:FTW302<01>LENXKSSP2AD CT ILM LS PA Stats TM p7ctf
#  type:IP link:FTW302<>LENXKSSP3AD type:IP:ETHERNET link:FTW302<00>LENXKSSP3AD CT ILM LS PA Stats TM

use lib '/h/bmetzger/s/p/hc/';
use HC qw(:ALL);  #functions available to all modules 

use English;
use Carp;
use Cwd;
use DBI;
use Net::Ping;
use File::Basename;
use File::Path;
use File::Glob;
use File::Copy;

###############3###
# define location of, and open files
##################

  my ($TmpDir,$sitelist,$global_problems,$global_details,$global_summary,$ArchiveDir) = InitVars();

  $ENV{'PATH'} = '/usr/bin:/usr/local/bin:/usr/sbin/:/usr/ucb:/etc/:/opt/platform7/lbin/:.';
  &initvars();

### checks
 ($header, $local_problems, $local_details)= &check(); 
  summarize($header, $local_problems, $local_details);

#################
sub initvars {
#################

   ($sys_day,$sys_mon,$sys_year) = (localtime)[3,4,5];
   $sys_mon += 1;  #jan is 0
   $sys_year += 1900;
   $today = sprintf "%02d.%02d.%d",$sys_mon,$sys_day,$sys_year;  # zero fill date

   $ENV{'PATH'} = '/usr/bin:/usr/local/bin:/usr/sbin/:/usr/ucb:/etc/:.';
} #initvars

####################
sub line_count {
####################
# perform a  wc -l

  my $file = shift;
    open my $fh, "<", $file or die "could not open $file:$!";
    my $lines = 0;
    $lines++ while <$fh>;
    return $lines;
    close ($fh);
} #line_count

####################
sub unique_array {
# Find elements that are in one array but not another.
# find only elements in @A and not in @B
#assume @A and @B are already loaded

   $refA = shift;
   $refB = shift;
   ($asize, $bsize, $missing) = 0;

#foreach (@$refA) {
#   print "$_\n";
#}
   %seen = ();                  # lookup table to test membership of B
   @aonly = ();                 # answer

   # build lookup table
   foreach $item (@$refB) { $seen{$item} = 1 }

   # find only elements in @A and not in @B
   foreach $item (@$refA) {
       unless ($seen{$item}) {
           # it's not in %seen, so add to @aonly
           push(@aonly, $item);
#print "aonly:$item\n";
       }
   }
       $asize = @$refA;
       $bsize = @$refB;
       $missing = scalar @aonly;

  return ($asize, $bsize, $missing, @aonly);

} #unique_array

#########
sub check {
# parse ETR file 

     print "identify SS7oIP apps\n";

     my $local_problems = "$TmpDir/link_problems";
     my $local_details  = "$TmpDir/link_details";
     my $local_junk1    = "$TmpDir/junk1";    # temp file for problems
     my $local_junk2    = "$TmpDir/junk2";    # temp file for details

     my (@arr, @apps)=();

# configurable
#      $etrfile = "/tmp/wm/burl.etr";
#       $etrfile = "/tmp/wm/wm.etr";
       $etrfile = "/h/bmetzger/s/tmp/all/wm.etr";

    # open local output files
    open PROBLEMS, ">>$local_problems" or croak "Can't open file $local_problems for write: $!\n";
    open DETAILS, ">>$local_details" or croak "Can't open file $local_details for write: $!\n";

     my $local_junk1    = "$TmpDir/junk1";    # temp file for problems
     my $local_junk2    = "$TmpDir/junk2";    # temp file for details
  
    unlink("$local_junk1");
  
    # if ETR file is missing, or created > one days ago.....
    if ( (! -e $etrfile) || (-C $etrfile > 1) ) {
         printf   "$etrfile missing or old\n";
         printf PROBLEMS  "$etrfile missing or old\n";

    }else {
         open (IN, "<$etrfile") or croak "Can't open etr $etrfile for read: $!\n";
         open (JUNK1, ">>$local_junk1") or croak "Can't open junk1 $local_junk1 for write: $!\n";
         while (<IN>) { 
              next if /^\#/; 
              next if /^ \#/; 

              if (/^\[linkset\]$/ ... /^\[area\] /) {   #range of all link info
                    chomp;
                    $_ =~ s/\s+/ /g; 
                    @arr = split(/ /,$_);

                    if (/^\[linkset\]$/ ... /^$/) {   #range of all link info
                           if ($_ =~ /^IP /) {  
                               $linksettype = $arr[0];
                               $linkset = $arr[4];
                           }
                   }
                   if (/^\[link\]$/ ... /^$/) { 
                          if ($_ =~ /^IP/) {  
                               $linktype = $arr[0];
                               $link = $arr[3];
                               @apps =();     #reset for every links (
                           }
                   }
                    if (/^\[interface\]$/ ... /^$/) {   #range of all link info
                           if ($_ !~ /^ /) {  
                               $netelement = $arr[0];
                           }
                   }
                   if (/^\[monitoring\]$/ ... /^$/) { 
                          if ($arr[1] eq "BOTH") {  
                              push (@apps,$arr[0]);
                           }
                   }
                   if (/^\[logicallinks\]$/) { 
                        # find apps being monitored which should not be
                        @GoodApps = (CT, ILM, PA, p7ctf);    #good apps.  Any extras are bad
                         my($asize, $bsize, $missing, @aonly) = &unique_array(\@apps,\@GoodApps);

                         if (scalar@aonly > 0) {
#debug                          printf "type:$linksettype link:$linkset type:$linktype link:$link "; 
                                printf PROBLEMS "type:$linksettype  link:$link "; 
                                printf PROBLEMS "@aonly";
                                printf PROBLEMS "\n";
                         }
                      # just for info
#                         printf DETAILS "type:$linksettype link:$linkset type:$linktype link:$link "; 
#                         printf DETAILS "@apps";
#                         printf DETAILS "\n";
                   }
              }
              
        } #end while (<IN>)
     }
     close(IN);
     close(JUNK1);
     close(PROBLEMS);
     close(DETAILS);
     unlink("$local_junk1") || print $!;
     unlink("$local_junk2") || print $!;


    my $badcount = line_count($local_problems);
 
    # open local output files
    open JUNK1, ">>$local_junk1" or croak "Can't open file $local_junk1 for write: $!\n";
    open JUNK2, ">>$local_junk2" or croak "Can't open file $local_junk2 for write: $!\n";

    my $header = "\n--- $badcount incorrect SS7oIP apps -$today \n";

    if ( $badcount > 0 ){  # at least one problem
        #format and header
         print JUNK1 $header;
            qx[cat $local_problems >> $local_junk1];
         close(JUNK1);

        print JUNK2 $header;
            qx[cat $local_details >> $local_junk2];
        close(JUNK2);
    } else {
         #format and header
         print JUNK2 $header;
             qx[cat $local_details >> $local_junk2];
         close(JUNK2);
    }

   copy($local_junk1,$local_problems) or die "junk1 cannot be copied";
   copy($local_junk2,$local_details) or die "junk2 cannot be copied";

   # cleanup
   unlink("$local_junk1") || print $!;
   unlink("$local_junk2") || print $!;

  return($header, $local_problems, $local_details);
} #check

