rusnmp 0.1.0

A lightweight, async SNMP v1/v2c/v3 client library for Rust with minimal dependencies.
Documentation

rusnmp

Crates.io Docs.rs License

rusnmp is a lightweight, async SNMP v1/v2c/v3 client library for Rust built on Tokio with minimal dependencies.


Features

  • ✅ Async UDP transport (Tokio)
  • ✅ SNMPv1 and SNMPv2c support
  • ✅ SNMPv3 with USM (User-based Security Model)
    • Authentication: MD5, SHA-1, SHA-256
    • Privacy: DES, AES-128
    • Automatic engine discovery (RFC 3414)
    • Key localization
  • ✅ GET, GETNEXT, GETBULK, SET operations
  • ✅ SNMP Walk (auto GETNEXT/GETBULK)
  • ✅ Trap receiver (v1/v2c/v3)
  • ✅ Pure Rust BER encoder/decoder
  • ✅ Typed values (Integer, OctetString, Counter32/64, Gauge32, TimeTicks, IpAddress, OID)
  • oid! macro for compile-time OID construction
  • ✅ Configurable timeout
  • ✅ Minimal dependencies — no C bindings, no libnetsnmp

Quick Start

[dependencies]
rusnmp = "0.1"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }

SNMPv2c

use rusnmp::{SnmpClient, oid};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut client = SnmpClient::new("192.168.1.1", "public").await?;

    // GET sysDescr.0
    let result = client.get_one(&oid!(1, 3, 6, 1, 2, 1, 1, 1, 0)).await?;
    println!("sysDescr: {}", result.value.as_str().unwrap_or("N/A"));

    // GET multiple OIDs
    let results = client.get(&[
        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?;
    for vb in &results {
        println!("{}: {:?}", vb.oid, vb.value);
    }

    // Walk ifTable
    let entries = client.walk(&oid!(1, 3, 6, 1, 2, 1, 2, 2)).await?;
    for vb in entries {
        println!("{}: {:?}", vb.oid, vb.value);
    }

    Ok(())
}

SNMPv3 (USM)

use rusnmp::{SnmpV3Client, oid};
use rusnmp::v3::{UsmCredentials, AuthProtocol, PrivProtocol};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // AuthPriv: SHA-1 authentication + AES-128 encryption
    let creds = UsmCredentials::auth_priv(
        "admin",
        AuthProtocol::Sha1, "authpass123",
        PrivProtocol::Aes128, "privpass123",
    );
    let mut client = SnmpV3Client::new("192.168.1.1", creds).await?;

    let result = client.get_one(&oid!(1, 3, 6, 1, 2, 1, 1, 1, 0)).await?;
    println!("sysDescr: {:?}", result.value.as_str());

    // Walk also works with v3
    let entries = client.walk(&oid!(1, 3, 6, 1, 2, 1, 2, 2)).await?;
    for vb in entries {
        println!("{}: {:?}", vb.oid, vb.value);
    }

    Ok(())
}

Trap Receiver

use rusnmp::TrapReceiver;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let receiver = TrapReceiver::bind("0.0.0.0:162").await?;
    println!("Listening for traps on port 162...");

    loop {
        let trap = receiver.recv().await?;
        println!("Trap from {}: version={:?}", trap.source, trap.version);
        for vb in &trap.varbinds {
            println!("  {}: {:?}", vb.oid, vb.value);
        }
    }
}

API Summary

SnmpClient (v1/v2c)

Method Description
SnmpClient::new(target, community) Create v2c client (default port 161)
SnmpClient::with_version(target, community, version) Create client with specific version
set_timeout(duration) Set request timeout
get(oids) GET one or more OIDs
get_one(oid) GET a single OID (convenience)
get_next(oids) GETNEXT operation
get_bulk(oids, non_repeaters, max_repetitions) GETBULK (v2c)
set(varbinds) SET operation
walk(root_oid) Walk subtree (auto GETNEXT/GETBULK)

SnmpV3Client (USM)

Method Description
SnmpV3Client::new(target, credentials) Create v3 client (auto engine discovery)
set_timeout(duration) Set request timeout
get(oids) GET one or more OIDs
get_one(oid) GET a single OID
get_next(oids) GETNEXT operation
get_bulk(oids, non_repeaters, max_repetitions) GETBULK
set(varbinds) SET operation
walk(root_oid) Walk subtree

TrapReceiver

Method Description
TrapReceiver::bind(addr) Bind trap listener (e.g. "0.0.0.0:162")
recv() Receive next trap (async)

USM Security Levels

Constructor Auth Priv
UsmCredentials::no_auth(user)
UsmCredentials::auth_only(user, proto, pass)
UsmCredentials::auth_priv(user, auth_proto, auth_pass, priv_proto, priv_pass)

Value Types

Variant Rust Type
Value::Integer i64
Value::OctetString Vec<u8>
Value::ObjectIdentifier Oid
Value::IpAddress [u8; 4]
Value::Counter32 u32
Value::Gauge32 u32
Value::TimeTicks u32
Value::Counter64 u64
Value::Null

Dependencies

Core (always required):

tokio, thiserror, log, rand

SNMPv3 crypto (optional v3 feature, enabled by default):

hmac, sha1, sha2, md-5, aes, cbc, cfb-mode, des, block-padding

To use without v3:

rusnmp = { version = "0.1", default-features = false }

License

MIT OR Apache-2.0