async-snmp 0.1.2

Modern async-first SNMP client library for Rust
Documentation

async-snmp

CI Crates.io Documentation MSRV License

Modern, async-first SNMP client library for Rust.

Features

  • Full protocol support: SNMPv1, v2c, and v3 (USM)
  • Async-first: Built on Tokio for high-performance async I/O
  • All operations: GET, GETNEXT, GETBULK, SET, WALK, BULKWALK
  • SNMPv3 security: MD5/SHA-1/SHA-2 authentication, DES/AES-128/192/256 privacy
  • Multiple transports: UDP, TCP, and shared UDP for high-throughput polling
  • Zero-copy decoding: Minimal allocations using bytes crate
  • Type-safe: Compile-time OID validation with oid! macro

Protocol Support Matrix

Feature v1 v2c v3
GET / GETNEXT Y Y Y
GETBULK - Y Y
SET Y Y Y
WALK / BULKWALK Y Y Y
Traps Y Y Y
Informs - Y Y

SNMPv3 Security

Authentication: MD5, SHA-1, SHA-224, SHA-256, SHA-384, SHA-512

Privacy: DES, AES-128, AES-192, AES-256

Installation

cargo add async-snmp

Or add to your Cargo.toml:

[dependencies]
async-snmp = "0.1"

Quick Start

SNMPv2c

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(())
}

SNMPv3 with Authentication and Privacy

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(())
}

Walking a Subtree

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(())
}

High-Throughput Polling (Shared Transport)

For monitoring systems polling thousands of targets:

use async_snmp::{Auth, Client, SharedUdpTransport, oid};

#[tokio::main]
async fn main() -> Result<(), async_snmp::Error> {
    // Single socket shared across all clients
    let shared = SharedUdpTransport::bind("0.0.0.0: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| {
            let addr = t.parse().unwrap();
            Client::builder(*t, Auth::v2c("public"))
                .build(shared.handle(addr))
        })
        .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(())
}

Documentation

Full API documentation is available on docs.rs.

Feature Flags

Feature Description
testing Expose transport::MockTransport for downstream testing
serde Serialize/Deserialize support for configuration types
cli CLI utilities (asnmp-get, asnmp-walk, asnmp-set)

Minimum Supported Rust Version

This crate requires Rust 1.88 or later. The MSRV may be increased in minor version releases.

License

Licensed under either of:

at your option.

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.