netlink-packet-netfilter 0.2.0

netlink packet types for the netfilter subprotocol
Documentation
// SPDX-License-Identifier: MIT

use netlink_packet_utils::{
    nla::DefaultNla, DecodeError, Emitable, Parseable, ParseableParametrized,
};

use crate::{
    buffer::NetfilterBuffer,
    constants::{NFNL_SUBSYS_ULOG, NFULNL_MSG_CONFIG, NFULNL_MSG_PACKET},
    nflog::nlas::{config::ConfigNla, packet::PacketNla},
};

#[derive(Debug, PartialEq, Eq, Clone)]
pub enum NfLogMessage {
    Config(Vec<ConfigNla>),
    Packet(Vec<PacketNla>),
    Other {
        message_type: u8,
        nlas: Vec<DefaultNla>,
    },
}

impl NfLogMessage {
    pub const SUBSYS: u8 = NFNL_SUBSYS_ULOG;

    pub fn message_type(&self) -> u8 {
        match self {
            NfLogMessage::Config(_) => NFULNL_MSG_CONFIG,
            NfLogMessage::Packet(_) => NFULNL_MSG_PACKET,
            NfLogMessage::Other { message_type, .. } => *message_type,
        }
    }
}

impl Emitable for NfLogMessage {
    fn buffer_len(&self) -> usize {
        match self {
            NfLogMessage::Config(nlas) => nlas.as_slice().buffer_len(),
            NfLogMessage::Packet(nlas) => nlas.as_slice().buffer_len(),
            NfLogMessage::Other { nlas, .. } => nlas.as_slice().buffer_len(),
        }
    }

    fn emit(&self, buffer: &mut [u8]) {
        match self {
            NfLogMessage::Config(nlas) => nlas.as_slice().emit(buffer),
            NfLogMessage::Packet(nlas) => nlas.as_slice().emit(buffer),
            NfLogMessage::Other { nlas, .. } => nlas.as_slice().emit(buffer),
        };
    }
}

impl<'a, T: AsRef<[u8]> + ?Sized>
    ParseableParametrized<NetfilterBuffer<&'a T>, u8> for NfLogMessage
{
    fn parse_with_param(
        buf: &NetfilterBuffer<&'a T>,
        message_type: u8,
    ) -> Result<Self, DecodeError> {
        Ok(match message_type {
            NFULNL_MSG_CONFIG => {
                let nlas =
                    buf.parse_all_nlas(|nla_buf| ConfigNla::parse(&nla_buf))?;
                NfLogMessage::Config(nlas)
            }
            NFULNL_MSG_PACKET => {
                let nlas =
                    buf.parse_all_nlas(|nla_buf| PacketNla::parse(&nla_buf))?;
                NfLogMessage::Packet(nlas)
            }
            _ => NfLogMessage::Other {
                message_type,
                nlas: buf.default_nlas()?,
            },
        })
    }
}