BGP MRT parser and route change analyzer in MoonBit
git clone https://github.com/prowk/mrtkit.git
cd mrtkit
npm run build
node cli/mrtkit.mjs parse fixtures/demo.mrt
node cli/mrtkit.mjs stats --threshold 3 fixtures/demo.mrt
node cli/mrtkit.mjs timeline --prefix 203.0.113.0/24 fixtures/demo.mrtnpm test
moon test --target wasm --deny-warn
moon test --target wasm-gc --deny-warn
moon info
moon fmt --checkpub struct Aggregation {
// private fields
}pub struct AggregationReport {
schema_version : String
scope : String
deduplication : String
ordering : String
changed_prefixes : Int
affected_peers : Int
change_notices : Int64
change_types : Map[String, Int64]
top_prefixes : Array[PrefixRanking]
} derive(ToJson)pub struct Analyzer {
// private fields
}fn Analyzer::new(window_seconds? : Int, threshold? : Int, capacity? : Int, from_time? : UInt, to_time? : UInt, from_micros? : Int, to_micros? : Int) -> Analyzer raise ParseErrorpub struct Attributes {
origin : Int?
path : Array[AsSegment]
wire_path : Array[AsSegment]
as4_path : Array[AsSegment]
next_hop : String?
med : UInt?
local_pref : UInt?
atomic_aggregate : Bool
aggregator : Aggregator?
wire_aggregator : Aggregator?
as4_aggregator : Aggregator?
raw_attributes : Array[RawAttribute]
communities : Array[UInt]
large_communities : Array[(UInt, UInt, UInt)]
other : Array[RawAttribute]
} derive(Eq, ToJson)pub struct Batch {
header : Header
microseconds : Int?
events : Array[RouteEvent]
states : Array[StateChange]
skipped : Bool
ignored_families : Int
message_type : Int?
diagnostics : Array[Diagnostic]
} derive(ToJson)pub struct BgpRecord {
message_type : Int
events : Array[RouteEvent]
states : Array[StateChange]
ignored_families : Int
ignored : Array[(Int, Int)]
}pub struct Change {
schema_version : String
timestamp : UInt
microseconds : Int?
prefix : String
path_id : UInt?
peer_asn : UInt
peer_ip : String
outbound : Bool
kind : String
source : Source?
before : RouteSnapshot?
after : RouteSnapshot
diff : RouteDiff
churn_count : Int?
} derive(ToJson)pub struct Decoder {
// private fields
}fn Decoder::decode_at(self : Decoder, data : Bytes, file : String, record : Int64, offset : Int64) -> Batch raise ParseErrorpub struct HopDiff {
before : String?
after : String?
}pub struct ObservationGap {
from_time : UInt
from_micros : Int
to_time : UInt
to_micros : Int
} derive(ToJson)fn ObservationGap::new(from_time : UInt, to_time : UInt, from_micros? : Int, to_micros? : Int) -> ObservationGappub struct Query {
// private fields
}fn Query::new(prefix? : String, prefix_mode? : String, asn? : UInt, path_id? : UInt, from_time? : UInt, to_time? : UInt, from_micros? : Int, to_micros? : Int) -> Query raise ParseErrorpub struct RouteDiff {
atomic_aggregate : AtomicAggregateDiff?
aggregator : AggregatorDiff?
path : PathDiff?
origin_as : OriginDiff?
next_hop : HopDiff?
communities : CommunityDiff?
large_communities : LargeCommunityDiff?
} derive(ToJson)pub struct RouteEvent {
schema_version : String
source : Source?
timestamp : UInt
microseconds : Int?
action : String
prefix : String
path_id : UInt?
peer_asn : UInt
peer_ip : String
outbound : Bool
originated : UInt?
attributes : Attributes
} derive(ToJson)pub struct RouteSnapshot {
timestamp : UInt
microseconds : Int?
active : Bool
attributes : Attributes
source : Source?
} derive(ToJson)pub struct Snapshot {
// private fields
}fn Snapshot::ingest(self : Snapshot, data : Bytes, file : String, record : Int64, offset : Int64, query? : Query, peer_asn? : UInt) -> Unit raise ParseErrorpub struct SnapshotChange {
schema_version : String
collector : String
kind : String
peer_asn : UInt
peer_ip : String
outbound : Bool
prefix : String?
path_id : UInt?
before : RouteEvent?
after : RouteEvent?
diff : RouteDiff?
before_source : Source?
after_source : Source?
} derive(ToJson)pub struct SnapshotReport {
schema_version : String
collector : String
interpretation : String
before_source : Source?
after_source : Source?
before_time : UInt?
after_time : UInt?
before_peers : Int
after_peers : Int
before_routes : Int
after_routes : Int
changes : Array[SnapshotChange]
} derive(ToJson)pub struct StreamDecoder {
// private fields
}pub struct Summary {
schema_version : String
baseline_status : String
warmup_records : Int64
records : Int64
skipped_records : Int64
ignored_families : Int64
rib_routes : Int64
announcements : Int64
withdrawals : Int64
path_changes : Int64
attribute_changes : Int64
origin_changes : Int64
duplicate_announcements : Int64
churn_alerts : Int64
out_of_order : Int64
session_resets : Int64
tracked_routes : Int
active_routes : Int
mean_path_length : Double
max_path_length : Int
} derive(ToJson)pub struct Timeline {
// private fields
}fn Timeline::new(prefix : String, analyzer : Analyzer, continuous? : Bool, gaps? : Array[ObservationGap], capacity? : Int, peer_asn? : UInt) -> Timeline raise ParseErrorfn Timeline::seed_peers(self : Timeline, table : PeerTable, timestamp : UInt) -> Unit raise ParseErrorpub struct TimelineEntry {
timestamp : UInt
microseconds : Int?
kind : String
prefix : String
path_id : UInt?
peer_asn : UInt?
peer_ip : String?
outbound : Bool?
accepted : Bool
source : Source?
before : RouteSnapshot?
after : RouteSnapshot?
changes : Array[Change]
} derive(ToJson)pub struct TimelinePeer {
peer_asn : UInt
peer_ip : String
outbound : Bool
visibility : String
visible_paths : Int
not_visible_paths : Int
unobserved_paths : Int
baseline_present : Bool
} derive(ToJson)pub struct TimelineReport {
schema_version : String
prefix : String
interpretation : String
baseline_status : String
continuous_observation : Bool
last_input_time : UInt64?
observed_window_end : UInt64?
gaps : Array[ObservationGap]
entries : Array[TimelineEntry]
intervals : Array[VisibilityInterval]
peer_intervals : Array[VisibilityInterval]
paths : Array[TimelinePath]
peers : Array[TimelinePeer]
} derive(ToJson)pub struct VisibilityInterval {
scope : String
prefix : String
path_id : UInt?
peer_asn : UInt
peer_ip : String
outbound : Bool
started_at : UInt64
measured_from : UInt64
observed_until : UInt64
recovery_time : UInt64?
known_invisible_microseconds : UInt64?
left_censored : Bool
right_censored : Bool
quality : String
closed_by : String
start_source : Source?
end_source : Source?
} derive(ToJson)Install
Download zipBGP MRT parser and route change analyzer in MoonBit