Rust使用bgpkit_parser解析BGP数据提取逗号分隔ASN值
解决方案
你无法继续提取ASN的核心原因是AsPathSegment是枚举类型,不做模式匹配无法访问其内部存储的Vec<Asn>;另外硬编码取segments[0]的写法存在panic风险,真实BGP数据中AS_PATH可能包含多段不同类型的段。
完整实现代码如下,处理逻辑兼容所有AS_PATH段类型,输出为你需要的逗号分隔ASN格式:
use bgpkit_parser::{BgpkitParser, AsPathSegment}; fn main() { let url: &str = "http://archive.routeviews.org/\ route-views.chile/bgpdata/2022.06/UPDATES/updates.20220601.0000.bz2"; let parser = BgpkitParser::new(url).unwrap(); for elem in parser { // 跳过不存在AS_PATH的BGP条目 let Some(as_path) = elem.as_path else { continue }; let mut asn_collect: Vec<u32> = Vec::new(); for seg in as_path.segments { match seg { // 常规AS序列段,提取所有ASN加入结果列表 AsPathSegment::AsSequence(asn_vec) => { asn_collect.extend(asn_vec.into_iter().map(|a| a.asn)) } // AS集合段:按常规路由规则集合段仅代表聚合路径,默认取第一个ASN输出,需要展开全量ASN可修改为和Sequence一致的逻辑 AsPathSegment::AsSet(asn_vec) => { // 全量输出AS_SET内容时打开下方注释即可 // asn_collect.extend(asn_vec.into_iter().map(|a| a.asn)) if let Some(first) = asn_vec.first() { asn_collect.push(first.asn) } } // 联邦AS段不属于公网AS_PATH范畴,直接跳过 AsPathSegment::ConfedSequence(_) | AsPathSegment::ConfedSet(_) => {} } } // 拼接为逗号分隔字符串输出 let res = asn_collect .iter() .map(|n| n.to_string()) .collect::<Vec<_>>() .join(", "); println!("{}", res); } }
注意:如果你不需要处理AS_SET、联邦段等特殊AS_PATH类型,且确定你的数据源所有AS_PATH第一个段都是AsSequence类型,也可以简化写法,直接对segments[0]做模式匹配取ASN即可,但生产环境解析公开BGP数据不建议这么写。
针对你给出的示例AS_PATH,上述代码的输出完全符合预期:27678, 27986, 262589, 32098。
内容的提问来源于stack exchange,提问作者e110
相关产品推荐
相关产品推荐

