pub struct AgentBuilder { /* private fields */ }Expand description
Builder for Agent.
Use this builder to configure and construct an SNMP agent. The builder
pattern allows you to chain configuration methods before calling
build() to create the agent.
§Minimal Example
use async_snmp::agent::Agent;
use async_snmp::handler::{MibHandler, RequestContext, GetResult, GetNextResult, BoxFuture};
use async_snmp::{Oid, Value, VarBind, oid};
use std::sync::Arc;
struct MyHandler;
impl MibHandler for MyHandler {
fn get<'a>(&'a self, _: &'a RequestContext, _: &'a Oid) -> BoxFuture<'a, GetResult> {
Box::pin(async { GetResult::NoSuchObject })
}
fn get_next<'a>(&'a self, _: &'a RequestContext, _: &'a Oid) -> BoxFuture<'a, GetNextResult> {
Box::pin(async { GetNextResult::EndOfMibView })
}
}
let agent = Agent::builder()
.bind("0.0.0.0:1161") // Use non-privileged port
.community(b"public")
.handler(oid!(1, 3, 6, 1, 4, 1, 99999), Arc::new(MyHandler))
.build()
.await?;Implementations§
Source§impl AgentBuilder
impl AgentBuilder
Sourcepub fn new() -> Self
pub fn new() -> Self
Create a new builder with default settings.
Defaults:
- Bind address:
0.0.0.0:161(UDP) - Max message size: 1472 bytes (Ethernet MTU - IP/UDP headers)
- No communities or USM users (all requests rejected)
- No handlers registered
Sourcepub fn bind(self, addr: impl Into<String>) -> Self
pub fn bind(self, addr: impl Into<String>) -> Self
Set the UDP bind address.
Default is 0.0.0.0:161 (standard SNMP agent port). Note that binding
to UDP port 161 typically requires root/administrator privileges.
§IPv4 Examples
use async_snmp::agent::Agent;
// Bind to all IPv4 interfaces on standard port (requires privileges)
let agent = Agent::builder().bind("0.0.0.0:161").community(b"public").build().await?;
// Bind to localhost only on non-privileged port
let agent = Agent::builder().bind("127.0.0.1:1161").community(b"public").build().await?;
// Bind to specific interface
let agent = Agent::builder().bind("192.168.1.100:161").community(b"public").build().await?;§IPv6 / Dual-Stack Examples
use async_snmp::agent::Agent;
// Bind to all interfaces via dual-stack (handles both IPv4 and IPv6)
let agent = Agent::builder().bind("[::]:161").community(b"public").build().await?;
// Bind to IPv6 localhost only
let agent = Agent::builder().bind("[::1]:1161").community(b"public").build().await?;Sourcepub fn community(self, community: &[u8]) -> Self
pub fn community(self, community: &[u8]) -> Self
Add an accepted community string for v1/v2c requests.
Multiple communities can be added. If none are added, all v1/v2c requests are rejected.
§Example
use async_snmp::agent::Agent;
let agent = Agent::builder()
.bind("0.0.0.0:1161")
.community(b"public") // Read-only access
.community(b"private") // Read-write access (with VACM)
.build()
.await?;Sourcepub fn communities<I, C>(self, communities: I) -> Self
pub fn communities<I, C>(self, communities: I) -> Self
Add multiple community strings.
§Example
use async_snmp::agent::Agent;
let communities = ["public", "private", "monitor"];
let agent = Agent::builder()
.bind("0.0.0.0:1161")
.communities(communities)
.build()
.await?;Sourcepub fn usm_user<F>(self, username: impl Into<Bytes>, configure: F) -> Self
pub fn usm_user<F>(self, username: impl Into<Bytes>, configure: F) -> Self
Add a USM user for SNMPv3 authentication.
Configure authentication and privacy settings using the closure. Multiple users can be added with different security levels.
§Security Levels
- noAuthNoPriv: No authentication or encryption (not recommended)
- authNoPriv: Authentication only (HMAC verification)
- authPriv: Authentication and encryption (most secure)
§Example
use async_snmp::agent::Agent;
use async_snmp::{AuthProtocol, PrivProtocol};
let agent = Agent::builder()
.bind("0.0.0.0:1161")
// Read-only user with authentication only
.usm_user("monitor", |u| {
u.auth(AuthProtocol::Sha256, b"monitorpass123")
})
// Admin user with full encryption
.usm_user("admin", |u| {
u.auth(AuthProtocol::Sha256, b"adminauth123")
.privacy(PrivProtocol::Aes128, b"adminpriv123")
})
.build()
.await?;Sourcepub fn engine_id(self, engine_id: impl Into<Vec<u8>>) -> Self
pub fn engine_id(self, engine_id: impl Into<Vec<u8>>) -> Self
Set the engine ID for SNMPv3.
If not set, a default engine ID will be generated based on the RFC 3411 format using enterprise number and timestamp.
§Example
use async_snmp::agent::Agent;
let agent = Agent::builder()
.bind("0.0.0.0:1161")
.engine_id(b"\x80\x00\x00\x00\x01MyEngine".to_vec())
.community(b"public")
.build()
.await?;Sourcepub fn max_message_size(self, size: usize) -> Self
pub fn max_message_size(self, size: usize) -> Self
Set the maximum message size for responses.
Default is 1472 octets (fits Ethernet MTU minus IP/UDP headers). GETBULK responses will be truncated to fit within this limit.
For SNMPv3 requests, the agent uses the minimum of this value and the msgMaxSize from the request.
Sourcepub fn handler(self, prefix: Oid, handler: Arc<dyn MibHandler>) -> Self
pub fn handler(self, prefix: Oid, handler: Arc<dyn MibHandler>) -> Self
Register a MIB handler for an OID subtree.
Handlers are matched by longest prefix. When a request comes in, the handler with the longest matching prefix is used.
§Example
use async_snmp::agent::Agent;
use async_snmp::handler::{MibHandler, RequestContext, GetResult, GetNextResult, BoxFuture};
use async_snmp::{Oid, Value, VarBind, oid};
use std::sync::Arc;
struct SystemHandler;
impl MibHandler for SystemHandler {
fn get<'a>(&'a self, _: &'a RequestContext, oid: &'a Oid) -> BoxFuture<'a, GetResult> {
Box::pin(async move {
if oid == &oid!(1, 3, 6, 1, 2, 1, 1, 1, 0) {
GetResult::Value(Value::OctetString("My Agent".into()))
} else {
GetResult::NoSuchObject
}
})
}
fn get_next<'a>(&'a self, _: &'a RequestContext, _: &'a Oid) -> BoxFuture<'a, GetNextResult> {
Box::pin(async { GetNextResult::EndOfMibView })
}
}
let agent = Agent::builder()
.bind("0.0.0.0:1161")
.community(b"public")
// Register handler for system MIB subtree
.handler(oid!(1, 3, 6, 1, 2, 1, 1), Arc::new(SystemHandler))
.build()
.await?;Sourcepub fn vacm<F>(self, configure: F) -> Self
pub fn vacm<F>(self, configure: F) -> Self
Configure VACM (View-based Access Control Model) using a builder function.
When VACM is enabled, all requests are checked against the configured
access control rules. Requests that don’t have proper access are rejected
with noAccess error (v2c/v3) or noSuchName (v1).
§Example
use async_snmp::agent::{Agent, SecurityModel, VacmBuilder};
use async_snmp::message::SecurityLevel;
use async_snmp::oid;
let agent = Agent::builder()
.bind("0.0.0.0:161")
.community(b"public")
.community(b"private")
.vacm(|v| v
.group("public", SecurityModel::V2c, "readonly_group")
.group("private", SecurityModel::V2c, "readwrite_group")
.access("readonly_group", |a| a
.read_view("full_view"))
.access("readwrite_group", |a| a
.read_view("full_view")
.write_view("write_view"))
.view("full_view", |v| v
.include(oid!(1, 3, 6, 1)))
.view("write_view", |v| v
.include(oid!(1, 3, 6, 1, 2, 1, 1))))
.build()
.await?;