#!/usr/bin/perl
#
# updaterpsl.pl: RPSL from Foundry Configuration script
# (c) 2004 Unilogic Networks B.V.
#
# 2004-11-27 cliff Updating script to automatically parse local preference from configuration file
#                  Updating script to automatically parse metrics from configuration file
# 2004-09-17 cliff Updating script to support our cisco border
#


### Configuration ###

### Here we specify our routers and there configuration files ###
#
my $local_asn = '28788';
my $local_asset = 'AS-UNILOGICNET';
my $release = '20041127-2';

my $default_localpref = '100';
my $default_metric = '0';
my $default_community = "$local_asn:1000";

$groupAnnouncement{"AMSIX-BACKUP"} = "ANY";
$groupAnnouncement{"AMSIX"} = "AS-UNILOGICNET";
$groupAnnouncement{"PPEERING"} = "AS28788";
$groupAnnouncement{"TRANSIT-NTT"} = "AS28788";
$groupAnnouncement{"TRANSIT-KPN"} = "AS28788";
$groupAnnouncement{"TRANSIT-TG"} = "AS28788";
$groupAnnouncement{"LIMBEX"} = "AS-UNILOGICNET";
$groupAnnouncement{"BNIX"} = "AS28788";
$groupAnnouncement{"M6OWN"} = "AS28788";
$groupAnnouncement{"NLIX"} = "AS-UNILOGICNET";

while (<>) {
	chomp;
	if ($_ =~ /neighbor (\d+\.\d+\.\d+\.\d+)\ peer-group\ +([^\ ]+)$/) {
	    $remoteGroup{$1} = $2;
	    chomp($remoteGroup{$1});
	    $preference{$1} = $groupPreference{$remoteGroup{$1}};
	    $announcement{$1} = $groupAnnouncement{$remoteGroup{$1}};
	};
	if ($_ =~ /neighbor (\d+\.\d+\.\d+\.\d+)\ remote-as\ (.+)$/) {
	    $remoteAS{$1} = $2;
	    if (!$remoteGroup{$1}) {
	      $announcement{$1} = 'ANY';
	    }
	};
	if ($_ =~ /neighbor (\d+\.\d+\.\d+\.\d+|[a-zA-Z0-9\-]+)\ route-map\ (in |out )?([^\ ]+)( in| out)?$/) {

	  if (($2 eq "in ") || ($4 eq " in")) {
	    $remoteRoutemapIn{$1} = $3;

	  } elsif (($2 eq "out ") || ($4 eq " out")) {
	    $remoteRoutemapOut{$1} = $3;
	  };
	};
	if ($_ =~ /neighbor\ +(\d+\.\d+\.\d+\.\d+)\ description\ +(.+)$/) { 
	  $remoteDescription{$1} = $2;
	};
	if ($_ =~ /route-map\ +(.+) permit\ +(\d+)/) {

	  $parseRouteMap = "$1,$2";
	};
	if ($parseRouteMap && $_ =~ /set local-preference (\d+)/) {
	  my ($route_map,$route_map_sub) = split(/,/,$parseRouteMap);
	  $routeMap{$route_map}{$route_map_sub}{"localPref"} = $1;

	};
	if ($parseRouteMap && $_ =~ /set metric [+]?(\d+)/) {
	  my ($route_map,$route_map_sub) = split(/,/,$parseRouteMap);
	  $routeMap{$route_map}{$route_map_sub}{"metric"} = $1;

	};
	if ($parseRouteMap && $_ =~ /set community\ +(\d+:\d+) additive/) {
	  my ($route_map,$route_map_sub) = split(/,/,$parseRouteMap);
	  $routeMap{$route_map}{$route_map_sub}{"community"} = $1;

	};
	if ($parseRouteMap && $_ =~ /set as-path prepend\ +([\d\ ]+)/) {
	  my ($route_map,$route_map_sub) = split(/,/,$parseRouteMap);
	  $routeMap{$route_map}{$route_map_sub}{"prepends"} = $1;

	};

};

@sorted = sort { $remoteAS{$a} <=> $remoteAS{$b} } keys %remoteAS;

foreach $nextHop (@sorted) {
	if (!($remoteAS{$nextHop} eq $local_asn)) {
  	my ($prepends,$localPref,$metric,$community,$prepend);
 	if ($remoteGroup{$nextHop}) {


		$localPref = calculate_localpref($routeMap{$remoteRoutemapIn{$remoteGroup{$nextHop}}}{1}{"localPref"});
		$metric = $routeMap{$remoteRoutemapIn{$remoteGroup{$nextHop}}}{1}{"metric"};
		$community = $routeMap{$remoteRoutemapIn{$remoteGroup{$nextHop}}}{1}{"community"};
		if ($routeMap{$remoteRoutemapOut{$remoteGroup{$nextHop}}}{1}{"prepends"}) {
		  $prepends = $routeMap{$remoteRoutemapOut{$remoteGroup{$nextHop}}}{1}{"prepends"};
		};
	}
	if ($routeMap{$remoteRoutemapIn{$nextHop}}{1}{"localPref"}) {
	 	$localPref = calculate_localpref($routeMap{$remoteRoutemapIn{$nextHop}}{1}{"localPref"});
	};
	if ($routeMap{$remoteRoutemapIn{$nextHop}}{1}{"metric"}) {
		$metric = $routeMap{$remoteRoutemapIn{$nextHop}}{1}{"metric"};
	};
	if ($routeMap{$remoteRoutemapIn{$nextHop}}{1}{"community"}) {
	        $community = $routeMap{$remoteRoutemapIn{$nextHop}}{1}{"community"};
	};
	if ($routeMap{$remoteRoutemapOut{$nextHop}}{1}{"prepends"}) {
	        $prepends = $routeMap{$remoteRoutemapIn{$nextHop}}{1}{"prepends"};

	};

	if (!$community) { $community = $default_community; };
	if (!$metric) { $metric = $default_metric; };
	if (!$localPref) { $localPref = $default_localpref; };

### Currently disabled because RIPEdb doesn't accept this prepend rule.
#
#	if ($prepends) {

#	 	$prepends =~ s/\ /,/g;
#		$prepend = "action aspath.prepend($prepends); ";
#	} else {
	 	$prepend = '';
#	};
		
	print "remarks: ---------------------------------------------------------------\n";
	print "remarks:	$remoteDescription{$nextHop}\n";
	print "remarks: ---------------------------------------------------------------\n";
	print "import:   from AS$remoteAS{$nextHop} $nextHop \taction pref=$localPref; med=$metric; community.append (".$community."); accept {0.0.0.0/0^0-27} AND NOT RS-UNFILTER\n";
	print "export:   to AS$remoteAS{$nextHop}\t $nextHop \t".$prepend."announce $announcement{$nextHop}\n";
	};
};

print "remarks: ---------------------------------------------------------------\n";


sub calculate_localpref () {
 	my ($localPref) = @_;
	return 200-$localPref;
	}
