You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

#!/usr/bin/perl
#

  1. $Id: expand-as-macro,v 1.18 2011/09/29 11:45:15 he Exp $
    #
  1. Copyright (c) 2011
  2. UNINETT A/S. All rights reserved.
    #
  3. Redistribution and use in source and binary forms, with or without
  4. modification, are permitted provided that the following conditions
  5. are met:
  6. 1. Redistributions of source code must retain the above copyright
  7. notice, this list of conditions and the following disclaimer.
  8. 2. Redistributions in binary form must reproduce the above copyright
  9. notice, this list of conditions and the following disclaimer in the
  10. documentation and/or other materials provided with the distribution.
    #
  11. THIS SOFTWARE IS PROVIDED BY UNINETT AND ``AS IS'' AND ANY
  12. EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  13. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  14. PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL UNINETT OR NORDUnet OR
  15. THEIR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  16. SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  17. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  18. DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  19. THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  20. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  21. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    #
  1. Expand an as-macro in the IRR into an as-origin list, and format the
  2. result either for IOS, IOS-XR or JunOS.
    #
  3. Prefers to use peval from the IRRtoolset package, resorts to using
  4. whois with either whois.ripe.net or whois.radb.net. The whois
  5. program is expected to honor POSIX argument parsing rules, in that
  6. "--" ends the parsing of the program option list.

use Getopt::Std;
use strict;

sub parse_rpsl {
my($fh) = @_;
my($inm) = 0;
my(@f);
our($opt_v);

while(<$fh>) {
chop;
if ($opt_v)

Unknown macro: { printf("%sn", $_); }

if ($inm) {
if (/^\s/)

Unknown macro: { $_ =~ s/,/ /g; @f = split; &add_ases(@f); }

else

Unknown macro: { $inm = 0; }

}
if (!$inm) {
if (/^members:/)

Unknown macro: { $inm = 1; $_ =~ s/,/ /g; @f = split; shift @f; &add_ases(@f); }

}
}
if ($opt_v)

Unknown macro: { print "n"; }

}

sub parse_ripe181 {
my($fh) = @_;
our($notripe, $opt_v);
my(@f);

while(<IN>) {
chop;
if ($opt_v)

if (/^% No entries found/)

Unknown macro: { $notripe = 1; }

if (/^as-list:/)

Unknown macro: { @f = split; shift @f; &add_ases(@f); }

}

}

sub getmacro_ripe {
my($mn) = @_;
our(%seen, $opt_a);
my($IN);

$mn = uc($mn);
$seen{$mn} = 1;
open($IN, "whois -h whois.ripe.net – \"$opt_a -r $mn\"|");
&parse_rpsl($IN);
close($IN);
}

sub getmacro_radb {
my($mn) = @_;
my($inm) = 0;
our(%seen);
my($IN);

$mn = uc($mn);
$seen{$mn} = 1;
open($IN, "whois -h whois.radb.net – \"-r $mn\"|");
&parse_rpsl($IN);
close($IN);
}

sub add_ases {
my(@a) = @_;
our(%seen);
our(@expand, @ases);

foreach my $as (@a) {
if ($as =~ /AS-[A-Z0-9]*/) {
if (! defined($seen{$as}))

Unknown macro: { push(@expand, $as); }

}
if ($as =~ /AS([0-9]+)/)

Unknown macro: { push(@ases, $1); }

}
}

sub getmacro_ratools {
my($mn) = @_;

$_ = `peval -h whois.ripe.net -protocol ripe -no-as $mn`;
if ($? != 0)

Unknown macro: { return undef; }

$_ =~ s/(//g;
$_ =~ s/)//g;
my(@a) = split;
&add_ases(@a);
return 1;
}

sub getmacro {
my($mn) = @_;
our($notripe);

if (&getmacro_ratools($mn))

Unknown macro: { return; }

else {
if ($notripe)

Unknown macro: { &getmacro_radb($mn); }

else {
&getmacro_ripe($mn);
if ($notripe)

Unknown macro: { &getmacro_radb($mn); }

}
}
}

sub getmacros {
my(@start) = @_;
our($notripe);
our(@expand);

$notripe = 0;
push(@expand, @start);
while($#expand != -1)

Unknown macro: { &getmacro(shift(@expand)); }

}

sub print_j {
my($apgn, @ases) = @_;
my($n, $s, $pfx);

printf("policy-options {\n");
printf("replace:\n");
printf(" as-path-group %s {\n", $apgn);
$n = 0;
$s = "";
foreach my $as (@ases) {
if ($s eq "" || length($s) >= 65) {
if ($s ne "")

Unknown macro: { $s .= ")";"; printf("%sn", $s); }

$n++;
$pfx = " as-path " . sprintf("%d \".*(", $n);
$s = $pfx;
} else

Unknown macro: { $s .= "|"; }

$s .= sprintf("%s", $as);
}
if ($s ne $pfx)

Unknown macro: { printf("%s)";n", $s); }

printf(" }\n}\n");
}

sub print_x {
my($apgn, @ases) = @_;
my($n, $s, $pfx);

printf("as-path-set %s\n", $apgn);
$n = 0;
$s = "";
foreach my $as (@ases) {
if ($s eq "" || length($s) >= 65) {
if ($s ne "")

Unknown macro: { $s .= ")$',"; printf("%sn", $s); }

$n++;
$pfx = " ios-regex '_(";
$s = $pfx;
} else

$s .= sprintf("%s", $as);
}
printf("%s)\$'\n", $s);
printf("end-set\n");
}

  1. Plain printing; just the numbers

sub print_p {
my(@ases) = @_;

foreach my $as (@ases)

Unknown macro: { printf("%dn", $as); }

}

sub printases {
my($num, @ases) = @_;
my(%as);
our($opt_p, $opt_j, $opt_x, $opt_1);

foreach my $as (@ases) {
$as{$as} = 1;
}
undef @ases;
foreach my $as (keys %as)

Unknown macro: { push(@ases, $as); }

my @sortas = sort {$a <=> $b} @ases;

if ($opt_p)

Unknown macro: { print_p(@sortas); return; }

if ($opt_j)

Unknown macro: { print_j($num, @sortas); return; }

if ($opt_x)

Unknown macro: { print_x($num, @sortas); return; }

my($s, $pfx, $sol);
printf("Unable to render embedded object: File (\nno ip as-path access-list $num\n) not found.\n");
$pfx = "ip as-path access-list $num permit ";
if (defined($opt_1)) {
foreach my $as (@sortas)

Unknown macro: { printf("%s_%d$n", $pfx, $as); }

} else {
$sol = $pfx . "_("; # start of line
$s = "";
foreach my $as (@sortas) {
if ($s eq "" || length($s) >= 65) {
if ($s ne "")

Unknown macro: { $s .= ")$"; printf("%sn", $s); }

$s = $sol;
} else

Unknown macro: { $s .= "|"; }

$s .= sprintf("%s", $as);
}
if ($s ne $sol)

Unknown macro: { printf("%s)$n", $s); }

}
printf("!\n");
}

getopts('1ajn:pvx');
our($opt_a, $opt_n, $opt_p);
our(@ases);

if (!defined($opt_n) && !defined($opt_p)) {
printf(STDERR
"usage: $0 [-a] [-p] [-v] [-j] [-x] [-1] " .
"-n aclnum/name as-macro ...\n");
printf(STDERR "\n");
printf(STDERR "-a pass through to whois to RIPE (all sources)\n");
printf(SDTERR "-p plain – just the AS numbers, one per line\n");
printf(STDERR "-v verbose – print whois output to stdout\n");
printf(STDERR "-j JunOS – format as-path-group for JunOS\n");
printf(STDERR "-x IOS-XR – format as-path-set for IOS-XR\n");
printf(STDERR "(none) IOS – default is to print IOS ACL\n");
printf(STDERR "-1 with IOS output, only one AS per line\n");
printf(STDERR "n name or number of IOS ACL / as-path

Unknown macro: {set|group}

\n");
exit(1);
}
if (defined($opt_a)) {
$opt_a = "-a";
}

&getmacros(@ARGV);
&printases($opt_n, @ases);

  • No labels