| Crates.io | async-snmp |
| lib.rs | async-snmp |
| version | 0.5.0 |
| created_at | 2026-01-01 00:26:38.471931+00 |
| updated_at | 2026-01-18 11:03:05.051341+00 |
| description | Modern async-first SNMP client library for Rust |
| homepage | |
| repository | https://github.com/lukeod/async-snmp |
| max_upload_size | |
| id | 2015540 |
| size | 1,341,085 |
Modern, async-first SNMP client library for Rust.
This library is not currently stable. While pre v1.0, breaking changes are likely to occur frequently, no attempt will be made to maintain backward compatibility pre-1.0.
bytes crateoid! macro| Feature | v1 | v2c | v3 |
|---|---|---|---|
| GET / GETNEXT | Y | Y | Y |
| GETBULK | - | Y | Y |
| SET | Y | Y | Y |
| WALK / BULKWALK | Y | Y | Y |
| Receive Traps | Y | Y | Y |
| Receive Informs | - | Y | Y |
Authentication: MD5, SHA-1, SHA-224, SHA-256, SHA-384, SHA-512
Privacy: DES, 3DES, AES-128, AES-192, AES-256
cargo add async-snmp
Or add to your Cargo.toml:
[dependencies]
async-snmp = "0.5"
use async_snmp::{Auth, Client, oid};
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<(), async_snmp::Error> {
let client = Client::builder("192.168.1.1:161", Auth::v2c("public"))
.timeout(Duration::from_secs(5))
.connect()
.await?;
let result = client.get(&oid!(1, 3, 6, 1, 2, 1, 1, 1, 0)).await?;
println!("sysDescr: {:?}", result.value);
Ok(())
}
use async_snmp::{Auth, Client, oid, v3::{AuthProtocol, PrivProtocol}};
#[tokio::main]
async fn main() -> Result<(), async_snmp::Error> {
let client = Client::builder("192.168.1.1:161",
Auth::usm("admin")
.auth(AuthProtocol::Sha256, "authpass123")
.privacy(PrivProtocol::Aes128, "privpass123"))
.connect()
.await?;
let result = client.get(&oid!(1, 3, 6, 1, 2, 1, 1, 1, 0)).await?;
println!("sysDescr: {:?}", result.value);
Ok(())
}
use async_snmp::{Auth, Client, oid};
use futures::StreamExt;
#[tokio::main]
async fn main() -> Result<(), async_snmp::Error> {
let client = Client::builder("192.168.1.1:161", Auth::v2c("public"))
.connect()
.await?;
// Walk the system subtree
let mut walk = client.walk(oid!(1, 3, 6, 1, 2, 1, 1))?;
while let Some(result) = walk.next().await {
let vb = result?;
println!("{}: {:?}", vb.oid, vb.value);
}
Ok(())
}
For monitoring systems polling thousands of targets, share a single UDP socket across all clients. This provides significant resource efficiency without sacrificing throughput:
use async_snmp::{Auth, Client, UdpTransport, oid};
#[tokio::main]
async fn main() -> Result<(), async_snmp::Error> {
// Single dual-stack socket shared across all clients
let shared = UdpTransport::bind("[::]:0").await?;
let targets = vec!["192.168.1.1:161", "192.168.1.2:161", "192.168.1.3:161"];
let clients: Vec<_> = targets.iter()
.map(|t| {
Client::builder(*t, Auth::v2c("public"))
.build_with(&shared)
})
.collect::<Result<_, _>>()?;
// Poll all targets concurrently - sharing one UDP socket
let results = futures::future::join_all(
clients.iter().map(|c| c.get(&oid!(1, 3, 6, 1, 2, 1, 1, 3, 0)))
).await;
for (client, result) in clients.iter().zip(results) {
match result {
Ok(vb) => println!("{}: {:?}", client.peer_addr(), vb.value),
Err(e) => eprintln!("{}: {}", client.peer_addr(), e),
}
}
Ok(())
}
Benefits of shared transport:
Scaling guidance:
| Approach | When to use |
|---|---|
| Single shared socket | Recommended for most use cases |
| Multiple shared sockets | Extreme scale (~100,000s+ targets), shard by target |
Per-client socket (.connect()) |
When scrape isolation is required (has FD and syscall overhead) |
The library uses the tracing crate for structured logging. Filter by target:
# All library logs at debug level
RUST_LOG=async_snmp=debug cargo run
# Trace client operations only
RUST_LOG=async_snmp::client=trace cargo run
# Debug transport layer
RUST_LOG=async_snmp::transport=debug cargo run
Available targets:
async_snmp::client, async_snmp::agent, async_snmp::notificationasync_snmp::ber, async_snmp::pdu, async_snmp::oid, async_snmp::valueasync_snmp::v3, async_snmp::usm, async_snmp::crypto, async_snmp::engineasync_snmp::transport, async_snmp::transport::tcp, async_snmp::transport::udpasync_snmp::walk, async_snmp::errorFull API documentation is available on docs.rs.
| Feature | Description |
|---|---|
cli |
CLI utilities (asnmp-get, asnmp-walk, asnmp-set) |
This crate requires Rust 1.88 or later. The MSRV may be increased in minor version releases.
Licensed under either of:
at your option.
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.