#!/usr/bin/perl

#################################################
## (c) 2003 Theo Zourzouvillys <theo@anlx.net> ##
##        http://www.crazygreek.co.uk/         ##
##         Use this code as you wish.          ##
#################################################
##
## Script to generate aut-num import/exports, to
## use as a *base* template.
##
## It won't work with anyhting but a simple
## config, and will only export your macro
## named in $Macro, so *make* *sure* you 
## edit it by hand before sending it off.
##
## Any comments, suggestions, patches, etc to the
## above address!
##
## If you need the Net::Whois::RIPE::RPSL perl
## module for debian, take a peek at:
##
##  <http://www.crazygreek.co.uk/downloads/debian/> 
##


my $RouterIP  = '<routerIP>';
my $Community = '<snmp community>';
my $Macro     = '<your AS-MACRO that you announce>';
my $MyAS      = '<my AS number (i.e 25061)>';
##
## The script tries to guess what it should be importing,
## but doesn't always get it right.  You can override
## what you import from an AS here...
##

my %Override = (
  21099 => ['AS-BARRYSWORLD-LIPEX']
);



use strict;
use Net::Whois::RIPE::RPSL;
use Socket;
my $whois = new RipeWhois(Host => 'whois.ripe.net', Port => 43,  FormatMode => 0);
die "Whois wibbled" unless(ref($whois));
die $whois->GetErrorString() if($whois->GetErrorCode());


use XML::DOM;
use SNMP;
use CGI::Request;

my %oids = (
    "SysUptime"         =>  "1.3.6.1.2.1.1.3.0",
    "bgpVersion"            =>  "1.3.6.1.2.1.15.1.0",
    "bgpLocalAs"            =>  "1.3.6.1.2.1.15.2.0",
#   "bgpPeerTable"          =>  "1.3.6.1.2.1.15.3",
    "bgpPeerEntry"          =>  "1.3.6.1.2.1.15.3.1",
    "bgpPeerIdentifier"     =>  "1.3.6.1.2.1.15.3.1.1",
    "bgpPeerState"          =>  "1.3.6.1.2.1.15.3.1.2",
    "bgpPeerAdminStatus"        =>  "1.3.6.1.2.1.15.3.1.3",
    "bgpPeerNegotiatedVersion"  =>  "1.3.6.1.2.1.15.3.1.4",
    "bgpPeerLocalAddr"      =>  "1.3.6.1.2.1.15.3.1.5",
    "bgpPeerLocalPort"      =>  "1.3.6.1.2.1.15.3.1.6",
    "bgpPeerRemoteAddr"     =>  "1.3.6.1.2.1.15.3.1.7",
    "bgpPeerRemotePort"     =>  "1.3.6.1.2.1.15.3.1.8",
    "bgpPeerRemoteAs"       =>  "1.3.6.1.2.1.15.3.1.9",
    "bgpPeerInUpdates"      =>  "1.3.6.1.2.1.15.3.1.10",
    "bgpPeerOutUpdates"     =>  "1.3.6.1.2.1.15.3.1.11",
    "bgpPeerInTotalMessages"    =>  "1.3.6.1.2.1.15.3.1.12",
    "bgpPeerOutTotalMessages"   =>  "1.3.6.1.2.1.15.3.1.13",
    "bgpPeerLastError"      =>  "1.3.6.1.2.1.15.3.1.14",
    "bgpPeerFsmEstablishedTransitions" =>   "1.3.6.1.2.1.15.3.1.15",
    "bgpPeerFsmEstablishedTime" =>  "1.3.6.1.2.1.15.3.1.16",
    "bgpPeerConnectRetryInterval"   =>  "1.3.6.1.2.1.15.3.1.17",
    "bgpPeerHoldTime"       =>  "1.3.6.1.2.1.15.3.1.18",
    "bgpPeerKeepAlive"      =>  "1.3.6.1.2.1.15.3.1.19",
    "bgpPeerHoldTimeConfigured" =>  "1.3.6.1.2.1.15.3.1.20",
    "bgpPeerKeepAliveConfigured"    =>  "1.3.6.1.2.1.15.3.1.21",
    "bgpPeerMinASOriginationInterval" =>    "1.3.6.1.2.1.15.3.1.22",
    "bgpPeerMinRouteAdvertisementInterval" => "1.3.6.1.2.1.15.3.1.23",
    "bgpPeerInUpdateElapsedTime"    =>  "1.3.6.1.2.1.15.3.1.24",

    "bgpIdentifier"         =>  "1.3.6.1.2.1.15.4.0",
    "bgpRcvdPathAttrTable"      =>  "1.3.6.1.2.1.15.5",

    "bgp4PathAttrTable"     =>  "1.3.6.1.2.1.15.6",

    "bgpPathAttrEntry"      =>  "1.3.6.1.2.1.15.5.1",
    "bgpPathAttrPeer"       =>  "1.3.6.1.2.1.15.5.1.1",
    "bgpPathAttrDestNetwork"    =>  "1.3.6.1.2.1.15.5.1.2",
    "bgpPathAttrOrigin"     =>  "1.3.6.1.2.1.15.5.1.3",
    "bgpPathAttrASPath"     =>  "1.3.6.1.2.1.15.5.1.4",
    "bgpPathAttrNextHop"        =>  "1.3.6.1.2.1.15.5.1.5",
    "bgpPathAttrInterASMetric"  =>  "1.3.6.1.2.1.15.5.1.6",

    "bgp4PathAttrEntry"     =>  "1.3.6.1.2.1.15.6.1",
    "bgp4PathAttrPeer"      =>  "1.3.6.1.2.1.15.6.1.1",
    "bgp4PathAttrIpAddrPrefixLen"   =>  "1.3.6.1.2.1.15.6.1.2",
    "bgp4PathAttrIpAddrPrefix"  =>  "1.3.6.1.2.1.15.6.1.3",
    "bgp4PathAttrOrigin"        =>  "1.3.6.1.2.1.15.6.1.4",
    "bgp4PathAttrASPathSegment" =>  "1.3.6.1.2.1.15.6.1.5",
    "bgp4PathAttrNextHop"       =>  "1.3.6.1.2.1.15.6.1.6",
    "bgp4PathAttrMultiExitDisc" =>  "1.3.6.1.2.1.15.6.1.7",
    "bgp4PathAttrLocalPref"     =>  "1.3.6.1.2.1.15.6.1.8",
    "bgp4PathAttrAtomicAggregate"   =>  "1.3.6.1.2.1.15.6.1.9",
    "bgp4PathAttrAggregatorAS"  =>  "1.3.6.1.2.1.15.6.1.10",
    "bgp4PathAttrAggregatorAddr"    =>  "1.3.6.1.2.1.15.6.1.11",
    "bgp4PathAttrCalcLocalPref" =>  "1.3.6.1.2.1.15.6.1.12",
    "bgp4PathAttrBest"      =>  "1.3.6.1.2.1.15.6.1.13",
    "bgp4PathAttrUnknown"       =>  "1.3.6.1.2.1.15.6.1.14",
    );

my %BgpPeerState = (
    1 => "idle",
    2 => "connect",
    3 => "active",
    4 => "opensnet",
    5 => "openconfirm",
    6 => "established"
    );


my $obj = new SNMP::Session(DestHost => $RouterIP, Community => $Community);


my $sess = new SNMP::Session ( DestHost => '81.91.96.1', Community => 'fckwit' );
my $bgpLocalAs = $sess->get("\." . $oids{bgpLocalAs});
my $bgpIdentifier = $sess->get("\." . $oids{bgpIdentifier} . ".0");

my (@Good, @Bad);

use RipeWhois;
my %Peers = ();

my @Brief = (

 [$oids{bgpPeerIdentifier}], 				# 0
 [$oids{bgpPeerRemoteAs}],					# 1
 [$oids{bgpPeerState}],						# 2 
 [$oids{bgpPeerFsmEstablishedTime}], 		# 3
 [$oids{bgpPeerLastError}],					# 4
 [$oids{bgpPeerRemoteAddr}],				# 5
 [$oids{bgpPeerRemotePort}],				# 6
 [$oids{bgpPeerLocalAddr}], 				# 7
 [$oids{bgpPeerLocalPort}],					# 8
 [$oids{bgpPeerInUpdates}],					# 9
 [$oids{bgpPeerOutUpdates}],				# 10
 [$oids{bgpPeerAdminStatus}],				# 11
 [$oids{bgpPeerFsmEstablishedTransitions}],	# 12

);

my $vars  = new SNMP::VarList( @Brief );

my @List = ();

for (my @vals = $sess->getnext($vars); $vars->[0]->tag =~ /15\.3\.1\.1/ and not $sess->{ErrorStr}; @vals = $sess->getnext($vars))
{
  next if ($vals[7] eq '0.0.0.0' || $vals[5] eq undef);
  push(@List, [ @vals ]);
}

my @Keys = sort { inet_aton($a->[5]) <=> inet_aton($b->[5]) } @List;

foreach my $as (@Keys)
{
  my @vals = @{$as};
  my $ASMacro = getASMacro($vals[1]);
  printf q|
#
##            # %s
##            # %s on %s
import:       from %s %s at %s action pref=100;
              accept %s
export:       to AS%s announce %s|,
  GetASDesc($vals[1]),
  $ASMacro,
  $vals[5],
  sprintf('AS%d', $vals[1]),
  $vals[5],
  $vals[7],
  $ASMacro,
  $vals[1],
  $Macro
;
}

print "\n\n# Done\n";

sub getASMacro
{
  my $AS = shift();

  my $result = $whois->QueryObjects(sprintf('-r -Taut-num AS%d', $AS));

  unless($result) 
  {
    printf(STDERR "Query error: %s\n", $whois->GetErrorString());
    return "UNKN-1";
  }

  my $ASObj = Net::Whois::RIPE::RPSL->new(@$result);

  my @Attrs = $ASObj->get('export');
  foreach my $Attr (@Attrs)
  {
    if ($Attr->clean_value =~ /^to AS$MyAS announce (\S+)/)
    {
      return $1;
    }
  }

  if ($Override{$AS})
  {
    return $Override{$AS}->[0];
  }

  return sprintf('AS%d', $AS);
}

sub GetASDesc
{
  my $AS = shift();
  my $result = $whois->QueryObjects(sprintf('-r -Taut-num AS%d', $AS));

  unless($result) {
    printf(STDERR "Query error: %s\n", $whois->GetErrorString());
    return "[Unknown]";
  }
  my $RPSL = Net::Whois::RIPE::RPSL->new(@$result);
  return ($RPSL->get('descr'))[0]->clean_value;
}


