mirror of
https://github.com/centreon/centreon-plugins.git
synced 2025-07-31 01:24:35 +02:00
enh(generic-snmp): snmpbulkget almost works and we have a timeout, 1000ms currently
This commit is contained in:
parent
4a31f1b2e4
commit
0760bc53eb
@ -2,7 +2,7 @@ extern crate serde;
|
|||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use snmp::{r_snmp_bulk_walk, SnmpResult, SnmpValue};
|
use snmp::{r_snmp_bulk_get, r_snmp_bulk_walk, SnmpResult, SnmpValue};
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
@ -182,6 +182,9 @@ impl Command {
|
|||||||
//ext: &CommandExt,
|
//ext: &CommandExt,
|
||||||
) -> CmdResult {
|
) -> CmdResult {
|
||||||
let mut res: BTreeMap<String, i64> = BTreeMap::new();
|
let mut res: BTreeMap<String, i64> = BTreeMap::new();
|
||||||
|
let mut to_get = Vec::new();
|
||||||
|
let mut get_name = Vec::new();
|
||||||
|
|
||||||
for s in self.collect.snmp.iter() {
|
for s in self.collect.snmp.iter() {
|
||||||
match s.query {
|
match s.query {
|
||||||
QueryType::Walk => {
|
QueryType::Walk => {
|
||||||
@ -203,8 +206,16 @@ impl Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
QueryType::Get => {
|
QueryType::Get => {
|
||||||
// let r = r_snmp_bulk_get(target, version, community, &s.oid);
|
to_get.push(s.oid.as_str());
|
||||||
// res.insert(&s.name, r);
|
get_name.push(&s.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !to_get.is_empty() {
|
||||||
|
let r = r_snmp_bulk_get(target, version, community, 1, 1, &to_get);
|
||||||
|
for (idx, result) in r.variables.iter().enumerate() {
|
||||||
|
if let SnmpValue::Integer(v) = result.value {
|
||||||
|
res.insert(get_name[idx].to_string(), v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -170,6 +170,9 @@ pub fn r_snmp_get(target: &str, oid: &str, community: &str) -> SnmpResult {
|
|||||||
// Send the message through an UDP socket
|
// Send the message through an UDP socket
|
||||||
let socket = UdpSocket::bind("0.0.0.0:0").unwrap();
|
let socket = UdpSocket::bind("0.0.0.0:0").unwrap();
|
||||||
socket.connect(target).expect("connect function failed");
|
socket.connect(target).expect("connect function failed");
|
||||||
|
let duration = std::time::Duration::from_millis(1000);
|
||||||
|
socket.set_read_timeout(Some(duration)).unwrap();
|
||||||
|
|
||||||
let encoded = rasn::der::encode(&message).unwrap();
|
let encoded = rasn::der::encode(&message).unwrap();
|
||||||
let res = socket.send(&encoded).unwrap();
|
let res = socket.send(&encoded).unwrap();
|
||||||
assert!(res == encoded.len());
|
assert!(res == encoded.len());
|
||||||
@ -237,11 +240,13 @@ pub fn r_snmp_walk(target: &str, oid: &str) -> SnmpResult {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut message = create_next_request(request_id, &oid_tab);
|
let mut message = create_next_request(request_id, &oid_tab);
|
||||||
|
// Send the message through an UDP socket
|
||||||
|
let socket = UdpSocket::bind("0.0.0.0:0").unwrap();
|
||||||
|
socket.connect(target).expect("connect function failed");
|
||||||
|
let duration = std::time::Duration::from_millis(1000);
|
||||||
|
socket.set_read_timeout(Some(duration)).unwrap();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
// Send the message through an UDP socket
|
|
||||||
let socket = UdpSocket::bind("0.0.0.0:0").unwrap();
|
|
||||||
socket.connect(target).expect("connect function failed");
|
|
||||||
let encoded: Vec<u8> = rasn::der::encode(&message).unwrap();
|
let encoded: Vec<u8> = rasn::der::encode(&message).unwrap();
|
||||||
let res: usize = socket.send(&encoded).unwrap();
|
let res: usize = socket.send(&encoded).unwrap();
|
||||||
assert!(res == encoded.len());
|
assert!(res == encoded.len());
|
||||||
@ -282,68 +287,67 @@ pub fn r_snmp_walk(target: &str, oid: &str) -> SnmpResult {
|
|||||||
/// use snmp_rust::r_snmp_bulk_get;
|
/// use snmp_rust::r_snmp_bulk_get;
|
||||||
/// let result = r_snmp_bulk_get("127.0.0.1:161", "2c", "public", "1.3.6.1.2.1.25.3.3.1.2");
|
/// let result = r_snmp_bulk_get("127.0.0.1:161", "2c", "public", "1.3.6.1.2.1.25.3.3.1.2");
|
||||||
/// ```
|
/// ```
|
||||||
pub fn r_snmp_bulk_get(target: &str, _version: &str, community: &str, oid: &str) -> SnmpResult {
|
pub fn r_snmp_bulk_get(
|
||||||
let mut oid_tab = oid
|
target: &str,
|
||||||
.split('.')
|
_version: &str,
|
||||||
.map(|x| x.parse::<u32>().unwrap())
|
community: &str,
|
||||||
.collect::<Vec<u32>>();
|
non_repeaters: u32,
|
||||||
|
max_repetitions: u32,
|
||||||
|
oid: &Vec<&str>,
|
||||||
|
) -> SnmpResult {
|
||||||
|
let mut oids_tab = oid
|
||||||
|
.iter()
|
||||||
|
.map(|x| {
|
||||||
|
x.split('.')
|
||||||
|
.map(|x| x.parse::<u32>().unwrap())
|
||||||
|
.collect::<Vec<u32>>()
|
||||||
|
})
|
||||||
|
.collect::<Vec<Vec<u32>>>();
|
||||||
|
|
||||||
let mut retval = SnmpResult::new();
|
let mut retval = SnmpResult::new();
|
||||||
let mut request_id: i32 = 1;
|
let mut request_id: i32 = 1;
|
||||||
|
|
||||||
let socket = UdpSocket::bind("0.0.0.0:0").unwrap();
|
let socket = UdpSocket::bind("0.0.0.0:0").unwrap();
|
||||||
socket.connect(target).expect("connect function failed");
|
socket.connect(target).expect("connect function failed");
|
||||||
|
let duration = std::time::Duration::from_millis(1000);
|
||||||
|
socket.set_read_timeout(Some(duration)).unwrap();
|
||||||
|
|
||||||
loop {
|
let variable_bindings = oids_tab
|
||||||
let variable_bindings = vec![VarBind {
|
.iter()
|
||||||
name: ObjectIdentifier::new_unchecked(oid_tab.to_vec().into()),
|
.map(|x| VarBind {
|
||||||
|
name: ObjectIdentifier::new_unchecked(x.to_vec().into()),
|
||||||
value: VarBindValue::Unspecified,
|
value: VarBindValue::Unspecified,
|
||||||
}];
|
})
|
||||||
|
.collect::<Vec<VarBind>>();
|
||||||
|
|
||||||
let pdu = BulkPdu {
|
let pdu = BulkPdu {
|
||||||
request_id,
|
request_id,
|
||||||
non_repeaters: 0,
|
non_repeaters,
|
||||||
max_repetitions: 10,
|
max_repetitions,
|
||||||
variable_bindings,
|
variable_bindings,
|
||||||
};
|
};
|
||||||
|
|
||||||
let get_request: GetBulkRequest = GetBulkRequest(pdu);
|
let get_request: GetBulkRequest = GetBulkRequest(pdu);
|
||||||
|
|
||||||
let message: Message<GetBulkRequest> = Message {
|
let message: Message<GetBulkRequest> = Message {
|
||||||
version: 1.into(),
|
version: 1.into(),
|
||||||
community: community.to_string().into(),
|
community: community.to_string().into(),
|
||||||
data: get_request.into(),
|
data: get_request.into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Send the message through an UDP socket
|
// Send the message through an UDP socket
|
||||||
let encoded: Vec<u8> = rasn::der::encode(&message).unwrap();
|
let encoded: Vec<u8> = rasn::der::encode(&message).unwrap();
|
||||||
let res: usize = socket.send(&encoded).unwrap();
|
let res: usize = socket.send(&encoded).unwrap();
|
||||||
assert!(res == encoded.len());
|
assert!(res == encoded.len());
|
||||||
|
|
||||||
let mut buf: [u8; 1024] = [0; 1024];
|
let mut buf: [u8; 1024] = [0; 1024];
|
||||||
let resp: (usize, std::net::SocketAddr) = socket.recv_from(buf.as_mut_slice()).unwrap();
|
let resp: (usize, std::net::SocketAddr) = socket.recv_from(buf.as_mut_slice()).unwrap();
|
||||||
|
|
||||||
trace!("Received {} bytes", resp.0);
|
trace!("Received {} bytes", resp.0);
|
||||||
assert!(resp.0 > 0);
|
assert!(resp.0 > 0);
|
||||||
let decoded: Message<Pdus> = rasn::ber::decode(&buf[0..resp.0]).unwrap();
|
let decoded: Message<Pdus> = rasn::ber::decode(&buf[0..resp.0]).unwrap();
|
||||||
if let Pdus::Response(resp) = &decoded.data {
|
let (result, _completed) = build_response(decoded, false);
|
||||||
let resp_oid = &resp.0.variable_bindings[0].name;
|
retval.concat(result);
|
||||||
let n = resp_oid.len() - 1;
|
|
||||||
}
|
|
||||||
let (result, completed) = build_response(decoded, true);
|
|
||||||
retval.concat(result);
|
|
||||||
if completed {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
oid_tab = retval
|
|
||||||
.variables
|
|
||||||
.last()
|
|
||||||
.unwrap()
|
|
||||||
.name
|
|
||||||
.split('.')
|
|
||||||
.map(|x| x.parse::<u32>().unwrap())
|
|
||||||
.collect::<Vec<u32>>();
|
|
||||||
}
|
|
||||||
retval
|
retval
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,6 +378,8 @@ pub fn r_snmp_bulk_walk(target: &str, _version: &str, community: &str, oid: &str
|
|||||||
|
|
||||||
let socket = UdpSocket::bind("0.0.0.0:0").unwrap();
|
let socket = UdpSocket::bind("0.0.0.0:0").unwrap();
|
||||||
socket.connect(target).expect("connect function failed");
|
socket.connect(target).expect("connect function failed");
|
||||||
|
let duration = std::time::Duration::from_millis(1000);
|
||||||
|
socket.set_read_timeout(Some(duration)).unwrap();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let variable_bindings = vec![VarBind {
|
let variable_bindings = vec![VarBind {
|
||||||
@ -474,11 +480,14 @@ fn build_response(decoded: Message<Pdus>, walk: bool) -> (SnmpResult, bool) {
|
|||||||
// We transform the value into a rust String
|
// We transform the value into a rust String
|
||||||
retval.add_variable(
|
retval.add_variable(
|
||||||
name,
|
name,
|
||||||
SnmpValue::String(String::from_utf8(value.to_vec()).unwrap()),
|
SnmpValue::String(
|
||||||
|
String::from_utf8(value.to_vec()).unwrap(),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
retval.add_variable(name, SnmpValue::String("Other".to_string()));
|
retval
|
||||||
|
.add_variable(name, SnmpValue::String("Other".to_string()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user