mod community;
mod v3;
pub use community::{CommunityMessage, CommunityPdu};
pub use v3::{
MsgFlags, MsgGlobalData, ScopedPdu, SecurityLevel, SecurityModel, V3Message, V3MessageData,
};
use crate::ber::Decoder;
use crate::error::internal::DecodeErrorKind;
use crate::error::{Error, Result, UNKNOWN_TARGET};
use crate::pdu::Pdu;
use crate::version::Version;
use bytes::Bytes;
#[derive(Debug)]
pub enum Message {
Community(CommunityMessage),
V3(V3Message),
}
impl Message {
pub fn pdu(&self) -> Option<&Pdu> {
match self {
Message::Community(m) => m.pdu.standard(),
Message::V3(m) => m.pdu(),
}
}
pub fn into_pdu(self) -> Option<Pdu> {
match self {
Message::Community(m) => match m.pdu {
CommunityPdu::Standard(p) => Some(p),
CommunityPdu::TrapV1(_) => None,
},
Message::V3(m) => m.into_pdu(),
}
}
pub fn version(&self) -> Version {
match self {
Message::Community(m) => m.version,
Message::V3(_) => Version::V3,
}
}
pub fn decode(data: Bytes) -> Result<Self> {
let mut decoder = Decoder::new(data);
let mut seq = decoder.read_sequence()?;
let version_num = seq.read_integer()?;
let version = Version::from_i32(version_num).ok_or_else(|| {
tracing::debug!(target: "async_snmp::ber", { offset = seq.offset(), kind = %DecodeErrorKind::UnknownVersion(version_num) }, "decode error");
Error::MalformedResponse {
target: UNKNOWN_TARGET,
}
.boxed()
})?;
match version {
Version::V1 | Version::V2c => {
let msg = CommunityMessage::decode_from_sequence(&mut seq, version)?;
Ok(Message::Community(msg))
}
Version::V3 => {
let msg = V3Message::decode_from_sequence(&mut seq)?;
Ok(Message::V3(msg))
}
}
}
}
impl From<CommunityMessage> for Message {
fn from(msg: CommunityMessage) -> Self {
Message::Community(msg)
}
}
impl From<V3Message> for Message {
fn from(msg: V3Message) -> Self {
Message::V3(msg)
}
}