#!/usr/bin/perl
#
- $Id: expand-as-macro,v 1.18 2011/09/29 11:45:15 he Exp $
#
- Copyright (c) 2011
- UNINETT A/S. All rights reserved.
# - Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
# - THIS SOFTWARE IS PROVIDED BY UNINETT AND ``AS IS'' AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL UNINETT OR NORDUnet OR
- THEIR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
- Expand an as-macro in the IRR into an as-origin list, and format the
- result either for IOS, IOS-XR or JunOS.
# - Prefers to use peval from the IRRtoolset package, resorts to using
- whois with either whois.ripe.net or whois.radb.net. The whois
- program is expected to honor POSIX argument parsing rules, in that
- "--" 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)
if ($inm) {
if (/^\s/)
else
}
if (!$inm) {
if (/^members:/)
}
}
if ($opt_v)
}
sub parse_ripe181 {
my($fh) = @_;
our($notripe, $opt_v);
my(@f);
while(<IN>) {
chop;
if ($opt_v)
if (/^% No entries found/)
if (/^as-list:/)
}
}
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}))
}
if ($as =~ /AS([0-9]+)/)
}
}
sub getmacro_ratools {
my($mn) = @_;
$_ = `peval -h whois.ripe.net -protocol ripe -no-as $mn`;
if ($? != 0)
$_ =~ s/(//g;
$_ =~ s/)//g;
my(@a) = split;
&add_ases(@a);
return 1;
}
sub getmacro {
my($mn) = @_;
our($notripe);
if (&getmacro_ratools($mn))
else {
if ($notripe)
else {
&getmacro_ripe($mn);
if ($notripe)
}
}
}
sub getmacros {
my(@start) = @_;
our($notripe);
our(@expand);
$notripe = 0;
push(@expand, @start);
while($#expand != -1)
}
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 "")
$n++;
$pfx = " as-path " . sprintf("%d \".*(", $n);
$s = $pfx;
} else
$s .= sprintf("%s", $as);
}
if ($s ne $pfx)
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 "")
$n++;
$pfx = " ios-regex '_(";
$s = $pfx;
} else
$s .= sprintf("%s", $as);
}
printf("%s)\$'\n", $s);
printf("end-set\n");
}
- Plain printing; just the numbers
sub print_p {
my(@ases) = @_;
foreach my $as (@ases)
}
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)
my @sortas = sort {$a <=> $b} @ases;
if ($opt_p)
if ($opt_j)
if ($opt_x)
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)
} else {
$sol = $pfx . "_("; # start of line
$s = "";
foreach my $as (@sortas) {
if ($s eq "" || length($s) >= 65) {
if ($s ne "")
$s = $sol;
} else
$s .= sprintf("%s", $as);
}
if ($s ne $sol)
}
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
\n");
exit(1);
}
if (defined($opt_a)) {
$opt_a = "-a";
}
&getmacros(@ARGV);
&printases($opt_n, @ases);