use async_snmp::{Auth, Client, Error, ErrorStatus, Retry, Value, oid};
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing_subscriber::fmt()
.with_env_filter(
tracing_subscriber::EnvFilter::from_default_env()
.add_directive("async_snmp=info".parse()?),
)
.init();
let target = ("127.0.0.1", 11161);
let client = Client::builder(target, Auth::v2c("public"))
.timeout(Duration::from_secs(5))
.retry(Retry::fixed(3, Duration::ZERO))
.connect()
.await?;
println!("Connected to {}", client.peer_addr());
println!("\n--- GET sysDescr.0 ---");
let sys_descr = oid!(1, 3, 6, 1, 2, 1, 1, 1, 0);
match client.get(&sys_descr).await {
Ok(varbind) => {
println!("OID: {}", varbind.oid);
println!("Value: {:?}", varbind.value);
if let Some(s) = varbind.value.as_str() {
println!("As string: {}", s);
}
}
Err(e) => {
handle_error("GET", &e);
}
}
println!("\n--- GET_MANY (system MIB) ---");
let oids = [
oid!(1, 3, 6, 1, 2, 1, 1, 1, 0), oid!(1, 3, 6, 1, 2, 1, 1, 3, 0), oid!(1, 3, 6, 1, 2, 1, 1, 5, 0), oid!(1, 3, 6, 1, 2, 1, 1, 6, 0), ];
match client.get_many(&oids).await {
Ok(varbinds) => {
for vb in varbinds {
println!(" {}: {:?}", vb.oid, vb.value);
}
}
Err(e) => {
handle_error("GET_MANY", &e);
}
}
println!("\n--- GETNEXT from system ---");
let system_oid = oid!(1, 3, 6, 1, 2, 1, 1);
match client.get_next(&system_oid).await {
Ok(varbind) => {
println!("Next OID after {}: {}", system_oid, varbind.oid);
println!("Value: {:?}", varbind.value);
}
Err(e) => {
handle_error("GETNEXT", &e);
}
}
println!("\n--- SET sysContact.0 ---");
let write_client = Client::builder(target, Auth::v2c("private"))
.timeout(Duration::from_secs(5))
.connect()
.await?;
let sys_contact = oid!(1, 3, 6, 1, 2, 1, 1, 4, 0);
let new_value = Value::from("admin@example.com");
match write_client.set(&sys_contact, new_value).await {
Ok(varbind) => {
println!("Set successful!");
println!(" {}: {:?}", varbind.oid, varbind.value);
}
Err(e) => {
handle_error("SET", &e);
}
}
println!("\n--- Verify SET ---");
match client.get(&sys_contact).await {
Ok(varbind) => {
println!("Current value: {:?}", varbind.value);
}
Err(e) => {
handle_error("GET (verify)", &e);
}
}
println!("\nExample complete!");
Ok(())
}
fn handle_error(operation: &str, error: &Error) {
match error {
Error::Snmp {
status, index, oid, ..
} => {
println!(
"{} failed: SNMP error {:?} at index {}",
operation, status, index
);
if let Some(oid) = oid {
println!(" Problematic OID: {}", oid);
}
match status {
ErrorStatus::NoSuchName => {
println!(" -> OID does not exist on this agent");
}
ErrorStatus::NotWritable => {
println!(" -> OID is read-only");
}
ErrorStatus::AuthorizationError => {
println!(" -> Access denied (check community string)");
}
_ => {}
}
}
Error::Timeout {
target,
elapsed,
retries,
..
} => {
println!(
"{} failed: Timeout after {:?} ({} retries)",
operation, elapsed, retries
);
println!(" -> Check if agent at {} is reachable", target);
}
Error::Network { target, source, .. } => {
println!("{} failed: Network error - {}", operation, source);
println!(" -> Target: {}", target);
}
_ => {
println!("{} failed: {}", operation, error);
}
}
}