NAME
Net::MRT - Perl extension for decoding RFC6396 Multi-Threaded Routing Toolkit (MRT) Routing Information Export Format
SYNOPSIS
Decode uncompressed MRT file:
use Net::MRT;
open(C, '<', 'file');
binmode(C);
while ($decode = Net::MRT::mrt_read_next(C))
{
do_something_useful($decode);
}
In-memory download/decode:
use LWP::Simple;
use PerlIO::gzip;
use Net::MRT;
$LWP::Simple::ua->show_progress(1);
$archive = get($url);
open $mrt, "<:gzip", \$archive or die $!;
while ($dd = Net::MRT::mrt_read_next($mrt))
{
do_something_useful($decode);
}
Note: In case of errors, reported message offset will be relative to Perl internal buffer
Decode some binary message of known type/subtype:
$hash = Net::MRT::mrt_decode_single($type, $subtype, $buffer);
Refer to t/ directory for a lot of examples, how each attribute decoded.
DESCRIPTION
"Net::MRT::mrt_read_next" Decodes next message from filehandle
NOTE Always set binary mode before call to mrt_read_next or got unexpected results.
"Net::MRT::mrt_decode_single" Decodes message of specified type & subtype. See t/* for a lot of examples
TODO TODO
EXPORT
None by default.
Methods
Net::MRT::mrt_read_next
{
'timestamp' => 1222905597,
'type' => X,
'subtype' => Y,
other decoded elements,
};
In case of unsupported type/subtype an error message is returned in error
.
{
'timestamp' => Z,
'type' => X,
'subtype' => Y,
'error' => 'Unsupported MRT type X subtype Y in message at N',
};
TODO TODO
Net::MRT::mrt_decode_single
TODO TODO
Examples of decoded messages
Type=13 TABLE_DUMP_V2
Subtype=1 PEER_INDEX_TABLE
{
'peers' => [
'1' => {
'peer_ip' => '2001:db8::dead:beef',
'bgp_id' => '10.11.12.13',
'as' => 35243
},
'0' => {
'peer_ip' => '5.6.7.8',
'bgp_id' => '1.2.3.4',
'as' => 2164197642
}
],
'collector_bgp_id' => '1.2.3.4',
'view_name' => 'testTEST',
};
Peer index table decoded as HASH with peer's ARRAY allowing reference by peer's index.
NOTE: view_name
marked with UTF8 flag, but this field is optional by RFC.
Subtype=2 RIB_IPV4_UNICAST & Subtype=4 RIB_IPV6_UNICAST
{
'timestamp' => 1222905597,
'type' => 13,
'subtype' => 2,
'prefix' => '10.0.0.0'
'bits' => 8,
'sequence' => 1,
'entries' => [
{ See Decoding of BGP attributes },
{ See Decoding of BGP attributes },
],
};
NOTE: type
subtype
timestamp
elements appended into HASH only while stream decode using Net::MRT::mrt_read_next.
Decoding of BGP attributes
BGP attributes decoded into the same HASHREF where decoded entry resides.
{
'peer_index' => 12,
'originated_time' => 1220989283
'ORIGIN' => 0,
'NEXT_HOP' => '10.68.129.132',
'AS_PATH' => [
65501,
65502,
[65503, 65504],
65505,
],
'unsupported7' => undef,
}
peer_index
is a reference to PEER_INDEX_TABLE.
The originated_time
contains the 4-octet time at which this prefix was heard. The value represents the time in seconds since 1 January 1970 00:00:00 UTC.
Unsupported (by Net::MRT) attributes reported as 'unsupportedX' where X is a BGP attribute code.
ORIGIN
{ 'ORIGIN' => 0 },
$Net::MRT::BGP_ORIGIN[$entry->{'ORIGIN'}]
The ORIGIN decoded as integer. Additional helper array can be used to decode into text representation.
AS_PATH
{
'AS_PATH' => [
65501,
65502,
65505,
[65503, 65504],
],
}
The AS_PATH decoded as array of elements. Each of element can be an AS_SEQUENCE (single AS number) or AS_SET (array of AS numbers).
NOTE: Multiple AS_PATH
attributes supported.
- "The ability of a BGP speaker to include more than one instance of
its own AS in the AS_PATH attribute for the purpose of inter-AS
traffic engineering."
Determination of ORIGINATED AS is to skip trailing AS_SET and take single AS:
foreach (reverse @{$_->{'AS_PATH'}}) {
next if ref($_);
print "Originated AS = $_\n";
last;
}
NOTE: MRT TABLE_DATA_V2 AS_PATH contain four-octet AS numbers in AS_PATH attribute. So, expect large numbers (> 65535).
- "All AS numbers in the AS_PATH attribute MUST be encoded as 4-byte AS numbers."
NEXT_HOP
IPv4 Next Hop:
{ 'NEXT_HOP' => [ '10.68.129.132' ], }
IPv6 Next Hop:
{ 'NEXT_HOP' => [ '2001:db8::1', 'fe80::dead:beef' ], }
MP_REACH_NLRI carries global and link-local next-hop addresses. As result, this attribute contains one or two entries in array.
In case, when entry will erroneously contain NEXT_HOP
and MP_REACH_NLRI
, then resulting array will contain all of NEXT_HOP entries in one array.
MULTI_EXIT_DISC
{ 'MULTI_EXIT_DISC' => 2140, }
LOCAL_PREF
{ 'LOCAL_PREF' => 2140, }
ATOMIC_AGGREGATE
{ 'ATOMIC_AGGREGATE' => 1, }
Atomic aggregate is a flag. So, hash element with undefined value will be present if this flag is set. Check for this flag using exists()
function:
if (exists $_->{'ATOMIC_AGGREGATE'}) ...
AGGREGATOR
{ 'AGGREGATOR_AS' => 65501, 'AGGREGATOR_BGPID' => '10.12.14.1', }
Aggregator decoded into two elements AGGREGATOR_AS
& AGGREGATOR_BGPID
. As per "AS_PATH", the AGGREGATOR_AS
also have 4 octets.
COMMUNITY
{ 'COMMUNITY' => [
'1:2',
'3:4',
], }
Communities decoded as array of communities (16 bit:16 bit)
MP_REACH_NLRI
Refer to NEXT_HOP attribute.
NOTE: The MP_REACH_NLRI
attribute can be decoded as per RFC4760 or RFC6396.
Due to recent changes in Quagga/RIPE RIS, the collected MRT data does not follow RFC6396 and the MP_REACH_NLRI
should be decoded as described in RFC4760
The $Net::MRT::USE_RFC4760
global variable control Net::MRT behavior:
$Net::MRT::USE_RFC4760 = 1;
- Decode as described in RFC4760$Net::MRT::USE_RFC4760 = undef;
- Decode as described in RFC6396 (default behavior). Please note that only NEXT-HOP will be decoded.$Net::MRT::USE_RFC4760 = -1;
- Do not decodeMP_REACH_NLRI
at all.
SEE ALSO
http://tools.ietf.org/html/rfc6396
http://www.ripe.net/data-tools/stats/ris/ris-raw-data
http://tools.ietf.org/html/rfc4760
AUTHOR
MaxiM Basunov, <maxim.basunov@gmail.com>
MODIFICATION HISTORY
See the Changes file.
COPYRIGHT AND LICENSE
Copyright (C) 2013 MaxiM Basunov <maxim.basunov@gmail.com> All rights reserved.
This program is free software; you may redistribute it and/or modify it under the same terms as Perl itself.