bgpkit_parser/lib.rs
1/*!
2BGPKIT Parser aims to provide the most ergonomic MRT/BGP/BMP message parsing Rust API.
3
4BGPKIT Parser has the following features:
5- **performant**: comparable to C-based implementations like `bgpdump` or `bgpreader`.
6- **actively maintained**: we consistently introduce feature updates and bug fixes, and support most of the relevant BGP RFCs.
7- **ergonomic API**: a three-line for loop can already get you started.
8- **battery-included**: ready to handle remote or local, bzip2 or gz data files out of the box
9
10# Getting Started
11
12Add `bgpkit-parser` to your `Cargo.toml`.
13
14Parse a BGP MRT file in three lines:
15
16```no_run
17use bgpkit_parser::BgpkitParser;
18
19for elem in BgpkitParser::new("http://archive.routeviews.org/route-views4/bgpdata/2022.01/UPDATES/updates.20220101.0000.bz2").unwrap() {
20 println!("{}", elem);
21}
22```
23
24# Examples
25
26The examples below are organized by complexity. For complete runnable examples, check out the [examples folder](https://github.com/bgpkit/bgpkit-parser/tree/main/examples).
27
28## Basic Examples
29
30### Parsing a Single MRT File
31
32Let's say we want to print out all the BGP announcements/withdrawal from a single MRT file, either located remotely or locally.
33Here is an example that does so.
34
35```no_run
36use bgpkit_parser::BgpkitParser;
37let parser = BgpkitParser::new("http://archive.routeviews.org/bgpdata/2021.10/UPDATES/updates.20211001.0000.bz2").unwrap();
38for elem in parser {
39 println!("{}", elem)
40}
41```
42
43Yes, it is this simple!
44
45### Counting BGP Messages
46
47You can use iterator methods for quick analysis. For example, counting the number of announcements/withdrawals in a file:
48
49```no_run
50use bgpkit_parser::BgpkitParser;
51let url = "http://archive.routeviews.org/bgpdata/2021.10/UPDATES/updates.20211001.0000.bz2";
52let count = BgpkitParser::new(url).unwrap().into_iter().count();
53println!("total: {}", count);
54```
55
56Output:
57```text
58total: 255849
59```
60
61## Intermediate Examples
62
63### Filtering BGP Messages
64
65BGPKIT Parser has a built-in [Filter] mechanism to efficiently filter messages. Add filters when creating the parser to only process matching [BgpElem]s.
66
67**Available filter types**: See the [Filter] enum documentation for all options.
68
69```no_run
70use bgpkit_parser::BgpkitParser;
71
72/// Filter by IP prefix
73let parser = BgpkitParser::new("http://archive.routeviews.org/bgpdata/2021.10/UPDATES/updates.20211001.0000.bz2").unwrap()
74 .add_filter("prefix", "211.98.251.0/24").unwrap();
75
76for elem in parser {
77 println!("{}", elem);
78}
79```
80
81**Common filters**:
82- `prefix`: Match a specific IP prefix
83- `origin_asn`: Match origin AS number
84- `peer_asn`: Match peer AS number
85- `peer_ip`: Match peer IP address
86- `type`: Filter by announcement (`a`) or withdrawal (`w`)
87- `as_path`: Match AS path with regex
88
89**Negative filters**: Most filters support negation by prefixing the filter value with `!`. For example:
90- `origin_asn = !13335`: Match elements where origin AS is NOT 13335
91- `prefix = !211.98.251.0/24`: Match elements where prefix is NOT 211.98.251.0/24
92- `peer_ip = !192.0.2.1`: Match elements where peer IP is NOT 192.0.2.1
93
94**Note**: Timestamp filters (`ts_start`, `ts_end`) do not support negation.
95
96```no_run
97use bgpkit_parser::BgpkitParser;
98
99// Filter out all elements from AS 13335 (get everything EXCEPT AS 13335)
100let parser = BgpkitParser::new("http://archive.routeviews.org/bgpdata/2021.10/UPDATES/updates.20211001.0000.bz2").unwrap()
101 .add_filter("origin_asn", "!13335").unwrap();
102
103for elem in parser {
104 println!("{}", elem);
105}
106```
107
108### Parsing Multiple MRT Files with BGPKIT Broker
109
110[BGPKIT Broker][broker-repo] library provides search API for all RouteViews and RIPE RIS MRT data files. Using the
111broker's Rust API ([`bgpkit-broker`][broker-crates-io]), we can easily compile a list of MRT files that we are interested
112in for any time period and any data type (`update` or `rib`). This allows users to gather information without needing to
113know about the locations of specific data files.
114
115[broker-repo]: https://github.com/bgpkit/bgpkit-broker
116[broker-crates-io]: https://crates.io/crates/bgpkit-broker
117
118The example below shows a relatively more interesting example that does the following:
119- find all BGP archive data created on time 1634693400
120- filter to only BGP updates files
121- find all announcements originated from AS13335
122- print out the total count of the announcements
123
124```no_run
125use bgpkit_parser::{BgpkitParser, BgpElem};
126
127let broker = bgpkit_broker::BgpkitBroker::new()
128 .ts_start("1634693400")
129 .ts_end("1634693400")
130 .page(1);
131
132for item in broker.into_iter().take(2) {
133 log::info!("downloading updates file: {}", &item.url);
134 let parser = BgpkitParser::new(item.url.as_str()).unwrap();
135
136 log::info!("parsing updates file");
137 // iterating through the parser. the iterator returns `BgpElem` one at a time.
138 let elems = parser
139 .into_elem_iter()
140 .filter_map(|elem| {
141 if let Some(origins) = &elem.origin_asns {
142 if origins.contains(&13335.into()) {
143 Some(elem)
144 } else {
145 None
146 }
147 } else {
148 None
149 }
150 })
151 .collect::<Vec<BgpElem>>();
152 log::info!("{} elems matches", elems.len());
153}
154```
155
156### Error Handling
157
158BGPKIT Parser returns `Result` types for operations that may fail. Here are common scenarios and how to handle them:
159
160**Handling Parser Creation Errors**
161
162```no_run
163use bgpkit_parser::BgpkitParser;
164
165// The URL might be invalid or unreachable
166match BgpkitParser::new("http://example.com/data.mrt.bz2") {
167 Ok(parser) => {
168 for elem in parser {
169 println!("{}", elem);
170 }
171 }
172 Err(e) => {
173 eprintln!("Failed to create parser: {}", e);
174 // Common causes:
175 // - Invalid URL or file path
176 // - Network connection issues
177 // - Unsupported compression format
178 }
179}
180```
181
182**Handling Filter Errors**
183
184```no_run
185use bgpkit_parser::BgpkitParser;
186
187let mut parser = BgpkitParser::new("http://example.com/data.mrt.bz2").unwrap();
188
189// Filter addition can fail with invalid input
190match parser.add_filter("prefix", "invalid-prefix") {
191 Ok(_) => println!("Filter added successfully"),
192 Err(e) => {
193 eprintln!("Invalid filter: {}", e);
194 // Common causes:
195 // - Invalid IP prefix format
196 // - Invalid AS number
197 // - Unknown filter type
198 }
199}
200```
201
202**Robust Production Code**
203
204```no_run
205use bgpkit_parser::BgpkitParser;
206
207fn process_mrt_file(url: &str) -> Result<usize, Box<dyn std::error::Error>> {
208 let parser = BgpkitParser::new(url)?
209 .add_filter("origin_asn", "13335")?;
210
211 let mut count = 0;
212 for elem in parser {
213 // Process element
214 count += 1;
215 }
216
217 Ok(count)
218}
219
220// Usage
221match process_mrt_file("http://example.com/updates.bz2") {
222 Ok(count) => println!("Processed {} elements", count),
223 Err(e) => eprintln!("Error: {}", e),
224}
225```
226
227## Advanced Examples
228
229### Parsing Real-time Data Streams
230
231BGPKIT Parser provides parsing for real-time data streams, including [RIS-Live][ris-live-url]
232and [BMP][bmp-rfc]/[OpenBMP][openbmp-url] messages.
233
234**Parsing Messages From RIS-Live**
235
236Here is an example of handling RIS-Live message streams. After connecting to the websocket server,
237we need to subscribe to a specific data stream. In this example, we subscribe to the data stream
238from one collector (`rrc21`). We can then loop and read messages from the websocket.
239
240RIS Live's JSON fields expose only a subset of BGP attributes. To parse the original BGP wire
241message instead, request `includeRaw` and use `parse_ris_live_message_raw`. The older
242`parse_ris_live_message` function remains available for parsing RIS Live's JSON-projected fields.
243
244```no_run
245# #[cfg(feature = "rislive")]
246use bgpkit_parser::{parse_ris_live_message_raw, RisLiveClientMessage, RisSubscribe};
247use tungstenite::{connect, Message};
248
249const RIS_LIVE_URL: &str = "ws://ris-live.ripe.net/v1/ws/?client=rust-bgpkit-parser";
250
251/// This is an example of subscribing to RIS-Live's streaming data from one host (`rrc21`).
252///
253/// For more RIS-Live details, check out their documentation at https://ris-live.ripe.net/manual/
254fn main() {
255 // connect to RIPE RIS Live websocket server
256 let (mut socket, _response) =
257 connect(RIS_LIVE_URL)
258 .expect("Can't connect to RIS Live websocket server");
259
260 // subscribe to messages from one collector and request hex-encoded raw BGP messages
261 let msg = RisSubscribe::new().host("rrc21").include_raw(true).to_json_string();
262 socket.send(Message::Text(msg.into())).unwrap();
263
264 loop {
265 let msg = socket.read().expect("Error reading message").to_string();
266# #[cfg(feature = "rislive")]
267 if let Ok(elems) = parse_ris_live_message_raw(msg.as_str()) {
268 for elem in elems {
269 println!("{}", elem);
270 }
271 }
272 }
273}
274```
275
276**Parsing OpenBMP Messages From RouteViews Kafka Stream**
277
278[RouteViews](http://www.routeviews.org/routeviews/) provides a real-time Kafka stream of the OpenBMP
279data received from their collectors. Below is a partial example of how we handle the raw bytes
280received from the Kafka stream. For full examples, check out the [examples folder on GitHub](https://github.com/bgpkit/bgpkit-parser/tree/main/examples).
281
282```rust,no_run
283# use log::{info, error};
284# use bytes::Bytes;
285# struct KafkaMessage { value: Vec<u8> }
286# let m = KafkaMessage { value: vec![] };
287use bgpkit_parser::parser::bmp::messages::*;
288use bgpkit_parser::parser::utils::*;
289use bgpkit_parser::{Elementor, parse_openbmp_header, parse_bmp_msg};
290
291let bytes = &m.value;
292let mut data = Bytes::from(bytes.clone());
293let header = parse_openbmp_header(&mut data).unwrap();
294let bmp_msg = parse_bmp_msg(&mut data);
295match bmp_msg {
296 Ok(msg) => {
297 let timestamp = header.timestamp;
298 let per_peer_header = msg.per_peer_header.unwrap();
299 match msg.message_body {
300 BmpMessageBody::RouteMonitoring(m) => {
301 for elem in Elementor::bgp_to_elems(
302 m.bgp_message,
303 timestamp,
304 &per_peer_header.peer_ip,
305 &per_peer_header.peer_asn
306 )
307 {
308 info!("{}", elem);
309 }
310 }
311 _ => {}
312 }
313 }
314 Err(_e) => {
315 let hex = hex::encode(bytes);
316 error!("{}", hex);
317 }
318}
319```
320
321[ris-live-url]: https://ris-live.ripe.net
322[bmp-rfc]: https://datatracker.ietf.org/doc/html/rfc7854
323[openbmp-url]: https://www.openbmp.org/
324
325### Encoding: Archiving Filtered MRT Records
326
327The example will download one MRT file from RouteViews, filter out all the BGP messages that
328are not originated from AS3356, and write the filtered MRT records to disk. Then it re-parses the
329filtered MRT file and prints out the number of BGP messages.
330
331```no_run
332use bgpkit_parser::Elementor;
333use itertools::Itertools;
334use std::io::Write;
335
336let mut updates_encoder = bgpkit_parser::encoder::MrtUpdatesEncoder::new();
337
338bgpkit_parser::BgpkitParser::new(
339 "http://archive.routeviews.org/bgpdata/2023.10/UPDATES/updates.20231029.2015.bz2",
340).unwrap()
341 .add_filter("origin_asn", "3356").unwrap()
342 .into_iter()
343 .for_each(|elem| {
344 updates_encoder.process_elem(&elem);
345 });
346
347let mut mrt_writer = oneio::get_writer("as3356_mrt.gz").unwrap();
348mrt_writer.write_all(updates_encoder.export_bytes().as_ref()).unwrap();
349drop(mrt_writer);
350```
351
352# FAQ & Troubleshooting
353
354## Common Issues
355
356### Parser creation fails with "unsupported compression"
357**Problem**: The file uses an unsupported compression format.
358
359**Solution**: BGPKIT Parser natively supports `.bz2` and `.gz` compression. For other formats, decompress the file first or use the [`oneio`](https://crates.io/crates/oneio) crate which supports additional formats.
360
361### Out of memory when parsing large files
362**Problem**: Collecting all elements into a vector exhausts available memory.
363
364**Solution**: Use streaming iteration instead of collecting:
365```rust,ignore
366// ❌ Don't do this for large files
367let all_elems: Vec<_> = parser.into_iter().collect();
368
369// ✅ Process iteratively
370for elem in parser {
371 // Process one element at a time
372 process(elem);
373}
374```
375
376### Slow performance on network files
377**Problem**: Remote file parsing is slower than expected.
378
379**Solution**:
380- Use the `--cache-dir` option in CLI to cache downloaded files
381- In library code, download the file first with appropriate buffering
382- Consider processing files in parallel if dealing with multiple files
383
384### Missing or incomplete BGP attributes
385**Problem**: Some [BgpElem] fields are `None` when you expect values.
386
387**Solution**: Not all BGP messages contain all attributes. Check the MRT format and BGP message type:
388- Withdrawals typically don't have AS paths or communities
389- Some collectors may not export certain attributes
390- Use pattern matching to handle `Option` types properly
391
392## Performance Tips
393
394### Use filters early
395Apply filters during parser creation to avoid processing unwanted data:
396```rust,ignore
397// ✅ Efficient - filters during parsing
398let parser = BgpkitParser::new(url)?
399 .add_filter("prefix", "1.1.1.0/24")?;
400
401// ❌ Less efficient - processes everything first
402let filtered: Vec<_> = BgpkitParser::new(url)?
403 .into_iter()
404 .filter(|e| e.prefix.to_string() == "1.1.1.0/24")
405 .collect();
406```
407
408### Process multiple files in parallel
409For bulk processing, use parallel iterators:
410```rust,ignore
411use rayon::prelude::*;
412
413let files = vec!["file1.mrt.bz2", "file2.mrt.bz2", "file3.mrt.bz2"];
414files.par_iter().for_each(|file| {
415 let parser = BgpkitParser::new(file).unwrap();
416 // Process each file in parallel
417});
418```
419
420### Choose the right data structure
421- Use [MrtRecord] iteration for minimal memory overhead
422- Use [MrtUpdate] for efficient batch processing without per-prefix attribute duplication
423- Use [BgpElem] for easier per-prefix analysis
424- See [Data Representation](#data-representation) for detailed comparison
425
426# Command Line Tool
427
428`bgpkit-parser` is bundled with a utility commandline tool `bgpkit-parser-cli`.
429
430## Installation
431
432### Install compiled binaries
433
434You can install the compiled `bgpkit-parser` CLI binaries with the following methods:
435- **Homebrew** (macOS): `brew install bgpkit/tap/bgpkit-parser`
436- [**Cargo binstall**](https://github.com/cargo-bins/cargo-binstall): `cargo binstall bgpkit-parser`
437
438### From source
439
440You can install the tool by running
441```bash
442cargo install bgpkit-parser --features cli
443```
444or checkout this repository and run
445```bash
446cargo install --path . --features cli
447```
448
449## Usage
450
451Run `bgpkit-parser --help` to see the full list of options.
452
453```text
454MRT/BGP/BMP data processing library
455
456Usage: bgpkit-parser [OPTIONS] <FILE>
457
458Arguments:
459 <FILE> File path to a MRT file, local or remote
460
461Options:
462 -c, --cache-dir <CACHE_DIR> Set the cache directory for caching remote files. Default behavior does not enable caching
463 --json Output as JSON objects
464 --psv Output as full PSV entries with header
465 --pretty Pretty-print JSON output
466 -e, --elems-count Count BGP elems
467 -r, --records-count Count MRT records
468 -o, --origin-asn <ORIGIN_ASN> Filter by origin AS Number
469 -f, --filter <FILTERS> Generic filter expression (key=value or key!=value)
470 -p, --prefix <PREFIX> Filter by network prefix
471 -4, --ipv4-only Filter by IPv4 only
472 -6, --ipv6-only Filter by IPv6 only
473 -s, --include-super Include super-prefix when filtering
474 -S, --include-sub Include sub-prefix when filtering
475 -j, --peer-ip <PEER_IP> Filter by peer IP address
476 -J, --peer-asn <PEER_ASN> Filter by peer ASN
477 -m, --elem-type <ELEM_TYPE> Filter by elem type: announce (a) or withdraw (w)
478 -t, --start-ts <START_TS> Filter by start unix timestamp inclusive
479 -T, --end-ts <END_TS> Filter by end unix timestamp inclusive
480 -a, --as-path <AS_PATH> Filter by AS path regex string
481 -h, --help Print help
482 -V, --version Print version
483
484```
485
486## Common CLI Examples
487
488### Basic usage - Print all BGP messages
489```bash
490bgpkit-parser http://archive.routeviews.org/bgpdata/2021.10/UPDATES/updates.20211001.0000.bz2
491```
492
493### Filter by origin AS
494```bash
495bgpkit-parser -o 13335 updates.20211001.0000.bz2
496```
497
498### Filter by prefix
499```bash
500bgpkit-parser -p 1.1.1.0/24 updates.20211001.0000.bz2
501```
502
503### Output as JSON
504```bash
505bgpkit-parser --json updates.20211001.0000.bz2 > output.json
506```
507
508### Count elements efficiently
509```bash
510bgpkit-parser -e updates.20211001.0000.bz2
511```
512
513### Cache remote files for faster repeated access
514```bash
515bgpkit-parser -c ~/.bgpkit-cache http://example.com/updates.mrt.bz2
516```
517
518### Combine filters
519```bash
520# IPv4 announcements from AS13335
521bgpkit-parser -o 13335 -m a -4 updates.bz2
522```
523
524### Negative filters (exclude matching elements)
525```bash
526# Exclude elements from AS 13335
527bgpkit-parser --filter "origin_asn!=13335" updates.bz2
528
529# Exclude a specific peer
530bgpkit-parser --filter "peer_ip!=192.168.1.1" updates.bz2
531
532# Combine positive and negative filters
533bgpkit-parser -o 13335 --filter "peer_asn!=64496" updates.bz2
534```
535
536# Data Representation
537
538BGPKIT Parser provides three ways to access parsed BGP data: [MrtRecord], [MrtUpdate], and [BgpElem]. Choose based on your needs:
539
540```text
541┌──────────────────────────────────────────────┐
542│ MRT File │
543│ (Binary format: bgp4mp, tabledumpv2, etc.) │
544└──────────────────────┬───────────────────────┘
545 │
546 ├──> Parser
547 │
548 ┌──────────────┼────────────────┐
549 │ │ │
550 ▼ ▼ ▼
551 [MrtRecord] [MrtUpdate] [BgpElem]
552 (Low-level) (Intermediate) (High-level)
553 │ │ │
554 └─────────────┴────────────────┘
555 │
556 ▼
557 Your Analysis Code
558```
559
560## [MrtRecord]: Low-level MRT Representation
561
562[MrtRecord] preserves the complete, unmodified information from the MRT file. Use this when you need:
563- **Raw MRT data access**: Direct access to all MRT fields
564- **Format-specific details**: Peer index tables, geo-location data, etc.
565- **Memory efficiency**: Minimal overhead, compact representation
566- **Re-encoding**: Converting back to MRT format
567
568See the [MrtRecord] documentation for the complete structure definition.
569
570**Key components**:
571- `common_header`: Contains timestamp, record type, and metadata
572- `message`: The actual MRT message (TableDump, TableDumpV2, or Bgp4Mp)
573
574**Iteration**: Use [`BgpkitParser::into_record_iter()`] to iterate over [MrtRecord]s.
575
576## [MrtUpdate]: Intermediate Message-Level Representation
577
578[MrtUpdate] provides access to BGP announcements without expanding them into individual per-prefix elements. This is a middle ground between [MrtRecord] and [BgpElem]. Use this when you need:
579- **Efficient batch processing**: Avoid duplicating attributes across prefixes
580- **Message-level analysis**: Work with UPDATE messages or RIB entries as units
581- **Memory efficiency**: Shared attributes aren't cloned for each prefix
582
583# RPKI RTR Protocol Support
584
585BGPKIT Parser includes support for the RPKI-to-Router (RTR) protocol, enabling downstream
586clients to communicate with RTR cache servers and fetch Route Origin Authorizations (ROAs).
587
588## Overview
589
590The RTR protocol is used to deliver validated RPKI data from a cache server to a router.
591BGPKIT Parser provides:
592- **PDU definitions**: All RTR protocol data structures for both v0 (RFC 6810) and v1 (RFC 8210)
593- **Parsing**: Decode binary RTR PDUs into structured Rust types
594- **Encoding**: Serialize RTR PDUs to binary format for sending to servers
595
596**Note**: This library provides PDU parsing/encoding only. Transport (TCP, SSH, TLS) and
597RPKI validation logic are out of scope and should be handled by downstream clients.
598
599## Quick Example
600
601```rust
602use bgpkit_parser::models::rpki::rtr::*;
603use bgpkit_parser::parser::rpki::rtr::{parse_rtr_pdu, RtrEncode};
604
605// Create a Reset Query to request the full ROA database
606let query = RtrResetQuery::new_v1();
607let bytes = query.encode();
608
609// Parse a PDU from bytes
610let (pdu, consumed) = parse_rtr_pdu(&bytes).unwrap();
611assert!(matches!(pdu, RtrPdu::ResetQuery(_)));
612```
613
614## Available PDU Types
615
616| PDU Type | Direction | Description |
617|----------|-----------|-------------|
618| Serial Notify | Server → Client | Notifies client of new data |
619| Serial Query | Client → Server | Requests incremental update |
620| Reset Query | Client → Server | Requests full database |
621| Cache Response | Server → Client | Begins data transfer |
622| IPv4 Prefix | Server → Client | ROA for IPv4 prefix |
623| IPv6 Prefix | Server → Client | ROA for IPv6 prefix |
624| End of Data | Server → Client | Ends data transfer |
625| Cache Reset | Server → Client | Cannot provide incremental update |
626| Router Key | Server → Client | BGPsec key (v1 only) |
627| Error Report | Bidirectional | Error notification |
628
629## Building an RTR Client
630
631See the [`rtr_client` example](https://github.com/bgpkit/bgpkit-parser/blob/main/examples/rtr_client.rs)
632for a complete working example that:
6331. Connects to an RTR server
6342. Sends a Reset Query
6353. Collects ROAs
6364. Validates a route announcement (1.1.1.0/24 → AS13335)
637
638```bash
639cargo run --example rtr_client -- rtr.rpki.cloudflare.com 8282
640```
641
642**Supported message types** (via enum variants):
643- `Bgp4MpUpdate`: BGP UPDATE messages from UPDATES files
644- `TableDumpV2Entry`: RIB entries from TableDumpV2 RIB dumps
645- `TableDumpMessage`: Legacy TableDump v1 messages
646
647**Example**:
648```no_run
649use bgpkit_parser::{BgpkitParser, MrtUpdate};
650
651let parser = BgpkitParser::new("updates.mrt.bz2").unwrap();
652for update in parser.into_update_iter() {
653 match update {
654 MrtUpdate::Bgp4MpUpdate(u) => {
655 // One UPDATE message may contain multiple prefixes sharing attributes
656 println!("Peer {} announced {} prefixes",
657 u.peer_ip,
658 u.message.announced_prefixes.len()
659 );
660 }
661 MrtUpdate::TableDumpV2Entry(e) => {
662 // One prefix with multiple RIB entries (one per peer)
663 println!("Prefix {} seen by {} peers",
664 e.prefix,
665 e.rib_entries.len()
666 );
667 }
668 MrtUpdate::TableDumpMessage(m) => {
669 println!("Legacy table dump for {}", m.prefix);
670 }
671 }
672}
673```
674
675**Iteration**: Use [`BgpkitParser::into_update_iter()`] to iterate over [MrtUpdate]s.
676
677## [BgpElem]: High-level Per-Prefix Representation
678
679[BgpElem] provides a simplified, per-prefix view of BGP data. Each [BgpElem] represents a single prefix announcement or withdrawal. Use this when you want:
680- **Simple analysis**: Focus on prefixes without worrying about MRT format details
681- **Format-agnostic processing**: Same structure regardless of MRT format
682- **BGP attributes**: Easy access to AS path, communities, etc.
683
684**Example transformation**:
685```text
686MRT Record with 3 prefixes → 3 BgpElem objects
687┌────────────────────────┐ ┌──────────────────┐
688│ BGP UPDATE Message │ │ BgpElem │
689│ AS Path: 64512 64513 │ ────────> │ prefix: P1 │
690│ Prefixes: │ │ as_path: 64512.. │
691│ - P1: 10.0.0.0/24 │ └──────────────────┘
692│ - P2: 10.0.1.0/24 │ ┌──────────────────┐
693│ - P3: 10.0.2.0/24 │ ────────> │ BgpElem │
694└────────────────────────┘ │ prefix: P2 │
695 │ as_path: 64512.. │
696 └──────────────────┘
697 ┌──────────────────┐
698 │ BgpElem │
699 ────────> │ prefix: P3 │
700 │ as_path: 64512.. │
701 └──────────────────┘
702```
703
704See the [BgpElem] documentation for the complete structure definition.
705
706**Key fields**:
707- `timestamp`: Unix timestamp of the BGP message
708- `elem_type`: Announcement or withdrawal
709- `peer_ip` / `peer_asn`: The BGP peer information
710- `prefix`: The IP prefix being announced or withdrawn
711- `as_path`: The AS path attribute (if present)
712- `origin_asns`: Origin AS numbers extracted from AS path
713- `communities`: BGP communities (standard, extended, and large)
714- `next_hop`, `local_pref`, `med`: Other BGP attributes
715
716**Iteration**: Use [`BgpkitParser::into_elem_iter()`] or default iteration to iterate over [BgpElem]s.
717
718## Which One Should I Use?
719
720| Use Case | Recommended | Why |
721|----------|-------------|-----|
722| Simple prefix analysis | [BgpElem] | Easy per-prefix access, format-agnostic |
723| High-performance processing | [MrtUpdate] | Avoids attribute duplication overhead |
724| Counting prefixes per UPDATE | [MrtUpdate] | Direct access to message structure |
725| Re-encoding MRT data | [MrtRecord] | Preserves complete MRT structure |
726| MRT format-specific details | [MrtRecord] | Access to peer index tables, geo-location, etc. |
727
728**Memory trade-off**:
729- [BgpElem] duplicates shared attributes (AS path, communities) for each prefix
730- [MrtUpdate] keeps attributes shared within each message/entry
731- [MrtRecord] has minimal overhead but requires more code to extract BGP data
732
733# RFCs Support
734
735BGPKIT Parser implements comprehensive BGP, MRT, BMP, and related protocol standards. All listed RFCs are fully supported.
736
737**Request a feature**: If you need support for a specific RFC not listed here, please [submit an issue on GitHub](https://github.com/bgpkit/bgpkit-parser/issues).
738
739## Core BGP Protocol
740
741**Most commonly used**:
742- [RFC 4271](https://datatracker.ietf.org/doc/html/rfc4271): A Border Gateway Protocol 4 (BGP-4) - Core protocol
743- [RFC 2858](https://datatracker.ietf.org/doc/html/rfc2858): Multiprotocol Extensions for BGP-4 (IPv6 support)
744- [RFC 6793](https://datatracker.ietf.org/doc/html/rfc6793): Four-Octet AS Number Space
745- [RFC 7911](https://datatracker.ietf.org/doc/html/rfc7911): Advertisement of Multiple Paths (ADD-PATH)
746
747**Additional BGP RFCs**:
748- [RFC 2042](https://datatracker.ietf.org/doc/html/rfc2042): Registering New BGP Attribute Types
749- [RFC 2918](https://datatracker.ietf.org/doc/html/rfc2918): Route Refresh Capability for BGP-4
750- [RFC 3392](https://datatracker.ietf.org/doc/html/rfc3392): Capabilities Advertisement with BGP-4
751- [RFC 4724](https://datatracker.ietf.org/doc/html/rfc4724): Graceful Restart Mechanism for BGP
752- [RFC 4456](https://datatracker.ietf.org/doc/html/rfc4456): BGP Route Reflection
753- [RFC 5065](https://datatracker.ietf.org/doc/html/rfc5065): Autonomous System Confederations for BGP
754- [RFC 5492](https://datatracker.ietf.org/doc/html/rfc5492): Capabilities Advertisement with BGP-4
755- [RFC 7606](https://datatracker.ietf.org/doc/html/rfc7606): Revised Error Handling for BGP UPDATE Messages
756- [RFC 8277](https://datatracker.ietf.org/doc/html/rfc8277): Using BGP to Bind MPLS Labels to Address Prefixes (obsoletes RFC 3107)
757- [RFC 8654](https://datatracker.ietf.org/doc/html/rfc8654): Extended Message Support for BGP
758- [RFC 8950](https://datatracker.ietf.org/doc/html/rfc8950): Advertising IPv4 NLRI with an IPv6 Next Hop
759- [RFC 9072](https://datatracker.ietf.org/doc/html/rfc9072): Extended Optional Parameters Length for BGP OPEN Message
760- [RFC 9234](https://datatracker.ietf.org/doc/html/rfc9234): Route Leak Prevention Using Roles in UPDATE and OPEN Messages
761
762## MRT (Multi-Threaded Routing Toolkit)
763
764- [RFC 6396](https://datatracker.ietf.org/doc/html/rfc6396): MRT Routing Information Export Format
765- [RFC 6397](https://datatracker.ietf.org/doc/html/rfc6397): MRT BGP Routing Information Export Format with Geo-Location Extensions
766- [RFC 8050](https://datatracker.ietf.org/doc/html/rfc8050): MRT Routing Information Export Format with BGP Additional Path Extensions
767
768## BMP (BGP Monitoring Protocol)
769
770- [RFC 7854](https://datatracker.ietf.org/doc/html/rfc7854): BGP Monitoring Protocol (BMP)
771- [RFC 8671](https://datatracker.ietf.org/doc/html/rfc8671): Support for Adj-RIB-Out in BMP
772- [RFC 9069](https://datatracker.ietf.org/doc/html/rfc9069): Support for Local RIB in BMP
773- [RFC 9515](https://datatracker.ietf.org/doc/html/rfc9515): Revision to Registration Procedures for Multiple BMP Registries
774- [RFC 9736](https://datatracker.ietf.org/doc/html/rfc9736): The BGP Monitoring Protocol (BMP) Peer Up Message Namespace
775- [RFC 9972](https://datatracker.ietf.org/doc/html/rfc9972): Advanced BGP Monitoring Protocol (BMP) Statistics Types
776
777## BGP Communities
778
779Full support for standard, extended, and large communities:
780- [RFC 1997](https://datatracker.ietf.org/doc/html/rfc1997): BGP Communities Attribute
781- [RFC 4360](https://datatracker.ietf.org/doc/html/rfc4360): BGP Extended Communities Attribute
782- [RFC 5668](https://datatracker.ietf.org/doc/html/rfc5668): 4-Octet AS Specific BGP Extended Community
783- [RFC 5701](https://datatracker.ietf.org/doc/html/rfc5701): IPv6 Address Specific BGP Extended Community Attribute
784- [RFC 7153](https://datatracker.ietf.org/doc/html/rfc7153): IANA Registries for BGP Extended Communities
785- [RFC 8097](https://datatracker.ietf.org/doc/html/rfc8097): BGP Prefix Origin Validation State Extended Community
786- [RFC 8092](https://datatracker.ietf.org/doc/html/rfc8092): BGP Large Communities
787
788## RPKI-to-Router (RTR) Protocol
789
790- [RFC 6810](https://datatracker.ietf.org/doc/html/rfc6810): The Resource Public Key Infrastructure (RPKI) to Router Protocol
791- [RFC 8210](https://datatracker.ietf.org/doc/html/rfc8210): The Resource Public Key Infrastructure (RPKI) to Router Protocol, Version 1
792
793## BGP Path Attributes
794
795Typed parsing for these RFC-defined BGP path attributes:
796
797- [RFC 7311](https://datatracker.ietf.org/doc/html/rfc7311): Accumulated IGP Metric (AIGP) Attribute
798- [RFC 9015](https://datatracker.ietf.org/doc/html/rfc9015): BGP SFP Attribute
799- [RFC 9026](https://datatracker.ietf.org/doc/html/rfc9026): BFD Discriminator Attribute
800- [RFC 8669](https://datatracker.ietf.org/doc/html/rfc8669): BGP Prefix-SID Attribute
801- [RFC 9793](https://datatracker.ietf.org/doc/html/rfc9793): BGP Extensions for BIER
802
803Additional known attribute type codes are raw-retained (`AttributeValue::Raw`) and re-encoded faithfully. Deprecated and unassigned codes are also preserved.
804
805## Advanced Features
806
807**FlowSpec**:
808- [RFC 8955](https://datatracker.ietf.org/doc/html/rfc8955): Dissemination of Flow Specification Rules
809- [RFC 8956](https://datatracker.ietf.org/doc/html/rfc8956): Dissemination of Flow Specification Rules for IPv6
810- [RFC 9117](https://datatracker.ietf.org/doc/html/rfc9117): Revised Validation Procedure for BGP Flow Specifications
811
812**Tunnel Encapsulation**:
813- [RFC 5640](https://datatracker.ietf.org/doc/html/rfc5640): Load-Balancing for Mesh Softwires
814- [RFC 8365](https://datatracker.ietf.org/doc/html/rfc8365): Ethernet VPN (EVPN)
815- [RFC 9012](https://datatracker.ietf.org/doc/html/rfc9012): BGP Tunnel Encapsulation Attribute
816
817**Link-State (BGP-LS)**:
818- [RFC 7752](https://datatracker.ietf.org/doc/html/rfc7752): North-Bound Distribution of Link-State and TE Information
819- [RFC 8571](https://datatracker.ietf.org/doc/html/rfc8571): BGP-LS Advertisement of IGP TE Performance Metric Extensions
820- [RFC 9085](https://datatracker.ietf.org/doc/html/rfc9085): BGP-LS Extensions for Segment Routing
821- [RFC 9294](https://datatracker.ietf.org/doc/html/rfc9294): BGP-LS Advertisement of Application-Specific Link Attributes
822
823# See Also
824
825## Related BGPKIT Projects
826
827- **[BGPKIT Broker](https://github.com/bgpkit/bgpkit-broker)**: Search and discover MRT data files from RouteViews and RIPE RIS
828- **[BGPKIT API](https://data.bgpkit.com)**: RESTful API for MRT data file discovery
829- **[Monocle](https://github.com/bgpkit/monocle)**: Real-time BGP monitoring and alerting
830- **[BGPKIT Commons](https://github.com/bgpkit/bgpkit-commons)**: Common data structures and utilities
831
832## Resources
833
834- **[GitHub Repository](https://github.com/bgpkit/bgpkit-parser)**: Source code, examples, and issue tracking
835- **[Documentation](https://docs.rs/bgpkit-parser)**: Full API documentation
836- **[Changelog](https://github.com/bgpkit/bgpkit-parser/blob/main/CHANGELOG.md)**: Version history and release notes
837
838## Community
839
840- **Questions?** Open a [GitHub Discussion](https://github.com/bgpkit/bgpkit-parser/discussions)
841- **Found a bug?** Submit a [GitHub Issue](https://github.com/bgpkit/bgpkit-parser/issues)
842
843*/
844
845#![doc(
846 html_logo_url = "https://raw.githubusercontent.com/bgpkit/assets/main/logos/icon-transparent.png",
847 html_favicon_url = "https://raw.githubusercontent.com/bgpkit/assets/main/logos/favicon.ico"
848)]
849
850#[cfg(feature = "parser")]
851pub mod encoder;
852pub mod error;
853pub mod models;
854#[cfg(feature = "parser")]
855pub mod parser;
856#[cfg(feature = "wasm")]
857pub mod wasm;
858
859pub use models::BgpElem;
860pub use models::BgpRouteElem;
861pub use models::MrtRecord;
862#[cfg(feature = "parser")]
863pub use parser::*;