#### ASpath-tree v.4.2 - Released on Thu APR 17 2003, h.16:58:12
#### File: lib/elaborate-aspaths.pl Last modified on Tue MAR 18 2003, h.22:58:34

# Routine to  initialize the basic arrays for further elaborations.
# %ROUTE_ENTRIES: hash array with the ASPaths as keys and the prefixes (separated by a blanck space if more
#                 than one) as value. The ASPath is normalised as a string of contiguous AS numbers, where
#                 each AS number is a 5 digit figure; 0s are added before shorter AS numbers;
#                 AS  number '00000' is used as paddinng; AS sets are encoded using 5 digit figures starting
#                 from 65536 (the first number out of the AS space)
# %ROUTE_FLAGS:   hash array with the prefixes as keys and BGP flags as values
# %ROUTE_EXCLUDED:hash array with the prefixes as keys and ASpaths as values
# %ASNAME:        hash array with AS numbers as keys and AS names as values (if no name found the string "(AS number)" is used)
# %PREPEND:       hash array with AS numbers as keys and values are pointer to hashes where prefixes are keys and "AS names#Num"
#                 are values (where Num is the number of prependend ASs)
# %ASSET:         hash array with conventional numbers for AS sets as keys and their {} repesentation  as values
# %HINTS:         hash array with AS numbers as keys and AS name suggestions as values
# %PTLAS:         hash array with 6Bone pTLAs as keys and owner organisations as values
# %STLAS:         hash array with sTLAs as keys and owner organisations as values
# Global  variable $maxASNs indicating the max length of an ASPath in table (current or recorded) is also initialized
sub initialize_arrays {
	my (@ori_lines) = @_;
	my ($prefix, $line, $ASNs, $key, $site, $ptla, $item, $stla) = ('', '', '', '', '', '', '', '');
	use vars qw (%ROUTE_ENTRIES %ROUTE_FLAG %ASNAME %PREPEND %ASSET %HINTS %PTLAS %STLAS);
	use vars qw ($maxASNs $ASSETNUMBER);
	$ASSETNUMBER = 65535;
	my $oldmaxASNs = 0;
	my $tobe_suppressed = 0;
	my (@lines) = ();
	my (@not_advertized_routes) = ();
	my (@elements) = ();
	my (@allfiles) = ();

# Filter router output (suppressed routes among the internal or directly connected ones)
	foreach $line (@ori_lines) {
		chomp($line);
		if ($FILTEROUT == 1) {$tobe_suppressed = (substr($line, 0, 1) eq 's')}
		elsif ($FILTEROUT == 2) {$tobe_suppressed = (substr($line, 0, 1) eq 's') && (substr($line, 2, 1) eq 'i' ||
													substr($line, 3, 1) == 1)}
		if ($tobe_suppressed) {push(@not_advertized_routes, $line)}
		else {push(@lines, $line)}
	}

# Evaluate max length of AS path in table (current and recorded)
	$maxASNs = 0;
	foreach $line (@lines) {
		@elements = split(/\s+/, $line);
		if ($maxASNs < $#elements) {$maxASNs = $#elements}
	}
	$maxASNs--;
	if (open(OLDFILE, "<$OLDASPATHSFILE")) {
		@oldaspaths = grep(/\d/, <OLDFILE>);
		close(OLDFILE);
		foreach $line (@oldaspaths) {
			@elements = split(/\s+/, $line);
			if ($oldmaxASNs < $#elements) {$oldmaxASNs = $#elements}
		}
	}
	if ($oldmaxASNs > $maxASNs) {$maxASNs = $oldmaxASNs}
# Create hash arrays %ROUTE_ENTRIES, %ROUTE_FLAGS, %ASNAME, %HINTS
	foreach $line (@lines) {
		@elements = split(/\s+/, $line);
		$ASNs = '';
		($ASNs, $iprep) = &normalize_aspath(@elements[(2)..($#elements)]);
		$ROUTE_ENTRIES{$ASNs} .= " $elements[1]";
		$ROUTE_FLAGS{$elements[1]} = $elements[0];
		$ROUTE_FLAGS{$elements[1]} =~ s/\-/ /;
		if (keys(%$iprep)) {foreach $key (keys(%$iprep)) {$PREPEND{$ASNs}{$elements[1]} .= "$key\#$$iprep{$key} "}}
	}

# Create hash array %PTLAS
	open(FILE,"<".$PTLA_FILE);
	while (<FILE>) {
		if (/(\S+)\s+(\S+)/ && $2 !~ /\-+/ && $2 !~ /owner/i) {
			$site = $1;
			$ptla = &normal($2);
			$site =~ /(.+)\/?.*/;
			$site = $1;
			if ($ptla) {$PTLAS{$ptla} = $site}
		}
	}
	close(FILE);

# Create hash array %STLAS
	open(FILE,"<".$STLA_FILE);
	while (<FILE>) {
		if (/(\S+)\s+(\S+)/ && $2 !~ /\-+/ && $2 !~ /owner/i) {
			$site = $1;
			$stla = &normal($2);
			$STLAS{$stla} = $site;
		}
	}
        close(FILE);

# Create hash for excluded route entries
	foreach $line (@not_advertized_routes) {
		@elements = split(/\s+/, $line);
		if ($#elements > 1) {$ROUTE_EXCLUDED{$elements[1]} = join(' ', @elements[(2)..($#elements)])}
		else {$ROUTE_EXCLUDED{$elements[1]} = ''}
		$ROUTE_FLAGS{$elements[1]} = $elements[0];
		$ROUTE_FLAGS{$elements[1]} =~ s/\-/ /;
	}
	return(0);
}

# Routine to normalize ASPath (see routine "initialize_arrays")
sub normalize_aspath {
	my (@asns) = @_;

	my ($k, $nbb) = (0, 0);
	my ($asn, $asn_0, $ASNs, $asset) = ('', '', '', '');
	my @asset_el = ();
	my %prepend = ();
	my $incr = 0;

	for ($k = 0;$k < $maxASNs; $k++) {
		if ($asns[$k] =~ /\#/) { # deal with AS sets
			$asset = $asns[$k];
			@asset_el = split(/\#/, $asset);
			foreach $asn (@asset_el) {&assoc_name_to_as($asn)}
			unless (grep(/$asset/, (values(%ASSET)))) {
				$ASSETNUMBER++;
				$ASNAME{$ASSETNUMBER} = '{AS'.$asset_el[0].'..}';
				$ASSET{$ASSETNUMBER} = $asset;
			}
			$ASNs .= "$ASSETNUMBER";
		}
		elsif ($asns[$k] =~ /\(?(\d+)\)?/) {
			$asn = $1;
			if ($asn ne $asn_0) { # deal with the problem of prepended ASs (thank to Philip Smith)
				$asn_0 = $asn;
				&assoc_name_to_as($asn);
				$asn = ("0" x (5-length($asn))) . $asn;
				$ASNs .= "$asn";
			} else {
				$prepend{$asn}++;
				$incr++;
			}
		}
		else {$ASNs .= '00000'}
	}
	if ($incr) {for ($k = 0;$k < $incr; $k++) {$ASNs .= '00000'}}
	return($ASNs, \%prepend);
}

# routine to associate organization names to AS numbers (initialize %ASNAME and %HINTS)
sub assoc_name_to_as {
	my ($asnumber) = @_;
	my $nbb = 0;
	my @names = ();

	unless ($ASNAME{$asnumber}) {
		($nbb, @names) = &asntosite($asnumber, $ASTABLE, $PTLA_FILE);
		if ((@names == 1 || $nbb == 1) && ($asnumber =~ /\d+/ && $asnumber < 65536)) {
			$ASNAME{$asnumber} = $names[0];
		}
		elsif (grep(/CSELT/, @names)) {$ASNAME{$asnumber} = 'TILAB'}
		else {
			$ASNAME{$asnumber} = "AS$asnumber";
			if (@names > 1) {
				for (@names) {
					$HINTS{$asnumber} .= "$_, ";
				}
				chop($HINTS{$asnumber});chop($HINTS{$asnumber});
			}
		}
	}

	return(0);
}

# Routine to convert normalised ASPath into standard ASPath
sub convert_asn {
	my ($string) = @_;
	my ($offset) = 0;
	my ($asn) = ('');
	my @asns = ();

	while ($offset < length($string)) {
		$asn = substr($string, $offset, 5);
		if ($asn eq '00000') {last}
		else {
			while (substr($asn, 0, 1) eq '0') {$asn = substr($asn, 1, length($asn)-1)}
		}
		push(@asns, $asn);
		$offset += 5;
	}
	return(@asns);
}

# Routine to update the historical information file "allprefixes.txt" and to create detail files
# The following global arrays are defined:
# @NRPTLAS     a list of non-reachable pTLAs
# @NMOREPTLAS  a list of pTLAs that become unreachable since last update
# @NEWRPTLAS   a list of pTLAs that become reachable since last unreachability update
# %CHANGESALL  a hash array with normalised ASpaths as keys and "new" or "old" as values for the whole table changes
# %CHANGESBBS  a hash array with normalised ASpaths as keys and "new" or "old" as values for the BB table changes
# %CHANGESOTH  a hash array with normalised ASpaths as keys and "new" or "old" as values for the otherIANA table changes
# %PTLAINFO    a hash array with pTLA site names as keys and the string "$prefix detailfilename" as values
# %PTLASTAB    a hash array with pTLA site names as keys and the instability figures as values
# %PTLAUNAV    a hash array with pTLA site names as keys and the unavailabilty figures as values
# %IANAINFO    a hash array with other IANA assigned site names as keys and the string "$prefix detailfilename" as values
# %IANASTAB    a hash array with other IANA assigned site names and the instability figures as values
# %IANAUNAV    a hash array with other IANA assigned site names and unavailabilty figures as values
# %ATTRIBUTES  a hash array with invalid or unaggregated prefixes as keys and the string "flag originAS originASnumber owner
#              pTLAowner aspath" as values, where:
#                  flag = 0 (invalid) and = 2 (unaggregated)
#                  originAS = name in registry or AS number (e.g. 5609) or "local" if not shown in table
#                  owner = name in registry or "?" if not present in registry
#                  pTLAowner = name in registry of belonging pTLA or "?" if within 6Bone address space
#                              but not in registry or "-" if outside the 6Bone address space
# %TREE_ROWS   hash array with the ASPaths as keys and the string "$flag_warning $N_as_in_path $filename";
#              "$flag_warning" contains a "u" if route changed recently and, for each prefix
#              reachable trohugh ASPath, a number with the following meaning:
#	       0 -> invalid prefix, 1 -> 6bone pTLA prefix, 2 -> 6bone unaggregated prefix,
#	       3 -> other IANA assigned prefix; filename is used to built the URL of a detail
#              for the key ASPath. The ASPath is normalised as a string of contiguous AS numbers, where
#              each AS number is a 5 digit figure. as in %ROUTE_ENTRIES.
# On output this routine provides:
# - the pointer to a hash array (%num) containing the counters for:
#    key          value
#    ASintrees    number of ASs in received route entries
#    origAS       number of originating only ASs
#    transitAS    number of transit only ASs
#    bothAS       number of originating and transit ASs
#    privAS       number of private ASs
#    reservedAS   number of reserved ASs
#    activePEERS  number of BGP neigbours annoncing routes
#    ASpaths      number of AS paths in table
#    averageDIST  average number of ASs crossed to reach prefixes
#    N_prefix     number of total prefixes in received route entries
#    N_reduced
#    N_invalid    number of invalid prefixes in received route entries
#    N_unaggr     number of unaggregated prefixes in received route entries
#    N_ptlas      number of pTLA prefixes in received route entries
#    N_otherIANA  number of sTLA prefixes in received route entries
#    N_6to4       number of 6to4 /16 prefixes (we expect 1!)
#    N_longer6to4 number of 6to4 prefixes longer than /16
# - the pointer to a hash array of AS distance, with the number of crossed ASs as keys and the number of
#   reachable prefixes as values
# - the pointer to a hash array of AS paths containing private AS numbers, with the private AS numbers as
#   keys and the normalized AS paths as value
# - the pointer to a hash array of AS paths containing reserved AS numbers, with the reserved AS numbers as
#   keys and the normalized AS paths as value
sub update_details_and_history {

	use vars qw (@NRPTLAS @NMOREPTLAS @NEWRPTLAS);
	use vars qw (%CHANGESALL %CHANGESBBS %CHANGESOTH %PTLAINFO %PTLASTAB %PTLAUNAV %IANAINFO %IANASTAB
		     %IANAUNAV %ATTRIBUTES %TREE_ROWS);
	my ($key, $filename, $aspath, $normal_aspath, $value, $value1, $origin_as, $tmp);
	my ($addr, $lpref, $pref1, $pref, $asis_prefix, $prefix, $time, $updates, $ptlafilename, $owner, $xtla_owner, $detailslink);
	my ($prefix_flag, $html_details_dir, $flag_warning, $nrptla, $ptla, $ptla_name, $name);
	my ($i, $n, $N_as_in_path) = (0, 0, 0);
	my ($N_prefix,$N_ptlas,$N_reduced,$N_invalid,$N_unaggr,$N_otherIANA) = (0, 0, 0, 0, 0, 0);
	my ($day_plus_1, $filename0, $filename1, $suffix);
	my ($todo_bgp_collect, $nsamples, $nchanges, $nunavail, $nas) = ('0', '0', '0', '0', '0');
	my @keys = ();
	my @aspfound = ();
	my @aspaths = ();
	my @asnumber = ();
	my @vector = ();
	my @vector_bb = ();
	my @vector_iana = ();
	my @newhistory = ();
	my @prefixes = ();
	my @local_prefixes = ();
	my @sorted_pref = ();
	my @oldnrptlas = ();
	my @allfiles = ();
	my @oldaspthall = ();
	my @oldaspthbbs = ();
	my @oldaspthoth = ();
	my %hints = ();
	my %ptla_present = ();
	my %other_present = ();
	my @ass = ();
	my @asspriv = ();
	my @assreserved = ();
	my @assann = ();
	my @asstransit = ();

	@NRPTLAS = ();
	@NMOREPTLAS = ();
	@NEWRPTLAS = ();
	%CHANGESALL = ();
	%CHANGESBBS = ();
	%CHANGESOTH = ();
	%PTLAINFO = ();
	%PTLASTAB = ();
	%PTLAUNAV = ();
	%IANAINFO = ();
	%IANASTAB = ();
	%IANAUNAV = ();
	%ATTRIBUTES = ();
	%distance = ();
	%num = ();
	%localnum = ();
	%paths_withasspriv = ();
	%paths_withassreserved = ();

# Read history file "allprefixes.txt"
	my @history = &read_history($HISTORYFILE);

# Read recorded ASpath files for detecting changes
	if (open(ASPFILE, "< $OLDASPATHSFILE")) {
		@oldaspathall = grep(/\d/, <ASPFILE>);
		close(ASPFILE);
		for ($i = 0; $i < @oldaspathall; $i++) {
			chomp($oldaspathall[$i]);
			($oldaspathall[$i], $tmp) = &normalize_aspath(split(/\s+/, $oldaspathall[$i]));
		}
	}
	if ($MORETREES) {
		if (open(ASPFILE, "< $OLDBBASPATHSFILE")) {
			@oldaspathbbs = grep(/\d/, <ASPFILE>);
			close(ASPFILE);
			for ($i = 0; $i < @oldaspathbbs; $i++) {
				chomp($oldaspathbbs[$i]);
				($oldaspathbbs[$i], $tmp) = &normalize_aspath(split(/\s+/, $oldaspathbbs[$i]));
			}
		}
		if (open(ASPFILE, "< $OLDOTHASPATHSFILE")) {
			@oldaspathoth = grep(/\d/, <ASPFILE>);
			close(ASPFILE);
			for ($i = 0; $i < @oldaspathoth; $i++) {
				chomp($oldaspathoth[$i]);
				($oldaspathoth[$i], $tmp) = &normalize_aspath(split(/\s+/, $oldaspathoth[$i]));
			}
		}
	}

	@keys = keys(%ROUTE_ENTRIES);
	$num{ASpaths} = 0;
	$num{N_prefix} = 0; $num{N_reduced} = 0; $num{N_invalid} = 0; $num{N_unaggr} = 0;
	$num{N_ptlas} = 0; $num{N_otherIANA} = 0; $num{N_6to4} = 0; $num{N_longer6to4} = 0;
	$localnum{N_prefix} = 0; $localnum{N_invalid} = 0;$localnum{N_unaggr} = 0;
	$localnum{N_ptlas} = 0;$localnum{N_otherIANA} = 0; $localnum{N_6to4} = 0; $localnum{N_longer6to4} = 0;
# Main loop over AS paths
	foreach $key (@keys) {
		@asnumbers = &convert_asn($key);
		if (@asnumbers) {
			$num{ASpaths}++;
			$suffix = ("0" x (4-length($num{ASpaths}))).$num{ASpaths};
			$filename = "file".$suffix.".html";
			$N_as_in_path = @asnumbers;
			$flag_warning = '';
			$aspath = '';
			$normal_aspath = '';
			undef %hints;
			@vector = ();
			@vector_bb = ();
			@vector_iana = ();
# Loop over AS numbers within an AS path
			for ($n=0;$n<@asnumbers;$n++) {
				$value = $asnumbers[$n];
				if ($value > 65535) { # deal with AS sets
					$normal_aspath .= "$ASSET{$value}\/";
					my @temp = split(/\#/, $ASSET{$value});
					$aspath .= '{';
					foreach $value1 (@temp) {
						if ($n eq $#asnumbers) {unless (grep(/^$value1$/,@assann)) {push(@assann,$value1)}}
						else {unless (grep(/^$value1$/,@asstransit)) {push(@asstransit,$value1)}}
						unless (grep(/^$value1$/,@ass)) {
							push(@ass, $value1);
							if ($value1 > 64511 && $value1 < 65535) {
								push (@asspriv,$value1);
								push (@{$paths_withasspriv{$value1}}, $key);
							} elsif ($value1 == 65535 || ($value1 > 32767 && $value1 < 64512)) {
								push (@assreserved,$value1);
								push (@{$paths_withassreserved{$value1}}, $key);
							}
						}
						if ($ASNAME{$value1} !~ /^AS\d+$/) {$aspath .= "$ASNAME{$value1} (AS$value1), "}
						else {
							$aspath .= "($ASNAME{$value1}), ";
							if ($HINTS{$value1}) {$hints{$value1} = $HINTS{$value1}};
						}
					}
					$aspath = substr($aspath, 0, length($aspath)-2);
					$aspath .= '} - ';
				}
				else {
					if ($n eq $#asnumbers) {unless (grep(/^$value$/,@assann)) {push(@assann,$value)}}
					else {unless (grep(/^$value$/,@asstransit)) {push(@asstransit,$value)}}
					unless (grep(/^$value$/,@ass)) {
						push(@ass, $value);
						if ($value > 64511 && $value < 65535) {
							push (@asspriv,$value);
							push (@{$paths_withasspriv{$value}}, $key);
						} elsif ($value == 65535 || ($value > 32767 && $value < 64512)) {
							push (@assreserved,$value);
							push (@{$paths_withassreserved{$value}}, $key);
						}
					}
					$normal_aspath .= "$value\/";
					if ($ASNAME{$value} !~ /^AS\d+$/) {$aspath .= "$ASNAME{$value} (AS$value) - "}
					else {
						$aspath .= "($ASNAME{$value}) - ";
						if ($HINTS{$value}) {$hints{$value} = $HINTS{$value}};
					}
				}
			}
			$aspath = substr($aspath, 0, length($aspath)-3);
			$normal_aspath = substr($normal_aspath, 0, length($normal_aspath)-1);

			@prefixes = split(/\s+/, substr($ROUTE_ENTRIES{$key}, 1, length($ROUTE_ENTRIES{$key})-1));
			$distance{$N_as_in_path} += @prefixes;
# Loop over prefixes
			foreach $asis_prefix (sort(@prefixes)) {
				$prefix = &normal($asis_prefix);
				$num{N_prefix}++;
				($time, $updates, @newhistory) = &update_history_line($prefix, $normal_aspath, \@history, \@newhistory);
				if (int($time/60) <= $WARNINGTIME) {$flag_warning .= "u"}
# Find origin AS (number and name), owner site and possible pTLA
				$origin_as = $asnumbers[$#asnumbers];
				if ($PTLAS{$prefix}) {
					$owner = $PTLAS{$prefix};
					$xtla_owner = $owner;
				} elsif ($STLAS{$prefix}) {
					$owner = $STLAS{$prefix};
					$xtla_owner = $owner;
				} else {
					$owner = &extract_name_from_prefix($prefix);
					$xtla_owner = &extract_xtla_from_prefix($prefix);
				}
# Check prefix
				$prefix_flag = &check_prefix($prefix);
				if ($prefix_flag == 0) {
					$num{N_invalid}++;
					$ATTRIBUTES{$asis_prefix} = "$prefix_flag $origin_as $owner $xtla_owner @asnumbers";
				} elsif ($prefix_flag == 1) {
					$num{N_ptlas}++;
				} elsif ($prefix_flag == 2) {
					$num{N_unaggr}++;
					$ATTRIBUTES{$asis_prefix} = "$prefix_flag $origin_as $owner $xtla_owner @asnumbers";
				} elsif ($prefix_flag == 3) {
					$num{N_otherIANA}++;
				} elsif ($prefix_flag == 4) {
					$num{N_6to4}++;
				} elsif ($prefix_flag == 5) {
					$num{N_longer6to4}++;
					$ATTRIBUTES{$asis_prefix} = "$prefix_flag $origin_as $owner - @asnumbers";
				}
				$flag_warning .= $prefix_flag;
# Update stability information for 6Bone pTLA and other IANA assigned prefixes
				if (($prefix_flag == 1 && $PTLAS{$prefix}) || ($prefix_flag == 3 && $STLAS{$prefix})) {
					if ($PTLAS{$prefix}) {
						$detailslink = $PTLAS{$prefix};
						$filename0 = "$PTLASHISTORYDIR/$detailslink";
						$filename1 = "$GLOBALPTLAHISTDIR/$detailslink";
					}
					else {
						$detailslink = $STLAS{$prefix};
						$filename0 = "$OTHERHISTORYDIR/$detailslink";
						$filename1 = "$GLOBALOTHERHISTDIR/$detailslink";
					}
					($nsamples, $nchanges, $nunavail, @aspaths) = &update_24h_stability_history($normal_aspath, $filename0);
					&create_html_stability_detailfile("$HISTORYHTMLDIR/$detailslink.html", $prefix, $aspath, $owner, $nunavail, $nchanges, $nsamples, @aspaths);
					if ($prefix_flag == 1) {
						$PTLAINFO{$owner} = "$prefix $detailslink";
						$PTLASTAB{$owner} = $nchanges/$nsamples;
						$PTLAUNAV{$owner} = $nunavail/$nsamples;
						$ptla_present{$prefix} = 1; # flag to find non reachable pTLAs
						if ($MORETREES) {
							push(@vector_bb, "$asis_prefix $owner $time $updates $detailslink $xtla_owner $origin_as");
						}
					} else {
						$IANAINFO{$owner} = "$prefix $detailslink";
						$IANASTAB{$owner} = $nchanges/$nsamples;
						$IANAUNAV{$owner} = $nunavail/$nsamples;
						$other_present{$prefix} = 1; # flag to find non reachable prefixes
						if ($MORETREES) {
							push(@vector_iana, "$asis_prefix $owner $time $updates $detailslink $xtla_owner $origin_as");
						}
					}
				}
				else {
					$detailslink = "n/a";
					if ($MORETREES) {
						if ($prefix_flag == 1 && !$PTLAS{$prefix}) {
							push(@vector_bb, "$asis_prefix $owner $time $updates $detailslink $xtla_owner $origin_as");
						} elsif ($prefix_flag == 3 && !$STLAS{$prefix}) {
							push(@vector_iana, "$asis_prefix $owner $time $updates $detailslink $xtla_owner $origin_as");
						}
					}
				}
				push(@vector, "$asis_prefix $owner $time $updates $detailslink $xtla_owner $origin_as");
			} #end loop over prefixes

# Create HTML detail file for ASpath (complete)
			&create_html_detailfile("$DETAILDIRCO/$filename", $aspath, \@vector, \%hints, $PREPEND{$key});

			if ($MORETREES) {
# Create HTML detail file for ASpath (backbone)
				if (@vector_bb) {
					&create_html_detailfile("$DETAILDIRBB/$filename", $aspath, \@vector_bb, \%hints, $PREPEND{$key});
				}

# Create HTML detail file for ASpath (otherIANA)
				if (@vector_iana) {
					&create_html_detailfile("$DETAILDIRIANA/$filename", $aspath, \@vector_iana, \%hints, $PREPEND{$key});
				}
			}

			$TREE_ROWS{$key} = "$flag_warning $N_as_in_path $filename";

# Grep new ASpaths not previously recorded
			if (!(grep(/$key/, @oldaspathall))) {$CHANGESALL{$key} = "new"}
			if ($MORETREES) {
				if (!(grep(/$key/, @oldaspathbbs)) && ($flag_warning =~ /[1]/)) {$CHANGESBBS{$key} = "new"}
				if (!(grep(/$key/, @oldaspathoth)) && ($flag_warning =~ /[3]/)) {$CHANGESOTH{$key} = "new"}
			}
		}
# prefixes advertised from the local site
		else {
			@prefixes = split(/\s+/, substr($ROUTE_ENTRIES{$key}, 1, length($ROUTE_ENTRIES{$key})-1));
			delete $ROUTE_ENTRIES{$key};
			foreach $asis_prefix (@prefixes) {
				$prefix = &normal($asis_prefix);
				$localnum{N_prefix}++;
				if ($PTLAS{$prefix}) {
					$owner = $PTLAS{$prefix};
					$xtla_owner = $owner;
				} elsif ($STLAS{$prefix}) {
					$owner = $STLAS{$prefix};
					$xtla_owner = $owner;
				} else {
					$owner = &extract_name_from_prefix($prefix);
					$xtla_owner = &extract_xtla_from_prefix($prefix);
				}
# Check prefix
				$prefix_flag = &check_prefix($prefix);
				if ($prefix_flag == 0) {
					$localnum{N_invalid}++;
				} elsif ($prefix_flag == 1) {
					$localnum{N_ptlas}++;
				} elsif ($prefix_flag == 2) {
					$localnum{N_unaggr}++;
				} elsif ($prefix_flag == 3) {
					$localnum{N_otherIANA}++;
				} elsif ($prefix_flag == 4) {
					$localnum{N_6to4}++;
				} elsif ($prefix_flag == 5) {
					$localnum{N_longer6to4}++;
				}
				push(@local_prefixes, $prefix);
			}
		}

	} #end main loop over ASpath
# Grep old ASpaths no more present
	foreach $key (@oldaspathall) {unless (grep(/$key/, @keys)) {$CHANGESALL{$key} = "old"}}
	if ($MORETREES) {
		foreach $key (@oldaspathbbs) {unless (grep(/$key/, @keys)) {$CHANGESBBS{$key} = "old"}}
		foreach $key (@oldaspathoth) {unless (grep(/$key/, @keys)) {$CHANGESOTH{$key} = "old"}}
	}
# Write history file "allprefixes.txt"
	&save_history($HISTORYFILE,@newhistory);
# Update last_alive peers history file
	if (defined($PEERLASTALIVEFILE)) {$num{activePEERS} = &last_alive_peers(\@newhistory, $PEERLASTALIVEFILE)}

	foreach $ptla (keys(%PTLAS)) {

		if ($ptla_present{$ptla} != 1 && !(grep(/$ptla/, @local_prefixes))) {
			($nsamples, $nchanges, $nunavail, @aspaths) = &update_24h_stability_history('0', "$PTLASHISTORYDIR/$PTLAS{$ptla}");
			&create_html_stability_detailfile("$HISTORYHTMLDIR/$PTLAS{$ptla}.html", $ptla, '0', $PTLAS{$ptla}, $nunavail, $nchanges, $nsamples, @aspaths);
			$PTLAINFO{$PTLAS{$ptla}} = "$ptla $PTLAS{$ptla}";
			$PTLASTAB{$PTLAS{$ptla}} = $nchanges/$nsamples;
			$PTLAUNAV{$PTLAS{$ptla}} = $nunavail/$nsamples;
			if ($MORETREES) {
				push(@NRPTLAS, $PTLAS{$ptla});
				if (@history && grep(/$ptla/, @history)) {push(@NMOREPTLAS, $PTLAS{$ptla})}
			}
		} elsif ($MORETREES && $ptla_present{$ptla} && @history && !(grep(/$ptla/, @history))) {
			push(@NEWRPTLAS, $PTLAS{$ptla});
		}

	}

# Update history for other IANA assigned non-reachable prefixes
	opendir(DIR, $OTHERHISTORYDIR);
	@allfiles = grep(!/^\./ && -f "$OTHERHISTORYDIR/$_", readdir(DIR));
	closedir(DIR);
	foreach $prefix (keys(%STLAS)) {
		if (!$other_present{$prefix} && grep(/$STLAS{$prefix}/, @allfiles)) {
			($nsamples, $nchanges, $nunavail, @aspaths) = &update_24h_stability_history('0', "$OTHERHISTORYDIR/$STLAS{$prefix}k");
			&create_html_stability_detailfile("$HISTORYHTMLDIR/$STLAS{$prefix}.html", $prefix, '0', $STLAS{$prefix}, $nunavail, $nchanges, $nsamples, @aspaths);
			$IANAINFO{$STLAS{$prefix}} = "$prefix $STLAS{$prefix}";
			$IANASTAB{$STLAS{$prefix}} = $nchanges/$nsamples;
			$IANAUNAV{$STLAS{$prefix}} = $nunavail/$nsamples;
		}
	}
	$num{ASintrees} = @ass;
	$num{origAS} = (@ass)-(@asstransit);
	$num{transitAS} = (@ass)-(@assann);
	$num{bothAS} = (@assann)+(@asstransit)-(@ass);
	$num{privAS} = @asspriv;
	$num{reservedAS} = @assreserved;

	my ($sum, $prod, $sumlong) = (0, 0, 0);
	foreach $key (keys(%distance)) {
		$sum += $distance{$key};
		$prod += $key*$distance{$key};
	}
	unless ($sum > 0) {$num{averageDIST} = 0}
	else {$num{averageDIST} = &trunc_number(($prod/$sum), 2)}

	return(\%num,\%distance,\%paths_withasspriv,\%paths_withassreserved);
}

(1);
#### ASpath-tree v.4.2 - Released on Thu APR 17 2003, h.16:58:12
#### File: lib/elaborate-aspaths.pl Last modified on Tue MAR 18 2003, h.22:58:34
