wl-nl80211 0.1.1

Linux kernel wireless(802.11) netlink Library
Documentation
// SPDX-License-Identifier: MIT

use anyhow::Context;
use byteorder::{ByteOrder, NativeEndian};
use netlink_packet_utils::{
    nla::{DefaultNla, Nla, NlaBuffer},
    parsers::parse_u32,
    DecodeError, Emitable, Parseable,
};

const NL80211_TXQ_STATS_BACKLOG_BYTES: u16 = 1;
const NL80211_TXQ_STATS_BACKLOG_PACKETS: u16 = 2;
const NL80211_TXQ_STATS_FLOWS: u16 = 3;
const NL80211_TXQ_STATS_DROPS: u16 = 4;
const NL80211_TXQ_STATS_ECN_MARKS: u16 = 5;
const NL80211_TXQ_STATS_OVERLIMIT: u16 = 6;
const NL80211_TXQ_STATS_OVERMEMORY: u16 = 7;
const NL80211_TXQ_STATS_COLLISIONS: u16 = 8;
const NL80211_TXQ_STATS_TX_BYTES: u16 = 9;
const NL80211_TXQ_STATS_TX_PACKETS: u16 = 10;
const NL80211_TXQ_STATS_MAX_FLOWS: u16 = 11;

#[derive(Debug, PartialEq, Eq, Clone)]
pub enum Nl80211TransmitQueueStat {
    BacklogBytes(u32),
    BacklogPackets(u32),
    Flows(u32),
    Drops(u32),
    EcnMarks(u32),
    Overlimit(u32),
    Overmemory(u32),
    Collisions(u32),
    TxBytes(u32),
    TxPackets(u32),
    MaxFlows(u32),
    Other(DefaultNla),
}

impl Nla for Nl80211TransmitQueueStat {
    fn value_len(&self) -> usize {
        match self {
            Self::BacklogBytes(_)
            | Self::BacklogPackets(_)
            | Self::Flows(_)
            | Self::Drops(_)
            | Self::EcnMarks(_)
            | Self::Overlimit(_)
            | Self::Overmemory(_)
            | Self::Collisions(_)
            | Self::TxBytes(_)
            | Self::TxPackets(_)
            | Self::MaxFlows(_) => 4,
            Self::Other(attr) => attr.value_len(),
        }
    }
    fn kind(&self) -> u16 {
        match self {
            Self::BacklogBytes(_) => NL80211_TXQ_STATS_BACKLOG_BYTES,
            Self::BacklogPackets(_) => NL80211_TXQ_STATS_BACKLOG_PACKETS,
            Self::Flows(_) => NL80211_TXQ_STATS_FLOWS,
            Self::Drops(_) => NL80211_TXQ_STATS_DROPS,
            Self::EcnMarks(_) => NL80211_TXQ_STATS_ECN_MARKS,
            Self::Overlimit(_) => NL80211_TXQ_STATS_OVERLIMIT,
            Self::Overmemory(_) => NL80211_TXQ_STATS_OVERMEMORY,
            Self::Collisions(_) => NL80211_TXQ_STATS_COLLISIONS,
            Self::TxBytes(_) => NL80211_TXQ_STATS_TX_BYTES,
            Self::TxPackets(_) => NL80211_TXQ_STATS_TX_PACKETS,
            Self::MaxFlows(_) => NL80211_TXQ_STATS_MAX_FLOWS,
            Self::Other(attr) => attr.kind(),
        }
    }
    fn emit_value(&self, buffer: &mut [u8]) {
        match self {
            Self::BacklogBytes(d)
            | Self::BacklogPackets(d)
            | Self::Flows(d)
            | Self::Drops(d)
            | Self::EcnMarks(d)
            | Self::Overlimit(d)
            | Self::Overmemory(d)
            | Self::Collisions(d)
            | Self::TxBytes(d)
            | Self::TxPackets(d)
            | Self::MaxFlows(d) => NativeEndian::write_u32(buffer, *d),
            Self::Other(ref attr) => attr.emit(buffer),
        }
    }
}

impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>>
    for Nl80211TransmitQueueStat
{
    fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
        let payload = buf.value();
        Ok(match buf.kind() {
            NL80211_TXQ_STATS_BACKLOG_BYTES => {
                let err_msg = format!(
                    "Invalid NL80211_TXQ_STATS_BACKLOG_BYTES value {:?}",
                    payload
                );
                Self::BacklogBytes(parse_u32(payload).context(err_msg)?)
            }
            NL80211_TXQ_STATS_BACKLOG_PACKETS => {
                let err_msg = format!(
                    "Invalid NL80211_TXQ_STATS_BACKLOG_PACKETS value: {:?}",
                    payload
                );
                Self::BacklogPackets(parse_u32(payload).context(err_msg)?)
            }

            NL80211_TXQ_STATS_FLOWS => {
                let err_msg = format!(
                    "Invalid NL80211_TXQ_STATS_FLOWS value: {:?}",
                    payload
                );
                Self::Flows(parse_u32(payload).context(err_msg)?)
            }

            NL80211_TXQ_STATS_DROPS => {
                let err_msg = format!(
                    "Invalid NL80211_TXQ_STATS_DROPS value: {:?}",
                    payload
                );
                Self::Drops(parse_u32(payload).context(err_msg)?)
            }

            NL80211_TXQ_STATS_ECN_MARKS => {
                let err_msg = format!(
                    "Invalid NL80211_TXQ_STATS_ECN_MARKS value: {:?}",
                    payload
                );
                Self::EcnMarks(parse_u32(payload).context(err_msg)?)
            }

            NL80211_TXQ_STATS_OVERLIMIT => {
                let err_msg = format!(
                    "Invalid NL80211_TXQ_STATS_OVERLIMIT value: {:?}",
                    payload
                );
                Self::Overlimit(parse_u32(payload).context(err_msg)?)
            }

            NL80211_TXQ_STATS_OVERMEMORY => {
                let err_msg = format!(
                    "Invalid NL80211_TXQ_STATS_OVERMEMORY value: {:?}",
                    payload
                );
                Self::Overmemory(parse_u32(payload).context(err_msg)?)
            }

            NL80211_TXQ_STATS_COLLISIONS => {
                let err_msg = format!(
                    "Invalid NL80211_TXQ_STATS_COLLISIONS value: {:?}",
                    payload
                );
                Self::Collisions(parse_u32(payload).context(err_msg)?)
            }

            NL80211_TXQ_STATS_TX_BYTES => {
                let err_msg = format!(
                    "Invalid NL80211_TXQ_STATS_TX_BYTES value: {:?}",
                    payload
                );
                Self::TxBytes(parse_u32(payload).context(err_msg)?)
            }

            NL80211_TXQ_STATS_TX_PACKETS => {
                let err_msg = format!(
                    "Invalid NL80211_TXQ_STATS_TX_PACKETS value: {:?}",
                    payload
                );
                Self::TxPackets(parse_u32(payload).context(err_msg)?)
            }

            NL80211_TXQ_STATS_MAX_FLOWS => {
                let err_msg = format!(
                    "Invalid NL80211_TXQ_STATS_MAX_FLOWS value: {:?}",
                    payload
                );
                Self::MaxFlows(parse_u32(payload).context(err_msg)?)
            }
            _ => Self::Other(
                DefaultNla::parse(buf).context("invalid NLA (unknown kind)")?,
            ),
        })
    }
}