async_snmp/handler/context.rs
1//! Request context for MIB handlers.
2//!
3//! This module provides [`RequestContext`], which contains information about
4//! incoming SNMP requests for use in handler authorization decisions.
5
6use std::net::SocketAddr;
7
8use bytes::Bytes;
9
10use crate::message::SecurityLevel;
11use crate::pdu::PduType;
12use crate::version::Version;
13
14use super::SecurityModel;
15
16/// Request context passed to MIB handlers.
17///
18/// Contains information about the incoming request for authorization decisions,
19/// including VACM-resolved access control information when VACM is enabled.
20///
21/// # Fields
22///
23/// The context provides:
24/// - **Request origin**: Source address and request ID
25/// - **Security info**: Version, model, level, and security name (community/username)
26/// - **VACM info**: Group name and view names (when VACM is configured)
27///
28/// # Example
29///
30/// ```rust
31/// use async_snmp::handler::{MibHandler, RequestContext, GetResult, BoxFuture};
32/// use async_snmp::{Oid, Value, oid};
33///
34/// struct LoggingHandler;
35///
36/// impl MibHandler for LoggingHandler {
37/// fn get<'a>(&'a self, ctx: &'a RequestContext, oid: &'a Oid) -> BoxFuture<'a, GetResult> {
38/// Box::pin(async move {
39/// // Log request details
40/// println!(
41/// "GET {} from {} (user: {:?}, version: {:?})",
42/// oid, ctx.source, ctx.security_name, ctx.version
43/// );
44///
45/// if oid == &oid!(1, 3, 6, 1, 4, 1, 99999, 1, 0) {
46/// GetResult::Value(Value::Integer(42))
47/// } else {
48/// GetResult::NoSuchObject
49/// }
50/// })
51/// }
52///
53/// fn get_next<'a>(
54/// &'a self,
55/// _ctx: &'a RequestContext,
56/// _oid: &'a Oid,
57/// ) -> BoxFuture<'a, async_snmp::handler::GetNextResult> {
58/// Box::pin(async { async_snmp::handler::GetNextResult::EndOfMibView })
59/// }
60/// }
61/// ```
62#[derive(Debug, Clone)]
63pub struct RequestContext {
64 /// Source address of the request.
65 ///
66 /// Use this for logging or additional access control beyond VACM.
67 pub source: SocketAddr,
68
69 /// SNMP version (V1, V2c, or V3).
70 pub version: Version,
71
72 /// Security model used for this request.
73 ///
74 /// - `V1` for SNMPv1 community-based
75 /// - `V2c` for SNMPv2c community-based
76 /// - `Usm` for SNMPv3 User-based Security Model
77 pub security_model: SecurityModel,
78
79 /// Security name (community string or USM username).
80 ///
81 /// For v1/v2c: the community string
82 /// For v3: the USM username
83 pub security_name: Bytes,
84
85 /// Security level (v3 only, NoAuthNoPriv for v1/v2c).
86 ///
87 /// Indicates whether authentication and/or privacy were used.
88 pub security_level: SecurityLevel,
89
90 /// Context name (v3 only, empty for v1/v2c).
91 ///
92 /// SNMPv3 contexts allow partitioning MIB views.
93 pub context_name: Bytes,
94
95 /// Request ID from the PDU.
96 ///
97 /// Useful for correlating requests with responses in logs.
98 pub request_id: i32,
99
100 /// PDU type (GetRequest, GetNextRequest, SetRequest, etc.).
101 pub pdu_type: PduType,
102
103 /// Resolved group name (if VACM enabled).
104 ///
105 /// Set when VACM successfully maps the security name to a group.
106 pub group_name: Option<Bytes>,
107
108 /// Read view name (if VACM enabled).
109 ///
110 /// The view that controls which OIDs can be read.
111 pub read_view: Option<Bytes>,
112
113 /// Write view name (if VACM enabled).
114 ///
115 /// The view that controls which OIDs can be written.
116 pub write_view: Option<Bytes>,
117}
118
119impl RequestContext {
120 /// Create a minimal context for unit testing.
121 pub fn test_context() -> Self {
122 use std::net::{IpAddr, Ipv4Addr, SocketAddr};
123
124 Self {
125 source: SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 0),
126 version: Version::V2c,
127 security_model: SecurityModel::V2c,
128 security_name: Bytes::from_static(b"public"),
129 security_level: SecurityLevel::NoAuthNoPriv,
130 context_name: Bytes::new(),
131 request_id: 1,
132 pdu_type: PduType::GetRequest,
133 group_name: None,
134 read_view: None,
135 write_view: None,
136 }
137 }
138}