Crates.io | snmp2 |
lib.rs | snmp2 |
version | 0.4.9 |
created_at | 2024-12-28 22:02:16.371869+00 |
updated_at | 2025-09-20 20:28:42.652686+00 |
description | SNMP v1/v2/v3 sync/async client library with traps and MIB support |
homepage | |
repository | https://github.com/roboplc/snmp2 |
max_upload_size | |
id | 1497810 |
size | 115,267 |
Dependency-free basic SNMP v1/v2/v3 client in Rust.
This is a fork of the original snmp crate which has been abandoned long time ago.
SNMP2 is a part of RoboPLC project.
New features added to the fork:
mibs
feature and libnetsnmp
library installed)tokio
feature)Supports:
mibs
feature, requires libnetsnmp
)v3
feature)use std::time::Duration;
use snmp2::{SyncSession, Value, Oid};
let sys_descr_oid = Oid::from(&[1,3,6,1,2,1,1,1,]).unwrap();
let agent_addr = "198.51.100.123:161";
let community = b"f00b4r";
let timeout = Duration::from_secs(2);
let mut sess = SyncSession::new_v2c(agent_addr, community, Some(timeout), 0).unwrap();
let mut response = sess.getnext(&sys_descr_oid).unwrap();
if let Some((_oid, Value::OctetString(sys_descr))) = response.varbinds.next() {
println!("myrouter sysDescr: {}", String::from_utf8_lossy(sys_descr));
}
use std::time::Duration;
use snmp2::{SyncSession, Oid};
let system_oid = Oid::from(&[1,3,6,1,2,1,1,]).unwrap();
let agent_addr = "[2001:db8:f00:b413::abc]:161";
let community = b"f00b4r";
let timeout = Duration::from_secs(2);
let non_repeaters = 0;
let max_repetitions = 7; // number of items in "system" OID
let mut sess = SyncSession::new_v2c(agent_addr, community, Some(timeout), 0).unwrap();
let response = sess.getbulk(&[&system_oid], non_repeaters, max_repetitions).unwrap();
for (name, val) in response.varbinds {
println!("{} => {:?}", name, val);
}
use std::time::Duration;
use snmp2::{SyncSession, Value, Oid};
let syscontact_oid = Oid::from(&[1,3,6,1,2,1,1,4,0]).unwrap();
let contact = Value::OctetString(b"Thomas A. Anderson");
let agent_addr = "[2001:db8:f00:b413::abc]:161";
let community = b"f00b4r";
let timeout = Duration::from_secs(2);
let mut sess = SyncSession::new_v2c(agent_addr, community, Some(timeout), 0).unwrap();
let response = sess.set(&[(&syscontact_oid, contact)]).unwrap();
assert_eq!(response.error_status, snmp2::snmp::ERRSTATUS_NOERROR);
for (name, val) in response.varbinds {
println!("{} => {:?}", name, val);
}
use std::net::UdpSocket;
use snmp2::Pdu;
let socket = UdpSocket::bind("0.0.0.0:1162").expect("Could not bind socket");
loop {
let mut buf = [0; 1500];
let size = socket.recv(&mut buf).expect("Could not receive data");
let data = &buf[..size];
let pdu = Pdu::from_bytes(data).expect("Could not parse PDU");
println!("Version: {}", pdu.version().unwrap());
println!("Community: {}", std::str::from_utf8(pdu.community).unwrap());
for (name, value) in pdu.varbinds {
println!("{}={:?}", name, value);
}
}
use std::time::Duration;
use snmp2::{AsyncSession, Value, Oid};
async fn get_next() {
// timeouts should be handled by the caller with `tokio::time::timeout`
let sys_descr_oid = Oid::from(&[1,3,6,1,2,1,1,1,]).unwrap();
let agent_addr = "198.51.100.123:161";
let community = b"f00b4r";
let mut sess = AsyncSession::new_v2c(agent_addr, community, 0).await.unwrap();
let mut response = sess.getnext(&sys_descr_oid).await.unwrap();
if let Some((_oid, Value::OctetString(sys_descr))) = response.varbinds.next() {
println!("myrouter sysDescr: {}", String::from_utf8_lossy(sys_descr));
}
}
Prepare the system
apt-get install libsnmp-dev snmp-mibs-downloader
use snmp2::{mibs::{self, MibConversion as _}, Oid};
mibs::init(&mibs::Config::new().mibs(&["./ibmConvergedPowerSystems.mib"]))
.unwrap();
let snmp_oid = Oid::from(&[1, 3, 6, 1, 4, 1, 2, 6, 201, 3]).unwrap();
let name = snmp_oid.mib_name().unwrap();
assert_eq!(name, "IBM-CPS-MIB::cpsSystemSendTrap");
let snmp_oid2 = Oid::from_mib_name(&name).unwrap();
assert_eq!(snmp_oid, snmp_oid2);
Requires v3
crate feature.
All cryptographic algorithms are provided by openssl.
For authentication, supports: MD5 (RFC3414), SHA1 (RFC3414) and non-standard SHA224, SHA256, SHA384, SHA512.
For privacy, supports: DES (RFC3414), AES128-CFB (RFC3826) and non-standard AES192-CFB, AES256-CFB. Additional/different AES modes are not supported and may require patching the crate.
Note: DES legacy encryption may be disabled in openssl by default or even not supported at all. Refer to the library documentation how to enable it.
Authentication: SHA1, encryption: AES128-CFB
use snmp2::{SyncSession, v3, Oid};
use std::time::Duration;
// the security parameters also keep authoritative engine ID and boot/time
// counters. these can be either set or resolved/updated automatically.
let security = v3::Security::new(b"public", b"secure")
.with_auth_protocol(v3::AuthProtocol::Sha1)
.with_auth(v3::Auth::AuthPriv {
cipher: v3::Cipher::Aes128,
privacy_password: b"secure-encrypt".to_vec(),
});
let mut sess =
SyncSession::new_v3("192.168.1.1:161", Some(Duration::from_secs(2)), 0, security).unwrap();
// In case if engine_id is not provided in security parameters, it is necessary
// to call init() method to send a blank unauthenticated request to the target
// to get the engine_id.
sess.init().unwrap();
loop {
let res = match sess.get(&Oid::from(&[1, 3, 6, 1, 2, 1, 1, 3, 0]).unwrap()) {
Ok(r) => r,
// In case if the engine boot / time counters are not set in the security parameters or
// they have been changed on the target, e.g. after a reboot, the session returns
// an error with the AuthUpdated code. In this case, security parameters are automatically
// updated and the request should be repeated.
Err(snmp2::Error::AuthUpdated) => continue,
Err(e) => panic!("{}", e),
};
println!("{} {:?}", res.version().unwrap(), res.varbinds);
std::thread::sleep(Duration::from_secs(1));
}
In case of problems (e.g. with cross-rs),
add openssl
with vendored
feature:
cargo add openssl --features vendored
The crate uses openssl cryptography only and becomes FIPS-140 compliant as soon
as FIPS mode is activated in openssl
. Refer to the
openssl crate crate and
openssl library documentation for more details.
1.68.0
Copyright 2016-2018 Hroi Sigurdsson
Copyright 2024 Serhij Symonenko, Bohemia Automation Limited
Licensed under the Apache License, Version 2.0 or the MIT license, at your option. This file may not be copied, modified, or distributed except according to those terms.