#! /bin/perl
########################################################################
#  By accessing this software, MAPMBONE, you are duly informed of
#  and agree to be bound by the conditions described below in
#  this notice:
#
#  This software product, MAPMBONE, is developed by Bradley Huffaker, and
#  copyrighted(C) 1998 by the University of California, San Diego (UCSD),
#  with all rights reserved.  UCSD administers the NLANR Cache grants,
#  NCR-9796082 and NCR-9616602, under which most of this code was
#  developed.
#
#  MAPMBONE is a free software. You can redistribute it and/or modify it
#  under the terms of the CAIDA/NLANR General Public License v.1 as
#  published by UCSD and is incorporated by reference herein.  MAPMBONE is
#  distributed WITHOUT ANY WARRANTY, IMPLIED OR EXPRESS, OF MERCHANTABILITY
#  OR FITNESS FOR A PARTICULAR PURPOSE or that the use of it will not
#  infringe on any third party's intellectual property rights.
#
#  You should have received a copy of the CAIDA/NLANR General Public
#  License v.1 along with the MAPMBONE program.  If for any reason you
#  have not received a copy, please write to
#
#                       University of California, San Diego
#                       SDSC/CAIDA/NLANR
#                       9500 Gilman Dr., MS-0505
#                       La Jolla, CA 92093 - 0505  USA
#
#  Or contact INFO@NLANR.NET
#######################################################################
# setup.pl -s source_file -f final_file -d degree
#	source_file - the source file to read data from
#	final_file - the output file
#	degree - the degree of the node before it is output

require '/i3/usr.local/etc/httpd/cgi-bin/Tools/net_mapping.pl';


$no_checks = 1;

$test="sfgasfgasgagagag";#rucs-gw.rutgers.edu";

#$home_dir = "/home/web/Caidants/Manta/Working/Data";
$home_dir=".";

$latlong_dir = "$home_dir/latlongs";
$source_dir = "$home_dir/source";

$latlongs_file = "$latlong_dir/latlongs_complete";

#$source_file = "$source_dir/mrinfo.new";
$source_file = "out";
$final_file = "data.txt"
	if (!$final_file);
$unknown_file = "unknown.txt";

$degree_bound = 0
	if (!$degree_bound);
print "$degree_bound,$final_file\n";

$COMMENT = '!';

($degree_bound, $source_file, $final_file) = &GetParams();
#print "setup:$degree_bound $final_file $source_file\n";
#exit;

print ("Getting Aliases\n");
&GetAliases();

&GetLatLongs($latlongs_file);

print ("Creating Arrays\n");
&Create_Arrays();

print ("Creating Output File\n");
&Create_Final();

print ("Creating Aliases File\n");
&Print_Aliases();

if ($num_nodes >0)
{
	printf ("total  :%d 100\%\n",$num_nodes);
	printf ("known  :%d %.2d\%\n",$know,100*($know/$num_nodes));
	printf ("unknown:%d %.2d\%\n",$unknow,100*($unknow/$num_nodes));
}
else
{
	printf ("No nodes found\n");
}

sub GetParams
{
	foreach $argv (@ARGV)
	{
		$depth = $argv
			if ($last eq "-d");
		$final_file = $argv
			if ($last eq "-f");
		$source_file = $argv
			if ($last eq "-s");
		$last = $argv;
	}
	return ($depth, $source_file, $final_file);
}

sub GetLatLongs
{
	my ($filename) = @_;
	print ("Getting Lat Longs:$filename\n");
	open (IN, "<$filename") || die ("Uable to open $filename:$!");
	while (<IN>)
	{
		($node,$rest) = /^([^\s]+)\s+([^\n]+)/;
		if ($node && $rest)
		{
			$node=~y/A-Z/a-z/;
			if ($node =~ /^[\d|\.]+$/)
			{
				$ip2latlongs{$node} = $rest;
			}
			else
			{
				$name2latlongs{$node} = $rest;
			}
		}
	}
	close IN;
}

sub GetAliases
{
	open (IN, "<$source_file") || 
		die("Unable to open $source_file:$!");
	while ($line = <IN>)
	{
	
		($machine1,$machine2) = ($line =~
		   /\= ([^\(]+\([\d|\.]+\)) ([^\(]+\([\d\.]+\))/);
		if ($machine1 && $machine2 
			&& !($machine2=~/INADDR_ANY/)
			&& $machine1 ne $machine2)
		{
			$machine1 =~ y/A-Z/a-z/; 
			$machine2 =~ y/A-Z/a-z/; 
			$alias{$machine2} = $machine1;
		}
	}
	foreach $name (keys %alias)
	{
		undef %reached;
		$reached{$name} = 1;
		do 
		{
			$name = $alias{$name};
			$reached{$name} = 1;
		}
		while ($name && !$reached{$name});
		undef $alias{$name}
			if ($name);
	}
		
}
	
	

sub Create_Arrays
{
	open (IN, "<$source_file") || 
		die("Unable to open $source_file:$!");
	$linenum = 0;
	while ($line = <IN>)
	{
		$linenum++;
		($machine1,$machine2,$scrap) = ($line =~
		   /\> ([^\(]+\([\d|\.]+\)) ([^\(]+\([\d\.]+\))([^\n]+)/);
		undef $machine2 if ($machine2 =~ /INADDR_ANY/);
		$machine1 =~ y/A-Z/a-z/; 
		$machine2 =~ y/A-Z/a-z/; 
		$machine1 = $alias{$machine1} 	
			if ($alias{$machine1});
		$machine2 = $alias{$machine2} 
			if ($alias{$machine2});
		if ($machine1 && $machine2)
		{
			$degree{$machine1}++;
			$degree{$machine2}++;
			$key1 = "$machine1-$machine2";
			$key2 = "$machine2-$machine1";
			if ($links{$key1})
			{
				$links{$key1} = "<";
				$link2scrap{$key1} = $scrap;
			}
			elsif ($links{$key2})
			{
				$links{$key2} = "<";
				$link2scrap{$key2} = $scrap;
			}
			else
			{
				$links{$key1} = ">";
			}
		}
	}
	close IN;
}

sub Create_Final
{
	open (OUT, ">$final_file")
		|| die("Unable to open $final_file:$!");
	open (UNKNOW, ">$unknown_file")
		|| die("Unable to open $unknow_file:$!");

	$num_nodes=0;
	undef %match;
	foreach $each (sort keys %degree)
	{
		print "$each=",$degree{$each},"\n" if ($each=~/$test/);
		my ($name,$ip) = ($each=~/([^\)]+)\(([^\)]+)\)/);
		if ($no_checks || ($degree{$each} > $degree_bound
			&& ($name2latlongs{$name} || $ip2latlongs{$ip})))
		{
			$match{$each} = $num_nodes++;
		}
	}
	
	print OUT &Header();
	print OUT "t $num_nodes\n";
			
#	$key = 0;
#foreach $each (sort keys %degree)
#{
#	print "$key $each ",$ip{$each},"\n";
#	$key++;
#}
#exit;
	$key = 0;
	foreach $each (sort keys %degree)
	{
		if ($match{$each})
		{
			$map = $each;#."(".$ip{$each}.")";
			$mapping{$map}= $key;
			my ($name,$ip) = ($each=~/([^\)]+)\(([^\)]+)\)/);
			$latlong = $name2latlongs{$name};
			$latlong = $ip2latlongs{$ip}
				if (!$latlong);
					# && !($each =~ /\.net$/)
					#&& !($each =~ /cisco.com/));
			($isp) = ($name =~ /([^\.]+)\.net\s*$/);
			$isp = "unknown" 
				if (!$isp);
			$machine2isp{$each} = $isp;
			if ($latlong)
			{
				print OUT "* ",$key," ",$name," "
					,$ip," ",$isp,
					," ",$latlong,"\n";
				$know++;
			} 
			else
			{
				print OUT "? ",$key," ",$name," "
					,$ip," ", $isp, "\n";
				print UNKNOW $each,"\n";
				$unknow++;
			}
			$key++;
		}
	}
	open (IN, "<$source_file")
		|| die("Unable to open $source_file:$!");
	while ($line = <IN>)
	{
		
		($machine1,$machine2,$scrap) = ($line =~
		 	/\> ([^\(]+\([\d|\.]+\)) ([^\(]+\([\d\.]+\))(.+)$/);
		$machine1 =~ y/A-Z/a-z/;
		$machine2 =~ y/A-Z/a-z/;
		$machine1 = $alias{$machine1} 	
			if ($alias{$machine1});
		$machine2 = $alias{$machine2} 
			if ($alias{$machine2});
		if ($mapping{$machine1} && $mapping{$machine2})
		{
			$isp1 = $machine2isp{$machine1};
			$isp2 = $machine2isp{$machine2};
			if ($isp1 && ($isp1 eq $isp2 || 
				(!$isp2 || $isp2 eq "unknown")))
			{
				$isp = $isp1;
			}
			elsif ($isp2 && (!$isp1 || $isp1 eq "unknown"))
			{
				$isp = $isp2;
			}
			else
			{
				$isp = "unknown";
			}
	
			$key1 = "$machine1-$machine2";
			$key2 = "$machine2-$machine1";

			$machine1 = $machine1,"(",$ip{$machine1},")";
			$machine2 = $machine2,"(",$ip{$machine2},")";
			if ($links{$key1})
			{
				$type = $links{$key1};
			
				print OUT $type," ",$mapping{$machine1}," "
				   ,$mapping{$machine2}," ",$isp,$scrap,
				   ,$link2scrap{$key1},"\n";
				undef $links{$key1};
			}
		}
		elsif (($key,$machine1,$scrap) 
			= ($line =~/([\:|\=]) ([^\(]+)\([\d|\.]+\)(.+)$/))
		{
			$machine1 =~ y/A-Z/a-z/;
			$machine1 = $alias{$machine1} 	
				if ($alias{$machine1});
			if ($mapping{$machine1})
			{
				print OUT $key." ".$mapping{$machine1}.$scrap,"\n";
			}
		}
	}
	close UNKNOW;
	close OUT;
	close IN;
}

sub Header
{
	$day = (localtime)[3];
	$month = (localtime)[4]+1;
	$year = (localtime)[5];
return<<EOP;
$COMMENT  
$COMMENT  Basic Data file for Mapmbone
$COMMENT  Bradley Huffaker  $month/$day/$year
$COMMENT ------------------------------------------------
$COMMENT formate
$COMMENT
$COMMENT	t number
$COMMENT		(number of nodes)
$COMMENT		number - the number of nodes
$COMMENT	? node_index name ip isp
$COMMENT	* node_index name ip isp lat long city 
$COMMENT		(node)
$COMMENT		node_index - index of the node  (int)
$COMMENT		name - dns name of machine (string no spaces)
$COMMENT		ip - ip address (string no spaces)
$COMMENT		lat - latidute  (float)
$COMMENT		long - longitude (float)
$COMMENT		isp - the isp for which the node belongs
$COMMENT		city - city it is located in (string up to '\\n')
$COMMENT
$COMMENT	: node_index  verions, flags1, flag2, .., date
$COMMENT		(node data)
$COMMENT		node_index - index of the node (int)
$COMMENT		version - verion of the software (float)
$COMMENT		flags - stings up to the ,
$COMMENT		date - machine friendly date (int)
$COMMENT
$COMMENT	= node_index machine(ip)
$COMMENT		(alias)
$COMMENT		node_index = index of the node (int)
$COMMENT		machine - machine name
$COMMENT		ip - ip address
$COMMENT
$COMMENT	> node_index1 node_index2 isp [metric,threshold,parms,..]
$COMMENT	< node_index1 node_index2 isp [metric,threshold,parms,..] [metric1,...]
$COMMENT		(link one way >)
$COMMENT		(link two way <)
$COMMENT		node_index* - the index of the two nodes connected (int)
$COMMENT		isp - the isp for which the node belongs
$COMMENT		metric - metric of the connection
$COMMENT		threshold - the threshold of the connection
$COMMENT		mertric2,threshold2 - are for the other connection
EOP
}

sub Print_Aliases
{
	open (OUT, ">aliases.txt");
	foreach $name (sort keys %alias)
	{
		print OUT "$name";
		my %reached;
		while ($alias{$name})
		{
			$name = $alias{$name};	
			print OUT "-> $name";
		}
		print OUT "\n";
	}
	close OUT;
}
