use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::sync::Arc;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Interface {
pub name: String,
pub alias: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct InterfaceDetails {
pub name: String,
pub alias: Option<String>,
pub mac_address: [u8; 6],
pub local_chassis: Option<Arc<Chassis>>,
pub neighbors: Vec<Neighbor>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Neighbor {
pub chassis: Arc<Chassis>,
pub port_id_subtype: PortIdSubtype,
pub port_id: Vec<u8>,
pub port_description: Option<String>,
pub ttl: u16,
}
impl Neighbor {
pub fn port_id_str(&self) -> Option<&str> {
std::str::from_utf8(&self.port_id).ok()
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct NeighborChange {
pub interface: String,
pub interface_alias: Option<String>,
pub kind: NeighborChangeKind,
pub neighbor: Option<Neighbor>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum NeighborChangeKind {
Added,
Updated,
Deleted,
Other(i32),
}
impl From<i32> for NeighborChangeKind {
fn from(v: i32) -> Self {
match v {
1 => Self::Added,
0 => Self::Updated,
-1 => Self::Deleted,
other => Self::Other(other),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Chassis {
pub id_subtype: ChassisIdSubtype,
pub id: Vec<u8>,
pub name: Option<String>,
pub description: Option<String>,
pub capabilities_available: Capabilities,
pub capabilities_enabled: Capabilities,
pub management_addresses: Vec<ManagementAddress>,
pub med: MedInventory,
}
impl Chassis {
pub fn id_str(&self) -> Option<&str> {
std::str::from_utf8(&self.id).ok()
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct MedInventory {
pub hardware_revision: Option<String>,
pub firmware_revision: Option<String>,
pub software_revision: Option<String>,
pub serial_number: Option<String>,
pub manufacturer: Option<String>,
pub model: Option<String>,
pub asset_id: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ManagementAddress {
family: u32,
octets: Vec<u8>,
pub interface_index: u32,
}
impl ManagementAddress {
pub(crate) fn new(family: u32, octets: Vec<u8>, interface_index: u32) -> Self {
Self {
family,
octets,
interface_index,
}
}
pub fn ip(&self) -> Option<IpAddr> {
match self.family {
1 if self.octets.len() >= 4 => Some(IpAddr::V4(Ipv4Addr::new(
self.octets[0],
self.octets[1],
self.octets[2],
self.octets[3],
))),
2 if self.octets.len() >= 16 => {
let mut b = [0u8; 16];
b.copy_from_slice(&self.octets[..16]);
Some(IpAddr::V6(Ipv6Addr::from(b)))
}
_ => None,
}
}
pub fn raw_octets(&self) -> &[u8] {
&self.octets
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ChassisIdSubtype {
ChassisComponent,
IfAlias,
PortComponent,
MacAddress,
NetworkAddress,
IfName,
Local,
Other(u8),
}
impl From<u8> for ChassisIdSubtype {
fn from(v: u8) -> Self {
match v {
1 => Self::ChassisComponent,
2 => Self::IfAlias,
3 => Self::PortComponent,
4 => Self::MacAddress,
5 => Self::NetworkAddress,
6 => Self::IfName,
7 => Self::Local,
other => Self::Other(other),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PortIdSubtype {
Unknown,
IfAlias,
PortComponent,
MacAddress,
NetworkAddress,
IfName,
AgentCircuitId,
Local,
Other(u8),
}
impl From<u8> for PortIdSubtype {
fn from(v: u8) -> Self {
match v {
0 => Self::Unknown,
1 => Self::IfAlias,
2 => Self::PortComponent,
3 => Self::MacAddress,
4 => Self::NetworkAddress,
5 => Self::IfName,
6 => Self::AgentCircuitId,
7 => Self::Local,
other => Self::Other(other),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct Capabilities(pub u16);
impl Capabilities {
pub const OTHER: u16 = 0x0001;
pub const REPEATER: u16 = 0x0002;
pub const BRIDGE: u16 = 0x0004;
pub const WLAN_ACCESS_POINT: u16 = 0x0008;
pub const ROUTER: u16 = 0x0010;
pub const TELEPHONE: u16 = 0x0020;
pub const DOCSIS_CABLE_DEVICE: u16 = 0x0040;
pub const STATION_ONLY: u16 = 0x0080;
pub const CVLAN_COMPONENT: u16 = 0x0100;
pub const SVLAN_COMPONENT: u16 = 0x0200;
pub const TWO_PORT_MAC_RELAY: u16 = 0x0400;
pub fn contains(self, bit: u16) -> bool {
self.0 & bit == bit
}
}