162 lines
4.4 KiB
Rust
162 lines
4.4 KiB
Rust
//! Types for handling network interface link state information
|
|
|
|
use core::fmt;
|
|
|
|
use abi_serde::{
|
|
des::{DeserializeError, Deserializer},
|
|
ser::Serializer,
|
|
Deserialize, Serialize,
|
|
};
|
|
|
|
use crate::primitive_enum;
|
|
|
|
primitive_enum! {
|
|
/// Defines an Ethernet link speed
|
|
pub enum EthernetSpeed: u8 {
|
|
/// 1Gbps link
|
|
Speed1000 = 3,
|
|
/// 100Mbps link
|
|
Speed100 = 2,
|
|
/// 10Mbps link
|
|
Speed10 = 1,
|
|
/// Link speed not available/unknown
|
|
Unknown = 0,
|
|
}
|
|
[with_serde]
|
|
}
|
|
|
|
primitive_enum! {
|
|
/// Defines whether an Ethernet link is capable of transmiting data both ways simultaneously
|
|
pub enum Duplex: u32 {
|
|
/// Half-duplex mode
|
|
Half = 1,
|
|
/// Full-duplex mode
|
|
Full = 2,
|
|
/// Duplex mode information not available/unknown
|
|
Unknown = 0,
|
|
}
|
|
[with_serde]
|
|
}
|
|
|
|
/// Represents the state of an Ethernet link
|
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
|
pub enum EthernetLinkState {
|
|
/// Link is up, fields indicate the link configuration
|
|
Up(EthernetSpeed, Duplex),
|
|
/// Link is down
|
|
Down,
|
|
}
|
|
|
|
/// Represents the state of network interface's link
|
|
#[derive(Debug, Clone, PartialEq)]
|
|
pub enum LinkState {
|
|
/// Ethernet link state
|
|
Ethernet(EthernetLinkState),
|
|
/// Any other device, just indicates whether the link is up or down
|
|
Other {
|
|
/// If `true`, the link is up
|
|
up: bool,
|
|
},
|
|
}
|
|
|
|
impl Serialize for EthernetLinkState {
|
|
fn serialize<S: Serializer>(&self, serializer: &mut S) -> Result<(), S::Error> {
|
|
match self {
|
|
Self::Up(speed, duplex) => {
|
|
serializer.write_u8(0x01)?;
|
|
speed.serialize(serializer)?;
|
|
duplex.serialize(serializer)
|
|
}
|
|
Self::Down => serializer.write_u8(0x00),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Serialize for LinkState {
|
|
fn serialize<S: Serializer>(&self, serializer: &mut S) -> Result<(), S::Error> {
|
|
match self {
|
|
Self::Ethernet(state) => {
|
|
serializer.write_u8(0xEE)?;
|
|
state.serialize(serializer)
|
|
}
|
|
Self::Other { up } => {
|
|
serializer.write_u8(0xFF)?;
|
|
up.serialize(serializer)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'de> Deserialize<'de> for EthernetLinkState {
|
|
fn deserialize<D: Deserializer<'de>>(deserializer: &mut D) -> Result<Self, D::Error> {
|
|
match deserializer.read_u8()? {
|
|
0x01 => {
|
|
let speed = EthernetSpeed::deserialize(deserializer)?;
|
|
let duplex = Duplex::deserialize(deserializer)?;
|
|
Ok(Self::Up(speed, duplex))
|
|
}
|
|
0x00 => Ok(Self::Down),
|
|
_ => Err(D::Error::INVALID_ENUM_VARIANT),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'de> Deserialize<'de> for LinkState {
|
|
fn deserialize<D: Deserializer<'de>>(deserializer: &mut D) -> Result<Self, D::Error> {
|
|
match deserializer.read_u8()? {
|
|
0xEE => EthernetLinkState::deserialize(deserializer).map(Self::Ethernet),
|
|
0xFF => {
|
|
let up = bool::deserialize(deserializer)?;
|
|
Ok(Self::Other { up })
|
|
}
|
|
_ => Err(D::Error::INVALID_ENUM_VARIANT),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for EthernetSpeed {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
let text = match self {
|
|
Self::Speed10 => "10Mbps",
|
|
Self::Speed100 => "100Mbps",
|
|
Self::Speed1000 => "1Gbps",
|
|
Self::Unknown => "N/A",
|
|
};
|
|
f.write_str(text)
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for Duplex {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
let text = match self {
|
|
Self::Half => "half-duplex",
|
|
Self::Full => "full-duplex",
|
|
Self::Unknown => "N/A duplex mode",
|
|
};
|
|
f.write_str(text)
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for EthernetLinkState {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
match self {
|
|
Self::Up(speed, duplex) => {
|
|
write!(f, "up, speed {speed}, {duplex}")
|
|
}
|
|
Self::Down => {
|
|
write!(f, "down")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for LinkState {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
match self {
|
|
Self::Other { up: true } => write!(f, "up"),
|
|
Self::Other { up: false } => write!(f, "down"),
|
|
Self::Ethernet(ethernet) => fmt::Display::fmt(ethernet, f),
|
|
}
|
|
}
|
|
}
|