use octseq::{Octets, Parser};
use crate::bgp::message::Header;
use crate::bgp::types::{Afi, AfiSafiType, RouteRefreshSubtype};
use crate::util::parser::ParseError;
#[derive(Clone, Debug)]
pub struct RouteRefreshMessage<Octets> {
octets: Octets,
afisafi: AfiSafiType,
subtype: RouteRefreshSubtype,
}
impl<Octs: Octets> RouteRefreshMessage<Octs> {
pub fn from_octets(octets: Octs) -> Result<Self, ParseError> {
let mut parser = Parser::from_ref(&octets);
{
let header = Header::parse(&mut parser)?;
if header.length() != 23 || parser.remaining() != 4 {
return Err(ParseError::form_error(
"ROUTEREFRESH of invalid size"
));
}
}
let afi = parser.parse_u16_be()?;
let subtype = parser.parse_u8()?.into();
let safi = parser.parse_u8()?;
let afisafi = (afi, safi).into();
Ok(RouteRefreshMessage { octets, afisafi, subtype })
}
pub fn octets(&self) -> &Octs {
&self.octets
}
}
impl<Octs> RouteRefreshMessage<Octs> {
pub fn afi(&self) -> Afi {
self.afisafi.afi()
}
pub fn afisafi(&self) -> AfiSafiType {
self.afisafi
}
pub fn subtype(&self) -> RouteRefreshSubtype {
self.subtype
}
}
impl<Octs: Octets> AsRef<[u8]> for RouteRefreshMessage<Octs> {
fn as_ref(&self) -> &[u8] {
self.octets.as_ref()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn from_octets() {
let raw = vec![
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x17, 0x05, 0x00, 0x01, 0x01, 0x01
];
let rr = RouteRefreshMessage::from_octets(&raw).unwrap();
assert_eq!(rr.afisafi(), AfiSafiType::Ipv4Unicast);
assert_eq!(rr.subtype(), RouteRefreshSubtype::Begin);
}
}