use std::net::IpAddr;
use bitflags::bitflags;
use bytes::Bytes;
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[non_exhaustive]
pub struct CdpMessage {
pub version: u8,
pub ttl_seconds: u8,
pub device_id: Option<Bytes>,
pub addresses: Vec<CdpAddress>,
pub port_id: Option<Bytes>,
pub capabilities: Option<CdpCapabilities>,
pub software_version: Option<Bytes>,
pub platform: Option<Bytes>,
pub native_vlan: Option<u16>,
pub duplex: Option<u8>,
pub vtp_domain: Option<Bytes>,
pub management_addresses: Vec<CdpAddress>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[non_exhaustive]
pub struct CdpAddress {
pub protocol_type: u8,
pub ip: Option<IpAddr>,
pub raw_address: Bytes,
}
bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct CdpCapabilities: u32 {
const ROUTER = 1 << 0;
const BRIDGE = 1 << 1;
const SOURCE_BRIDGE = 1 << 2;
const SWITCH = 1 << 3;
const HOST = 1 << 4;
const IGMP = 1 << 5;
const REPEATER = 1 << 6;
const PHONE = 1 << 7;
const REMOTELY_MANAGED = 1 << 8;
}
}
#[cfg(feature = "serde")]
impl serde::Serialize for CdpCapabilities {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_u32(self.bits())
}
}
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for CdpCapabilities {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let bits = <u32 as serde::Deserialize>::deserialize(deserializer)?;
Ok(CdpCapabilities::from_bits_truncate(bits))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn capability_bits_layout() {
assert_eq!(CdpCapabilities::ROUTER.bits(), 0x01);
assert_eq!(CdpCapabilities::SWITCH.bits(), 0x08);
assert_eq!(CdpCapabilities::PHONE.bits(), 0x80);
}
}