Created
April 11, 2025 06:38
-
-
Save HEKUCHAN/7e0f628f2980fac4a9207fa836e96c7f to your computer and use it in GitHub Desktop.
[Rust] - SNMPを使って指定IPの機器から複数のOIDをGET/WALKする
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(¤t_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