async_snmp/message/
mod.rs1mod community;
11mod v3;
12
13pub use community::CommunityMessage;
14pub use v3::{
15 MsgFlags, MsgGlobalData, ScopedPdu, SecurityLevel, SecurityModel, V3Message, V3MessageData,
16};
17
18use crate::ber::Decoder;
19use crate::error::internal::DecodeErrorKind;
20use crate::error::{Error, Result, UNKNOWN_TARGET};
21use crate::pdu::Pdu;
22use crate::version::Version;
23use bytes::Bytes;
24
25#[derive(Debug)]
30pub enum Message {
31 Community(CommunityMessage),
33 V3(V3Message),
35}
36
37impl Message {
38 pub fn pdu(&self) -> &Pdu {
43 match self {
44 Message::Community(m) => &m.pdu,
45 Message::V3(m) => m.pdu().expect("V3 message is encrypted; use try_pdu()"),
46 }
47 }
48
49 pub fn try_pdu(&self) -> Option<&Pdu> {
53 match self {
54 Message::Community(m) => Some(&m.pdu),
55 Message::V3(m) => m.pdu(),
56 }
57 }
58
59 pub fn into_pdu(self) -> Pdu {
64 match self {
65 Message::Community(m) => m.into_pdu(),
66 Message::V3(m) => m.into_pdu().expect("V3 message is encrypted"),
67 }
68 }
69
70 pub fn try_into_pdu(self) -> Option<Pdu> {
74 match self {
75 Message::Community(m) => Some(m.into_pdu()),
76 Message::V3(m) => m.into_pdu(),
77 }
78 }
79
80 pub fn version(&self) -> Version {
82 match self {
83 Message::Community(m) => m.version,
84 Message::V3(_) => Version::V3,
85 }
86 }
87
88 pub fn decode(data: Bytes) -> Result<Self> {
92 let mut decoder = Decoder::new(data);
93 let mut seq = decoder.read_sequence()?;
94
95 let version_num = seq.read_integer()?;
97 let version = Version::from_i32(version_num).ok_or_else(|| {
98 tracing::debug!(target: "async_snmp::ber", { offset = seq.offset(), kind = %DecodeErrorKind::UnknownVersion(version_num) }, "decode error");
99 Error::MalformedResponse {
100 target: UNKNOWN_TARGET,
101 }
102 .boxed()
103 })?;
104
105 match version {
107 Version::V1 | Version::V2c => {
108 let msg = CommunityMessage::decode_from_sequence(&mut seq, version)?;
109 Ok(Message::Community(msg))
110 }
111 Version::V3 => {
112 let msg = V3Message::decode_from_sequence(&mut seq)?;
113 Ok(Message::V3(msg))
114 }
115 }
116 }
117}
118
119impl From<CommunityMessage> for Message {
121 fn from(msg: CommunityMessage) -> Self {
122 Message::Community(msg)
123 }
124}
125
126impl From<V3Message> for Message {
127 fn from(msg: V3Message) -> Self {
128 Message::V3(msg)
129 }
130}