bgpkit_parser/parser/bgp/attributes/
attr_07_18_aggregator.rs1use crate::models::*;
2use crate::parser::ReadUtils;
3use crate::ParserError;
4use bytes::{Buf, BufMut, Bytes, BytesMut};
5use log::warn;
6use std::net::IpAddr;
7
8pub fn parse_aggregator(
20 mut input: Bytes,
21 asn_len: &AsnLength,
22) -> Result<(Asn, BgpIdentifier), ParserError> {
23 let asn_len_found = match input.remaining() {
24 8 => AsnLength::Bits32,
25 6 => AsnLength::Bits16,
26 _ => {
27 return Err(ParserError::ParseError(format!(
28 "Aggregator attribute length is invalid: found {}, should 6 or 8",
29 input.remaining()
30 )))
31 }
32 };
33 if asn_len_found != *asn_len {
34 warn!(
35 "Aggregator attribute with ASN length set to {:?} but found {:?}",
36 asn_len, asn_len_found
37 );
38 }
39 let asn = input.read_asn(asn_len_found)?;
40
41 let identifier = input.read_ipv4_address()?;
43 Ok((asn, identifier))
44}
45
46pub fn encode_aggregator(asn: &Asn, addr: &IpAddr) -> Bytes {
47 let mut bytes = BytesMut::new();
48
49 bytes.extend(asn.encode());
50 match addr {
51 IpAddr::V4(ip) => bytes.put_u32((*ip).into()),
52 IpAddr::V6(ip) => {
53 bytes.put_u128((*ip).into());
54 }
55 }
56 bytes.freeze()
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62 use std::net::{Ipv4Addr, Ipv6Addr};
63 use std::str::FromStr;
64
65 #[test]
66 fn test_parse_aggregator() {
67 let identifier = Ipv4Addr::from_str("10.0.0.1").unwrap();
68 let mut data = vec![];
69 data.extend([1u8, 2]);
70 data.extend(identifier.octets());
71 let bytes = Bytes::from(data);
72
73 if let Ok((asn, n)) = parse_aggregator(bytes, &AsnLength::Bits16) {
74 assert_eq!(n, identifier);
75 assert_eq!(asn, Asn::new_16bit(258))
76 }
77
78 let mut data = vec![];
79 data.extend([0u8, 0, 1, 2]);
80 data.extend(identifier.octets());
81 let bytes = Bytes::from(data);
82
83 if let Ok((asn, n)) = parse_aggregator(bytes, &AsnLength::Bits32) {
84 assert_eq!(n, identifier);
85 assert_eq!(asn, Asn::new_32bit(258))
86 }
87
88 let mut data = vec![];
90 data.extend([0u8, 0, 1, 2, 3]);
91 data.extend(identifier.octets());
92 let bytes = Bytes::from(data);
93 assert!(parse_aggregator(bytes, &AsnLength::Bits32).is_err());
94
95 let mut data = vec![];
97 data.extend([0u8, 0, 1, 2, 3, 4]); data.extend(identifier.octets());
99 let bytes = Bytes::from(data);
100 assert!(parse_aggregator(bytes, &AsnLength::Bits32).is_err());
101 }
102
103 #[test]
104 fn test_encode_aggregator() {
105 let ipv4 = Ipv4Addr::from_str("10.0.0.1").unwrap();
106 let asn = Asn::new_16bit(258);
107 let bytes = encode_aggregator(&asn, &ipv4.into());
108 assert_eq!(bytes, Bytes::from_static(&[1u8, 2, 10, 0, 0, 1]));
109
110 let ipv6 = Ipv6Addr::from_str("fc00::1").unwrap();
111 let asn = Asn::new_32bit(258);
112 let bytes = encode_aggregator(&asn, &ipv6.into());
113 assert_eq!(
114 bytes,
115 Bytes::from_static(&[
116 0u8, 0, 1, 2, 0xfc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x01
117 ])
118 );
119 }
120}