Skip to content

Instantly share code, notes, and snippets.

@HEKUCHAN
Created April 11, 2025 06:38
Show Gist options
  • Save HEKUCHAN/7e0f628f2980fac4a9207fa836e96c7f to your computer and use it in GitHub Desktop.
Save HEKUCHAN/7e0f628f2980fac4a9207fa836e96c7f to your computer and use it in GitHub Desktop.
[Rust] - SNMPを使って指定IPの機器から複数のOIDをGET/WALKする
use encoding_rs::SHIFT_JIS;
use snmp::{SyncSession, Value};
use std::{error::Error, net::ToSocketAddrs, time::Duration};
fn main() -> Result<(), Box<dyn Error>> {
let target = "10.200.32.27:161".to_socket_addrs()?.next().unwrap();
let community = b"public";
let mut session = SyncSession::new(target, community, Some(Duration::from_secs(2)), 0)?;
let oid_get_list: Vec<Vec<u32>> = vec![
vec![1, 3, 6, 1, 2, 1, 25, 3, 5, 1, 1, 1], // hrPrinterStatus
vec![1, 3, 6, 1, 2, 1, 25, 3, 2, 1, 5, 1], // hrDeviceStatus
vec![1, 3, 6, 1, 2, 1, 43, 10, 2, 1, 4, 1, 1], // prtMarkerLifeCount
];
let oid_walks: Vec<Vec<u32>> = vec![
vec![1, 3, 6, 1, 2, 1, 43, 11, 1, 1, 9, 1],
vec![1, 3, 6, 1, 2, 1, 43, 8, 2, 1, 10, 1],
vec![1, 3, 6, 1, 2, 1, 43, 11, 1, 1, 6, 1],
vec![1, 3, 6, 1, 2, 1, 43, 11, 1, 1, 8, 1],
vec![1, 3, 6, 1, 2, 1, 43, 8, 2, 1, 4, 1],
vec![1, 3, 6, 1, 2, 1, 43, 16, 5, 1, 2, 1],
vec![1, 3, 6, 1, 2, 1, 43, 8, 2, 1, 9, 1],
vec![1, 3, 6, 1, 2, 1, 43, 18, 1, 1, 8, 1],
];
println!("=== SNMP GET ===");
for oid in oid_get_list.iter() {
match session.get(&oid) {
Ok(pdu) => {
let mut varbinds = pdu.varbinds;
if let Some((oid, val)) = varbinds.next() {
match val {
Value::Integer(v) => println!(" {:?}: {}", oid, v),
Value::OctetString(bytes) => {
// Try UTF-8 first
match String::from_utf8(bytes.to_vec()) {
Ok(utf8_str) => println!(" {:?}: {}", oid, utf8_str),
Err(_) => {
// Fallback: Shift_JIS
let (cow, _, _) = SHIFT_JIS.decode(&bytes);
println!(" {:?}: {}", oid, cow);
}
}
}
v => println!(" {:?}: {:?}", oid, v),
}
} else {
println!("No response (empty varbind) for OID: {:?}", oid);
}
}
Err(e) => {
eprintln!("Error during SNMP get for {:?}: {:?}", oid, e);
}
}
}
println!("=== SNMP WALK (manual via getnext) ===");
for base_oid in oid_walks.iter() {
let mut current_oid = base_oid.clone();
loop {
let pdu = match session.getnext(&current_oid) {
Ok(pdu) => pdu,
Err(e) => {
eprintln!("Error during SNMP getnext: {:?}", e);
break;
}
};
if let Some((oid, val)) = pdu.varbinds.into_iter().next() {
let mut buf = [0u32; 128];
let oid_vec = match oid.read_name(&mut buf) {
Ok(slice) => slice.to_vec(),
Err(e) => {
eprintln!("Failed to decode OID: {:?}", e);
break;
}
};
if !oid_vec.starts_with(base_oid) {
break;
}
match val {
Value::Integer(v) => println!(" {:?}: {}", oid, v),
Value::OctetString(bytes) => {
match String::from_utf8(bytes.to_vec()) {
Ok(utf8_str) => println!(" {:?}: {}", oid, utf8_str),
Err(_) => {
let (cow, _, _) = SHIFT_JIS.decode(&bytes);
println!(" {:?}: {}", oid, cow);
}
}
}
v => println!(" {:?}: {:?}", oid, v),
}
current_oid = oid_vec;
}
}
}
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment