use netlink_packet_core::{
NetlinkDeserializable, NetlinkHeader, NetlinkPayload, NetlinkSerializable,
};
use netlink_packet_utils::{
traits::{Emitable, ParseableParametrized},
DecodeError,
};
use crate::{constants::*, rules::RuleMessage, AuditBuffer, StatusMessage};
#[derive(Debug, PartialEq, Eq, Clone)]
#[non_exhaustive]
pub enum AuditMessage {
GetStatus(Option<StatusMessage>),
SetStatus(StatusMessage),
AddRule(RuleMessage),
DelRule(RuleMessage),
ListRules(Option<RuleMessage>),
Event((u16, String)),
Other((u16, String)),
}
impl AuditMessage {
pub fn is_event(&self) -> bool {
matches!(self, AuditMessage::Event(_))
}
pub fn is_get_status(&self) -> bool {
matches!(self, AuditMessage::GetStatus(_))
}
pub fn is_set_status(&self) -> bool {
matches!(self, AuditMessage::GetStatus(_))
}
pub fn is_add_rule(&self) -> bool {
matches!(self, AuditMessage::AddRule(_))
}
pub fn is_del_rule(&self) -> bool {
matches!(self, AuditMessage::DelRule(_))
}
pub fn is_list_rules(&self) -> bool {
matches!(self, AuditMessage::ListRules(_))
}
pub fn message_type(&self) -> u16 {
use self::AuditMessage::*;
match self {
GetStatus(_) => AUDIT_GET,
SetStatus(_) => AUDIT_SET,
ListRules(_) => AUDIT_LIST_RULES,
AddRule(_) => AUDIT_ADD_RULE,
DelRule(_) => AUDIT_DEL_RULE,
Event((message_type, _)) => *message_type,
Other((message_type, _)) => *message_type,
}
}
}
impl Emitable for AuditMessage {
fn buffer_len(&self) -> usize {
use self::AuditMessage::*;
match self {
GetStatus(Some(ref msg)) => msg.buffer_len(),
SetStatus(ref msg) => msg.buffer_len(),
AddRule(ref msg) => msg.buffer_len(),
DelRule(ref msg) => msg.buffer_len(),
ListRules(Some(ref msg)) => msg.buffer_len(),
GetStatus(None) | ListRules(None) => 0,
Event((_, ref data)) => data.len(),
Other((_, ref data)) => data.len(),
}
}
fn emit(&self, buffer: &mut [u8]) {
use self::AuditMessage::*;
match self {
GetStatus(Some(ref msg)) => msg.emit(buffer),
SetStatus(ref msg) => msg.emit(buffer),
AddRule(ref msg) => msg.emit(buffer),
DelRule(ref msg) => msg.emit(buffer),
ListRules(Some(ref msg)) => msg.emit(buffer),
ListRules(None) | GetStatus(None) => {}
Event((_, ref data)) => buffer.copy_from_slice(data.as_bytes()),
Other((_, ref data)) => buffer.copy_from_slice(data.as_bytes()),
}
}
}
impl NetlinkSerializable for AuditMessage {
fn message_type(&self) -> u16 {
self.message_type()
}
fn buffer_len(&self) -> usize {
<Self as Emitable>::buffer_len(self)
}
fn serialize(&self, buffer: &mut [u8]) {
self.emit(buffer)
}
}
impl NetlinkDeserializable for AuditMessage {
type Error = DecodeError;
fn deserialize(
header: &NetlinkHeader,
payload: &[u8],
) -> Result<Self, Self::Error> {
match AuditBuffer::new_checked(payload) {
Err(e) => Err(e),
Ok(buffer) => match AuditMessage::parse_with_param(
&buffer,
header.message_type,
) {
Err(e) => Err(e),
Ok(message) => Ok(message),
},
}
}
}
impl From<AuditMessage> for NetlinkPayload<AuditMessage> {
fn from(message: AuditMessage) -> Self {
NetlinkPayload::InnerMessage(message)
}
}