use crate::message::attributes::*;
#[cfg(feature = "serialization")]
use serde::{Deserialize, Serialize};
use std::net::IpAddr;
#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[cfg(feature = "serialization")]
#[derive(Serialize, Deserialize)]
#[serde(transparent)]
pub struct BgpOriginatorID {
pub value: IpAddr,
}
impl BgpOriginatorID {
pub fn new(o: IpAddr) -> BgpOriginatorID {
BgpOriginatorID { value: o }
}
pub fn decode_from(peer: &BgpSessionParams, buf: &[u8]) -> Result<BgpOriginatorID, BgpError> {
match peer.peer_mode {
BgpTransportMode::IPv4 => Ok(BgpOriginatorID {
value: decode_addr_from(&buf[..4])?,
}),
BgpTransportMode::IPv6 => Ok(BgpOriginatorID {
value: if buf.len() < 16 {
decode_addr_from(&buf[..4])?
} else {
decode_addr_from(&buf[..16])?
},
}),
}
}
}
impl std::fmt::Debug for BgpOriginatorID {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("BgpOriginatorID")
.field("value", &self.value)
.finish()
}
}
impl std::fmt::Display for BgpOriginatorID {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.value)
}
}
impl BgpAttr for BgpOriginatorID {
fn attr(&self) -> BgpAttrParams {
BgpAttrParams {
typecode: 9,
flags: 0x80,
}
}
fn encode_to(&self, peer: &BgpSessionParams, buf: &mut [u8]) -> Result<usize, BgpError> {
match peer.peer_mode {
BgpTransportMode::IPv4 => {
if let IpAddr::V4(ref a) = self.value {
encode_addrv4_to(a, buf)
} else {
Err(BgpError::static_str("Invalid originatorid kind"))
}
}
BgpTransportMode::IPv6 => {
if let IpAddr::V6(ref a) = self.value {
encode_addrv6_to(a, buf)
} else {
Err(BgpError::static_str("Invalid originatorid kind"))
}
}
}
}
}