pub struct Client<T: Transport = UdpHandle> { /* private fields */ }Expand description
SNMP client.
Generic over transport type, with UdpHandle as default.
Implementations§
Source§impl<T: Transport> Client<T>
impl<T: Transport> Client<T>
Sourcepub async fn rediscover_engine(&self) -> Result<()>
pub async fn rediscover_engine(&self) -> Result<()>
Discover and replace the established authoritative engine.
This is the intentional recovery path when a device at the target address has been replaced or reconfigured with a new engine ID. Discovery never replaces an established identity during ordinary request processing. The current identity, localized keys, and shared cache mapping remain usable until a fresh response has been strictly validated and replacement keys have been derived. A failed or cancelled rediscovery therefore leaves the previous generation intact.
Client clones share a successful replacement because they share the
same live engine state. Independently constructed clients retain their
own established identity until explicitly rediscovered. For UDP,
source-address policy is controlled by
TargetClientBuilder::strict_source or
by the supplied transport handle.
This convenience method discards accepted discovery-response metadata.
Use Self::rediscover_engine_with_metadata to retain it.
Sourcepub async fn rediscover_engine_with_metadata(&self) -> Result<ResponseMetadata>
pub async fn rediscover_engine_with_metadata(&self) -> Result<ResponseMetadata>
Discover and replace the authoritative engine while retaining accepted wire deviations from the discovery Report.
Source§impl Client<UdpHandle>
impl Client<UdpHandle>
Sourcepub fn builder(
target: impl Into<Target>,
auth: impl Into<Auth>,
) -> TargetClientBuilder
pub fn builder( target: impl Into<Target>, auth: impl Into<Auth>, ) -> TargetClientBuilder
Create an SNMP client builder.
This convenience entry point configures a library-maintained target
transport. Use ClientBuilder::new when supplying an existing
transport or reusing protocol/client policy across targets.
§Example
use async_snmp::{Auth, Client, Retry};
use std::time::Duration;
// (host, port) tuple - convenient when host and port are separate
let client = Client::builder(("192.168.1.1", 161), Auth::v2c("public"))
.connect().await?;
// Combined address string (port defaults to 161 if omitted)
let client = Client::builder("switch.local", Auth::v2c("public"))
.connect().await?;
// SocketAddr works too
let addr: std::net::SocketAddr = "192.168.1.1:161".parse().unwrap();
let client = Client::builder(addr, Auth::v2c("public"))
.connect().await?;UDP clients expose endpoint observation but not lifecycle authority:
async fn invalid(client: async_snmp::UdpClient) {
let _control = client.control();
client.shutdown().await;
}Sourcepub fn stats(&self) -> UdpStats
pub fn stats(&self) -> UdpStats
Snapshot cumulative statistics for this client’s UDP endpoint.
Dedicated clients observe their private endpoint. Clients built from a
shared UdpTransport observe the same counters as
every other client and handle using that endpoint.
Source§impl<T: Transport> Client<T>
impl<T: Transport> Client<T>
Sourcepub fn new(transport: T, config: ClientConfig) -> Result<Self>
pub fn new(transport: T, config: ClientConfig) -> Result<Self>
Create a client with the given transport and configuration.
For most use cases, prefer Client::builder() for a library-created
transport or ClientBuilder::build_with_transport for an existing or
custom Transport. Use this lower-level constructor when configuring
the client directly with ClientConfig.
§Errors
Returns Error::Config when the configuration violates a client
invariant, or Error::RandomSource when an authPriv client cannot
initialize its privacy salt.
Sourcepub fn with_engine_cache(
transport: T,
config: ClientConfig,
engine_cache: Arc<EngineCache>,
) -> Result<Self>
pub fn with_engine_cache( transport: T, config: ClientConfig, engine_cache: Arc<EngineCache>, ) -> Result<Self>
Create an SNMPv3 client with a shared engine cache.
§Errors
Returns Error::Config when the configuration violates a client
invariant, or Error::RandomSource when an authPriv client cannot
initialize its privacy salt.
Sourcepub fn peer_addr(&self) -> SocketAddr
pub fn peer_addr(&self) -> SocketAddr
Returns the peer address.
Returns the remote address that this client sends requests to.
Named to match std::net::TcpStream::peer_addr().
Sourcepub fn version(&self) -> Version
pub fn version(&self) -> Version
Returns the SNMP version configured for this client.
The version is selected by the client’s authentication configuration and does not expose community or USM identity data.
Sourcepub fn decode_config(&self) -> DecodeConfig
pub fn decode_config(&self) -> DecodeConfig
Return the configured response decode configuration.
Sourcepub fn walk_options(&self) -> WalkOptions
pub fn walk_options(&self) -> WalkOptions
Return the default options snapshotted by Self::walk and
Self::walk_with_metadata.
Sourcepub fn security_level(&self) -> Option<SecurityLevel>
pub fn security_level(&self) -> Option<SecurityLevel>
Returns the configured SNMPv3 USM security level.
Returns None for SNMPv1 and SNMPv2c clients. For SNMPv3 clients, the
value describes the configured security level and does not expose the
USM identity or credentials.
Sourcepub async fn get(&self, oid: &Oid) -> Result<FixedCardinalityResponse>
pub async fn get(&self, oid: &Oid) -> Result<FixedCardinalityResponse>
GET a single OID.
Compatible mode preserves every returned binding and describes empty,
excess, or renamed responses in anomalies.
Sourcepub async fn get_many(&self, oids: &[Oid]) -> Result<FixedCardinalityResponse>where
T: 'static,
pub async fn get_many(&self, oids: &[Oid]) -> Result<FixedCardinalityResponse>where
T: 'static,
GET multiple OIDs.
If the OID list exceeds max_oids_per_request, the request is
automatically split into multiple batches. Response bindings are retained
in received batch order; consult anomalies before assuming positional
correspondence with the input OIDs. If any batch fails, this aggregate
convenience method returns the error without returning earlier results;
use get_many_chunks() to retain partial work.
§Example
let results = client.get_many(&[
oid!(1, 3, 6, 1, 2, 1, 1, 1, 0), // sysDescr
oid!(1, 3, 6, 1, 2, 1, 1, 3, 0), // sysUpTime
oid!(1, 3, 6, 1, 2, 1, 1, 5, 0), // sysName
]).await?;Sourcepub fn get_many_chunks(
&self,
oids: &[Oid],
) -> Result<FixedCardinalityChunkStream<T>>where
T: 'static,
pub fn get_many_chunks(
&self,
oids: &[Oid],
) -> Result<FixedCardinalityChunkStream<T>>where
T: 'static,
Lazily GET multiple OIDs as sequential wire-level response chunks.
All OIDs are validated when this method is called. No request is sent
until the returned stream is polled, and after each item the next request
waits for another poll. An agent tooBig response or a local
Error::OutboundMessageTooLarge bisects a multi-OID request range and
exposes successful child leaves independently. Either error on a
single-OID range is terminal and is returned in
FixedCardinalityChunkError::source.
The stream emits one FixedCardinalityChunkError for a terminal
failure, then remains fused. Dropping a chunk stream while a TCP request
is in flight follows TcpTransport’s cancellation
contract: cancellation after acquiring the connection lock poisons that
connection, and later operations fail with Error::Closed.
§Errors
Returns Error::InvalidOid before any I/O if any input OID cannot be
represented on the wire.
Sourcepub async fn get_next(&self, oid: &Oid) -> Result<FixedCardinalityResponse>
pub async fn get_next(&self, oid: &Oid) -> Result<FixedCardinalityResponse>
GETNEXT for a single OID.
Sourcepub async fn get_next_many(
&self,
oids: &[Oid],
) -> Result<FixedCardinalityResponse>where
T: 'static,
pub async fn get_next_many(
&self,
oids: &[Oid],
) -> Result<FixedCardinalityResponse>where
T: 'static,
GETNEXT for multiple OIDs.
If the OID list exceeds max_oids_per_request, the request is
automatically split into multiple batches. Response bindings are retained
in received batch order; consult anomalies before assuming positional
correspondence with the input OIDs. If any batch fails, this aggregate
convenience method returns the error without returning earlier results;
use get_next_many_chunks() to retain
partial work.
§Example
let results = client.get_next_many(&[
oid!(1, 3, 6, 1, 2, 1, 2, 2, 1, 2), // ifDescr
oid!(1, 3, 6, 1, 2, 1, 2, 2, 1, 3), // ifType
]).await?;Sourcepub fn get_next_many_chunks(
&self,
oids: &[Oid],
) -> Result<FixedCardinalityChunkStream<T>>where
T: 'static,
pub fn get_next_many_chunks(
&self,
oids: &[Oid],
) -> Result<FixedCardinalityChunkStream<T>>where
T: 'static,
Lazily GETNEXT multiple OIDs as sequential wire-level response chunks.
This has the same validation, backpressure, bisection, terminal-error,
and TCP cancellation behavior as get_many_chunks().
Sourcepub async fn set(
&self,
oid: &Oid,
value: Value,
) -> Result<FixedCardinalityResponse>
pub async fn set( &self, oid: &Oid, value: Value, ) -> Result<FixedCardinalityResponse>
SET a single OID.
Sourcepub async fn set_many(
&self,
varbinds: &[(Oid, Value)],
) -> Result<FixedCardinalityResponse>
pub async fn set_many( &self, varbinds: &[(Oid, Value)], ) -> Result<FixedCardinalityResponse>
SET multiple OIDs in a single atomic PDU.
RFC 3416 requires that a SET request be atomic: either all variables
in the request are set, or none are. To preserve this guarantee,
set_many refuses to split the varbind list across multiple PDUs.
If varbinds.len() exceeds max_oids_per_request, this method
returns Error::Config rather than silently batching the request.
Callers that need to set more variables than the per-request limit
must issue multiple explicit set_many calls and handle partial
failure themselves.
§Example
let results = client.set_many(&[
(oid!(1, 3, 6, 1, 2, 1, 1, 5, 0), Value::from("new-hostname")),
(oid!(1, 3, 6, 1, 2, 1, 1, 6, 0), Value::from("new-location")),
]).await?;Sourcepub async fn send_trap(
&self,
trap_oid: &Oid,
uptime: u32,
varbinds: Vec<VarBind>,
) -> Result<()>
pub async fn send_trap( &self, trap_oid: &Oid, uptime: u32, varbinds: Vec<VarBind>, ) -> Result<()>
Send a trap (fire-and-forget).
For V1 clients: constructs a TrapV1 PDU. The trap_oid is reverse-mapped
to v1 generic_trap/specific_trap/enterprise fields per RFC 3584 Section 3.2.
The agent_addr is set from the transport’s local IPv4 address, or [0,0,0,0]
if the local address is IPv6. Use send_v1_trap for
explicit control over v1 fields.
For V2c/V3 clients: constructs a TrapV2 PDU with the mandatory sysUpTime.0
and snmpTrapOID.0 prefix.
For V3: uses the persisted local authoritative engine state configured
through ClientBuilder::local_authoritative_engine.
§Arguments
trap_oid- The trap OID (snmpTrapOID.0 value)uptime- sysUpTime.0 value in hundredths of secondsvarbinds- Additional variable bindings (appended after the prefix)
Sourcepub async fn send_v1_trap(&self, trap: TrapV1Notification) -> Result<()>
pub async fn send_v1_trap(&self, trap: TrapV1Notification) -> Result<()>
Send an SNMPv1 trap with explicit v1 PDU fields.
This is a lower-level method that accepts a validated TrapV1Notification,
giving full control over enterprise OID, agent_addr, generic_trap,
specific_trap, and time_stamp fields.
The client must be configured for V1 (Auth::v1()). Returns an error
if the client version is not V1.
§Example
let client = Client::builder("192.168.1.100:162", Auth::v1("public"))
.connect().await?;
let trap = TrapV1Notification::new(
oid!(1, 3, 6, 1, 4, 1, 9999), // enterprise
[192, 168, 1, 1], // agent address
GenericTrap::ColdStart,
0,
12345, // uptime in centiseconds
vec![],
)?;
client.send_v1_trap(trap).await?;Sourcepub async fn send_inform(
&self,
trap_oid: &Oid,
uptime: u32,
varbinds: Vec<VarBind>,
) -> Result<()>
pub async fn send_inform( &self, trap_oid: &Oid, uptime: u32, varbinds: Vec<VarBind>, ) -> Result<()>
Send a v2c/v3 inform and wait for acknowledgement.
Constructs an InformRequest PDU with the mandatory sysUpTime.0 and
snmpTrapOID.0 prefix, sends it to the target, and waits for a Response
PDU that echoes the request variable bindings. Uses the same retry and
timeout logic as other request types.
For V3: uses engine discovery against the receiver (same as GET/SET). V1 is not supported and returns an error.
§Arguments
trap_oid- The trap OID (snmpTrapOID.0 value)uptime- sysUpTime.0 value in hundredths of secondsvarbinds- Additional variable bindings (appended after the prefix)
This convenience method intentionally discards accepted wire-deviation
metadata. Use Self::send_inform_with_metadata when it is needed.
Sourcepub async fn send_inform_with_metadata(
&self,
trap_oid: &Oid,
uptime: u32,
varbinds: Vec<VarBind>,
) -> Result<ResponseMetadata>
pub async fn send_inform_with_metadata( &self, trap_oid: &Oid, uptime: u32, varbinds: Vec<VarBind>, ) -> Result<ResponseMetadata>
Send an Inform and retain metadata from discovery, correction Reports, and the acknowledgement in exchange order.
Sourcepub async fn get_bulk(
&self,
oids: &[Oid],
non_repeaters: u32,
max_repetitions: u32,
) -> Result<Vec<VarBind>>
pub async fn get_bulk( &self, oids: &[Oid], non_repeaters: u32, max_repetitions: u32, ) -> Result<Vec<VarBind>>
GETBULK request (SNMPv2c/v3 only).
Efficiently retrieves multiple variable bindings in a single request. GETBULK splits the requested OIDs into two groups:
- Non-repeaters (first N OIDs): Each gets a single GETNEXT, returning
the first lexicographic successor of the requested OID. To retrieve a
scalar instance such as
sysUpTime.0, request its object OID without the.0instance suffix. - Repeaters (remaining OIDs): Each gets up to
max_repetitionsGETNEXTs, returning multiple values per OID. Use for walking table columns.
§Arguments
oids- OIDs to retrievenon_repeaters- How many OIDs (from the start) are non-repeatingmax_repetitions- Maximum rows to return for each repeating OID
§Errors
Returns Error::InvalidMessage when either GETBULK parameter exceeds
i32::MAX.
§Example
// Get sysUpTime.0 (non-repeater) plus 10 interface descriptions (repeater).
// Both inputs are object OIDs; GETBULK returns their instance successors.
let results = client.get_bulk(
&[oid!(1, 3, 6, 1, 2, 1, 1, 3), oid!(1, 3, 6, 1, 2, 1, 2, 2, 1, 2)],
1, // first OID is non-repeating
10, // get up to 10 values for the second OID
).await?;
// Results: [sysUpTime value, ifDescr.1, ifDescr.2, ..., ifDescr.10]This convenience method discards accepted response metadata. Use
Self::get_bulk_with_metadata when compatibility deviations must be
retained.
Sourcepub async fn get_bulk_with_metadata(
&self,
oids: &[Oid],
non_repeaters: u32,
max_repetitions: u32,
) -> Result<BulkResponse>
pub async fn get_bulk_with_metadata( &self, oids: &[Oid], non_repeaters: u32, max_repetitions: u32, ) -> Result<BulkResponse>
GETBULK with accepted wire deviations retained as response metadata.
Sourcepub fn walk(&self, oid: Oid) -> Result<WalkStream<T>>where
T: 'static,
pub fn walk(&self, oid: Oid) -> Result<WalkStream<T>>where
T: 'static,
Walk an OID subtree.
Auto-selects GETNEXT for V1 and GETBULK for V2c/V3 by default.
WalkOptions::method can select either operation explicitly.
Returns an async stream that yields each variable binding in the subtree.
This convenience stream intentionally discards decode metadata; use
Self::walk_with_metadata to retain it.
The walk terminates when an OID outside the subtree is encountered or
when EndOfMibView is returned. All consumption methods observe this same
GETNEXT/GETBULK sequence. A scalar instance OID is not retrieved as a
fallback; use get() to retrieve a scalar value.
Uses the client’s snapshotted WalkOptions. At a configured result limit,
the stream inspects one look-ahead candidate and may make one extra
request. Definite truncation is emitted as
WalkAbortReason::ResultLimitExceeded.
A walk is not an atomic MIB snapshot; values can change between the main
sequence and the look-ahead.
§Example
// Auto-selects GETBULK for V2c/V3, GETNEXT for V1
let results = client.walk(oid!(1, 3, 6, 1, 2, 1, 1))?.collect().await?;Sourcepub fn walk_with(&self, oid: Oid, options: WalkOptions) -> Result<WalkStream<T>>where
T: 'static,
pub fn walk_with(&self, oid: Oid, options: WalkOptions) -> Result<WalkStream<T>>where
T: 'static,
Walk using an operation-specific options snapshot.
This override does not mutate the client default or teach the client a
persistent device capability. GetBulk on SNMPv1 is rejected here,
before the returned stream can perform transport I/O.
Sourcepub fn walk_with_metadata(&self, oid: Oid) -> Result<WalkMetadataStream<T>>where
T: 'static,
pub fn walk_with_metadata(&self, oid: Oid) -> Result<WalkMetadataStream<T>>where
T: 'static,
Walk using the client’s default options while retaining response metadata.
Sourcepub fn walk_with_metadata_and(
&self,
oid: Oid,
options: WalkOptions,
) -> Result<WalkMetadataStream<T>>where
T: 'static,
pub fn walk_with_metadata_and(
&self,
oid: Oid,
options: WalkOptions,
) -> Result<WalkMetadataStream<T>>where
T: 'static,
Walk with metadata using an operation-specific options snapshot.
Sourcepub fn walk_getnext(&self, oid: Oid) -> Result<WalkStream<T>>where
T: 'static,
pub fn walk_getnext(&self, oid: Oid) -> Result<WalkStream<T>>where
T: 'static,
Explicit GETNEXT convenience returning the common plain stream type.
Sourcepub fn walk_getnext_with_metadata(
&self,
oid: Oid,
) -> Result<WalkMetadataStream<T>>where
T: 'static,
pub fn walk_getnext_with_metadata(
&self,
oid: Oid,
) -> Result<WalkMetadataStream<T>>where
T: 'static,
Explicit GETNEXT convenience returning the common metadata stream type.
Sourcepub fn bulk_walk(&self, oid: Oid, max_repetitions: u32) -> Result<WalkStream<T>>where
T: 'static,
pub fn bulk_walk(&self, oid: Oid, max_repetitions: u32) -> Result<WalkStream<T>>where
T: 'static,
Explicit GETBULK convenience returning the common plain stream type.
Sourcepub fn bulk_walk_with_metadata(
&self,
oid: Oid,
max_repetitions: u32,
) -> Result<WalkMetadataStream<T>>where
T: 'static,
pub fn bulk_walk_with_metadata(
&self,
oid: Oid,
max_repetitions: u32,
) -> Result<WalkMetadataStream<T>>where
T: 'static,
Explicit GETBULK convenience returning the common metadata stream type.
Sourcepub fn bulk_walk_default(&self, oid: Oid) -> Result<WalkStream<T>>where
T: 'static,
pub fn bulk_walk_default(&self, oid: Oid) -> Result<WalkStream<T>>where
T: 'static,
Explicit GETBULK convenience using the client’s default repetitions.