#
# Copyright (c) Xerox Corporation 1997, 1998. All rights reserved.
#
# License is granted to copy, to use, and to make and to use derivative
# works, provided that Xerox is acknowledged in all documentation
# pertaining to any such copy or derivative work. Xerox grants no other
# licenses expressed or implied. The Xerox trade name should not be used
# in any advertising without its written permission.
#
# XEROX CORPORATION MAKES NO REPRESENTATIONS CONCERNING EITHER THE
# MERCHANTABILITY OF THIS SOFTWARE OR THE SUITABILITY OF THIS SOFTWARE
# FOR ANY PARTICULAR PURPOSE.  The software is provided "as is" without
# express or implied warranty of any kind.
#
# These notices must be retained in any copies of any part of this software.
#
#--------- AS statistic operations ---------
#----- exported variables:
#-----    %asdata = the array of as data, indexed by as number
#-----       used by html
#-----    $aslookupdir = the aslookup directory
#-----       used by preamble
#-----    $aslookup = the aslookup executable
#-----       used by preamble
#-----    %stats = the array of route statistics, indexed by source
#-----       used by stats, update, and util
#-----    @array = the array of stats for the source to save or add
#-----       used by update, as, hour, week, and month
#----- internal variables:
#-----    $opt_l = the command line option for $aslookupdir
#-----    $asscript = the name of the aslookup executable plus -h dir -d 
#-----    $opt_L = the command line option for $asscript
#-----    $asinfile = the as lookup input file
#-----    $asoutfile = the as lookup output file
#-----    $aspidfile = the name of the aslookup pid file
#-----    $looking_up_as = flag to indicate we are running aslookup
#-----    $need_lookup = flag indicating we need to run aslookup
#-----    %need_as = array of sources which need the as looked up
#
#----- fatal errors:
#-----    none
#----- warnings:
#-----    aspidfile = unable to write pid file, no AS lookup done
#-----    asout = unable to open as lookup output file, no AS lookup done
#-----    asline = invalid line is as output file, line ignored
#-----    assrc = unknown source in as output file, source ignored
#-----    asin = unable to write as lookup input file, no As lookup done
#-----    asstart = unable to launch as lookup script, no AS lookup done

sub init_as {
    # initialize the as lookup variables
    if (defined($opt_l)) {
	$aslookupdir = $opt_l;
    }
    if (defined($opt_L)) {
	$asscript = "$opt_L -h $aslookupdir -d";
    } else {
	$asscript = "$aslookup -h $aslookupdir -d";
    }
    $asinfile = "$aslookupdir/find_as_for";
    $asoutfile = "$aslookupdir/found_as_for";
    $aspidfile = "$aslookupdir/as_lookup.pid";
    $looking_up_as = "no";
    $asdata{-3} = "-3 0 0 0 0.0.0.0 0 0 0.0.0.0 0";
}

sub reset_as_stats {
    # AS number, num sources, num down, num flapping, worst source, worst flaps
    my($num,$size,$down,$wflap,$wsrc,$wmax,$mflap,$msrc,$mmax);
    #reset the totals for each AS and read any aslookup results
    $size = 0; $down = 0; $wflap =0; $wsrc = "0.0.0.0"; $wmax = 0;
    $mflap = 0; $msrc = "0.0.0.0"; $mmax = 0;
    foreach $num (keys %asdata) {
	$asdata{$num} = 
	    "$num $size $down $wflap $wsrc $wmax $mflap $msrc $mmax";
    }
    if ($looking_up_as ne "yes") {
	# we have not asked the as script to lookup any source as numbers
	return(1);
    }
    # set the looking up as flag to no unless we discover it's still running
    $looking_up_as = "no";
    # we have asked for as numbers, see if the script is still working
    # get the routemonitor pid from its pid file
    open(ASPID, "$aspidfile") || &log_error(aspidfile,$aspidfile);
    my($aspid) = <ASPID>;
    chop($aspid);
    close(ASPID);
    # check if pid is really running
    if (kill(0,$aspid) == 1) {
	# the as lookup script is still working
	$looking_up_as = "yes";
	return(1); 
    }
    my($a) = &field_num("asnum");
    if ($a == -1) { return(-1); }
    # the as lookup script exited, read in the new as data
    open(ASOUT, "$asoutfile") || &log_error(asout,$asoutfile);
    my($aline,$asrc, $anum);
    while($aline = <ASOUT>) {
	if (split(" ",$aline) != 2) {
	    # something bad happened to as lookup output
	    &log_error(asline,$aline);
	} else {
	    # get the source and number from the output file
	    ($asrc,$anum) = split(" ",$aline);
	    if (!defined($stats{$asrc})) {
		# why are we looking the as for an unknown source
		&log_error(assrc,$asrc);
	    } else {
		# update the asnum for the source
		@array = split(" ",$stats{$asrc});
		$array[$a] = $anum;
		&save_src;
	    }
	    # delete the record indicating we an as for this source
	    delete $need_as{$asrc}; 
	}
    }
    close(ASOUT);
}

sub update_as_stats {
    # add an active source to the current as data
    # AS number, num sources, num down, num flapping, worst source, worst flaps
    my($num,$size,$down,$wflap,$wsrc,$wmax,$mflap,$msrc,$mmax);
    # get the asnum, weekly flaps and monthly flaps for the current source
    my($a,$w,$m,$mywflap,$mymflap);
    $a = &field_num("asnum"); 
    $w = &field_num("wflaps"); $m = &field_num("mflaps"); 
    if (($a == -1) || ($w == -1) || ($m == -1)) {
	return(-1);
    }
    $num = $array[$a]; $mywflap = $array[$w]; $mymflap = $array[$m];
    if (!defined($asdata{$num})) {
	# define a new as number structure if needed
	$size = 0; $down = 0; 
	$wflap = 0; $wsrc = "0.0.0.0"; $wmax = 0;
	$mflap = 0; $msrc = "0.0.0.0"; $mmax = 0;
    } else {
	($num,$size,$down,$wflap,$wsrc,$wmax,$mflap,$msrc,$mmax) = 
	    split(" ",$asdata{$num});
    }
    if ($num == -2) {
	# we need to lookup an asnumber for this source
	if (!defined($need_as{$src}) || ($need_lookup ne "yes")) {
	    # we have not already request a lookup for this source
	    $need_as{$src} = "yes";
	    $need_lookup = "yes";
	}
    }
    if ($mywflap >= $wmax) {
	# if the new source is the worst weekly flapper for this as
	$wmax = $mywflap;
	$wsrc = $src;
    }
    if ($mymflap >= $mmax) {
	# if the new source is the worst weekly flapper for this as
	$mmax = $mymflap;
	$msrc = $src;
    }
    if (int($mywflap) > 0) {
	# add the weekly flapping count for the as
	$wflap++;
    }
    if (int($mymflap) > 0) {
	# add the monthly flapping count for the as
	$mflap++;
    }
    $size++;
    $asdata{$num} = "$num $size $down $wflap $wsrc $wmax $mflap $msrc $mmax";
}

sub inactive_as_stats {
    # the source did not appear this hour
    # identical to the actions done for an active source:
    &update_as_stats;
    #except we also need to increment the down counter
    # AS number, num sources, num down, num flapping, worst source, worst flaps
    my($num,$size,$down,$wflap,$wsrc,$wmax,$mflap,$msrc,$mmax);
    $a = &field_num("asnum");
    if ($a == -1) { return(-1); }
    $num = $array[$a];
    ($num,$size,$down,$wflap,$wsrc,$wmax,$mflap,$msrc,$mmax) = 
	split(" ",$asdata{$num});
    $down++;
    $asdata{$num} = "$num $size $down $wflap $wsrc $wmax $mflap $msrc $mmax";
}

sub as_lookup {
    # lookup as numbers for sources if needed
    if (($looking_up_as eq "yes") || ($need_lookup eq "no")) {
	# we are already looking up stuff or don't need to lookup anything
	return(1);
    }
    # write the sources we want to look up into an input file
    open(ASIN,">$asinfile") || &log_error(asin,$asinfile);
    my($asrc);
    foreach $asrc (keys %need_as) { print ASIN "$asrc\n"; }
    close(ASIN);
    # launch the as lookup program
    my($myscript) = "$asscript -i $asinfile -o $asoutfile";
    my($ret) = system("$myscript > /dev/null &");
    if ($ret != 0) { &log_error(asstart,$myscript); }
    $need_lookup = "no";
    $looking_up_as = "yes";
}






