#
# 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.
#
#---- reading a new route table dump -----------
#----- exported variables:
#-----    $rtemontable = the routemonitor table output
#-----       used by rtemon and archive
#-----    $rpt_interval = the expected report interval
#-----       used by main
#-----    $rptint = the actual report interval
#-----       used by html
#-----    $src = a source appearing in the new route table
#-----       used by as, hour, week, and month
#-----    $metric = the current hour's metric for the source
#-----       used by hour
#-----    $updates = the current hour's update count for the source
#-----       used by hour
#-----    $flaps = the current hour's flaps for the source
#-----       used by as, hour, week, and month
#-----    $first = the current first hop to for the source
#-----       used by none (reserved for future use)
#-----    $tree = the number of times the first hop (ie tree) changed
#-----       used by none (reserved for future use)
#-----    @array = the array of stats for the source to save or add
#-----       used by util, as, hour, week, and month
#-----    %stats = the array of route statistics, indexed by source
#-----       used by as, stats, and util
#-----    %active = the array indicating if a source appeared this hour
#-----       used by week, month, as, stats, and util
#-----    $dtime = the date of the last route table output
#-----       used by stats, month, week, hour, archive, and util
#-----    $new_week = is this the start of a new week
#-----       used by week and archive
#----- internal variables:
#-----    $table_diff = the allowable time between the output and the read
#-----    $interval_diff = the allowable variation in the report period
#-----    $expire = the amount of time before a route expires for stats file
#-----
#
#----- fatal errors:
#-----     none
#----- warnings:
#-----    newtable = unable to read route output table, table ignored
#-----    tablestart = the table header lines were invalid, table ignored
#-----    oldtable = the route table was too old to be valid, table ignored
#-----    interval = the report interval was incorrect, table ignored


sub init_update {
    #how often route monitor data is updated in minutes
    #really, really likes this to be 60 minutes
    $rpt_interval = 60;
    #the interval reported by route monitor must be within this many minutes
    $interval_diff = 5;
    #route table must have been written within this many seconds of update
    $table_diff = 600;
    #the number of seconds a down route should be left in the statistics file
    # recommend 60 days
    $expire = 5184000;
}
 
sub update_stats {
    # check that we have a valid table, get time and period
    if (&valid_table == -1) {
	return(-1);
    }
    # reset all counters for the new output
    &reset_hourly_stats;
    &reset_weekly_stats;
    &reset_monthly_stats;
    &reset_as_stats;
    # update each source in the new route table
    my($line);
    while($line = <NEWTABLE>) {
	($src,$first,$metric,$flaps,$updates,$tree) = split(" ",$line);
	if (!defined($stats{$src})) { &new_src; }
	$active{$src} = "yes";
	@array = split(" ",$stats{$src});
	&update_hourly_stats;
	&update_weekly_stats;
	&update_monthly_stats;
	&update_as_stats;
	&save_src;
    }
    close(NEWTABLE);
    # update each source not appearing in the new route table
    foreach $src (keys %stats) {
	if ($active{$src} eq "no") {
	    @array = split(" ",$stats{$src});
	    if (&expire_src == -1) {
		&inactive_hourly_stats;
		&inactive_weekly_stats;
		&inactive_monthly_stats;
		&inactive_as_stats;
		$active{$src} = "no";
		&save_src;
	    }
	} else {
	    $active{$src} = "no";
	}
    }
    # clean up and write output
    &compute_worst;
    &write_hourly_html;
    if ($new_week == 1) {
	&write_lweek_html;
    }
    &write_weekly_html;
    &write_monthly_html;
    &as_lookup;
}

sub valid_table {
    # return 1 if the new route table is valid, -1 otherwise
    my($difftime,$diffint,$line);
    open(NEWTABLE, "$rtemontable") || &log_error(newtable,$rtemontable);
    $line = <NEWTABLE>;
    # check the first header line is correct
    my($Route,$Table,$Dumped,$At,$Time,$Total,$Routes,$In,$Table2);
    ($Route,$Table,$Dumped,$At,$dtime,$Time,$Total,$Routes,$In,$Table2) = 
	split(" ",$line);
    if (($Route ne "Route") || (split(" ",$line) != 10)) {
	&log_error(tablestart,$line);
	$dtime = time;
	return(-1);
    }
    # check the second header line is correct, learn time and interval
    $line = <NEWTABLE>;
    my($Report,$Interval, $Is, $Minutes, $Table3, $Last, $Reset, $At1, $Ltime,
     $Time2);
    ($Report,$Interval,$Is,$rptint,$Minutes, $Table3,$Last,$Reset,$At1,$Ltime, 
     $Time2) = split(" ",$line);
    if (($Report ne "Report") || (split(" ",$line) != 11)) {
	&log_error(tablestart,$line);
	$dtime = time;
	return(-1);
    }
    # check the route table was written within a reasonable time
    $difftime = abs($dtime - time);
    if ($difftime > $table_diff) {
	&log_error(oldtable,$difftime);
	return(-1);
    }
    # check the update period is the correct number of minutes
    $diffint = abs($rptint - $rpt_interval);
    if ($diffint > $interval_diff) {
	&log_error(interval,$rptint);
	return(-1);
    }
    return(1);
}

sub expire_src {
    # if the source has been inactive for a long period delete the source
    # and return 1, else return -1
    my($s,$c,$downtime);
    $s = &field_num("state"); $c = &field_num("change"); 
    if (($s == -1) || ($c == -1)) {
	return(-1);
    }
    $downtime = $dtime - $array[$c];
    if (($downtime > $expire) && ($array[$s] eq "down")) {
	delete $stats{$src};
	delete $active{$src};
	return(1);
    }
    return(-1);
}


	    
	

