pod2usage( -exitval => 0, -verbose => 2 ) if $man;
my $bgpdump_path = can_run('bgpdump')
- or warn 'bgpdump is not found, will try to use Net::MRT instead; results can be incomplete';
+ or warn 'bgpdump is not found, will try to use Net::MRT instead; results can be incomplete';
sub download_file {
my ($u) = @_;
sub is_bougus_asn {
my $as = shift;
+
# 64496-64511 Reserved for use in documentation and sample code
# 64512-65534 Designated for private use
# 65535 Reserved
# 65536-65551 Reserved for use in documentation and sample code
# 65552-131071 Reserved
return 1 if $as >= 64496 && $as <= 131071;
+
# 4294967295
return 1 if $as == 4294967295;
+
# AS0 is reserved
# AS1 is legal AS, but in most cases used by others without permission
# of owner (probably lame admins use AS1 as private AS).
if ($bgpdump_path) {
use constant {
- F_MARKER => 0,
- F_TIMESTAMP => 1,
- F_PEER_IP => 3,
- F_PEER_AS => 4,
- F_PREFIX => 5,
- F_AS_PATH => 6,
- F_ORIGIN => 7,
+ F_MARKER => 0,
+ F_TIMESTAMP => 1,
+ F_PEER_IP => 3,
+ F_PEER_AS => 4,
+ F_PREFIX => 5,
+ F_AS_PATH => 6,
+ F_ORIGIN => 7,
};
- open(my $bgpd, '-|', "$bgpdump_path -v -M $fname") or die "can't start bgpdump: $!";
+ open( my $bgpd, '-|', "$bgpdump_path -v -M $fname" ) or die "can't start bgpdump: $!";
while (<$bgpd>) {
chomp;
my @e = split /\|/;
- if ($e[F_MARKER] ne 'TABLE_DUMP2') {
+ if ( $e[F_MARKER] ne 'TABLE_DUMP2' ) {
warn "bad line: $_\n";
next;
}
my $origin_as;
my $prefix = $e[F_PREFIX];
- my $ipv6 = 0;
+ my $ipv6 = 0;
- if ($prefix !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\d{1,2}$/) {
+ if ( $prefix !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\d{1,2}$/ ) {
$ipv6 = 1;
}
- if ($e[F_AS_PATH]) {
+ if ( $e[F_AS_PATH] ) {
+
# not empty AS_PATH
my @as_path = split /\s/, $e[F_AS_PATH];
$origin_as = pop @as_path;
- if (substr($origin_as, 0, 1) eq '{') {
+ if ( substr( $origin_as, 0, 1 ) eq '{' ) {
+
# route is aggregated
- if ($origin_as =~ /^{(\d+)}$/) {
+ if ( $origin_as =~ /^{(\d+)}$/ ) {
+
# single AS aggregated, just remove { } around
$origin_as = $1;
- } else {
+ }
+ else {
# use previous AS from AS_PATH
$origin_as = pop @as_path;
}
}
+
# strip bogus AS
- while (is_bougus_asn($origin_as)) {
+ while ( is_bougus_asn($origin_as) ) {
$origin_as = pop @as_path;
last if scalar @as_path == 0;
}
}
+
# empty AS_PATH or all AS_PATH elements is stripped as bogus - use PEER_AS is origin AS
$origin_as //= $e[F_PEER_AS];
- if (!$networks->{$origin_as}) {
- if (!$ipv6) {
- $networks->{$origin_as} = { nets_v4 => [ $prefix ], nets_v6 => [] };
+ if ( !$networks->{$origin_as} ) {
+ if ( !$ipv6 ) {
+ $networks->{$origin_as} = { nets_v4 => [$prefix], nets_v6 => [] };
}
else {
- $networks->{$origin_as} = { nets_v6 => [ $prefix ], nets_v4 => [] };
+ $networks->{$origin_as} = { nets_v6 => [$prefix], nets_v4 => [] };
}
}
else {
- if (!$ipv6) {
- push @{$networks->{$origin_as}->{'nets_v4'}}, $prefix;
+ if ( !$ipv6 ) {
+ push @{ $networks->{$origin_as}->{'nets_v4'} }, $prefix;
}
else {
- push @{$networks->{$origin_as}->{'nets_v6'}}, $prefix;
+ push @{ $networks->{$origin_as}->{'nets_v6'} }, $prefix;
}
}
}
open( my $fh, "<:gzip", $fname )
or die "Cannot open $fname: $!";
- while (my $dd = eval {Net::MRT::mrt_read_next($fh)}) {
- if ($dd->{'prefix'} && $dd->{'bits'}) {
+ while ( my $dd = eval { Net::MRT::mrt_read_next($fh) } ) {
+ if ( $dd->{'prefix'} && $dd->{'bits'} ) {
next if $dd->{'subtype'} == 2 and !$v4;
next if $dd->{'subtype'} == 4 and !$v6;
my $entry = $dd->{'entries'}->[0];
- my $net = $dd->{'prefix'} . '/' . $dd->{'bits'};
- if ($entry && $entry->{'AS_PATH'}) {
+ my $net = $dd->{'prefix'} . '/' . $dd->{'bits'};
+ if ( $entry && $entry->{'AS_PATH'} ) {
my $as = $entry->{'AS_PATH'}->[-1];
- if (ref($as) eq "ARRAY") {
+ if ( ref($as) eq "ARRAY" ) {
$as = @{$as}[0];
}
- next if (is_bougus_asn($as));
+ next if ( is_bougus_asn($as) );
- if (!$networks->{$as}) {
- if ($dd->{'subtype'} == 2) {
- $networks->{$as} = { nets_v4 => [ $net ], nets_v6 => [] };
+ if ( !$networks->{$as} ) {
+ if ( $dd->{'subtype'} == 2 ) {
+ $networks->{$as} = { nets_v4 => [$net], nets_v6 => [] };
}
else {
- $networks->{$as} = { nets_v6 => [ $net ], nets_v4 => [] };
+ $networks->{$as} = { nets_v6 => [$net], nets_v4 => [] };
}
}
else {
- if ($dd->{'subtype'} == 2) {
- push @{$networks->{$as}->{'nets_v4'}}, $net;
+ if ( $dd->{'subtype'} == 2 ) {
+ push @{ $networks->{$as}->{'nets_v4'} }, $net;
}
else {
- push @{$networks->{$as}->{'nets_v6'}}, $net;
+ push @{ $networks->{$as}->{'nets_v6'} }, $net;
}
}
}