#!/usr/bin/perl
require 5.005;

$|=1;
$ripe = "whois.ripe.net";
$ra = "whois.ra.net";

# $output = PATH . FILENAME
$output = "/var/www/techie/manap-peer.html";  

#
# If you have the two ASs for one organization, use the same
# abbreviation for each.
#
%peers = (
#	"AS_NUM",  "ORG_HANDLE:ORG_NAME",
# e.g.: "8315", "MAN:MANAP",
"2856", "BTN:BTNet",
"5669", "VIA:VIA Net.Works (U-Net)",
"6765", "INS:INS",
"6847", "BSv:Business Serve",
"8250", "ZET:ZETNET",
"8406", "XTM:XTML",
"8468", "Ent:Entanet",
"8546", "NWB:Norweb Comms",
"8548", "NNW:Net NorthWest (G-MING)",
"8553", "Avs:Avensys Networks",
"8586", "RED:Rednet",
"12536","MAN:MaNAP",
"12621","1AN:1A Networks",
"12390","KNG:Kingston Internet",
"12449","DSV:DSVR",
"13005","C2I:C2 Internet",
"13037","Zen:Zen Internet",
"13285","Opl:Opal Telecom",
"15444","NSv:Net Services",
"15558","Twp:Timewarp Internet",
"15758","Fst:Firstnet Services",
"15861","Lgd:Legend Internet",
"20834","Cld:Caladan",
);

#
# Build table keyed by abbreviation, using lowest AS entry
#

foreach $i (sort numerically keys %peers) {
	($abbrev, $name) = (split(/:/, $peers{$i}));
	if (!(defined($peeraslist{$abbrev}))) {
            $peerkeyas{$i} = $abbrev;
            $peeraslist{$abbrev} = $i;
	    $peername{$abbrev} = $name;
	}
        else
        {
            $peeraslist{$abbrev} = $peeraslist{$abbrev}.",".$i;
        }
        $peerabbrev{$i}=$abbrev;
}
#
# fill in matrix
#
# Iterate through each AS (multiple ASs for those with multiple
# AS's presented).
#
foreach $i (sort numerically keys %peers) {
        # return a list of which AS this peers with
	%ases = &matchas(\%peers, $i);
        # iterate through each AS presented again
	foreach $j (sort numerically keys %peers) {
                # OR this peering relationship in on the appropriate line.
		$$peerswith{$peerabbrev{$i}}{$peerabbrev{$j}} =
		   $$peerswith{$peerabbrev{$i}}{$peerabbrev{$j}} ||
		   (defined($ases{$j}));
	}
}

open(OUTPUT, ">${output}.new") || die "can't open output file ${output}.new";

#
# page header
#

print OUTPUT <<EOT;
<HTML>
<HEAD>
<TITLE>Peering Details</TITLE>
</HEAD>
<BODY>
<H1><A HREF="http://www.manap.net/">MaNAP<!---
<IMG SRC="http://www.manap.net/images/manap.GIF" ALT="MaNAP" BORDER=0>
---></A>
Peering Details
</H1>
<P>
<TABLE BORDER=2 CELLPADDING=1>
<TR>
<TH><FONT FACE="Arial,Sans-Serif,Sans Serif"><FONT SIZE=-1>Member (by AS number)</TH>
<TD><FONT FACE="Arial,Sans-Serif,Sans Serif"><FONT SIZE=-1><STRONG>AS</STRONG></TD>
EOT

foreach $i (sort numerically keys %peerkeyas) {
        $ai=$peerkeyas{$i};
        $ai =~ s/(.)/$1<BR>/g;
        $ai =~ s/<BR>^//g;
	print OUTPUT "<TH><FONT FACE=\"Arial,Sans-Serif,Sans Serif\">",
	       	     "<FONT SIZE=-1>$ai</TH>\n";
}
print OUTPUT "</TR>";

#
# rows
#
foreach $i (sort numerically keys %peerkeyas) {
        $ai=$peerkeyas{$i};
        $name=$peername{$ai};
        $as=$peeraslist{$ai};
	print OUTPUT "<TR>",
		"<TD><FONT FACE=\"Arial,Sans-Serif,Sans Serif\">",
		"<FONT SIZE=-1><STRONG>$name ($ai)</STRONG></TD>\n",
		"<TD align=\"right\">",
		"<FONT FACE=\"Arial,Sans-Serif,Sans Serif\"><FONT SIZE=-1>",
		"<STRONG>$as</STRONG></TD>\n";
	foreach $j (sort numerically keys %peerkeyas) {
                $aj=$peerkeyas{$j};
		if ($ai eq $aj) {
			print OUTPUT "<TD></TD>\n";
			next;
		}
		my $peers = $$peerswith{$ai}{$aj};
		my $sympeer = ($peers == $$peerswith{$aj}{$ai});
	        print OUTPUT '<TD BGCOLOR="',
		  ($peers?($sympeer?'#FFD700':'#FF4000'):
		          ($sympeer?'#A0A0A0':'#FF0080')),
		  '"><FONT FACE="Arial,Sans-Serif,Sans Serif"><FONT SIZE=-1>',
                  ($sympeer?'':'<B>'),
                  ($peers?'Y':'N'),
                  ($sympeer?'':'</B>'),
	          "</TD>\n";
	}
}



print OUTPUT <<EOF;
</TABLE>
<P>

This table is generated from objects in the <A HREF="http://www.ripe.net/">
RIPE</A> and <A HREF="http://www.ra.net/">RA</A> databases. If there is
something missing or wrong then please refer to the original data in
the databases.

<P>

The information given here can apply to peering arrangements between
members anywhere in the world, and is not limited to the traffic
flowing through this organization.

<P>

The table is sorted by AS number, not member name, and all members are
shown, even new ones without installed lines yet.

<P>
<STRONG>Glossary</STRONG>:
<P>
Y: Active Peering<BR>
N: No Peering<BR>
<B>Y</B> or <B>N</B>: Inconsitent policy between members<BR>
EOF
print OUTPUT "<P><I>Generated at ",scalar(gmtime())," UTC</I><P>";
print OUTPUT <<EOF;
</BODY>
</HTML>
EOF

close OUTPUT;
system ("mv ${output}.new $output");

exit 0;

sub matchas
{
	local($peers) = shift @_;
	local($as) = shift @_;
	local(%ases);
	open(WHOIS, "/usr/bin/whois -h $ripe AS$as|") || die "whois $ripe failed";
	print "Try RIPE for info on AS$as...";

	while (<WHOIS>) {
		if (/No entries/) {
			print "Try the RA for info on AS$as...";
			close(WHOIS);
			open(WHOIS, "/usr/bin/whois -h $ra AS$as|") || die "whois $ra failed\n";
			next;
		}
		next unless /^(import|export)/;
		s/[a-z-]+:\s+[a-z]*\s*(AS|as)([0-9]+).*$/$2/;
		chop;
		$peer = $_;
		if (defined($$peers{$peer})) {
			$ases{$peer} = $peer;
		}
	}

	close WHOIS;
	print " got it.\n";
	return %ases;
}

sub numerically { $a <=> $b }
